From beb7b8245d0b28662a988efb6c856af8fb35d280 Mon Sep 17 00:00:00 2001 From: John Schulz Date: Wed, 5 Aug 2020 07:08:04 -0400 Subject: [PATCH 001/106] [Ingest Manager] prevent crash on unhandled rejection from setupIngestManager (#74300) * Add test to ensure setup rejects if errors thrown. * Return the promise from setup so test passes --- .../server/services/setup.test.ts | 44 +++++++++++++++++++ .../ingest_manager/server/services/setup.ts | 5 +++ 2 files changed, 49 insertions(+) create mode 100644 x-pack/plugins/ingest_manager/server/services/setup.test.ts diff --git a/x-pack/plugins/ingest_manager/server/services/setup.test.ts b/x-pack/plugins/ingest_manager/server/services/setup.test.ts new file mode 100644 index 0000000000000..474b2fde23c81 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/setup.test.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { setupIngestManager } from './setup'; +import { savedObjectsClientMock } from 'src/core/server/mocks'; + +describe('setupIngestManager', () => { + it('returned promise should reject if errors thrown', async () => { + const { savedObjectsClient, callClusterMock } = makeErrorMocks(); + const setupPromise = setupIngestManager(savedObjectsClient, callClusterMock); + await expect(setupPromise).rejects.toThrow('mocked'); + }); +}); + +function makeErrorMocks() { + jest.mock('./app_context'); // else fails w/"Logger not set." + jest.mock('./epm/registry/registry_url', () => { + return { + fetchUrl: () => { + throw new Error('mocked registry#fetchUrl'); + }, + }; + }); + + const callClusterMock = jest.fn(); + const savedObjectsClient = savedObjectsClientMock.create(); + savedObjectsClient.find = jest.fn().mockImplementation(() => { + throw new Error('mocked SO#find'); + }); + savedObjectsClient.get = jest.fn().mockImplementation(() => { + throw new Error('mocked SO#get'); + }); + savedObjectsClient.update = jest.fn().mockImplementation(() => { + throw new Error('mocked SO#update'); + }); + + return { + savedObjectsClient, + callClusterMock, + }; +} diff --git a/x-pack/plugins/ingest_manager/server/services/setup.ts b/x-pack/plugins/ingest_manager/server/services/setup.ts index c91cae98e17d2..4ef093d38879a 100644 --- a/x-pack/plugins/ingest_manager/server/services/setup.ts +++ b/x-pack/plugins/ingest_manager/server/services/setup.ts @@ -127,6 +127,11 @@ export async function setupIngestManager( // if anything errors, reject/fail onSetupReject(error); } + + // be sure to return the promise because it has the resolved/rejected status attached to it + // otherwise, we effectively return success every time even if there are errors + // because `return undefined` -> `Promise.resolve(undefined)` in an `async` function + return setupIngestStatus; } export async function setupFleet( From 8231b0ccfc12f9756dedf16ba7c36d8dcae0769a Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Wed, 5 Aug 2020 13:18:29 +0200 Subject: [PATCH 002/106] [ML] Fix initial plugin's bundle size (#74047) * [ML] use dynamic imports * [ML] fix react-use imports * [ML] change embeddables imports * [ML] embeddable exports * [ML] move SCSS import * [ML] management page styles * [ML] refactor with types and constants files * [ML] move declarations --- .../plugins/ml/public/application/_index.scss | 6 -- x-pack/plugins/ml/public/application/app.tsx | 1 + .../components/data_grid/use_column_chart.tsx | 2 +- .../explorer/add_to_dashboard_control.tsx | 6 +- .../explorer/swimlane_container.tsx | 7 +- .../public/application/management/_index.scss | 1 - .../management/jobs_list/_index.scss | 5 +- .../application/management/jobs_list/index.ts | 1 + .../application/routing/routes/jobs_list.tsx | 2 +- .../routing/routes/timeseriesexplorer.tsx | 2 +- .../public/application/routing/use_refresh.ts | 2 +- .../public/application/util/string_utils.ts | 4 +- .../anomaly_swimlane_embeddable.tsx | 74 +++---------------- ...omaly_swimlane_embeddable_factory.test.tsx | 6 +- .../anomaly_swimlane_embeddable_factory.ts | 28 ++++--- .../anomaly_swimlane_initializer.tsx | 2 +- .../anomaly_swimlane_setup_flyout.tsx | 6 +- .../embeddable_swim_lane_container.test.tsx | 7 +- .../embeddable_swim_lane_container.tsx | 16 ++-- .../embeddables/anomaly_swimlane/index.ts | 1 - .../swimlane_input_resolver.test.ts | 5 +- .../swimlane_input_resolver.ts | 10 +-- .../ml/public/embeddables/constants.ts | 7 ++ x-pack/plugins/ml/public/embeddables/index.ts | 3 + x-pack/plugins/ml/public/embeddables/types.ts | 66 +++++++++++++++++ x-pack/plugins/ml/public/index.scss | 1 - x-pack/plugins/ml/public/index.ts | 1 - x-pack/plugins/ml/public/plugin.ts | 25 +++---- .../apply_influencer_filters_action.tsx | 7 +- .../ui_actions/apply_time_range_action.tsx | 7 +- .../ui_actions/edit_swimlane_panel_action.tsx | 16 ++-- x-pack/plugins/ml/public/ui_actions/index.ts | 10 ++- .../open_in_anomaly_explorer_action.tsx | 7 +- x-pack/plugins/ml/public/url_generator.ts | 12 ++- 34 files changed, 180 insertions(+), 176 deletions(-) delete mode 100644 x-pack/plugins/ml/public/application/management/_index.scss create mode 100644 x-pack/plugins/ml/public/embeddables/constants.ts create mode 100644 x-pack/plugins/ml/public/embeddables/types.ts delete mode 100644 x-pack/plugins/ml/public/index.scss diff --git a/x-pack/plugins/ml/public/application/_index.scss b/x-pack/plugins/ml/public/application/_index.scss index 65e914a1ac923..45b14543946c7 100644 --- a/x-pack/plugins/ml/public/application/_index.scss +++ b/x-pack/plugins/ml/public/application/_index.scss @@ -1,11 +1,6 @@ // ML has it's own variables for coloring @import 'variables'; -// Kibana management page ML section -#kibanaManagementMLSection { - @import 'management/index'; -} - // Protect the rest of Kibana from ML generic namespacing // SASSTODO: Prefix ml selectors instead .ml-app { @@ -24,7 +19,6 @@ // Components @import 'components/annotations/annotation_description_list/index'; // SASSTODO: This file overwrites EUI directly @import 'components/anomalies_table/index'; // SASSTODO: This file overwrites EUI directly - @import 'components/chart_tooltip/index'; @import 'components/color_range_legend/index'; @import 'components/controls/index'; @import 'components/entity_cell/index'; diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx index cc3af9d7f4980..42c462fa9d869 100644 --- a/x-pack/plugins/ml/public/application/app.tsx +++ b/x-pack/plugins/ml/public/application/app.tsx @@ -5,6 +5,7 @@ */ import React, { FC } from 'react'; +import './_index.scss'; import ReactDOM from 'react-dom'; import { AppMountParameters, CoreStart, HttpStart } from 'kibana/public'; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/use_column_chart.tsx b/x-pack/plugins/ml/public/application/components/data_grid/use_column_chart.tsx index a762c44e243bf..6b5fbbb22120d 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/use_column_chart.tsx +++ b/x-pack/plugins/ml/public/application/components/data_grid/use_column_chart.tsx @@ -8,7 +8,7 @@ import moment from 'moment'; import { BehaviorSubject } from 'rxjs'; import React from 'react'; -import { useObservable } from 'react-use'; +import useObservable from 'react-use/lib/useObservable'; import { euiPaletteColorBlind, EuiDataGridColumn } from '@elastic/eui'; diff --git a/x-pack/plugins/ml/public/application/explorer/add_to_dashboard_control.tsx b/x-pack/plugins/ml/public/application/explorer/add_to_dashboard_control.tsx index 3ad749c9d0631..04ce7f79e1c02 100644 --- a/x-pack/plugins/ml/public/application/explorer/add_to_dashboard_control.tsx +++ b/x-pack/plugins/ml/public/application/explorer/add_to_dashboard_control.tsx @@ -25,13 +25,11 @@ import { EuiInMemoryTable } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useMlKibana } from '../contexts/kibana'; import { SavedObjectDashboard } from '../../../../../../src/plugins/dashboard/public'; -import { - ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, - getDefaultPanelTitle, -} from '../../embeddables/anomaly_swimlane/anomaly_swimlane_embeddable'; +import { getDefaultPanelTitle } from '../../embeddables/anomaly_swimlane/anomaly_swimlane_embeddable'; import { useDashboardService } from '../services/dashboard_service'; import { SWIMLANE_TYPE, SwimlaneType } from './explorer_constants'; import { JobId } from '../../../common/types/anomaly_detection_jobs'; +import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE } from '../../embeddables'; export interface DashboardItem { id: string; diff --git a/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx b/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx index 51ea0f00d5f6a..0fefa71dea48b 100644 --- a/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx +++ b/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx @@ -15,12 +15,9 @@ import { } from '@elastic/eui'; import { throttle } from 'lodash'; -import { - ExplorerSwimlane, - ExplorerSwimlaneProps, -} from '../../application/explorer/explorer_swimlane'; +import { ExplorerSwimlane, ExplorerSwimlaneProps } from './explorer_swimlane'; -import { MlTooltipComponent } from '../../application/components/chart_tooltip'; +import { MlTooltipComponent } from '../components/chart_tooltip'; import { SwimLanePagination } from './swimlane_pagination'; import { SWIMLANE_TYPE } from './explorer_constants'; import { ViewBySwimLaneData } from './explorer_utils'; diff --git a/x-pack/plugins/ml/public/application/management/_index.scss b/x-pack/plugins/ml/public/application/management/_index.scss deleted file mode 100644 index e14df2d7c2039..0000000000000 --- a/x-pack/plugins/ml/public/application/management/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'jobs_list/index'; diff --git a/x-pack/plugins/ml/public/application/management/jobs_list/_index.scss b/x-pack/plugins/ml/public/application/management/jobs_list/_index.scss index 841415620d691..d4928a4126c1b 100644 --- a/x-pack/plugins/ml/public/application/management/jobs_list/_index.scss +++ b/x-pack/plugins/ml/public/application/management/jobs_list/_index.scss @@ -1 +1,4 @@ -@import 'components/index'; +// Kibana management page ML section +#kibanaManagementMLSection { + @import 'components/index'; +} diff --git a/x-pack/plugins/ml/public/application/management/jobs_list/index.ts b/x-pack/plugins/ml/public/application/management/jobs_list/index.ts index b16f680a2a362..81190a412abc0 100644 --- a/x-pack/plugins/ml/public/application/management/jobs_list/index.ts +++ b/x-pack/plugins/ml/public/application/management/jobs_list/index.ts @@ -12,6 +12,7 @@ import { MlStartDependencies } from '../../../plugin'; import { JobsListPage } from './components'; import { getJobsListBreadcrumbs } from '../breadcrumbs'; import { setDependencyCache, clearCache } from '../../util/dependency_cache'; +import './_index.scss'; const renderApp = (element: HTMLElement, coreStart: CoreStart) => { ReactDOM.render(React.createElement(JobsListPage, { coreStart }), element); diff --git a/x-pack/plugins/ml/public/application/routing/routes/jobs_list.tsx b/x-pack/plugins/ml/public/application/routing/routes/jobs_list.tsx index db58b6a537e06..38a7900916ba8 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/jobs_list.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/jobs_list.tsx @@ -5,7 +5,7 @@ */ import React, { useEffect, FC } from 'react'; -import { useObservable } from 'react-use'; +import useObservable from 'react-use/lib/useObservable'; import { i18n } from '@kbn/i18n'; import { NavigateToPath } from '../../contexts/kibana'; diff --git a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx index 6486db818e113..1f122ed18a851 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx @@ -6,7 +6,7 @@ import { isEqual } from 'lodash'; import React, { FC, useCallback, useEffect, useState } from 'react'; -import { usePrevious } from 'react-use'; +import usePrevious from 'react-use/lib/usePrevious'; import moment from 'moment'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/plugins/ml/public/application/routing/use_refresh.ts b/x-pack/plugins/ml/public/application/routing/use_refresh.ts index 539ce6f88a421..332677e3c5796 100644 --- a/x-pack/plugins/ml/public/application/routing/use_refresh.ts +++ b/x-pack/plugins/ml/public/application/routing/use_refresh.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useObservable } from 'react-use'; +import useObservable from 'react-use/lib/useObservable'; import { merge } from 'rxjs'; import { map } from 'rxjs/operators'; diff --git a/x-pack/plugins/ml/public/application/util/string_utils.ts b/x-pack/plugins/ml/public/application/util/string_utils.ts index 55dd16082a07c..88900c8b0ce71 100644 --- a/x-pack/plugins/ml/public/application/util/string_utils.ts +++ b/x-pack/plugins/ml/public/application/util/string_utils.ts @@ -7,7 +7,6 @@ /* * Contains utility functions for performing operations on Strings. */ -import _ from 'lodash'; import d3 from 'd3'; import he from 'he'; @@ -28,7 +27,8 @@ export function replaceStringTokens( ) { return String(str).replace(/\$([^?&$\'"]+)\$/g, (match, name) => { // Use lodash get to allow nested JSON fields to be retrieved. - let tokenValue = _.get(valuesByTokenName, name, null); + let tokenValue = + valuesByTokenName && valuesByTokenName[name] !== undefined ? valuesByTokenName[name] : null; if (encodeForURI === true && tokenValue !== null) { tokenValue = encodeURIComponent(tokenValue); } diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx index 9f96b73d67c57..e837cabf0b494 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx @@ -9,29 +9,17 @@ import ReactDOM from 'react-dom'; import { CoreStart } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { Subject } from 'rxjs'; -import { - Embeddable, - EmbeddableInput, - EmbeddableOutput, - IContainer, - IEmbeddable, -} from '../../../../../../src/plugins/embeddable/public'; +import { Embeddable, IContainer } from '../../../../../../src/plugins/embeddable/public'; import { EmbeddableSwimLaneContainer } from './embeddable_swim_lane_container'; -import { AnomalyDetectorService } from '../../application/services/anomaly_detector_service'; import { JobId } from '../../../common/types/anomaly_detection_jobs'; -import { AnomalyTimelineService } from '../../application/services/anomaly_timeline_service'; -import { - Filter, - Query, - RefreshInterval, - TimeRange, -} from '../../../../../../src/plugins/data/common'; -import { SwimlaneType } from '../../application/explorer/explorer_constants'; import { MlDependencies } from '../../application/app'; -import { AppStateSelectedCells } from '../../application/explorer/explorer_utils'; -import { SWIM_LANE_SELECTION_TRIGGER } from '../../ui_actions/triggers'; - -export const ANOMALY_SWIMLANE_EMBEDDABLE_TYPE = 'ml_anomaly_swimlane'; +import { SWIM_LANE_SELECTION_TRIGGER } from '../../ui_actions'; +import { + ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, + AnomalySwimlaneEmbeddableInput, + AnomalySwimlaneEmbeddableOutput, + AnomalySwimlaneServices, +} from '..'; export const getDefaultPanelTitle = (jobIds: JobId[]) => i18n.translate('xpack.ml.swimlaneEmbeddable.title', { @@ -39,51 +27,7 @@ export const getDefaultPanelTitle = (jobIds: JobId[]) => values: { jobIds: jobIds.join(', ') }, }); -export interface AnomalySwimlaneEmbeddableCustomInput { - jobIds: JobId[]; - swimlaneType: SwimlaneType; - viewBy?: string; - perPage?: number; - - // Embeddable inputs which are not included in the default interface - filters: Filter[]; - query: Query; - refreshConfig: RefreshInterval; - timeRange: TimeRange; -} - -export interface EditSwimlanePanelContext { - embeddable: IEmbeddable; -} - -export interface SwimLaneDrilldownContext extends EditSwimlanePanelContext { - /** - * Optional data provided by swim lane selection - */ - data?: AppStateSelectedCells; -} - -export type AnomalySwimlaneEmbeddableInput = EmbeddableInput & AnomalySwimlaneEmbeddableCustomInput; - -export type AnomalySwimlaneEmbeddableOutput = EmbeddableOutput & - AnomalySwimlaneEmbeddableCustomOutput; - -export interface AnomalySwimlaneEmbeddableCustomOutput { - perPage?: number; - fromPage?: number; - interval?: number; -} - -export interface AnomalySwimlaneServices { - anomalyDetectorService: AnomalyDetectorService; - anomalyTimelineService: AnomalyTimelineService; -} - -export type AnomalySwimlaneEmbeddableServices = [ - CoreStart, - MlDependencies, - AnomalySwimlaneServices -]; +export type IAnomalySwimlaneEmbeddable = typeof AnomalySwimlaneEmbeddable; export class AnomalySwimlaneEmbeddable extends Embeddable< AnomalySwimlaneEmbeddableInput, diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.test.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.test.tsx index 243369982ac1f..12813ad6277aa 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.test.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.test.tsx @@ -7,10 +7,8 @@ import { AnomalySwimlaneEmbeddableFactory } from './anomaly_swimlane_embeddable_factory'; import { coreMock } from '../../../../../../src/core/public/mocks'; import { dataPluginMock } from '../../../../../../src/plugins/data/public/mocks'; -import { - AnomalySwimlaneEmbeddable, - AnomalySwimlaneEmbeddableInput, -} from './anomaly_swimlane_embeddable'; +import { AnomalySwimlaneEmbeddable } from './anomaly_swimlane_embeddable'; +import { AnomalySwimlaneEmbeddableInput } from '..'; jest.mock('./anomaly_swimlane_embeddable', () => ({ AnomalySwimlaneEmbeddable: jest.fn(), diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.ts index 14fbf77544b21..9d2fd07e11be5 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.ts @@ -10,23 +10,16 @@ import { StartServicesAccessor } from 'kibana/public'; import { EmbeddableFactoryDefinition, - ErrorEmbeddable, IContainer, } from '../../../../../../src/plugins/embeddable/public'; +import { HttpService } from '../../application/services/http_service'; +import { MlPluginStart, MlStartDependencies } from '../../plugin'; +import { MlDependencies } from '../../application/app'; import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, - AnomalySwimlaneEmbeddable, AnomalySwimlaneEmbeddableInput, AnomalySwimlaneEmbeddableServices, -} from './anomaly_swimlane_embeddable'; -import { HttpService } from '../../application/services/http_service'; -import { AnomalyDetectorService } from '../../application/services/anomaly_detector_service'; -import { AnomalyTimelineService } from '../../application/services/anomaly_timeline_service'; -import { mlResultsServiceProvider } from '../../application/services/results_service'; -import { resolveAnomalySwimlaneUserInput } from './anomaly_swimlane_setup_flyout'; -import { mlApiServicesProvider } from '../../application/services/ml_api_service'; -import { MlPluginStart, MlStartDependencies } from '../../plugin'; -import { MlDependencies } from '../../application/app'; +} from '..'; export class AnomalySwimlaneEmbeddableFactory implements EmbeddableFactoryDefinition { @@ -50,6 +43,7 @@ export class AnomalySwimlaneEmbeddableFactory const [coreStart] = await this.getServices(); try { + const { resolveAnomalySwimlaneUserInput } = await import('./anomaly_swimlane_setup_flyout'); return await resolveAnomalySwimlaneUserInput(coreStart); } catch (e) { return Promise.reject(); @@ -59,6 +53,15 @@ export class AnomalySwimlaneEmbeddableFactory private async getServices(): Promise { const [coreStart, pluginsStart] = await this.getStartServices(); + const { AnomalyDetectorService } = await import( + '../../application/services/anomaly_detector_service' + ); + const { AnomalyTimelineService } = await import( + '../../application/services/anomaly_timeline_service' + ); + const { mlApiServicesProvider } = await import('../../application/services/ml_api_service'); + const { mlResultsServiceProvider } = await import('../../application/services/results_service'); + const httpService = new HttpService(coreStart.http); const anomalyDetectorService = new AnomalyDetectorService(httpService); const anomalyTimelineService = new AnomalyTimelineService( @@ -77,8 +80,9 @@ export class AnomalySwimlaneEmbeddableFactory public async create( initialInput: AnomalySwimlaneEmbeddableInput, parent?: IContainer - ): Promise { + ): Promise { const services = await this.getServices(); + const { AnomalySwimlaneEmbeddable } = await import('./anomaly_swimlane_embeddable'); return new AnomalySwimlaneEmbeddable(initialInput, services, parent); } } diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_initializer.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_initializer.tsx index e5a13adca05db..026d4e225f45b 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_initializer.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_initializer.tsx @@ -22,7 +22,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { SWIMLANE_TYPE, SwimlaneType } from '../../application/explorer/explorer_constants'; -import { AnomalySwimlaneEmbeddableInput } from './anomaly_swimlane_embeddable'; +import { AnomalySwimlaneEmbeddableInput } from '..'; export interface AnomalySwimlaneInitializerProps { defaultTitle: string; diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_setup_flyout.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_setup_flyout.tsx index 1ffdadb60aaa3..3a3597a7fa927 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_setup_flyout.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_setup_flyout.tsx @@ -16,12 +16,10 @@ import { AnomalySwimlaneInitializer } from './anomaly_swimlane_initializer'; import { JobSelectorFlyout } from '../../application/components/job_selector/job_selector_flyout'; import { AnomalyDetectorService } from '../../application/services/anomaly_detector_service'; import { getInitialGroupsMap } from '../../application/components/job_selector/job_selector'; -import { - AnomalySwimlaneEmbeddableInput, - getDefaultPanelTitle, -} from './anomaly_swimlane_embeddable'; +import { getDefaultPanelTitle } from './anomaly_swimlane_embeddable'; import { getMlGlobalServices } from '../../application/app'; import { HttpService } from '../../application/services/http_service'; +import { AnomalySwimlaneEmbeddableInput } from '..'; export async function resolveAnomalySwimlaneUserInput( coreStart: CoreStart, diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.test.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.test.tsx index 23045834eae5f..ff621953cc577 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.test.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.test.tsx @@ -12,11 +12,7 @@ import { } from './embeddable_swim_lane_container'; import { BehaviorSubject, Observable } from 'rxjs'; import { I18nProvider } from '@kbn/i18n/react'; -import { - AnomalySwimlaneEmbeddable, - AnomalySwimlaneEmbeddableInput, - AnomalySwimlaneServices, -} from './anomaly_swimlane_embeddable'; +import { AnomalySwimlaneEmbeddable } from './anomaly_swimlane_embeddable'; import { CoreStart } from 'kibana/public'; import { useSwimlaneInputResolver } from './swimlane_input_resolver'; import { SWIMLANE_TYPE } from '../../application/explorer/explorer_constants'; @@ -25,6 +21,7 @@ import { MlDependencies } from '../../application/app'; import { uiActionsPluginMock } from 'src/plugins/ui_actions/public/mocks'; import { TriggerContract } from 'src/plugins/ui_actions/public/triggers'; import { TriggerId } from 'src/plugins/ui_actions/public'; +import { AnomalySwimlaneEmbeddableInput, AnomalySwimlaneServices } from '..'; jest.mock('./swimlane_input_resolver', () => ({ useSwimlaneInputResolver: jest.fn(() => { diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx index 8ee4e391fcdde..60681446ac7aa 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx @@ -10,12 +10,7 @@ import { Observable } from 'rxjs'; import { CoreStart } from 'kibana/public'; import { FormattedMessage } from '@kbn/i18n/react'; -import { - AnomalySwimlaneEmbeddable, - AnomalySwimlaneEmbeddableInput, - AnomalySwimlaneEmbeddableOutput, - AnomalySwimlaneServices, -} from './anomaly_swimlane_embeddable'; +import { IAnomalySwimlaneEmbeddable } from './anomaly_swimlane_embeddable'; import { useSwimlaneInputResolver } from './swimlane_input_resolver'; import { SwimlaneType } from '../../application/explorer/explorer_constants'; import { @@ -24,11 +19,16 @@ import { } from '../../application/explorer/swimlane_container'; import { AppStateSelectedCells } from '../../application/explorer/explorer_utils'; import { MlDependencies } from '../../application/app'; -import { SWIM_LANE_SELECTION_TRIGGER } from '../../ui_actions/triggers'; +import { SWIM_LANE_SELECTION_TRIGGER } from '../../ui_actions'; +import { + AnomalySwimlaneEmbeddableInput, + AnomalySwimlaneEmbeddableOutput, + AnomalySwimlaneServices, +} from '..'; export interface ExplorerSwimlaneContainerProps { id: string; - embeddableContext: AnomalySwimlaneEmbeddable; + embeddableContext: InstanceType; embeddableInput: Observable; services: [CoreStart, MlDependencies, AnomalySwimlaneServices]; refresh: Observable; diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/index.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/index.ts index c0b02960d5144..ba2e1c88b3ea8 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/index.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/index.ts @@ -5,4 +5,3 @@ */ export { AnomalySwimlaneEmbeddableFactory } from './anomaly_swimlane_embeddable_factory'; -export { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE } from './anomaly_swimlane_embeddable'; diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.test.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.test.ts index a34955adebf62..258b72067cddd 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.test.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.test.ts @@ -8,12 +8,9 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { processFilters, useSwimlaneInputResolver } from './swimlane_input_resolver'; import { BehaviorSubject, Observable, of, Subject } from 'rxjs'; import { SWIMLANE_TYPE } from '../../application/explorer/explorer_constants'; -import { - AnomalySwimlaneEmbeddableInput, - AnomalySwimlaneServices, -} from './anomaly_swimlane_embeddable'; import { CoreStart, IUiSettingsClient } from 'kibana/public'; import { MlStartDependencies } from '../../plugin'; +import { AnomalySwimlaneEmbeddableInput, AnomalySwimlaneServices } from '..'; describe('useSwimlaneInputResolver', () => { let embeddableInput: BehaviorSubject>; diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts index f17c779a00252..6ddb1e954e57b 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts @@ -20,11 +20,6 @@ import { } from 'rxjs/operators'; import { CoreStart } from 'kibana/public'; import { TimeBuckets } from '../../application/util/time_buckets'; -import { - AnomalySwimlaneEmbeddableInput, - AnomalySwimlaneEmbeddableOutput, - AnomalySwimlaneServices, -} from './anomaly_swimlane_embeddable'; import { MlStartDependencies } from '../../plugin'; import { ANOMALY_SWIM_LANE_HARD_LIMIT, @@ -41,6 +36,11 @@ import { AnomalyDetectorService } from '../../application/services/anomaly_detec import { isViewBySwimLaneData } from '../../application/explorer/swimlane_container'; import { ViewMode } from '../../../../../../src/plugins/embeddable/public'; import { CONTROLLED_BY_SWIM_LANE_FILTER } from '../../ui_actions/apply_influencer_filters_action'; +import { + AnomalySwimlaneEmbeddableInput, + AnomalySwimlaneEmbeddableOutput, + AnomalySwimlaneServices, +} from '..'; const FETCH_RESULTS_DEBOUNCE_MS = 500; diff --git a/x-pack/plugins/ml/public/embeddables/constants.ts b/x-pack/plugins/ml/public/embeddables/constants.ts new file mode 100644 index 0000000000000..054cb8ba4b0bc --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/constants.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const ANOMALY_SWIMLANE_EMBEDDABLE_TYPE = 'ml_anomaly_swimlane'; diff --git a/x-pack/plugins/ml/public/embeddables/index.ts b/x-pack/plugins/ml/public/embeddables/index.ts index db9f094d5721e..cc4bec0b67836 100644 --- a/x-pack/plugins/ml/public/embeddables/index.ts +++ b/x-pack/plugins/ml/public/embeddables/index.ts @@ -8,6 +8,9 @@ import { AnomalySwimlaneEmbeddableFactory } from './anomaly_swimlane'; import { MlCoreSetup } from '../plugin'; import { EmbeddableSetup } from '../../../../../src/plugins/embeddable/public'; +export * from './constants'; +export * from './types'; + export function registerEmbeddables(embeddable: EmbeddableSetup, core: MlCoreSetup) { const anomalySwimlaneEmbeddableFactory = new AnomalySwimlaneEmbeddableFactory( core.getStartServices diff --git a/x-pack/plugins/ml/public/embeddables/types.ts b/x-pack/plugins/ml/public/embeddables/types.ts new file mode 100644 index 0000000000000..93ec79d9b8310 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/types.ts @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CoreStart } from 'kibana/public'; +import { JobId } from '../../common/types/anomaly_detection_jobs'; +import { SwimlaneType } from '../application/explorer/explorer_constants'; +import { Filter } from '../../../../../src/plugins/data/common/es_query/filters'; +import { Query, RefreshInterval, TimeRange } from '../../../../../src/plugins/data/common/query'; +import { + EmbeddableInput, + EmbeddableOutput, + IEmbeddable, +} from '../../../../../src/plugins/embeddable/public'; +import { AnomalyDetectorService } from '../application/services/anomaly_detector_service'; +import { AnomalyTimelineService } from '../application/services/anomaly_timeline_service'; +import { MlDependencies } from '../application/app'; +import { AppStateSelectedCells } from '../application/explorer/explorer_utils'; + +export interface AnomalySwimlaneEmbeddableCustomInput { + jobIds: JobId[]; + swimlaneType: SwimlaneType; + viewBy?: string; + perPage?: number; + + // Embeddable inputs which are not included in the default interface + filters: Filter[]; + query: Query; + refreshConfig: RefreshInterval; + timeRange: TimeRange; +} + +export type AnomalySwimlaneEmbeddableInput = EmbeddableInput & AnomalySwimlaneEmbeddableCustomInput; + +export interface AnomalySwimlaneServices { + anomalyDetectorService: AnomalyDetectorService; + anomalyTimelineService: AnomalyTimelineService; +} + +export type AnomalySwimlaneEmbeddableServices = [ + CoreStart, + MlDependencies, + AnomalySwimlaneServices +]; + +export interface AnomalySwimlaneEmbeddableCustomOutput { + perPage?: number; + fromPage?: number; + interval?: number; +} + +export type AnomalySwimlaneEmbeddableOutput = EmbeddableOutput & + AnomalySwimlaneEmbeddableCustomOutput; + +export interface EditSwimlanePanelContext { + embeddable: IEmbeddable; +} + +export interface SwimLaneDrilldownContext extends EditSwimlanePanelContext { + /** + * Optional data provided by swim lane selection + */ + data?: AppStateSelectedCells; +} diff --git a/x-pack/plugins/ml/public/index.scss b/x-pack/plugins/ml/public/index.scss deleted file mode 100644 index 9bd47b6473372..0000000000000 --- a/x-pack/plugins/ml/public/index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './application/index'; diff --git a/x-pack/plugins/ml/public/index.ts b/x-pack/plugins/ml/public/index.ts index 5a956651c86d8..80308977735d2 100755 --- a/x-pack/plugins/ml/public/index.ts +++ b/x-pack/plugins/ml/public/index.ts @@ -5,7 +5,6 @@ */ import { PluginInitializer, PluginInitializerContext } from 'kibana/public'; -import './index.scss'; import { MlPlugin, MlPluginSetup, diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index a8e1e804c2fe3..aa6163379f9c0 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -6,36 +6,35 @@ import { i18n } from '@kbn/i18n'; import { - Plugin, - CoreStart, - CoreSetup, AppMountParameters, + CoreSetup, + CoreStart, + Plugin, PluginInitializerContext, } from 'kibana/public'; import { BehaviorSubject } from 'rxjs'; import { take } from 'rxjs/operators'; import { ManagementSetup } from 'src/plugins/management/public'; -import { SharePluginSetup, SharePluginStart, UrlGeneratorState } from 'src/plugins/share/public'; +import { SharePluginSetup, SharePluginStart } from 'src/plugins/share/public'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { DataPublicPluginStart } from 'src/plugins/data/public'; import { HomePublicPluginSetup } from 'src/plugins/home/public'; import { EmbeddableSetup } from 'src/plugins/embeddable/public'; -import { AppStatus, AppUpdater } from '../../../../src/core/public'; +import { AppStatus, AppUpdater, DEFAULT_APP_CATEGORIES } from '../../../../src/core/public'; import { SecurityPluginSetup } from '../../security/public'; import { LicensingPluginSetup } from '../../licensing/public'; import { registerManagementSection } from './application/management'; import { LicenseManagementUIPluginSetup } from '../../license_management/public'; import { setDependencyCache } from './application/util/dependency_cache'; -import { PLUGIN_ID, PLUGIN_ICON } from '../common/constants/app'; +import { PLUGIN_ICON, PLUGIN_ID } from '../common/constants/app'; import { registerFeature } from './register_feature'; -import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public'; -import { registerEmbeddables } from './embeddables'; import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public'; import { registerMlUiActions } from './ui_actions'; import { KibanaLegacyStart } from '../../../../src/plugins/kibana_legacy/public'; -import { registerUrlGenerator, MlUrlGeneratorState, ML_APP_URL_GENERATOR } from './url_generator'; -import { isMlEnabled, isFullLicense } from '../common/license'; +import { registerUrlGenerator } from './url_generator'; +import { isFullLicense, isMlEnabled } from '../common/license'; +import { registerEmbeddables } from './embeddables'; export interface MlStartDependencies { data: DataPublicPluginStart; @@ -56,12 +55,6 @@ export interface MlSetupDependencies { share: SharePluginSetup; } -declare module '../../../../src/plugins/share/public' { - export interface UrlGeneratorStateMapping { - [ML_APP_URL_GENERATOR]: UrlGeneratorState; - } -} - export type MlCoreSetup = CoreSetup; export class MlPlugin implements Plugin { diff --git a/x-pack/plugins/ml/public/ui_actions/apply_influencer_filters_action.tsx b/x-pack/plugins/ml/public/ui_actions/apply_influencer_filters_action.tsx index 3af39993d39fd..9e50410751c37 100644 --- a/x-pack/plugins/ml/public/ui_actions/apply_influencer_filters_action.tsx +++ b/x-pack/plugins/ml/public/ui_actions/apply_influencer_filters_action.tsx @@ -6,13 +6,10 @@ import { i18n } from '@kbn/i18n'; import { ActionContextMapping, createAction } from '../../../../../src/plugins/ui_actions/public'; -import { - AnomalySwimlaneEmbeddable, - SwimLaneDrilldownContext, -} from '../embeddables/anomaly_swimlane/anomaly_swimlane_embeddable'; import { MlCoreSetup } from '../plugin'; import { SWIMLANE_TYPE, VIEW_BY_JOB_LABEL } from '../application/explorer/explorer_constants'; import { Filter, FilterStateStore } from '../../../../../src/plugins/data/common'; +import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, SwimLaneDrilldownContext } from '../embeddables'; export const APPLY_INFLUENCER_FILTERS_ACTION = 'applyInfluencerFiltersAction'; @@ -73,7 +70,7 @@ export function createApplyInfluencerFiltersAction( async isCompatible({ embeddable, data }: SwimLaneDrilldownContext) { // Only compatible with view by influencer swim lanes and single selection return ( - embeddable instanceof AnomalySwimlaneEmbeddable && + embeddable.type === ANOMALY_SWIMLANE_EMBEDDABLE_TYPE && data !== undefined && data.type === SWIMLANE_TYPE.VIEW_BY && data.viewByFieldName !== VIEW_BY_JOB_LABEL && diff --git a/x-pack/plugins/ml/public/ui_actions/apply_time_range_action.tsx b/x-pack/plugins/ml/public/ui_actions/apply_time_range_action.tsx index ec59ba20acf98..325e903de0e2d 100644 --- a/x-pack/plugins/ml/public/ui_actions/apply_time_range_action.tsx +++ b/x-pack/plugins/ml/public/ui_actions/apply_time_range_action.tsx @@ -7,11 +7,8 @@ import { i18n } from '@kbn/i18n'; import moment from 'moment'; import { ActionContextMapping, createAction } from '../../../../../src/plugins/ui_actions/public'; -import { - AnomalySwimlaneEmbeddable, - SwimLaneDrilldownContext, -} from '../embeddables/anomaly_swimlane/anomaly_swimlane_embeddable'; import { MlCoreSetup } from '../plugin'; +import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, SwimLaneDrilldownContext } from '../embeddables'; export const APPLY_TIME_RANGE_SELECTION_ACTION = 'applyTimeRangeSelectionAction'; @@ -52,7 +49,7 @@ export function createApplyTimeRangeSelectionAction( }); }, async isCompatible({ embeddable, data }: SwimLaneDrilldownContext) { - return embeddable instanceof AnomalySwimlaneEmbeddable && data !== undefined; + return embeddable.type === ANOMALY_SWIMLANE_EMBEDDABLE_TYPE && data !== undefined; }, }); } diff --git a/x-pack/plugins/ml/public/ui_actions/edit_swimlane_panel_action.tsx b/x-pack/plugins/ml/public/ui_actions/edit_swimlane_panel_action.tsx index cfd90f92e3238..c40d1e175ec77 100644 --- a/x-pack/plugins/ml/public/ui_actions/edit_swimlane_panel_action.tsx +++ b/x-pack/plugins/ml/public/ui_actions/edit_swimlane_panel_action.tsx @@ -6,13 +6,9 @@ import { i18n } from '@kbn/i18n'; import { ActionContextMapping, createAction } from '../../../../../src/plugins/ui_actions/public'; -import { - AnomalySwimlaneEmbeddable, - EditSwimlanePanelContext, -} from '../embeddables/anomaly_swimlane/anomaly_swimlane_embeddable'; -import { resolveAnomalySwimlaneUserInput } from '../embeddables/anomaly_swimlane/anomaly_swimlane_setup_flyout'; import { ViewMode } from '../../../../../src/plugins/embeddable/public'; import { MlCoreSetup } from '../plugin'; +import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, EditSwimlanePanelContext } from '../embeddables'; export const EDIT_SWIMLANE_PANEL_ACTION = 'editSwimlanePanelAction'; @@ -27,7 +23,7 @@ export function createEditSwimlanePanelAction(getStartServices: MlCoreSetup['get i18n.translate('xpack.ml.actions.editSwimlaneTitle', { defaultMessage: 'Edit swim lane', }), - execute: async ({ embeddable }: EditSwimlanePanelContext) => { + async execute({ embeddable }: EditSwimlanePanelContext) { if (!embeddable) { throw new Error('Not possible to execute an action without the embeddable context'); } @@ -35,15 +31,19 @@ export function createEditSwimlanePanelAction(getStartServices: MlCoreSetup['get const [coreStart] = await getStartServices(); try { + const { resolveAnomalySwimlaneUserInput } = await import( + '../embeddables/anomaly_swimlane/anomaly_swimlane_setup_flyout' + ); + const result = await resolveAnomalySwimlaneUserInput(coreStart, embeddable.getInput()); embeddable.updateInput(result); } catch (e) { return Promise.reject(); } }, - isCompatible: async ({ embeddable }: EditSwimlanePanelContext) => { + async isCompatible({ embeddable }: EditSwimlanePanelContext) { return ( - embeddable instanceof AnomalySwimlaneEmbeddable && + embeddable.type === ANOMALY_SWIMLANE_EMBEDDABLE_TYPE && embeddable.getInput().viewMode === ViewMode.EDIT ); }, diff --git a/x-pack/plugins/ml/public/ui_actions/index.ts b/x-pack/plugins/ml/public/ui_actions/index.ts index b7262a330b310..437a38acf6f8b 100644 --- a/x-pack/plugins/ml/public/ui_actions/index.ts +++ b/x-pack/plugins/ml/public/ui_actions/index.ts @@ -13,7 +13,6 @@ import { createOpenInExplorerAction, OPEN_IN_ANOMALY_EXPLORER_ACTION, } from './open_in_anomaly_explorer_action'; -import { EditSwimlanePanelContext } from '../embeddables/anomaly_swimlane/anomaly_swimlane_embeddable'; import { UiActionsSetup } from '../../../../../src/plugins/ui_actions/public'; import { MlPluginStart, MlStartDependencies } from '../plugin'; import { CONTEXT_MENU_TRIGGER } from '../../../../../src/plugins/embeddable/public'; @@ -22,11 +21,18 @@ import { createApplyInfluencerFiltersAction, } from './apply_influencer_filters_action'; import { SWIM_LANE_SELECTION_TRIGGER, swimLaneSelectionTrigger } from './triggers'; -import { SwimLaneDrilldownContext } from '../embeddables/anomaly_swimlane/anomaly_swimlane_embeddable'; import { APPLY_TIME_RANGE_SELECTION_ACTION, createApplyTimeRangeSelectionAction, } from './apply_time_range_action'; +import { EditSwimlanePanelContext, SwimLaneDrilldownContext } from '../embeddables'; + +export { APPLY_TIME_RANGE_SELECTION_ACTION } from './apply_time_range_action'; +export { EDIT_SWIMLANE_PANEL_ACTION } from './edit_swimlane_panel_action'; +export { APPLY_INFLUENCER_FILTERS_ACTION } from './apply_influencer_filters_action'; +export { OPEN_IN_ANOMALY_EXPLORER_ACTION } from './open_in_anomaly_explorer_action'; + +export { SWIM_LANE_SELECTION_TRIGGER } from './triggers'; /** * Register ML UI actions diff --git a/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx b/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx index 211840467e38c..e18f593145f9c 100644 --- a/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx +++ b/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx @@ -6,12 +6,9 @@ import { i18n } from '@kbn/i18n'; import { ActionContextMapping, createAction } from '../../../../../src/plugins/ui_actions/public'; -import { - AnomalySwimlaneEmbeddable, - SwimLaneDrilldownContext, -} from '../embeddables/anomaly_swimlane/anomaly_swimlane_embeddable'; import { MlCoreSetup } from '../plugin'; import { ML_APP_URL_GENERATOR } from '../url_generator'; +import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, SwimLaneDrilldownContext } from '../embeddables'; export const OPEN_IN_ANOMALY_EXPLORER_ACTION = 'openInAnomalyExplorerAction'; @@ -60,7 +57,7 @@ export function createOpenInExplorerAction(getStartServices: MlCoreSetup['getSta await application.navigateToUrl(anomalyExplorerUrl!); }, async isCompatible({ embeddable }: SwimLaneDrilldownContext) { - return embeddable instanceof AnomalySwimlaneEmbeddable; + return embeddable.type === ANOMALY_SWIMLANE_EMBEDDABLE_TYPE; }, }); } diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index b7cf64159a827..4e08c57c0b2e0 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -5,13 +5,23 @@ */ import { CoreSetup } from 'kibana/public'; -import { SharePluginSetup, UrlGeneratorsDefinition } from '../../../../src/plugins/share/public'; +import { + SharePluginSetup, + UrlGeneratorsDefinition, + UrlGeneratorState, +} from '../../../../src/plugins/share/public'; import { TimeRange } from '../../../../src/plugins/data/public'; import { setStateToKbnUrl } from '../../../../src/plugins/kibana_utils/public'; import { JobId } from '../../reporting/common/types'; import { ExplorerAppState } from './application/explorer/explorer_dashboard_service'; import { MlStartDependencies } from './plugin'; +declare module '../../../../src/plugins/share/public' { + export interface UrlGeneratorStateMapping { + [ML_APP_URL_GENERATOR]: UrlGeneratorState; + } +} + export const ML_APP_URL_GENERATOR = 'ML_APP_URL_GENERATOR'; export interface ExplorerUrlState { From b26bd6175d11d52c577e62ebfc3186dea9d7ec58 Mon Sep 17 00:00:00 2001 From: Sonja Krause-Harder Date: Wed, 5 Aug 2020 13:48:11 +0200 Subject: [PATCH 003/106] [Ingest Manager] Adjust dataset aggs to use datastream fields instead (#74342) * [Ingest Manager] Adjust dataset aggs to use datastream fields instead Elastic Agent and Elasticsearch are switching over from using dataset.* to datastream.*. This adjust the aggregation on the dataset page to get the datastreams. For this to work properly, the most recent version of Elasticsearch 7.9 must be used and is pending updates on all the packages to ship also the datastream fields, see https://github.com/elastic/integrations/pull/213 * Update datastream to data_stream * Update data stream name generation * Fix typo * Temporarily use datastream instead of data_stream * updating to use `data_stream` instead of `datastream` Co-authored-by: ruflin Co-authored-by: Jen Huang --- .../server/routes/data_streams/handlers.ts | 10 +++++----- .../services/epm/elasticsearch/template/template.ts | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/routes/data_streams/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/data_streams/handlers.ts index df37aeb27c75c..43ae2b72f6077 100644 --- a/x-pack/plugins/ingest_manager/server/routes/data_streams/handlers.ts +++ b/x-pack/plugins/ingest_manager/server/routes/data_streams/handlers.ts @@ -31,12 +31,12 @@ export const getListHandler: RequestHandler = async (context, request, response) must: [ { exists: { - field: 'dataset.namespace', + field: 'data_stream.namespace', }, }, { exists: { - field: 'dataset.name', + field: 'data_stream.dataset', }, }, ], @@ -54,19 +54,19 @@ export const getListHandler: RequestHandler = async (context, request, response) aggs: { dataset: { terms: { - field: 'dataset.name', + field: 'data_stream.dataset', size: 1, }, }, namespace: { terms: { - field: 'dataset.namespace', + field: 'data_stream.namespace', size: 1, }, }, type: { terms: { - field: 'dataset.type', + field: 'data_stream.type', size: 1, }, }, diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts index a739806d5868b..71e49acf1766f 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts @@ -393,14 +393,14 @@ const updateExistingIndex = async ({ // are added in https://github.com/elastic/kibana/issues/66551. namespace value we will continue // to skip updating and assume the value in the index mapping is correct delete mappings.properties.stream; - delete mappings.properties.dataset; + delete mappings.properties.data_stream; - // get the dataset values from the index template to compose data stream name + // get the data_stream values from the index template to compose data stream name const indexMappings = await getIndexMappings(indexName, callCluster); - const dataset = indexMappings[indexName].mappings.properties.dataset.properties; - if (!dataset.type.value || !dataset.name.value || !dataset.namespace.value) - throw new Error(`dataset values are missing from the index template ${indexName}`); - const dataStreamName = `${dataset.type.value}-${dataset.name.value}-${dataset.namespace.value}`; + const dataStream = indexMappings[indexName].mappings.properties.data_stream.properties; + if (!dataStream.type.value || !dataStream.dataset.value || !dataStream.namespace.value) + throw new Error(`data_stream values are missing from the index template ${indexName}`); + const dataStreamName = `${dataStream.type.value}-${dataStream.dataset.value}-${dataStream.namespace.value}`; // try to update the mappings first try { From 7a1b09dcf1189ef9b5c950678d36ac0844572140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Wed, 5 Aug 2020 13:28:13 +0100 Subject: [PATCH 004/106] [APM] Average for transaction error rate includes null values (#74345) --- .../shared/charts/ErroneousTransactionsRateChart/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/apm/public/components/shared/charts/ErroneousTransactionsRateChart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/ErroneousTransactionsRateChart/index.tsx index a433b0b507239..8214c081e6ce1 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/ErroneousTransactionsRateChart/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/ErroneousTransactionsRateChart/index.tsx @@ -6,7 +6,6 @@ import { EuiTitle } from '@elastic/eui'; import theme from '@elastic/eui/dist/eui_theme_light.json'; import { i18n } from '@kbn/i18n'; -import { mean } from 'lodash'; import React, { useCallback } from 'react'; import { EuiPanel } from '@elastic/eui'; import { useChartsSync } from '../../../../hooks/useChartsSync'; @@ -79,7 +78,7 @@ export function ErroneousTransactionsRateChart() { { color: theme.euiColorVis7, data: [], - legendValue: tickFormatY(mean(errorRates.map((rate) => rate.y))), + legendValue: tickFormatY(data?.average), legendClickDisabled: true, title: i18n.translate('xpack.apm.errorRateChart.avgLabel', { defaultMessage: 'Avg.', From f9fc83fb1d0b2e44c4a080ef7e96f7123072fd96 Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Wed, 5 Aug 2020 14:28:56 +0200 Subject: [PATCH 005/106] Add README files for Kibana app plugins (#74277) * Add README files for Kibana app plugins * Update src/plugins/timelion/README.md Co-authored-by: Matthias Wilhelm * Update src/plugins/vis_type_vislib/README.md Co-authored-by: Matthias Wilhelm Co-authored-by: Matthias Wilhelm --- .github/CODEOWNERS | 1 - src/plugins/dashboard/README.md | 1 + src/plugins/discover/README.md | 1 + src/plugins/input_control_vis/README.md | 1 + src/plugins/timelion/README.md | 2 ++ src/plugins/vis_type_markdown/README.md | 1 + src/plugins/vis_type_metric/README.md | 1 + src/plugins/vis_type_table/README.md | 1 + src/plugins/vis_type_tagcloud/README.md | 1 + src/plugins/vis_type_timelion/README.md | 2 ++ src/plugins/vis_type_timeseries/README.md | 1 + src/plugins/vis_type_vega/README.md | 1 + src/plugins/vis_type_vislib/README.md | 2 ++ src/plugins/vis_type_xy/README.md | 2 ++ src/plugins/visualizations/README.md | 2 ++ src/plugins/visualize/README.md | 2 ++ x-pack/plugins/dashboard_enhanced/README.md | 2 +- x-pack/plugins/dashboard_mode/README.md | 1 + x-pack/plugins/discover_enhanced/README.md | 1 + 19 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/plugins/dashboard/README.md create mode 100644 src/plugins/discover/README.md create mode 100644 src/plugins/input_control_vis/README.md create mode 100644 src/plugins/timelion/README.md create mode 100644 src/plugins/vis_type_markdown/README.md create mode 100644 src/plugins/vis_type_metric/README.md create mode 100644 src/plugins/vis_type_table/README.md create mode 100644 src/plugins/vis_type_tagcloud/README.md create mode 100644 src/plugins/vis_type_timeseries/README.md create mode 100644 src/plugins/vis_type_vega/README.md create mode 100644 src/plugins/vis_type_vislib/README.md create mode 100644 src/plugins/vis_type_xy/README.md create mode 100644 src/plugins/visualizations/README.md create mode 100644 src/plugins/visualize/README.md create mode 100644 x-pack/plugins/dashboard_mode/README.md create mode 100644 x-pack/plugins/discover_enhanced/README.md diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f1a374445657f..73fb10532fd8d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -7,7 +7,6 @@ /x-pack/plugins/discover_enhanced/ @elastic/kibana-app /x-pack/plugins/lens/ @elastic/kibana-app /x-pack/plugins/graph/ @elastic/kibana-app -/src/legacy/core_plugins/kibana/public/local_application_service/ @elastic/kibana-app /src/plugins/dashboard/ @elastic/kibana-app /src/plugins/discover/ @elastic/kibana-app /src/plugins/input_control_vis/ @elastic/kibana-app diff --git a/src/plugins/dashboard/README.md b/src/plugins/dashboard/README.md new file mode 100644 index 0000000000000..f44bd943eaca9 --- /dev/null +++ b/src/plugins/dashboard/README.md @@ -0,0 +1 @@ +Contains the dashboard application. \ No newline at end of file diff --git a/src/plugins/discover/README.md b/src/plugins/discover/README.md new file mode 100644 index 0000000000000..a914d651eef35 --- /dev/null +++ b/src/plugins/discover/README.md @@ -0,0 +1 @@ +Contains the Discover application and the saved search embeddable. \ No newline at end of file diff --git a/src/plugins/input_control_vis/README.md b/src/plugins/input_control_vis/README.md new file mode 100644 index 0000000000000..67266079dede5 --- /dev/null +++ b/src/plugins/input_control_vis/README.md @@ -0,0 +1 @@ +Contains the input control visualization allowing to place custom filter controls on a dashboard. \ No newline at end of file diff --git a/src/plugins/timelion/README.md b/src/plugins/timelion/README.md new file mode 100644 index 0000000000000..d29a33028e967 --- /dev/null +++ b/src/plugins/timelion/README.md @@ -0,0 +1,2 @@ +Contains the deprecated timelion application. For the timelion visualization, +which also contains the timelion APIs and backend, look at the vis_type_timelion plugin. diff --git a/src/plugins/vis_type_markdown/README.md b/src/plugins/vis_type_markdown/README.md new file mode 100644 index 0000000000000..ae79a4822d4ac --- /dev/null +++ b/src/plugins/vis_type_markdown/README.md @@ -0,0 +1 @@ +The markdown visualization that can be used to place text panels on dashboards. \ No newline at end of file diff --git a/src/plugins/vis_type_metric/README.md b/src/plugins/vis_type_metric/README.md new file mode 100644 index 0000000000000..78df92832bdbf --- /dev/null +++ b/src/plugins/vis_type_metric/README.md @@ -0,0 +1 @@ +Contains the metric visualization. \ No newline at end of file diff --git a/src/plugins/vis_type_table/README.md b/src/plugins/vis_type_table/README.md new file mode 100644 index 0000000000000..cf37e133ed1cf --- /dev/null +++ b/src/plugins/vis_type_table/README.md @@ -0,0 +1 @@ +Contains the data table visualization, that allows presenting data in a simple table format. \ No newline at end of file diff --git a/src/plugins/vis_type_tagcloud/README.md b/src/plugins/vis_type_tagcloud/README.md new file mode 100644 index 0000000000000..7e8f2a6e5b72a --- /dev/null +++ b/src/plugins/vis_type_tagcloud/README.md @@ -0,0 +1 @@ +Contains the tagcloud visualization. \ No newline at end of file diff --git a/src/plugins/vis_type_timelion/README.md b/src/plugins/vis_type_timelion/README.md index c306e03abf2c6..89d34527c51d6 100644 --- a/src/plugins/vis_type_timelion/README.md +++ b/src/plugins/vis_type_timelion/README.md @@ -1,5 +1,7 @@ # Vis type Timelion +Contains the timelion visualization and the timelion backend. + # Generate a parser If your grammar was changed in `public/chain.peg` you need to re-generate the static parser. You could use a grunt task: diff --git a/src/plugins/vis_type_timeseries/README.md b/src/plugins/vis_type_timeseries/README.md new file mode 100644 index 0000000000000..4b4184b6eadd9 --- /dev/null +++ b/src/plugins/vis_type_timeseries/README.md @@ -0,0 +1 @@ +Contains everything around TSVB (the editor, visualizatin implementations and backends). \ No newline at end of file diff --git a/src/plugins/vis_type_vega/README.md b/src/plugins/vis_type_vega/README.md new file mode 100644 index 0000000000000..3d9bfd387e2c5 --- /dev/null +++ b/src/plugins/vis_type_vega/README.md @@ -0,0 +1 @@ +Contains the Vega visualization. \ No newline at end of file diff --git a/src/plugins/vis_type_vislib/README.md b/src/plugins/vis_type_vislib/README.md new file mode 100644 index 0000000000000..7641ea2acd1ec --- /dev/null +++ b/src/plugins/vis_type_vislib/README.md @@ -0,0 +1,2 @@ +Contains the vislib visualizations. These are the classical area/line/bar, pie, gauge/goal and +heatmap charts. diff --git a/src/plugins/vis_type_xy/README.md b/src/plugins/vis_type_xy/README.md new file mode 100644 index 0000000000000..70ddb21c1e9db --- /dev/null +++ b/src/plugins/vis_type_xy/README.md @@ -0,0 +1,2 @@ +Contains the new xy-axis chart using the elastic-charts library, which will eventually +replace the vislib xy-axis (bar, area, line) charts. \ No newline at end of file diff --git a/src/plugins/visualizations/README.md b/src/plugins/visualizations/README.md new file mode 100644 index 0000000000000..c61beb670a503 --- /dev/null +++ b/src/plugins/visualizations/README.md @@ -0,0 +1,2 @@ +Contains most of the visualization infrastructure, e.g. the visualization type registry or the +visualization embeddable. \ No newline at end of file diff --git a/src/plugins/visualize/README.md b/src/plugins/visualize/README.md new file mode 100644 index 0000000000000..be3e555a1407b --- /dev/null +++ b/src/plugins/visualize/README.md @@ -0,0 +1,2 @@ +Contains the visualize application which includes the listing page and the app frame, +which will load the visualization's editor. \ No newline at end of file diff --git a/x-pack/plugins/dashboard_enhanced/README.md b/x-pack/plugins/dashboard_enhanced/README.md index d9296ae158621..0aeb156a99f1f 100644 --- a/x-pack/plugins/dashboard_enhanced/README.md +++ b/x-pack/plugins/dashboard_enhanced/README.md @@ -1 +1 @@ -# X-Pack part of Dashboard app +Contains the enhancements to the OSS dashboard app. \ No newline at end of file diff --git a/x-pack/plugins/dashboard_mode/README.md b/x-pack/plugins/dashboard_mode/README.md new file mode 100644 index 0000000000000..4e244afb97fdf --- /dev/null +++ b/x-pack/plugins/dashboard_mode/README.md @@ -0,0 +1 @@ +The deprecated dashboard only mode. \ No newline at end of file diff --git a/x-pack/plugins/discover_enhanced/README.md b/x-pack/plugins/discover_enhanced/README.md new file mode 100644 index 0000000000000..08d0dbb9cdbef --- /dev/null +++ b/x-pack/plugins/discover_enhanced/README.md @@ -0,0 +1 @@ +Contains the enhancements to the OSS discover app. \ No newline at end of file From bf22fe54e1f1579821e2b55f211d432f12555bd5 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 5 Aug 2020 09:21:57 -0400 Subject: [PATCH 006/106] [Ingest Node Pipelines] Refactor pipeline simulator code (#72328) --- .../components/pipeline_form/index.ts | 2 +- .../pipeline_form/pipeline_form.tsx | 22 -- .../pipeline_form/pipeline_form_fields.tsx | 18 +- .../pipeline_form/pipeline_form_provider.tsx | 20 -- .../pipeline_test_flyout.tsx | 203 ------------------ .../pipeline_test_flyout_provider.tsx | 47 ---- .../pipeline_form/processors_header.tsx | 28 +-- .../pipeline_processors_editor.helpers.tsx | 6 +- .../pipeline_processors_editor.test.tsx | 5 + .../components/index.ts | 2 + .../components/pipeline_processors_editor.tsx | 1 + .../components/test_pipeline/button.tsx | 30 +++ .../test_pipeline/flyout_provider.tsx | 171 +++++++++++++++ .../test_pipeline/flyout_tabs}/index.ts | 0 .../flyout_tabs}/pipeline_test_tabs.tsx | 0 .../test_pipeline/flyout_tabs}/schema.tsx | 4 +- .../flyout_tabs}/tab_documents.tsx | 23 +- .../test_pipeline/flyout_tabs}/tab_output.tsx | 3 +- .../components/test_pipeline}/index.ts | 2 +- .../context/context.tsx | 42 ++++ .../context/index.ts | 15 ++ .../processors_context.tsx} | 25 ++- .../context}/test_config_context.tsx | 0 .../pipeline_processors_editor/index.ts | 4 +- .../pipeline_processors_editor/types.ts | 4 + .../public/application/services/api.ts | 2 +- .../application/services/documentation.ts | 4 - .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - 29 files changed, 323 insertions(+), 366 deletions(-) delete mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_provider.tsx delete mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/pipeline_test_flyout.tsx delete mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/pipeline_test_flyout_provider.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/button.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_provider.tsx rename x-pack/plugins/ingest_pipelines/public/application/components/{pipeline_form/pipeline_test_flyout/tabs => pipeline_processors_editor/components/test_pipeline/flyout_tabs}/index.ts (100%) rename x-pack/plugins/ingest_pipelines/public/application/components/{pipeline_form/pipeline_test_flyout/tabs => pipeline_processors_editor/components/test_pipeline/flyout_tabs}/pipeline_test_tabs.tsx (100%) rename x-pack/plugins/ingest_pipelines/public/application/components/{pipeline_form/pipeline_test_flyout/tabs => pipeline_processors_editor/components/test_pipeline/flyout_tabs}/schema.tsx (96%) rename x-pack/plugins/ingest_pipelines/public/application/components/{pipeline_form/pipeline_test_flyout/tabs => pipeline_processors_editor/components/test_pipeline/flyout_tabs}/tab_documents.tsx (85%) rename x-pack/plugins/ingest_pipelines/public/application/components/{pipeline_form/pipeline_test_flyout/tabs => pipeline_processors_editor/components/test_pipeline/flyout_tabs}/tab_output.tsx (97%) rename x-pack/plugins/ingest_pipelines/public/application/components/{pipeline_form/pipeline_test_flyout => pipeline_processors_editor/components/test_pipeline}/index.ts (70%) create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/context.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/index.ts rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/{context.tsx => context/processors_context.tsx} (91%) rename x-pack/plugins/ingest_pipelines/public/application/components/{pipeline_form => pipeline_processors_editor/context}/test_config_context.tsx (100%) diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/index.ts index 2b007a25667a1..21a2ee30a84e1 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { PipelineFormProvider as PipelineForm } from './pipeline_form_provider'; +export { PipelineForm } from './pipeline_form'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form.tsx index 341e15132d353..5279bd718c16e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form.tsx @@ -16,7 +16,6 @@ import './pipeline_form.scss'; import { OnUpdateHandlerArg, OnUpdateHandler } from '../pipeline_processors_editor'; import { PipelineRequestFlyout } from './pipeline_request_flyout'; -import { PipelineTestFlyout } from './pipeline_test_flyout'; import { PipelineFormFields } from './pipeline_form_fields'; import { PipelineFormError } from './pipeline_form_error'; import { pipelineFormSchema } from './schema'; @@ -48,8 +47,6 @@ export const PipelineForm: React.FunctionComponent = ({ }) => { const [isRequestVisible, setIsRequestVisible] = useState(false); - const [isTestingPipeline, setIsTestingPipeline] = useState(false); - const { processors: initialProcessors, on_failure: initialOnFailureProcessors, @@ -79,10 +76,6 @@ export const PipelineForm: React.FunctionComponent = ({ } }; - const handleTestPipelineClick = () => { - setIsTestingPipeline(true); - }; - const { form } = useForm({ schema: pipelineFormSchema, defaultValue: defaultFormValues, @@ -90,7 +83,6 @@ export const PipelineForm: React.FunctionComponent = ({ }); const onEditorFlyoutOpen = useCallback(() => { - setIsTestingPipeline(false); setIsRequestVisible(false); }, [setIsRequestVisible]); @@ -137,8 +129,6 @@ export const PipelineForm: React.FunctionComponent = ({ onFailure={processorsState.onFailure} onProcessorsUpdate={onProcessorsChangeHandler} hasVersion={Boolean(defaultValue.version)} - isTestButtonDisabled={isTestingPipeline || form.isValid === false} - onTestPipelineClick={handleTestPipelineClick} isEditing={isEditing} /> @@ -198,18 +188,6 @@ export const PipelineForm: React.FunctionComponent = ({ closeFlyout={() => setIsRequestVisible((prevIsRequestVisible) => !prevIsRequestVisible)} /> ) : null} - - {/* Test pipeline flyout */} - {isTestingPipeline ? ( - - processorStateRef.current?.getData() || { processors: [], on_failure: [] } - } - closeFlyout={() => { - setIsTestingPipeline((prevIsTestingPipeline) => !prevIsTestingPipeline); - }} - /> - ) : null} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_fields.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_fields.tsx index 0e7a45e8d07b9..32beb61039a90 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_fields.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_fields.tsx @@ -13,7 +13,7 @@ import { Processor } from '../../../../common/types'; import { getUseField, getFormRow, Field, useKibana } from '../../../shared_imports'; import { - PipelineProcessorsContextProvider, + ProcessorsEditorContextProvider, GlobalOnFailureProcessorsEditor, ProcessorsEditor, OnUpdateHandler, @@ -29,8 +29,6 @@ interface Props { onLoadJson: OnDoneLoadJsonHandler; onProcessorsUpdate: OnUpdateHandler; hasVersion: boolean; - isTestButtonDisabled: boolean; - onTestPipelineClick: () => void; onEditorFlyoutOpen: () => void; isEditing?: boolean; } @@ -45,8 +43,6 @@ export const PipelineFormFields: React.FunctionComponent = ({ onProcessorsUpdate, isEditing, hasVersion, - isTestButtonDisabled, - onTestPipelineClick, onEditorFlyoutOpen, }) => { const { services } = useKibana(); @@ -125,20 +121,18 @@ export const PipelineFormFields: React.FunctionComponent = ({ {/* Pipeline Processors Editor */} -
- + @@ -154,7 +148,7 @@ export const PipelineFormFields: React.FunctionComponent = ({
-
+ ); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_provider.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_provider.tsx deleted file mode 100644 index e6482a9fc12c2..0000000000000 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_form_provider.tsx +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; - -import { PipelineForm as PipelineFormUI, PipelineFormProps } from './pipeline_form'; -import { TestConfigContextProvider } from './test_config_context'; - -export const PipelineFormProvider: React.FunctionComponent = ( - passThroughProps -) => { - return ( - - - - ); -}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/pipeline_test_flyout.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/pipeline_test_flyout.tsx deleted file mode 100644 index da5e6cf77364c..0000000000000 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/pipeline_test_flyout.tsx +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { useState, useEffect, useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; - -import { - EuiFlyout, - EuiFlyoutBody, - EuiFlyoutHeader, - EuiSpacer, - EuiTitle, - EuiCallOut, -} from '@elastic/eui'; - -import { useKibana } from '../../../../shared_imports'; -import { Pipeline } from '../../../../../common/types'; -import { Tabs, Tab, OutputTab, DocumentsTab } from './tabs'; -import { useTestConfigContext } from '../test_config_context'; - -export interface PipelineTestFlyoutProps { - closeFlyout: () => void; - pipeline: Pipeline; - isPipelineValid: boolean; -} - -export const PipelineTestFlyout: React.FunctionComponent = ({ - closeFlyout, - pipeline, - isPipelineValid, -}) => { - const { services } = useKibana(); - - const { testConfig } = useTestConfigContext(); - const { documents: cachedDocuments, verbose: cachedVerbose } = testConfig; - - const initialSelectedTab = cachedDocuments ? 'output' : 'documents'; - const [selectedTab, setSelectedTab] = useState(initialSelectedTab); - - const [shouldExecuteImmediately, setShouldExecuteImmediately] = useState(false); - const [isExecuting, setIsExecuting] = useState(false); - const [executeError, setExecuteError] = useState(null); - const [executeOutput, setExecuteOutput] = useState(undefined); - - const handleExecute = useCallback( - async (documents: object[], verbose?: boolean) => { - const { name: pipelineName, ...pipelineDefinition } = pipeline; - - setIsExecuting(true); - setExecuteError(null); - - const { error, data: output } = await services.api.simulatePipeline({ - documents, - verbose, - pipeline: pipelineDefinition, - }); - - setIsExecuting(false); - - if (error) { - setExecuteError(error); - return; - } - - setExecuteOutput(output); - - services.notifications.toasts.addSuccess( - i18n.translate('xpack.ingestPipelines.testPipelineFlyout.successNotificationText', { - defaultMessage: 'Pipeline executed', - }), - { - toastLifeTimeMs: 1000, - } - ); - - setSelectedTab('output'); - }, - [pipeline, services.api, services.notifications.toasts] - ); - - useEffect(() => { - if (cachedDocuments) { - setShouldExecuteImmediately(true); - } - // We only want to know on initial mount if there are cached documents - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - useEffect(() => { - // If the user has already tested the pipeline once, - // use the cached test config and automatically execute the pipeline - if (shouldExecuteImmediately && Object.entries(pipeline).length > 0) { - setShouldExecuteImmediately(false); - handleExecute(cachedDocuments!, cachedVerbose); - } - }, [ - pipeline, - handleExecute, - cachedDocuments, - cachedVerbose, - isExecuting, - shouldExecuteImmediately, - ]); - - let tabContent; - - if (selectedTab === 'output') { - tabContent = ( - - ); - } else { - // default to "documents" tab - tabContent = ( - - ); - } - - return ( - - - -

- {pipeline.name ? ( - - ) : ( - - )} -

-
-
- - - !executeOutput && tabId === 'output'} - /> - - - - {/* Execute error */} - {executeError ? ( - <> - - } - color="danger" - iconType="alert" - > -

{executeError.message}

-
- - - ) : null} - - {/* Invalid pipeline error */} - {!isPipelineValid ? ( - <> - - } - color="danger" - iconType="alert" - /> - - - ) : null} - - {/* Documents or output tab content */} - {tabContent} -
-
- ); -}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/pipeline_test_flyout_provider.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/pipeline_test_flyout_provider.tsx deleted file mode 100644 index 7f91672d64df4..0000000000000 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/pipeline_test_flyout_provider.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { useState, useEffect } from 'react'; - -import { Pipeline } from '../../../../../common/types'; -import { useFormContext } from '../../../../shared_imports'; - -import { ReadProcessorsFunction } from '../types'; - -import { PipelineTestFlyout, PipelineTestFlyoutProps } from './pipeline_test_flyout'; - -interface Props extends Omit { - readProcessors: ReadProcessorsFunction; -} - -export const PipelineTestFlyoutProvider: React.FunctionComponent = ({ - closeFlyout, - readProcessors, -}) => { - const form = useFormContext(); - const [formData, setFormData] = useState({} as Pipeline); - const [isFormDataValid, setIsFormDataValid] = useState(false); - - useEffect(() => { - const subscription = form.subscribe(async ({ isValid, validate, data }) => { - const isFormValid = isValid ?? (await validate()); - if (isFormValid) { - setFormData(data.format() as Pipeline); - } - setIsFormDataValid(isFormValid); - }); - - return subscription.unsubscribe; - }, [form]); - - return ( - - ); -}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/processors_header.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/processors_header.tsx index 5e5cddbd36b92..3e8cd999a484a 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/processors_header.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/processors_header.tsx @@ -5,25 +5,23 @@ */ import React, { FunctionComponent } from 'react'; -import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiLink, EuiText, EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiText, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { usePipelineProcessorsContext } from '../pipeline_processors_editor/context'; -import { LoadFromJsonButton, OnDoneLoadJsonHandler } from '../pipeline_processors_editor'; +import { + LoadFromJsonButton, + OnDoneLoadJsonHandler, + TestPipelineButton, +} from '../pipeline_processors_editor'; export interface Props { - onTestPipelineClick: () => void; - isTestButtonDisabled: boolean; onLoadJson: OnDoneLoadJsonHandler; } -export const ProcessorsHeader: FunctionComponent = ({ - onTestPipelineClick, - isTestButtonDisabled, - onLoadJson, -}) => { +export const ProcessorsHeader: FunctionComponent = ({ onLoadJson }) => { const { links } = usePipelineProcessorsContext(); return ( = ({ - - - + ); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx index e7258a74f4732..227513dcdaacc 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx @@ -7,7 +7,7 @@ import { act } from 'react-dom/test-utils'; import React from 'react'; import { registerTestBed, TestBed } from '../../../../../../../test_utils'; import { - PipelineProcessorsContextProvider, + ProcessorsEditorContextProvider, Props, ProcessorsEditor, GlobalOnFailureProcessorsEditor, @@ -62,9 +62,9 @@ jest.mock('react-virtualized', () => { const testBedSetup = registerTestBed( (props: Props) => ( - + - + ), { doMountAsync: false, diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx index df4832f9a45e0..a45a677846b2e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx @@ -3,8 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { notificationServiceMock } from 'src/core/public/mocks'; + import { setup, SetupResult } from './pipeline_processors_editor.helpers'; import { Pipeline } from '../../../../../common/types'; +import { apiService } from '../../../services'; const testProcessors: Pick = { processors: [ @@ -46,6 +49,8 @@ describe('Pipeline Editor', () => { links: { esDocsBasePath: 'test', }, + toasts: notificationServiceMock.createSetupContract().toasts, + api: apiService, }); }); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts index b532b2d953e65..bf724be950fdf 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts @@ -20,4 +20,6 @@ export { ProcessorRemoveModal } from './processor_remove_modal'; export { OnDoneLoadJsonHandler, LoadFromJsonButton } from './load_from_json'; +export { TestPipelineButton } from './test_pipeline'; + export { PipelineProcessorsItemTooltip, Position } from './pipeline_processors_editor_item_tooltip'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor.tsx index c89ff1d3d99ac..ef8bf790a18aa 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor.tsx @@ -21,6 +21,7 @@ export const PipelineProcessorsEditor: FunctionComponent = memo( state: { editor, processors }, } = usePipelineProcessorsContext(); const baseSelector = useMemo(() => [stateSlice], [stateSlice]); + return ( { + return ( + + {(openFlyout) => { + return ( + + {i18nTexts.buttonLabel} + + ); + }} + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_provider.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_provider.tsx new file mode 100644 index 0000000000000..ad88259e3bcc4 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_provider.tsx @@ -0,0 +1,171 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useState, useEffect, useCallback } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; + +import { + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiSpacer, + EuiTitle, + EuiCallOut, +} from '@elastic/eui'; + +import { usePipelineProcessorsContext, useTestConfigContext } from '../../context'; +import { serialize } from '../../serialize'; + +import { Tabs, Tab, OutputTab, DocumentsTab } from './flyout_tabs'; + +export interface Props { + children: (openFlyout: () => void) => React.ReactNode; +} + +export const FlyoutProvider: React.FunctionComponent = ({ children }) => { + const { + state: { processors }, + api, + toasts, + } = usePipelineProcessorsContext(); + + const serializedProcessors = serialize(processors.state); + + const { testConfig } = useTestConfigContext(); + const { documents: cachedDocuments, verbose: cachedVerbose } = testConfig; + + const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); + + const initialSelectedTab = cachedDocuments ? 'output' : 'documents'; + const [selectedTab, setSelectedTab] = useState(initialSelectedTab); + + const [shouldExecuteImmediately, setShouldExecuteImmediately] = useState(false); + const [isExecuting, setIsExecuting] = useState(false); + const [executeError, setExecuteError] = useState(null); + const [executeOutput, setExecuteOutput] = useState(undefined); + + const handleExecute = useCallback( + async (documents: object[], verbose?: boolean) => { + setIsExecuting(true); + setExecuteError(null); + + const { error, data: output } = await api.simulatePipeline({ + documents, + verbose, + pipeline: { ...serializedProcessors }, + }); + + setIsExecuting(false); + + if (error) { + setExecuteError(error); + return; + } + + setExecuteOutput(output); + + toasts.addSuccess( + i18n.translate('xpack.ingestPipelines.testPipelineFlyout.successNotificationText', { + defaultMessage: 'Pipeline executed', + }), + { + toastLifeTimeMs: 1000, + } + ); + + setSelectedTab('output'); + }, + [serializedProcessors, api, toasts] + ); + + useEffect(() => { + if (isFlyoutVisible === false && cachedDocuments) { + setShouldExecuteImmediately(true); + } + }, [isFlyoutVisible, cachedDocuments]); + + useEffect(() => { + // If the user has already tested the pipeline once, + // use the cached test config and automatically execute the pipeline + if (isFlyoutVisible && shouldExecuteImmediately && cachedDocuments) { + setShouldExecuteImmediately(false); + handleExecute(cachedDocuments!, cachedVerbose); + } + }, [handleExecute, cachedDocuments, cachedVerbose, isFlyoutVisible, shouldExecuteImmediately]); + + let tabContent; + + if (selectedTab === 'output') { + tabContent = ( + + ); + } else { + // default to "Documents" tab + tabContent = ; + } + + return ( + <> + {children(() => setIsFlyoutVisible(true))} + + {isFlyoutVisible && ( + setIsFlyoutVisible(false)} + data-test-subj="testPipelineFlyout" + > + + +

+ +

+
+
+ + + !executeOutput && tabId === 'output'} + /> + + + + {/* Execute error */} + {executeError ? ( + <> + + } + color="danger" + iconType="alert" + > +

{executeError.message}

+
+ + + ) : null} + + {/* Documents or output tab content */} + {tabContent} +
+
+ )} + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/tabs/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_tabs/index.ts similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/tabs/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_tabs/index.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/tabs/pipeline_test_tabs.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_tabs/pipeline_test_tabs.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/tabs/pipeline_test_tabs.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_tabs/pipeline_test_tabs.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/tabs/schema.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_tabs/schema.tsx similarity index 96% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/tabs/schema.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_tabs/schema.tsx index de9910344bd4b..e8ac223d56ed9 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/tabs/schema.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_tabs/schema.tsx @@ -9,8 +9,8 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { EuiCode } from '@elastic/eui'; -import { FormSchema, fieldValidators, ValidationFuncArg } from '../../../../../shared_imports'; -import { parseJson, stringifyJson } from '../../../../lib'; +import { FormSchema, fieldValidators, ValidationFuncArg } from '../../../../../../shared_imports'; +import { parseJson, stringifyJson } from '../../../../../lib'; const { emptyField, isJsonField } = fieldValidators; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/tabs/tab_documents.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_tabs/tab_documents.tsx similarity index 85% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/tabs/tab_documents.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_tabs/tab_documents.tsx index be9ebc57c69ee..593347f8b2343 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_form/pipeline_test_flyout/tabs/tab_documents.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/flyout_tabs/tab_documents.tsx @@ -17,32 +17,27 @@ import { Form, useForm, FormConfig, - useKibana, -} from '../../../../../shared_imports'; +} from '../../../../../../shared_imports'; + +import { usePipelineProcessorsContext, useTestConfigContext, TestConfig } from '../../../context'; import { documentsSchema } from './schema'; -import { useTestConfigContext, TestConfig } from '../../test_config_context'; const UseField = getUseField({ component: Field }); interface Props { handleExecute: (documents: object[], verbose: boolean) => void; - isPipelineValid: boolean; isExecuting: boolean; } -export const DocumentsTab: React.FunctionComponent = ({ - isPipelineValid, - handleExecute, - isExecuting, -}) => { - const { services } = useKibana(); +export const DocumentsTab: React.FunctionComponent = ({ handleExecute, isExecuting }) => { + const { links } = usePipelineProcessorsContext(); const { setCurrentTestConfig, testConfig } = useTestConfigContext(); const { verbose: cachedVerbose, documents: cachedDocuments } = testConfig; const executePipeline: FormConfig['onSubmit'] = async (formData, isValid) => { - if (!isValid || !isPipelineValid) { + if (!isValid) { return; } @@ -76,7 +71,7 @@ export const DocumentsTab: React.FunctionComponent = ({ values={{ learnMoreLink: ( @@ -98,7 +93,7 @@ export const DocumentsTab: React.FunctionComponent = ({
{/* Documents editor */} @@ -125,7 +120,7 @@ export const DocumentsTab: React.FunctionComponent = ({ onClick={form.submit} size="s" isLoading={isExecuting} - disabled={(form.isSubmitted && !form.isValid) || !isPipelineValid} + disabled={form.isSubmitted && !form.isValid} > {isExecuting ? ( = ({ + children, + links, + api, + toasts, + onUpdate, + value, + onFlyoutOpen, +}: Props) => { + return ( + + + {children} + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/index.ts new file mode 100644 index 0000000000000..1664b3410c1c0 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { ProcessorsEditorContextProvider } from './context'; + +export { TestConfigContextProvider, useTestConfigContext, TestConfig } from './test_config_context'; + +export { + PipelineProcessorsContextProvider, + usePipelineProcessorsContext, + Props, +} from './processors_context'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx similarity index 91% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx index 098473b0d2572..db4629823ef52 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx @@ -15,7 +15,10 @@ import React, { useRef, } from 'react'; -import { Processor } from '../../../../common/types'; +import { NotificationsSetup } from 'src/core/public'; + +import { Processor } from '../../../../../common/types'; +import { ApiService } from '../../../services'; import { EditorMode, @@ -26,29 +29,31 @@ import { ContextValueState, Links, ProcessorInternal, -} from './types'; +} from '../types'; -import { useProcessorsState, isOnFailureSelector } from './processors_reducer'; +import { useProcessorsState, isOnFailureSelector } from '../processors_reducer'; -import { deserialize } from './deserialize'; +import { deserialize } from '../deserialize'; -import { serialize } from './serialize'; +import { serialize } from '../serialize'; -import { OnActionHandler } from './components/processors_tree'; +import { OnActionHandler } from '../components/processors_tree'; import { ProcessorRemoveModal, PipelineProcessorsItemTooltip, ProcessorSettingsForm, OnSubmitHandler, -} from './components'; +} from '../components'; -import { getValue } from './utils'; +import { getValue } from '../utils'; const PipelineProcessorsContext = createContext({} as any); export interface Props { links: Links; + api: ApiService; + toasts: NotificationsSetup['toasts']; value: { processors: Processor[]; onFailure?: Processor[]; @@ -62,6 +67,8 @@ export interface Props { export const PipelineProcessorsContextProvider: FunctionComponent = ({ links, + api, + toasts, value: { processors: originalProcessors, onFailure: originalOnFailureProcessors }, onUpdate, onFlyoutOpen, @@ -205,6 +212,8 @@ export const PipelineProcessorsContextProvider: FunctionComponent = ({ ; + pipeline: Pick; }) { const result = await this.sendRequest({ path: `${API_BASE_PATH}/simulate`, diff --git a/x-pack/plugins/ingest_pipelines/public/application/services/documentation.ts b/x-pack/plugins/ingest_pipelines/public/application/services/documentation.ts index 7f6a87a46fea3..daed338eb6ab4 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/services/documentation.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/services/documentation.ts @@ -34,10 +34,6 @@ export class DocumentationService { public getPutPipelineApiUrl() { return `${this.esDocBasePath}/put-pipeline-api.html`; } - - public getSimulatePipelineApiUrl() { - return `${this.esDocBasePath}/simulate-pipeline-api.html`; - } } export const documentationService = new DocumentationService(); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index aa12e2a34075e..7e1ce610a1948 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9799,7 +9799,6 @@ "xpack.ingestPipelines.pipelineEditor.setForm.valueFieldLabel": "値", "xpack.ingestPipelines.pipelineEditor.setForm.valueRequiredError": "設定する値が必要です。", "xpack.ingestPipelines.pipelineEditor.settingsForm.learnMoreLabelLink.processor": "{processorLabel}ドキュメント", - "xpack.ingestPipelines.pipelineEditor.testPipelineButtonLabel": "パイプラインをテスト", "xpack.ingestPipelines.pipelineEditor.typeField.fieldRequiredError": "タイプが必要です。", "xpack.ingestPipelines.pipelineEditor.typeField.typeFieldLabel": "プロセッサー", "xpack.ingestPipelines.processors.label.append": "末尾に追加", @@ -9857,13 +9856,11 @@ "xpack.ingestPipelines.testPipelineFlyout.documentsTab.simulateDocumentionLink": "詳細", "xpack.ingestPipelines.testPipelineFlyout.documentsTab.tabDescriptionText": "投入するパイプラインのドキュメントの配列を指定します。{learnMoreLink}", "xpack.ingestPipelines.testPipelineFlyout.executePipelineError": "パイプラインを実行できません", - "xpack.ingestPipelines.testPipelineFlyout.invalidPipelineErrorMessage": "実行するパイプラインが無効です。", "xpack.ingestPipelines.testPipelineFlyout.outputTab.descriptionLinkLabel": "出力を更新", "xpack.ingestPipelines.testPipelineFlyout.outputTab.descriptionText": "出力データを表示するか、パイプライン経由で渡されるときに各プロセッサーがドキュメントにどのように影響するのかを確認します。", "xpack.ingestPipelines.testPipelineFlyout.outputTab.verboseSwitchLabel": "冗長出力を表示", "xpack.ingestPipelines.testPipelineFlyout.successNotificationText": "パイプラインが実行されました", "xpack.ingestPipelines.testPipelineFlyout.title": "パイプラインをテスト", - "xpack.ingestPipelines.testPipelineFlyout.withPipelineNameTitle": "パイプライン'{pipelineName}'をテスト", "xpack.lens.app.docLoadingError": "保存されたドキュメントの保存中にエラーが発生", "xpack.lens.app.docSavingError": "ドキュメントの保存中にエラーが発生", "xpack.lens.app.indexPatternLoadingError": "インデックスパターンの読み込み中にエラーが発生", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index befce4de3d247..e82ba7cc1d60f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9801,7 +9801,6 @@ "xpack.ingestPipelines.pipelineEditor.setForm.valueFieldLabel": "值", "xpack.ingestPipelines.pipelineEditor.setForm.valueRequiredError": "需要设置值。", "xpack.ingestPipelines.pipelineEditor.settingsForm.learnMoreLabelLink.processor": "{processorLabel}文档", - "xpack.ingestPipelines.pipelineEditor.testPipelineButtonLabel": "测试管道", "xpack.ingestPipelines.pipelineEditor.typeField.fieldRequiredError": "类型必填。", "xpack.ingestPipelines.pipelineEditor.typeField.typeFieldLabel": "处理器", "xpack.ingestPipelines.processors.label.append": "追加", @@ -9859,13 +9858,11 @@ "xpack.ingestPipelines.testPipelineFlyout.documentsTab.simulateDocumentionLink": "了解详情", "xpack.ingestPipelines.testPipelineFlyout.documentsTab.tabDescriptionText": "为管道提供要采集的一系列文档。{learnMoreLink}", "xpack.ingestPipelines.testPipelineFlyout.executePipelineError": "无法执行管道", - "xpack.ingestPipelines.testPipelineFlyout.invalidPipelineErrorMessage": "要执行的管道无效。", "xpack.ingestPipelines.testPipelineFlyout.outputTab.descriptionLinkLabel": "刷新输出", "xpack.ingestPipelines.testPipelineFlyout.outputTab.descriptionText": "查看输出数据或了解文档通过管道时每个处理器对文档的影响。", "xpack.ingestPipelines.testPipelineFlyout.outputTab.verboseSwitchLabel": "查看详细输出", "xpack.ingestPipelines.testPipelineFlyout.successNotificationText": "管道已执行", "xpack.ingestPipelines.testPipelineFlyout.title": "测试管道", - "xpack.ingestPipelines.testPipelineFlyout.withPipelineNameTitle": "测试管道“{pipelineName}”", "xpack.lens.app.docLoadingError": "加载已保存文档时出错", "xpack.lens.app.docSavingError": "保存文档时出错", "xpack.lens.app.indexPatternLoadingError": "加载索引模式时出错", From 87596465766158ccd758bb7eafa10d4d6d6acb99 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Wed, 5 Aug 2020 16:28:03 +0300 Subject: [PATCH 007/106] update docs (#74364) --- .../architecture/code-exploration.asciidoc | 74 ++++++++++--------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/docs/developer/architecture/code-exploration.asciidoc b/docs/developer/architecture/code-exploration.asciidoc index 4481dea44795c..bb7222020180c 100644 --- a/docs/developer/architecture/code-exploration.asciidoc +++ b/docs/developer/architecture/code-exploration.asciidoc @@ -58,9 +58,9 @@ The Charts plugin is a way to create easier integration of shared colors, themes WARNING: Missing README. -- {kib-repo}blob/{branch}/src/plugins/dashboard[dashboard] +- {kib-repo}blob/{branch}/src/plugins/dashboard/README.md[dashboard] -WARNING: Missing README. +Contains the dashboard application. - {kib-repo}blob/{branch}/src/plugins/data/README.md[data] @@ -76,9 +76,9 @@ Routing will be handled by the id of the dev tool - your dev tool will be mounte This API doesn't support angular, for registering angular dev tools, bootstrap a local module on mount into the given HTML element. -- {kib-repo}blob/{branch}/src/plugins/discover[discover] +- {kib-repo}blob/{branch}/src/plugins/discover/README.md[discover] -WARNING: Missing README. +Contains the Discover application and the saved search embeddable. - {kib-repo}blob/{branch}/src/plugins/embeddable/README.md[embeddable] @@ -109,9 +109,9 @@ Moves the legacy ui/registry/feature_catalogue module for registering "features" WARNING: Missing README. -- {kib-repo}blob/{branch}/src/plugins/input_control_vis[inputControlVis] +- {kib-repo}blob/{branch}/src/plugins/input_control_vis/README.md[inputControlVis] -WARNING: Missing README. +Contains the input control visualization allowing to place custom filter controls on a dashboard. - {kib-repo}blob/{branch}/src/plugins/inspector/README.md[inspector] @@ -206,9 +206,10 @@ This plugin adds the Advanced Settings section for the Usage Data collection (ak WARNING: Missing README. -- {kib-repo}blob/{branch}/src/plugins/timelion[timelion] +- {kib-repo}blob/{branch}/src/plugins/timelion/README.md[timelion] -WARNING: Missing README. +Contains the deprecated timelion application. For the timelion visualization, +which also contains the timelion APIs and backend, look at the vis_type_timelion plugin. - {kib-repo}blob/{branch}/src/plugins/ui_actions/README.md[uiActions] @@ -222,59 +223,63 @@ Usage Collection allows collecting usage data for other services to consume (tel To integrate with the telemetry services for usage collection of your feature, there are 2 steps: -- {kib-repo}blob/{branch}/src/plugins/vis_type_markdown[visTypeMarkdown] +- {kib-repo}blob/{branch}/src/plugins/vis_type_markdown/README.md[visTypeMarkdown] -WARNING: Missing README. +The markdown visualization that can be used to place text panels on dashboards. -- {kib-repo}blob/{branch}/src/plugins/vis_type_metric[visTypeMetric] +- {kib-repo}blob/{branch}/src/plugins/vis_type_metric/README.md[visTypeMetric] -WARNING: Missing README. +Contains the metric visualization. -- {kib-repo}blob/{branch}/src/plugins/vis_type_table[visTypeTable] +- {kib-repo}blob/{branch}/src/plugins/vis_type_table/README.md[visTypeTable] -WARNING: Missing README. +Contains the data table visualization, that allows presenting data in a simple table format. -- {kib-repo}blob/{branch}/src/plugins/vis_type_tagcloud[visTypeTagcloud] +- {kib-repo}blob/{branch}/src/plugins/vis_type_tagcloud/README.md[visTypeTagcloud] -WARNING: Missing README. +Contains the tagcloud visualization. - {kib-repo}blob/{branch}/src/plugins/vis_type_timelion/README.md[visTypeTimelion] -If your grammar was changed in public/chain.peg you need to re-generate the static parser. You could use a grunt task: +Contains the timelion visualization and the timelion backend. -- {kib-repo}blob/{branch}/src/plugins/vis_type_timeseries[visTypeTimeseries] +- {kib-repo}blob/{branch}/src/plugins/vis_type_timeseries/README.md[visTypeTimeseries] -WARNING: Missing README. +Contains everything around TSVB (the editor, visualizatin implementations and backends). -- {kib-repo}blob/{branch}/src/plugins/vis_type_vega[visTypeVega] +- {kib-repo}blob/{branch}/src/plugins/vis_type_vega/README.md[visTypeVega] -WARNING: Missing README. +Contains the Vega visualization. -- {kib-repo}blob/{branch}/src/plugins/vis_type_vislib[visTypeVislib] +- {kib-repo}blob/{branch}/src/plugins/vis_type_vislib/README.md[visTypeVislib] -WARNING: Missing README. +Contains the vislib visualizations. These are the classical area/line/bar, pie, gauge/goal and +heatmap charts. -- {kib-repo}blob/{branch}/src/plugins/vis_type_xy[visTypeXy] +- {kib-repo}blob/{branch}/src/plugins/vis_type_xy/README.md[visTypeXy] -WARNING: Missing README. +Contains the new xy-axis chart using the elastic-charts library, which will eventually +replace the vislib xy-axis (bar, area, line) charts. -- {kib-repo}blob/{branch}/src/plugins/visualizations[visualizations] +- {kib-repo}blob/{branch}/src/plugins/visualizations/README.md[visualizations] -WARNING: Missing README. +Contains most of the visualization infrastructure, e.g. the visualization type registry or the +visualization embeddable. -- {kib-repo}blob/{branch}/src/plugins/visualize[visualize] +- {kib-repo}blob/{branch}/src/plugins/visualize/README.md[visualize] -WARNING: Missing README. +Contains the visualize application which includes the listing page and the app frame, +which will load the visualization's editor. [discrete] @@ -345,9 +350,12 @@ You can run a local cluster and simulate a remote cluster within a single Kibana - {kib-repo}blob/{branch}/x-pack/plugins/dashboard_enhanced/README.md[dashboardEnhanced] -- {kib-repo}blob/{branch}/x-pack/plugins/dashboard_mode[dashboardMode] +Contains the enhancements to the OSS dashboard app. -WARNING: Missing README. + +- {kib-repo}blob/{branch}/x-pack/plugins/dashboard_mode/README.md[dashboardMode] + +The deprecated dashboard only mode. - {kib-repo}blob/{branch}/x-pack/plugins/data_enhanced[dataEnhanced] @@ -355,9 +363,9 @@ WARNING: Missing README. WARNING: Missing README. -- {kib-repo}blob/{branch}/x-pack/plugins/discover_enhanced[discoverEnhanced] +- {kib-repo}blob/{branch}/x-pack/plugins/discover_enhanced/README.md[discoverEnhanced] -WARNING: Missing README. +Contains the enhancements to the OSS discover app. - {kib-repo}blob/{branch}/x-pack/plugins/embeddable_enhanced[embeddableEnhanced] From 3fb77fb546054d11b2aa731ab205f82e2b51d4f3 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Wed, 5 Aug 2020 10:31:47 -0400 Subject: [PATCH 008/106] [ML] DF Analytics creation wizard: show link to results (#74025) * show view results card once job complete * update types * update types and move css to own file --- .../data_frame_analytics/_index.scss | 1 + .../analytics_creation/components/_index.scss | 3 + .../back_to_list_panel/back_to_list_panel.tsx | 6 +- .../components/create_step/create_step.tsx | 10 +- .../create_step_footer.tsx} | 122 +++++++----------- .../components/create_step_footer/index.ts | 7 + .../create_step_footer/progress_stats.tsx | 83 ++++++++++++ .../components/view_results_panel/index.ts | 7 + .../view_results_panel/view_results_panel.tsx | 46 +++++++ .../components/analytics_list/common.ts | 2 +- 10 files changed, 201 insertions(+), 86 deletions(-) create mode 100644 x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/_index.scss rename x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/{create_step/progress_stats.tsx => create_step_footer/create_step_footer.tsx} (55%) create mode 100644 x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/index.ts create mode 100644 x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/progress_stats.tsx create mode 100644 x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/index.ts create mode 100644 x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/_index.scss b/x-pack/plugins/ml/public/application/data_frame_analytics/_index.scss index 140593cb17f6e..231d0f6a0d8c5 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/_index.scss +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/_index.scss @@ -1,3 +1,4 @@ @import 'pages/analytics_exploration/components/regression_exploration/index'; @import 'pages/analytics_management/components/analytics_list/index'; @import 'pages/analytics_management/components/create_analytics_button/index'; +@import 'pages/analytics_creation/components/index'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/_index.scss b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/_index.scss new file mode 100644 index 0000000000000..28d0928eb4d35 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/_index.scss @@ -0,0 +1,3 @@ +.dfAnalyticsCreationWizard__card { + width: 300px; +} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx index 183cbe084f9b3..babb557105270 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx @@ -5,7 +5,7 @@ */ import React, { FC, Fragment } from 'react'; -import { EuiCard, EuiHorizontalRule, EuiIcon } from '@elastic/eui'; +import { EuiCard, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useNavigateToPath } from '../../../../../contexts/kibana'; @@ -18,10 +18,8 @@ export const BackToListPanel: FC = () => { return ( - } title={i18n.translate('xpack.ml.dataframe.analytics.create.analyticsListCardTitle', { defaultMessage: 'Data Frame Analytics', diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx index 8ad49b84134cb..dc9f1bd586d9f 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx @@ -18,8 +18,7 @@ import { i18n } from '@kbn/i18n'; import { CreateAnalyticsFormProps } from '../../../analytics_management/hooks/use_create_analytics_form'; import { Messages } from '../shared'; import { ANALYTICS_STEPS } from '../../page'; -import { BackToListPanel } from '../back_to_list_panel'; -import { ProgressStats } from './progress_stats'; +import { CreateStepFooter } from '../create_step_footer'; interface Props extends CreateAnalyticsFormProps { step: ANALYTICS_STEPS; @@ -28,7 +27,7 @@ interface Props extends CreateAnalyticsFormProps { export const CreateStep: FC = ({ actions, state, step }) => { const { createAnalyticsJob, startAnalyticsJob } = actions; const { isAdvancedEditorValidJson, isJobCreated, isJobStarted, isValid, requestMessages } = state; - const { jobId } = state.form; + const { jobId, jobType } = state.form; const [checked, setChecked] = useState(true); const [showProgress, setShowProgress] = useState(false); @@ -86,8 +85,9 @@ export const CreateStep: FC = ({ actions, state, step }) => { )} - {isJobCreated === true && showProgress && } - {isJobCreated === true && } + {isJobCreated === true && ( + + )} ); }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/progress_stats.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/create_step_footer.tsx similarity index 55% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/progress_stats.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/create_step_footer.tsx index c87f0f4206feb..93d88ebc0b5ac 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/progress_stats.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/create_step_footer.tsx @@ -4,38 +4,43 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { FC, useState, useEffect } from 'react'; -import { - EuiCallOut, - EuiFlexGroup, - EuiFlexItem, - EuiProgress, - EuiSpacer, - EuiText, -} from '@elastic/eui'; +import React, { FC, useEffect, useState } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useMlKibana } from '../../../../../contexts/kibana'; + import { getDataFrameAnalyticsProgressPhase, DATA_FRAME_TASK_STATE, } from '../../../analytics_management/components/analytics_list/common'; import { isGetDataFrameAnalyticsStatsResponseOk } from '../../../analytics_management/services/analytics_service/get_analytics'; +import { useMlKibana } from '../../../../../contexts/kibana'; import { ml } from '../../../../../services/ml_api_service'; -import { DataFrameAnalyticsId } from '../../../../common/analytics'; +import { BackToListPanel } from '../back_to_list_panel'; +import { ViewResultsPanel } from '../view_results_panel'; +import { ProgressStats } from './progress_stats'; +import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; export const PROGRESS_REFRESH_INTERVAL_MS = 1000; -export const ProgressStats: FC<{ jobId: DataFrameAnalyticsId }> = ({ jobId }) => { +interface Props { + jobId: string; + jobType: ANALYSIS_CONFIG_TYPE; + showProgress: boolean; +} + +export interface AnalyticsProgressStats { + currentPhase: number; + progress: number; + totalPhases: number; +} + +export const CreateStepFooter: FC = ({ jobId, jobType, showProgress }) => { const [initialized, setInitialized] = useState(false); const [failedJobMessage, setFailedJobMessage] = useState(undefined); - const [currentProgress, setCurrentProgress] = useState< - | { - currentPhase: number; - progress: number; - totalPhases: number; - } - | undefined - >(undefined); + const [jobFinished, setJobFinished] = useState(false); + const [currentProgress, setCurrentProgress] = useState( + undefined + ); const { services: { notifications }, @@ -77,6 +82,7 @@ export const ProgressStats: FC<{ jobId: DataFrameAnalyticsId }> = ({ jobId }) => jobStats.state === DATA_FRAME_TASK_STATE.STOPPED ) { clearInterval(interval); + setJobFinished(true); } } else { clearInterval(interval); @@ -95,62 +101,26 @@ export const ProgressStats: FC<{ jobId: DataFrameAnalyticsId }> = ({ jobId }) => return () => clearInterval(interval); }, [initialized]); - if (currentProgress === undefined) return null; - return ( - <> - - {failedJobMessage !== undefined && ( - <> - -

{failedJobMessage}

-
- - - )} - - - {i18n.translate('xpack.ml.dataframe.analytics.create.analyticsProgressTitle', { - defaultMessage: 'Progress', - })} - - - - - - - - {i18n.translate('xpack.ml.dataframe.analytics.create.analyticsProgressPhaseTitle', { - defaultMessage: 'Phase', - })}{' '} - {currentProgress.currentPhase}/{currentProgress.totalPhases} - - - - - - - - {`${currentProgress.progress}%`} - - - + + + {showProgress && ( + + )} + + + + + + + + {jobFinished === true && ( + + + + )} + + + ); }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/index.ts new file mode 100644 index 0000000000000..fc4e230ba1034 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { CreateStepFooter } from './create_step_footer'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/progress_stats.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/progress_stats.tsx new file mode 100644 index 0000000000000..522bafa54a270 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/progress_stats.tsx @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC } from 'react'; +import { + EuiCallOut, + EuiFlexGroup, + EuiFlexItem, + EuiProgress, + EuiSpacer, + EuiText, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { AnalyticsProgressStats } from './create_step_footer'; + +interface Props { + currentProgress?: AnalyticsProgressStats; + failedJobMessage: string | undefined; +} + +export const ProgressStats: FC = ({ currentProgress, failedJobMessage }) => { + if (currentProgress === undefined) return null; + + return ( + <> + + {failedJobMessage !== undefined && ( + <> + +

{failedJobMessage}

+
+ + + )} + + + {i18n.translate('xpack.ml.dataframe.analytics.create.analyticsProgressTitle', { + defaultMessage: 'Progress', + })} + + + + + + + + {i18n.translate('xpack.ml.dataframe.analytics.create.analyticsProgressPhaseTitle', { + defaultMessage: 'Phase', + })}{' '} + {currentProgress.currentPhase}/{currentProgress.totalPhases} + + + + + + + + {`${currentProgress.progress}%`} + + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/index.ts new file mode 100644 index 0000000000000..ef3c0cce38652 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { ViewResultsPanel } from './view_results_panel'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx new file mode 100644 index 0000000000000..13706eb548ec8 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment } from 'react'; +import { EuiCard, EuiIcon } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useNavigateToPath } from '../../../../../contexts/kibana'; +import { getResultsUrl } from '../../../analytics_management/components/analytics_list/common'; +import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; + +interface Props { + jobId: string; + analysisType: ANALYSIS_CONFIG_TYPE; +} + +export const ViewResultsPanel: FC = ({ jobId, analysisType }) => { + const navigateToPath = useNavigateToPath(); + + const redirectToAnalyticsManagementPage = async () => { + const path = getResultsUrl(jobId, analysisType); + await navigateToPath(path); + }; + + return ( + + } + title={i18n.translate('xpack.ml.dataframe.analytics.create.viewResultsCardTitle', { + defaultMessage: 'View Results', + })} + description={i18n.translate( + 'xpack.ml.dataframe.analytics.create.viewResultsCardDescription', + { + defaultMessage: 'View results for the analytics job.', + } + )} + onClick={redirectToAnalyticsManagementPage} + data-test-subj="analyticsWizardViewResultsCard" + /> + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts index e2d9ecccf0626..cc52138d7c7b7 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts @@ -130,6 +130,6 @@ export function isCompletedAnalyticsJob(stats: DataFrameAnalyticsStats) { return stats.state === DATA_FRAME_TASK_STATE.STOPPED && progress === 100; } -export function getResultsUrl(jobId: string, analysisType: string) { +export function getResultsUrl(jobId: string, analysisType: ANALYSIS_CONFIG_TYPE | string) { return `#/data_frame_analytics/exploration?_g=(ml:(jobId:${jobId},analysisType:${analysisType}))`; } From 88c063134464047c5da471e480dd26cabe471a02 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Wed, 5 Aug 2020 18:32:19 +0300 Subject: [PATCH 009/106] Update @typescript-eslint to ensure compatibility with TypeScript v3.9 (#74091) * bump @typescript-eslint deps * update rules * fix errors in pacakges * fix src/ * fix x-pack * fix test * fix typings * fix examples * allow _ as prefix and suffix * roll back prefix and suffix changes * add eslint-plugin-eslint-comments * report unused rules * remove unused eslint comments from tests * remove unused eslint comments 2nd pass * remove unused eslint comments from src/ * remove unused comments in x-pack * use no-script-url and no-unsanitized/property for ts files * remove unused eslint comments * eui/href-or-on-click removed when not complained * no import/* rules for ts files * cleanup * remove the unused eslint-disable * rollback unnecessary changes * allow underscore prefix & sufix in type name * update docs * fix type error in enterprise search plugin mocks * rename platform hack __coreProvider --> _coreProvider * rollback space removal in src/core/public/legacy/legacy_service.test.ts * fix naming convention in APM --- ...a_utils-public-state_sync.isyncstateref.md | 2 +- .../public/components/create_alert.tsx | 1 + examples/alerting_example/public/plugin.tsx | 1 + kibana.d.ts | 1 - package.json | 5 +- packages/eslint-config-kibana/package.json | 9 +- packages/eslint-config-kibana/typescript.js | 91 +++++++++++++++++-- packages/kbn-plugin-helpers/src/lib/utils.ts | 4 +- src/cli/cluster/cluster_manager.ts | 2 +- src/core/server/config/config_service.test.ts | 2 - .../lifecycle_handlers.test.ts | 5 +- src/core/server/legacy/legacy_service.ts | 1 + .../migrations/core/call_cluster.ts | 2 - .../integration_tests/bulk_create.test.ts | 8 +- .../routes/integration_tests/bulk_get.test.ts | 8 +- .../integration_tests/bulk_update.test.ts | 8 +- .../routes/integration_tests/create.test.ts | 8 +- .../routes/integration_tests/delete.test.ts | 8 +- .../routes/integration_tests/export.test.ts | 8 +- .../routes/integration_tests/find.test.ts | 8 +- .../routes/integration_tests/import.test.ts | 8 +- .../log_legacy_import.test.ts | 6 +- .../resolve_import_errors.test.ts | 8 +- .../routes/integration_tests/update.test.ts | 8 +- .../saved_objects/serialization/serializer.ts | 3 +- .../saved_objects/service/lib/repository.ts | 1 + src/core/server/status/status_service.ts | 2 - src/core/server/utils/package_json.ts | 1 - .../core_plugins/elasticsearch/index.d.ts | 2 - .../public/new_platform/__mocks__/helpers.ts | 2 - .../ui/public/new_platform/new_platform.ts | 1 + .../public/new_platform/set_services.test.ts | 2 - .../management_app/components/field/field.tsx | 2 + .../management_app/components/form/form.tsx | 1 + .../console_history/console_history.tsx | 1 - .../legacy_core_editor/create_readonly.ts | 1 - .../legacy_core_editor/legacy_core_editor.ts | 4 +- .../public/lib/autocomplete/autocomplete.ts | 1 - src/plugins/console/public/lib/es/es.ts | 2 +- .../lib/spec_definitions/js/aggregations.ts | 2 +- .../server/lib/spec_definitions/js/aliases.ts | 1 - .../lib/spec_definitions/js/document.ts | 1 - .../server/lib/spec_definitions/js/filter.ts | 1 - .../server/lib/spec_definitions/js/globals.ts | 1 - .../server/lib/spec_definitions/js/ingest.ts | 1 - .../lib/spec_definitions/js/mappings.ts | 1 - .../lib/spec_definitions/js/query/dsl.ts | 1 - .../spec_definitions/js/query/templates.ts | 1 - .../server/lib/spec_definitions/js/reindex.ts | 1 - .../server/lib/spec_definitions/js/search.ts | 1 - .../lib/spec_definitions/js/settings.ts | 1 - .../server/lib/spec_definitions/js/shared.ts | 1 - .../actions/clone_panel_action.test.tsx | 2 - .../actions/expand_panel_action.test.tsx | 2 - .../actions/replace_panel_action.test.tsx | 2 - .../public/application/application.ts | 2 +- .../embeddable/dashboard_container.test.tsx | 3 - .../embeddable/grid/dashboard_grid.test.tsx | 1 - .../embeddable/grid/dashboard_grid.tsx | 2 + .../viewport/dashboard_viewport.test.tsx | 1 - .../public/embeddable_plugin_test_samples.ts | 1 - .../dashboard/public/url_generator.test.ts | 1 - .../index_patterns/index_patterns.test.ts | 1 - .../date_interval_utils/is_valid_interval.ts | 4 +- src/plugins/data/public/search/aggs/mocks.ts | 1 - .../search_source/normalize_sort_request.ts | 1 + .../index_pattern_select.tsx | 10 +- .../query_string_input/query_bar_top_row.tsx | 1 + .../data/public/ui/search_bar/search_bar.tsx | 3 +- .../ui/typeahead/suggestion_component.tsx | 1 + .../autocomplete/value_suggestions_route.ts | 1 + .../components/table/table_row.tsx | 1 + .../discover/public/url_generator.test.ts | 1 - .../embeddable_child_panel.test.tsx | 1 - .../lib/panel/embeddable_panel.test.tsx | 1 - .../add_panel/add_panel_action.test.tsx | 1 - .../inspect_panel_action.test.tsx | 1 - .../lib/panel/panel_header/panel_header.tsx | 1 + src/plugins/embeddable/public/mocks.tsx | 2 - .../public/tests/apply_filter_action.test.ts | 1 - .../embeddable/public/tests/container.test.ts | 1 - .../tests/customize_panel_modal.test.tsx | 1 - .../public/tests/explicit_input.test.ts | 1 - .../embeddable/public/tests/test_plugin.ts | 2 - .../ace/use_ui_ace_keyboard_mode.tsx | 1 - .../forms/hook_form_lib/hooks/use_field.ts | 1 + .../expressions/common/execution/container.ts | 1 - src/plugins/expressions/public/mocks.tsx | 2 - src/plugins/expressions/server/mocks.ts | 3 - .../data_sets/ecommerce/saved_objects.ts | 1 - .../data_sets/logs/saved_objects.ts | 1 - .../step_index_pattern/step_index_pattern.tsx | 1 + .../editor/range_control_editor.test.tsx | 2 +- .../public/components/vis/form_row.test.tsx | 6 +- .../components/vis/input_control_vis.test.tsx | 8 +- .../components/vis/list_control.test.tsx | 4 +- .../components/vis/range_control.test.tsx | 4 +- .../public/control/control.ts | 2 - src/plugins/inspector/public/mocks.ts | 1 - .../public/utils/inject_header_style.ts | 1 + .../adapters/ui_to_react_component.test.tsx | 4 + .../public/markdown/markdown.test.tsx | 10 +- .../validated_range/validated_dual_range.tsx | 6 +- .../public/state_sync/public.api.md | 2 +- .../public/state_sync/state_sync.ts | 2 +- .../public/storage/hashed_item_store/mock.ts | 1 + .../public/plugin.test.ts | 2 - .../telemetry_collection/get_local_stats.ts | 1 + src/plugins/timelion/public/application.ts | 2 +- .../public/components/metric_vis_value.tsx | 2 + .../public/table_vis_controller.test.ts | 3 - .../public/table_vis_fn.test.ts | 1 - .../vis_type_timeseries/common/vis_schema.ts | 1 + .../application/components/color_picker.tsx | 2 +- .../public/data_model/vega_parser.ts | 1 - .../vis_type_vislib/public/pie_fn.test.ts | 1 - .../vislib/components/legend/legend.tsx | 1 + .../vislib/components/legend/legend_item.tsx | 1 + .../public/legacy/build_pipeline.ts | 6 +- .../saved_visualizations.ts | 2 +- src/test_utils/public/http_test_setup.ts | 2 - test/functional/apps/console/_console.ts | 1 - test/functional/apps/home/_navigation.ts | 1 - .../functional/apps/visualize/_chart_types.ts | 1 - .../apps/visualize/_linked_saved_searches.ts | 1 - test/functional/apps/visualize/_tsvb_chart.ts | 1 - .../apps/visualize/_tsvb_markdown.ts | 1 - .../apps/visualize/_tsvb_time_series.ts | 1 - test/functional/apps/visualize/_vega_chart.ts | 1 - test/functional/apps/visualize/index.ts | 1 - .../input_control_vis/input_control_range.ts | 1 - test/mocha_decorations.d.ts | 1 - .../plugins/core_app_status/public/plugin.tsx | 2 +- .../plugins/core_app_status/public/types.ts | 2 +- .../core_provider_plugin/public/index.ts | 2 +- .../plugins/core_provider_plugin/types.ts | 2 +- .../test_suites/application_links/index.ts | 1 - .../application_links/redirect_app_links.ts | 7 +- .../core_plugins/application_leave_confirm.ts | 1 - .../core_plugins/application_status.ts | 5 +- .../test_suites/core_plugins/applications.ts | 1 - .../core_plugins/elasticsearch_client.ts | 1 - .../test_suites/core_plugins/index.ts | 1 - .../core_plugins/legacy_plugins.ts | 1 - .../test_suites/core_plugins/rendering.ts | 1 - .../core_plugins/server_plugins.ts | 1 - .../test_suites/core_plugins/top_nav.ts | 1 - .../test_suites/core_plugins/ui_plugins.ts | 9 +- .../test_suites/core_plugins/ui_settings.ts | 7 +- .../test_suites/data_plugin/index_patterns.ts | 1 - .../test_suites/doc_views/doc_views.ts | 1 - test/typings/rison_node.d.ts | 4 +- typings/rison_node.d.ts | 4 +- .../beats_management/common/io_ts_types.ts | 1 - .../beats_management/scripts/fake_env.ts | 6 +- .../beats_management/server/lib/beats.ts | 2 +- .../server/builtin_action_types/index.test.ts | 4 +- .../servicenow/case_types.ts | 2 - .../alerts/server/alert_type_registry.test.ts | 3 - x-pack/plugins/alerts/server/alerts_client.ts | 1 + x-pack/plugins/alerts/server/types.ts | 1 - .../apm/e2e/cypress/integration/helpers.ts | 2 - .../CytoscapeExampleData.stories.tsx | 1 - .../plugins/apm/public/hooks/useFetcher.tsx | 2 - .../plugins/apm/public/utils/testHelpers.tsx | 4 + .../apm/scripts/shared/read-kibana-config.ts | 2 + .../scripts/upload-telemetry-data/index.ts | 1 - x-pack/plugins/apm/server/index.ts | 2 + .../collect_data_telemetry/tasks.test.ts | 2 + .../__tests__/get_buckets.test.ts | 2 + .../server/lib/helpers/setup_request.test.ts | 2 + .../settings/apm_indices/get_apm_indices.ts | 4 + .../lib/transaction_groups/get_error_rate.ts | 10 +- .../avg_duration_by_country/index.ts | 1 + .../lib/transactions/breakdown/index.test.ts | 2 + .../get_timeseries_data/fetcher.test.ts | 2 + .../apm/server/routes/settings/apm_indices.ts | 2 + .../apm/server/saved_objects/apm_indices.ts | 1 + .../public/components/tag/tag_edit.tsx | 5 +- .../functions/external/saved_map.ts | 1 - x-pack/plugins/canvas/public/application.tsx | 1 - .../confirm_modal/confirm_modal.tsx | 1 - .../custom_element_modal.tsx | 1 - .../canvas/public/lib/aeroelastic/index.d.ts | 12 +-- .../plugins/canvas/public/lib/elastic_logo.ts | 1 - .../canvas/public/state/selectors/workpad.ts | 5 +- .../server/routes/shareables/zip.test.ts | 1 + .../shareable_runtime/components/canvas.tsx | 2 + .../components/footer/page_controls.tsx | 8 +- .../components/footer/page_preview.tsx | 4 +- .../footer/settings/autoplay_settings.tsx | 2 + .../footer/settings/toolbar_settings.tsx | 6 +- .../canvas/shareable_runtime/test/utils.ts | 1 + .../canvas/storybook/addon/src/register.tsx | 2 - .../api/cases/comments/delete_all_comments.ts | 1 + .../api/cases/comments/delete_comment.ts | 1 + .../api/cases/comments/patch_comment.ts | 1 + .../routes/api/cases/comments/post_comment.ts | 1 + .../api/cases/configure/patch_configure.ts | 1 + .../api/cases/configure/post_configure.ts | 1 + .../server/routes/api/cases/delete_cases.ts | 1 + .../server/routes/api/cases/patch_cases.ts | 1 + .../case/server/routes/api/cases/post_case.ts | 1 + .../case/server/routes/api/cases/push_case.ts | 1 + .../plugins/case/server/routes/api/utils.ts | 2 + .../server/services/user_actions/helpers.ts | 1 + .../auto_follow_pattern_serialization.ts | 13 ++- .../services/follower_index_serialization.ts | 4 +- .../public/app/index.tsx | 4 +- .../server/lib/ccr_stats_serialization.ts | 2 +- .../server/lib/format_es_error.ts | 7 +- .../server/search/es_search_strategy.ts | 1 + .../lib/enterprise_search_config_api.test.ts | 1 + .../server/routes/__mocks__/router.mock.ts | 12 +-- .../server/routes/app_search/engines.test.ts | 1 + .../routes/workplace_search/overview.test.ts | 1 + .../server/es/cluster_client_adapter.ts | 1 + .../routes/integration_tests/find.test.ts | 6 +- x-pack/plugins/graph/public/application.ts | 2 +- .../components/field_manager/field_editor.tsx | 1 + .../components/field_manager/field_picker.tsx | 1 + .../graph_visualization.tsx | 2 + .../guidance_panel/guidance_panel.tsx | 2 + .../components/settings/url_template_form.tsx | 1 + .../server/lib/kibana_framework.ts | 14 ++- .../api/templates/register_fetch_route.ts | 3 +- .../helpers/setup_environment.tsx | 1 - .../home/data_streams_tab.helpers.ts | 4 +- .../client_integration/home/home.helpers.ts | 4 +- .../home/index_templates_tab.helpers.ts | 2 +- .../home/indices_tab.helpers.ts | 4 +- .../template_clone.helpers.ts | 2 +- .../template_create.helpers.ts | 2 +- .../template_edit.helpers.ts | 2 +- .../common/lib/data_stream_serialization.ts | 5 +- .../helpers/setup_environment.tsx | 1 - .../component_templates.tsx | 1 + .../component_templates_selector.tsx | 1 + .../component_templates/lib/documentation.ts | 1 + .../datatypes/text_datatype.test.tsx | 3 + .../configuration_form/configuration_form.tsx | 4 + .../dynamic_mapping_section.tsx | 1 + .../field_parameters/dynamic_parameter.tsx | 1 + .../fields/create_field/create_field.tsx | 2 + .../fields/fields_list_item.tsx | 8 ++ .../search_fields/search_result_item.tsx | 5 + .../templates_form/templates_form.tsx | 1 + .../mappings_editor/mappings_editor.tsx | 2 + .../data_stream_table/data_stream_table.tsx | 1 - .../server/routes/api/templates/lib.ts | 1 + .../index_management/server/routes/helpers.ts | 7 +- x-pack/plugins/infra/common/errors/metrics.ts | 1 - .../inventory/components/expression.tsx | 1 - .../infra/public/alerting/inventory/index.ts | 1 - .../components/expression.tsx | 1 - .../public/components/document_title.tsx | 6 +- .../logging/log_text_stream/jump_to_tail.tsx | 2 - .../log_text_stream/loading_item_view.tsx | 2 - .../scrollable_log_text_stream_view.tsx | 2 - .../components/navigation/routed_tabs.tsx | 1 - .../metrics_explorer/components/charts.tsx | 4 +- .../lib/adapters/framework/adapter_types.ts | 4 +- .../framework/kibana_framework_adapter.ts | 8 +- .../lib/adapters/metrics/adapter_types.ts | 8 +- .../alerting/metric_threshold/test_mocks.ts | 1 + .../lib/log_analysis/log_entry_anomalies.ts | 1 + .../queries/log_entry_categories.ts | 1 + .../queries/log_entry_category_examples.ts | 1 + .../applications/ingest_manager/index.tsx | 1 - .../components/settings/index.tsx | 1 + .../edit_package_config_page/index.tsx | 3 + .../server/services/agent_config.ts | 2 + .../server/services/agents/crud.ts | 1 + .../server/services/agents/events.ts | 1 + .../services/api_keys/enrollment_api_key.ts | 1 + .../server/services/package_config.ts | 1 + .../helpers/pipelines_clone.helpers.ts | 2 +- .../helpers/pipelines_create.helpers.ts | 2 +- .../helpers/pipelines_edit.helpers.ts | 2 +- .../helpers/setup_environment.tsx | 2 - .../context_menu.tsx | 1 + .../inline_text_input.tsx | 1 + .../pipeline_processors_editor_item.tsx | 7 +- .../components/drop_zone_button.tsx | 3 + .../server/routes/api/create.ts | 1 + .../server/routes/api/update.ts | 1 + .../editor_frame/suggestion_panel.tsx | 2 + .../workspace_panel_wrapper.tsx | 1 + .../dimension_panel/field_select.tsx | 2 + .../public/persistence/saved_object_store.ts | 1 - .../lists/common/schemas/common/schemas.ts | 2 +- .../index_es_list_item_schema.ts | 2 - .../elastic_query/index_es_list_schema.ts | 2 - .../update_es_list_item_schema.ts | 2 - .../elastic_query/update_es_list_schema.ts | 2 - .../search_es_list_item_schema.ts | 2 - .../elastic_response/search_es_list_schema.ts | 2 - .../create_endpoint_list_item_schema.ts | 2 - .../create_exception_list_item_schema.ts | 2 - .../request/create_exception_list_schema.ts | 2 - .../request/create_list_item_schema.ts | 2 - .../delete_endpoint_list_item_schema.ts | 2 - .../delete_exception_list_item_schema.ts | 2 - .../request/delete_exception_list_schema.ts | 2 - .../request/delete_list_item_schema.ts | 2 - .../schemas/request/delete_list_schema.ts | 2 - .../request/export_list_item_query_schema.ts | 2 - .../request/find_endpoint_list_item_schema.ts | 2 - .../find_exception_list_item_schema.ts | 2 - .../request/find_exception_list_schema.ts | 2 - .../schemas/request/find_list_item_schema.ts | 2 - .../schemas/request/find_list_schema.ts | 2 - .../request/import_list_item_query_schema.ts | 2 - .../request/import_list_item_schema.ts | 2 - .../schemas/request/patch_list_item_schema.ts | 2 - .../schemas/request/patch_list_schema.ts | 2 - .../request/read_endpoint_list_item_schema.ts | 2 - .../read_exception_list_item_schema.ts | 2 - .../request/read_exception_list_schema.ts | 2 - .../schemas/request/read_list_item_schema.ts | 2 - .../schemas/request/read_list_schema.ts | 2 - .../update_endpoint_list_item_schema.ts | 2 - .../update_exception_list_item_schema.ts | 2 - .../request/update_exception_list_schema.ts | 2 - .../request/update_list_item_schema.ts | 2 - .../schemas/request/update_list_schema.ts | 2 - .../response/create_endpoint_list_schema.ts | 2 - .../response/exception_list_item_schema.ts | 2 - .../schemas/response/exception_list_schema.ts | 2 - .../found_exception_list_item_schema.ts | 2 - .../response/found_exception_list_schema.ts | 2 - .../response/found_list_item_schema.ts | 2 - .../schemas/response/found_list_schema.ts | 2 - .../schemas/response/list_item_schema.ts | 2 - .../common/schemas/response/list_schema.ts | 2 - .../exceptions_list_so_schema.ts | 2 - .../lists/common/schemas/types/comment.ts | 2 - .../lists/common/schemas/types/entries.ts | 2 - .../common/schemas/types/entry_exists.ts | 2 - .../lists/common/schemas/types/entry_list.ts | 2 - .../lists/common/schemas/types/entry_match.ts | 2 - .../common/schemas/types/entry_match_any.ts | 2 - .../common/schemas/types/entry_nested.ts | 2 - .../exceptions/hooks/use_exception_list.ts | 1 + x-pack/plugins/lists/public/lists/api.ts | 3 + .../server/services/exception_lists/utils.ts | 4 + .../utils/transform_elastic_to_list_item.ts | 2 + .../maps/public/actions/map_actions.ts | 2 - .../layers/tile_layer/tile_layer.test.ts | 1 - .../convert_to_geojson.test.ts | 4 + .../convert_to_lines.test.ts | 5 + .../mvt_field_config_editor.tsx | 1 - .../mvt_single_layer_vector_source_editor.tsx | 1 - .../vector/components/legend/symbol_icon.tsx | 7 +- .../properties/dynamic_icon_property.test.tsx | 1 - .../properties/dynamic_style_property.tsx | 7 +- .../public/classes/util/es_agg_utils.test.ts | 1 + .../tooltip_selector/tooltip_selector.tsx | 2 + .../flyout_body/flyout_body.tsx | 1 - .../flyout_body/layer_wizard_select.test.tsx | 1 + .../maps/public/index_pattern_util.test.ts | 2 + .../maps_legacy_licensing/public/plugin.ts | 1 - .../chart_tooltip/chart_tooltip.tsx | 2 +- .../components/data_grid/column_chart.tsx | 1 + .../components/data_grid/use_data_grid.tsx | 1 - .../contexts/kibana/kibana_context.ts | 1 - .../data_frame_analytics/common/fields.ts | 1 + .../analysis_fields_table.tsx | 4 +- .../hooks/use_index_data.ts | 3 - .../use_exploration_results.ts | 2 - .../outlier_exploration.tsx | 1 - .../outlier_exploration/use_outlier_data.ts | 2 - .../regression_exploration/evaluate_panel.tsx | 2 + .../components/action_clone/clone_button.tsx | 1 + .../analytics_list/expanded_row.tsx | 2 + .../hooks/use_create_analytics_form/state.ts | 1 - .../services/results_service/index.ts | 4 +- .../application/util/custom_url_utils.test.ts | 1 - .../monitoring/public/alerts/panel.tsx | 1 - .../monitoring/public/lib/setup_mode.tsx | 4 +- .../telemetry_collection/get_kibana_stats.ts | 2 + .../observability/public/data_handler.ts | 1 - .../public/hooks/use_route_params.tsx | 2 - .../public/services/get_news_feed.ts | 1 - .../services/get_observability_alerts.ts | 1 - .../oss_telemetry/server/test_utils/index.ts | 1 - .../application/components/main_controls.tsx | 1 + x-pack/plugins/painless_lab/public/links.ts | 1 + .../lib/job_completion_notifications.ts | 6 +- .../get_csv_panel_action.test.ts | 4 +- .../export_types/common/validate_urls.test.ts | 1 + .../server/lib/screenshots/observable.test.ts | 1 - .../server/routes/generation.test.ts | 6 +- .../reporting/server/routes/jobs.test.ts | 6 +- .../server/test_helpers/create_mock_server.ts | 1 - .../rollup/server/lib/format_es_error.ts | 7 +- .../components/percentage_badge.tsx | 2 + .../register_privileges_with_cluster.test.ts | 1 + .../schemas/common/schemas.ts | 2 +- .../request/add_prepackaged_rules_schema.ts | 2 - .../add_prepackged_rules_schema.test.ts | 1 + .../request/create_rules_schema.test.ts | 2 + .../schemas/request/create_rules_schema.ts | 2 - .../schemas/request/export_rules_schema.ts | 2 - .../schemas/request/find_rules_schema.ts | 2 - .../request/import_rules_schema.test.ts | 1 + .../schemas/request/import_rules_schema.ts | 2 - .../schemas/request/patch_rules_schema.ts | 2 - .../schemas/request/query_rules_schema.ts | 2 - .../request/set_signal_status_schema.ts | 2 - .../request/update_rules_schema.test.ts | 1 + .../schemas/request/update_rules_schema.ts | 2 - .../schemas/response/error_schema.ts | 2 - .../schemas/response/import_rules_schema.ts | 2 - .../response/prepackaged_rules_schema.ts | 2 - .../prepackaged_rules_status_schema.ts | 2 - .../schemas/response/rules_schema.ts | 1 - .../response/type_timeline_only_schema.ts | 2 - .../types/default_max_signals_number.ts | 1 - .../types/default_risk_score_mapping_array.ts | 1 - .../types/default_severity_mapping_array.ts | 1 - .../detection_engine/transform_actions.ts | 2 +- .../common/types/timeline/index.ts | 19 ++-- .../security_solution/public/app/index.tsx | 1 - .../components/configure_cases/index.tsx | 1 + .../components/endpoint/link_to_app.tsx | 1 - .../components/exceptions/builder/helpers.tsx | 1 - .../common/components/exceptions/helpers.tsx | 2 + .../viewer/exception_item/index.stories.tsx | 1 + .../public/common/components/links/index.tsx | 2 + .../navigation/breadcrumbs/index.ts | 1 - .../public/common/hooks/types.ts | 1 - .../common/lib/compose/kibana_compose.tsx | 1 - .../public/common/lib/kibana/services.ts | 1 - .../public/common/mock/kibana_core.ts | 1 - .../alerts_histogram_panel/helpers.tsx | 1 + .../alerts_table/default_config.tsx | 2 - .../rules/description_step/index.test.tsx | 1 - .../detection_engine/rules/types.ts | 2 - .../detection_engine/rules/create/index.tsx | 2 - .../detection_engine/rules/details/index.tsx | 7 +- .../detection_engine/rules/edit/index.tsx | 2 - .../pages/detection_engine/rules/utils.ts | 1 - .../public/hosts/pages/details/utils.ts | 1 - .../view/details/host_details.tsx | 2 +- .../pages/endpoint_hosts/view/index.test.tsx | 1 + .../pages/endpoint_hosts/view/index.tsx | 1 - .../policy/models/policy_details_config.ts | 16 ++-- .../policy/store/policy_details/selectors.ts | 1 + .../public/network/pages/ip_details/utils.ts | 1 - .../alerts_by_category/index.test.tsx | 2 - .../models/indexed_process_tree/index.ts | 2 - .../public/resolver/store/data/selectors.ts | 7 +- .../store/middleware/resolver_tree_fetcher.ts | 2 - .../simulator/mock_resolver.tsx | 1 - .../public/resolver/types.ts | 8 +- .../public/resolver/view/map.tsx | 2 - .../view/resolver_without_providers.tsx | 2 - .../components/formatted_ip/index.tsx | 2 +- .../open_timeline/export_timeline/mocks.ts | 1 + .../components/open_timeline/helpers.ts | 3 - .../timelines_table/actions_columns.tsx | 2 - .../server/endpoint/routes/resolver/entity.ts | 1 + .../manifest_manager/manifest_manager.ts | 1 + .../routes/signals/query_signals_route.ts | 2 +- .../get_rule_actions_saved_object.ts | 1 + .../signals/bulk_create_threshold_signals.ts | 1 + .../lib/detection_engine/signals/types.ts | 1 + .../server/lib/framework/types.ts | 2 +- .../server/lib/matrix_histogram/utils.ts | 2 + .../timeline/routes/utils/create_timelines.ts | 1 - .../server/lib/tls/elasticsearch_adapter.ts | 2 +- .../helpers/home.helpers.ts | 1 - .../helpers/policy_add.helpers.ts | 1 - .../helpers/policy_edit.helpers.ts | 1 - .../helpers/repository_add.helpers.ts | 1 - .../helpers/repository_edit.helpers.ts | 1 - .../helpers/restore_snapshot.helpers.ts | 1 - .../helpers/setup_environment.tsx | 1 - .../policy_list/policy_table/policy_table.tsx | 1 - .../repository_table/repository_table.tsx | 1 - .../snapshot_table/snapshot_table.tsx | 1 - .../server/lib/wrap_es_error.ts | 7 +- .../snapshot_restore/test/fixtures/policy.ts | 1 - .../server/lib/spaces_client/spaces_client.ts | 2 + .../spaces_usage_collector.ts | 1 + .../plugins/task_manager/server/task_store.ts | 2 + .../aggregation_list/popover_form.tsx | 1 - .../components/group_by_list/popover_form.tsx | 4 +- .../application/components/health_check.tsx | 3 + .../public/custom_time_range_action.test.ts | 2 - ...nnected_flyout_manage_drilldowns.story.tsx | 6 +- .../flyout_drilldown_wizard.story.tsx | 8 +- .../deprecations/reindex/flyout/container.tsx | 1 + .../reindex/flyout/step_progress.tsx | 1 + .../uptime/server/lib/alerts/status_check.ts | 1 + .../__tests__/get_monitor_status.test.ts | 2 + .../server/lib/requests/__tests__/helper.ts | 1 + .../lib/requests/get_monitor_availability.ts | 1 + .../lib/requests/get_monitor_locations.ts | 1 + .../server/lib/requests/get_monitor_status.ts | 2 +- .../helpers/app_context.mock.tsx | 1 - .../helpers/setup_environment.ts | 1 - .../helpers/watch_create_json.helpers.ts | 2 - .../helpers/watch_create_threshold.helpers.ts | 2 - .../helpers/watch_edit.helpers.ts | 2 - .../helpers/watch_list.helpers.ts | 1 - .../helpers/watch_status.helpers.ts | 1 - .../public/application/app_context.tsx | 1 + .../alerting_api_integration/common/config.ts | 1 - .../spaces_only/tests/alerting/alerts_base.ts | 1 - .../apis/lens/existing_fields.ts | 1 - .../api_integration/apis/lens/field_stats.ts | 1 - .../api_integration/apis/lens/telemetry.ts | 1 - .../apis/metrics_ui/log_analysis.ts | 1 - .../apis/ml/annotations/create_annotations.ts | 1 - .../apis/ml/annotations/delete_annotations.ts | 1 - .../apis/ml/annotations/get_annotations.ts | 1 - .../apis/ml/annotations/update_annotations.ts | 1 - .../apis/ml/anomaly_detectors/create.ts | 1 - .../apis/ml/calendars/create_calendars.ts | 1 - .../apis/ml/calendars/delete_calendars.ts | 1 - .../apis/ml/calendars/get_calendars.ts | 1 - .../apis/ml/calendars/update_calendars.ts | 1 - .../data_visualizer/get_field_histograms.ts | 1 - .../ml/data_visualizer/get_field_stats.ts | 1 - .../ml/data_visualizer/get_overall_stats.ts | 1 - .../ml/fields_service/field_cardinality.ts | 1 - .../ml/fields_service/time_field_range.ts | 1 - .../apis/ml/filters/create_filters.ts | 1 - .../apis/ml/filters/delete_filters.ts | 1 - .../apis/ml/filters/get_filters.ts | 1 - .../apis/ml/filters/update_filters.ts | 1 - .../job_validation/bucket_span_estimator.ts | 1 - .../calculate_model_memory_limit.ts | 1 - .../apis/ml/job_validation/cardinality.ts | 1 - .../apis/ml/job_validation/validate.ts | 1 - .../ml/jobs/categorization_field_examples.ts | 1 - .../apis/ml/jobs/close_jobs.ts | 1 - .../apis/ml/jobs/delete_jobs.ts | 1 - .../apis/ml/jobs/jobs_summary.ts | 1 - .../apis/ml/modules/get_module.ts | 1 - .../apis/ml/modules/recognize_module.ts | 1 - .../apis/ml/modules/setup_module.ts | 1 - .../ml/results/get_anomalies_table_data.ts | 1 - .../apis/transform/delete_transforms.ts | 1 - .../case_api_integration/common/lib/mock.ts | 1 + .../case_api_integration/common/lib/utils.ts | 2 + .../common/config.ts | 1 - .../detection_engine_api_integration/utils.ts | 5 + x-pack/test/functional/apps/lens/index.ts | 1 - .../functional/apps/lens/lens_reporting.ts | 1 - .../apps/lens/persistent_context.ts | 1 - .../test/functional/apps/lens/smokescreen.ts | 1 - .../apps/ml/anomaly_detection/advanced_job.ts | 1 - .../ml/anomaly_detection/anomaly_explorer.ts | 1 - .../anomaly_detection/categorization_job.ts | 1 - .../ml/anomaly_detection/date_nanos_job.ts | 1 - .../ml/anomaly_detection/multi_metric_job.ts | 1 - .../ml/anomaly_detection/population_job.ts | 1 - .../ml/anomaly_detection/saved_search_job.ts | 1 - .../ml/anomaly_detection/single_metric_job.ts | 1 - .../anomaly_detection/single_metric_viewer.ts | 1 - .../data_visualizer/file_data_visualizer.ts | 1 - .../data_visualizer/index_data_visualizer.ts | 1 - x-pack/test/functional_with_es_ssl/config.ts | 1 - .../fixtures/plugins/alerts/public/plugin.ts | 1 + .../apis/agent_config/agent_config.ts | 1 + .../test/licensing_plugin/public/updates.ts | 8 +- x-pack/test/mocha_decorations.d.ts | 1 - .../apis/implicit_flow/index.ts | 1 - .../apis/implicit_flow/oidc_auth.ts | 1 - .../implicit_flow.config.ts | 1 - .../licensed_feature_usage/feature_usage.ts | 1 - x-pack/test/plugin_functional/config.ts | 1 - .../global_search/global_search_api.ts | 2 +- .../global_search/global_search_providers.ts | 2 +- .../test/security_solution_cypress/runner.ts | 1 + .../security_and_spaces/apis/get_all.ts | 2 + x-pack/test/ui_capabilities/common/config.ts | 1 - .../common/nav_links_builder.ts | 4 +- x-pack/typings/rison_node.d.ts | 4 +- yarn.lock | 69 +++++++++----- 583 files changed, 669 insertions(+), 779 deletions(-) diff --git a/docs/development/plugins/kibana_utils/public/state_sync/kibana-plugin-plugins-kibana_utils-public-state_sync.isyncstateref.md b/docs/development/plugins/kibana_utils/public/state_sync/kibana-plugin-plugins-kibana_utils-public-state_sync.isyncstateref.md index 137db68cd6b48..b4bc93fd78a9d 100644 --- a/docs/development/plugins/kibana_utils/public/state_sync/kibana-plugin-plugins-kibana_utils-public-state_sync.isyncstateref.md +++ b/docs/development/plugins/kibana_utils/public/state_sync/kibana-plugin-plugins-kibana_utils-public-state_sync.isyncstateref.md @@ -8,7 +8,7 @@ Signature: ```typescript -export interface ISyncStateRef +export interface ISyncStateRef ``` ## Properties diff --git a/examples/alerting_example/public/components/create_alert.tsx b/examples/alerting_example/public/components/create_alert.tsx index a8e1f06cb3914..72e3835b100fe 100644 --- a/examples/alerting_example/public/components/create_alert.tsx +++ b/examples/alerting_example/public/components/create_alert.tsx @@ -30,6 +30,7 @@ import { ALERTING_EXAMPLE_APP_ID } from '../../common/constants'; export const CreateAlert = ({ http, + // eslint-disable-next-line @typescript-eslint/naming-convention triggers_actions_ui, charts, uiSettings, diff --git a/examples/alerting_example/public/plugin.tsx b/examples/alerting_example/public/plugin.tsx index f0635a1071f64..3f972fa9fe2ee 100644 --- a/examples/alerting_example/public/plugin.tsx +++ b/examples/alerting_example/public/plugin.tsx @@ -46,6 +46,7 @@ export interface AlertingExamplePublicStartDeps { export class AlertingExamplePlugin implements Plugin { public setup( core: CoreSetup, + // eslint-disable-next-line @typescript-eslint/naming-convention { alerts, triggers_actions_ui, developerExamples }: AlertingExamplePublicSetupDeps ) { core.application.register({ diff --git a/kibana.d.ts b/kibana.d.ts index 21e3e99abaa90..d64752abd8b60 100644 --- a/kibana.d.ts +++ b/kibana.d.ts @@ -35,7 +35,6 @@ import * as LegacyKibanaServer from './src/legacy/server/kbn_server'; /** * Re-export legacy types under a namespace. */ -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Legacy { export type KibanaConfig = LegacyKibanaServer.KibanaConfig; export type Request = LegacyKibanaServer.Request; diff --git a/package.json b/package.json index 880534997cff0..aaa7ae7ee4684 100644 --- a/package.json +++ b/package.json @@ -400,8 +400,8 @@ "@types/vinyl": "^2.0.4", "@types/vinyl-fs": "^2.4.11", "@types/zen-observable": "^0.8.0", - "@typescript-eslint/eslint-plugin": "^2.34.0", - "@typescript-eslint/parser": "^2.34.0", + "@typescript-eslint/eslint-plugin": "^3.7.1", + "@typescript-eslint/parser": "^3.7.1", "angular-mocks": "^1.7.9", "archiver": "^3.1.1", "axe-core": "^3.4.1", @@ -425,6 +425,7 @@ "eslint-plugin-babel": "^5.3.0", "eslint-plugin-ban": "^1.4.0", "eslint-plugin-cypress": "^2.8.1", + "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-import": "^2.19.1", "eslint-plugin-jest": "^23.10.0", "eslint-plugin-jsx-a11y": "^6.2.3", diff --git a/packages/eslint-config-kibana/package.json b/packages/eslint-config-kibana/package.json index e14423d681a4e..967e53249da75 100644 --- a/packages/eslint-config-kibana/package.json +++ b/packages/eslint-config-kibana/package.json @@ -11,17 +11,18 @@ "author": "Spencer Alger ", "license": "Apache-2.0", "bugs": { - "url": "https://github.com/elastic/eslint-config-kibana/issues" + "url": "https://github.com/elastic/kibana/tree/master/packages/eslint-config-kibana" }, - "homepage": "https://github.com/elastic/eslint-config-kibana#readme", + "homepage": "https://github.com/elastic/kibana/tree/master/packages/eslint-config-kibana", "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^2.34.0", - "@typescript-eslint/parser": "^2.34.0", + "@typescript-eslint/eslint-plugin": "^3.7.1", + "@typescript-eslint/parser": "^3.7.1", "babel-eslint": "^10.0.3", "eslint": "^6.8.0", "eslint-plugin-babel": "^5.3.0", "eslint-plugin-ban": "^1.4.0", "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-import": "^2.19.1", "eslint-plugin-jest": "^23.10.0", "eslint-plugin-mocha": "^6.2.2", diff --git a/packages/eslint-config-kibana/typescript.js b/packages/eslint-config-kibana/typescript.js index a55ca9391011d..18b11eb62beef 100644 --- a/packages/eslint-config-kibana/typescript.js +++ b/packages/eslint-config-kibana/typescript.js @@ -8,6 +8,11 @@ const PKG = require('../../package.json'); const eslintConfigPrettierTypescriptEslintRules = require('eslint-config-prettier/@typescript-eslint').rules; +// The current implementation excluded all the variables matching the regexp. +// We should remove it as soon as multiple underscores are supported by the linter. +// https://github.com/typescript-eslint/typescript-eslint/issues/1712 +// Due to the same reason we have to duplicate the "filter" option for "default" and other "selectors". +const allowedNameRegexp = '^(UNSAFE_|_{1,3})|_{1,3}$'; module.exports = { overrides: [ { @@ -19,6 +24,7 @@ module.exports = { 'ban', 'import', 'prefer-object-spread', + 'eslint-comments' ], settings: { @@ -87,16 +93,82 @@ module.exports = { 'React.StatelessComponent': { message: 'Use FunctionComponent instead.', fixWith: 'React.FunctionComponent' - } + }, + // used in the codebase in the wild + '{}': false, + 'object': false, + 'Function': false, } }], 'camelcase': 'off', - '@typescript-eslint/camelcase': ['error', { - 'properties': 'never', - 'ignoreDestructuring': true, - 'allow': ['^[A-Z0-9_]+$', '^UNSAFE_'] - }], - '@typescript-eslint/class-name-casing': 'error', + '@typescript-eslint/naming-convention': [ + 'error', + { + selector: 'default', + format: ['camelCase'], + filter: { + regex: allowedNameRegexp, + match: false + } + }, + { + selector: 'variable', + format: [ + 'camelCase', + 'UPPER_CASE', // const SOMETHING = ... + 'PascalCase', // React.FunctionComponent = + ], + filter: { + regex: allowedNameRegexp, + match: false + } + }, + { + selector: 'parameter', + format: [ + 'camelCase', + 'PascalCase', + ], + filter: { + regex: allowedNameRegexp, + match: false + } + }, + { + selector: 'memberLike', + format: [ + 'camelCase', + 'PascalCase', + 'snake_case', // keys in elasticsearch requests / responses + 'UPPER_CASE' + ], + filter: { + regex: allowedNameRegexp, + match: false + } + }, + { + selector: 'function', + format: [ + 'camelCase', + 'PascalCase' // React.FunctionComponent = + ], + filter: { + regex: allowedNameRegexp, + match: false + } + }, + { + selector: 'typeLike', + format: ['PascalCase', 'UPPER_CASE'], + leadingUnderscore: 'allow', + trailingUnderscore: 'allow', + }, + { + selector: 'enum', + format: ['PascalCase', 'UPPER_CASE', 'camelCase'], + }, + ], '@typescript-eslint/explicit-member-accessibility': ['error', { accessibility: 'off', @@ -145,10 +217,12 @@ module.exports = { 'no-extend-native': 'error', 'no-eval': 'error', 'no-new-wrappers': 'error', + 'no-script-url': 'error', 'no-shadow': 'error', 'no-throw-literal': 'error', 'no-undef-init': 'error', 'no-unsafe-finally': 'error', + 'no-unsanitized/property': 'error', 'no-unused-expressions': 'error', 'no-unused-labels': 'error', 'no-var': 'error', @@ -171,6 +245,9 @@ module.exports = { ], 'import/no-default-export': 'error', + + 'eslint-comments/no-unused-disable': 'error', + 'eslint-comments/no-unused-enable': 'error' }, eslintConfigPrettierTypescriptEslintRules ) diff --git a/packages/kbn-plugin-helpers/src/lib/utils.ts b/packages/kbn-plugin-helpers/src/lib/utils.ts index 0348f9f8deda9..be7fa65cc2939 100644 --- a/packages/kbn-plugin-helpers/src/lib/utils.ts +++ b/packages/kbn-plugin-helpers/src/lib/utils.ts @@ -26,10 +26,10 @@ export function babelRegister() { try { // add support for moved @babel/register source: https://github.com/elastic/kibana/pull/13973 - require(resolve(plugin.kibanaRoot, 'src/setup_node_env/babel_register')); // eslint-disable-line import/no-dynamic-require + require(resolve(plugin.kibanaRoot, 'src/setup_node_env/babel_register')); } catch (error) { if (error.code === 'MODULE_NOT_FOUND') { - require(resolve(plugin.kibanaRoot, 'src/optimize/babel/register')); // eslint-disable-line import/no-dynamic-require + require(resolve(plugin.kibanaRoot, 'src/optimize/babel/register')); } else { throw error; } diff --git a/src/cli/cluster/cluster_manager.ts b/src/cli/cluster/cluster_manager.ts index f193f33e6f47e..5ada95bfeef94 100644 --- a/src/cli/cluster/cluster_manager.ts +++ b/src/cli/cluster/cluster_manager.ts @@ -354,6 +354,6 @@ export class ClusterManager { onWatcherError = (err: any) => { this.log.bad('failed to watch files!\n', err.stack); - process.exit(1); // eslint-disable-line no-process-exit + process.exit(1); }; } diff --git a/src/core/server/config/config_service.test.ts b/src/core/server/config/config_service.test.ts index 236cf6579d7c8..95153447bd4a9 100644 --- a/src/core/server/config/config_service.test.ts +++ b/src/core/server/config/config_service.test.ts @@ -17,8 +17,6 @@ * under the License. */ -/* eslint-disable max-classes-per-file */ - import { BehaviorSubject, Observable } from 'rxjs'; import { first, take } from 'rxjs/operators'; diff --git a/src/core/server/http/integration_tests/lifecycle_handlers.test.ts b/src/core/server/http/integration_tests/lifecycle_handlers.test.ts index 2120fb5b881de..e23426e630455 100644 --- a/src/core/server/http/integration_tests/lifecycle_handlers.test.ts +++ b/src/core/server/http/integration_tests/lifecycle_handlers.test.ts @@ -17,10 +17,10 @@ * under the License. */ -import { resolve } from 'path'; import supertest from 'supertest'; import { BehaviorSubject } from 'rxjs'; import { ByteSizeValue } from '@kbn/config-schema'; +import pkg from '../../../../../package.json'; import { createHttpServer } from '../test_utils'; import { HttpService } from '../http_service'; @@ -30,8 +30,7 @@ import { IRouter, RouteRegistrar } from '../router'; import { configServiceMock } from '../../config/config_service.mock'; import { contextServiceMock } from '../../context/context_service.mock'; -const pkgPath = resolve(__dirname, '../../../../../package.json'); -const actualVersion = require(pkgPath).version; +const actualVersion = pkg.version; const versionHeader = 'kbn-version'; const xsrfHeader = 'kbn-xsrf'; const nameHeader = 'kbn-name'; diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index fada40e773f12..976d92e6fe7fb 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -375,6 +375,7 @@ export class LegacyService implements CoreService { // from being started multiple times in different processes. // We only want one REPL. if (this.coreContext.env.cliArgs.repl && process.env.kbnWorkerType === 'server') { + // eslint-disable-next-line @typescript-eslint/no-var-requires require('../../../cli/repl').startRepl(kbnServer); } diff --git a/src/core/server/saved_objects/migrations/core/call_cluster.ts b/src/core/server/saved_objects/migrations/core/call_cluster.ts index 628f2785e6c64..ad2e0e9660a63 100644 --- a/src/core/server/saved_objects/migrations/core/call_cluster.ts +++ b/src/core/server/saved_objects/migrations/core/call_cluster.ts @@ -25,7 +25,6 @@ import { IndexMapping } from '../../mappings'; -/* eslint-disable @typescript-eslint/unified-signatures */ export interface CallCluster { (path: 'bulk', opts: { body: object[] }): Promise; (path: 'count', opts: CountOpts): Promise<{ count: number; _shards: ShardsInfo }>; @@ -49,7 +48,6 @@ export interface CallCluster { error?: ErrorResponse; }>; } -/* eslint-enable @typescript-eslint/unified-signatures */ /////////////////////////////////////////////////////////////////// // callCluster argument type definitions diff --git a/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts b/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts index 28afdefe1413f..3d455ff9d594c 100644 --- a/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts @@ -23,12 +23,12 @@ import { registerBulkCreateRoute } from '../bulk_create'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; describe('POST /api/saved_objects/_bulk_create', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; - let handlerContext: setupServerReturn['handlerContext']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let handlerContext: SetupServerReturn['handlerContext']; let savedObjectsClient: ReturnType; beforeEach(async () => { diff --git a/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts b/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts index 521e62e16b1d8..5deea94299d7d 100644 --- a/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts @@ -23,12 +23,12 @@ import { registerBulkGetRoute } from '../bulk_get'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; describe('POST /api/saved_objects/_bulk_get', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; - let handlerContext: setupServerReturn['handlerContext']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let handlerContext: SetupServerReturn['handlerContext']; let savedObjectsClient: ReturnType; beforeEach(async () => { diff --git a/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts b/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts index 9c888406b0c96..45f310ecc3fa2 100644 --- a/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts @@ -23,12 +23,12 @@ import { registerBulkUpdateRoute } from '../bulk_update'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; describe('PUT /api/saved_objects/_bulk_update', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; - let handlerContext: setupServerReturn['handlerContext']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let handlerContext: SetupServerReturn['handlerContext']; let savedObjectsClient: ReturnType; beforeEach(async () => { diff --git a/src/core/server/saved_objects/routes/integration_tests/create.test.ts b/src/core/server/saved_objects/routes/integration_tests/create.test.ts index ba3d620f8fdb5..9e69c3dbc64ec 100644 --- a/src/core/server/saved_objects/routes/integration_tests/create.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/create.test.ts @@ -23,12 +23,12 @@ import { registerCreateRoute } from '../create'; import { savedObjectsClientMock } from '../../service/saved_objects_client.mock'; import { setupServer } from '../test_utils'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; describe('POST /api/saved_objects/{type}', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; - let handlerContext: setupServerReturn['handlerContext']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let handlerContext: SetupServerReturn['handlerContext']; let savedObjectsClient: ReturnType; const clientResponse = { diff --git a/src/core/server/saved_objects/routes/integration_tests/delete.test.ts b/src/core/server/saved_objects/routes/integration_tests/delete.test.ts index 652d267f08fe7..a58f400ec3e1d 100644 --- a/src/core/server/saved_objects/routes/integration_tests/delete.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/delete.test.ts @@ -23,12 +23,12 @@ import { registerDeleteRoute } from '../delete'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; describe('DELETE /api/saved_objects/{type}/{id}', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; - let handlerContext: setupServerReturn['handlerContext']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let handlerContext: SetupServerReturn['handlerContext']; let savedObjectsClient: ReturnType; beforeEach(async () => { diff --git a/src/core/server/saved_objects/routes/integration_tests/export.test.ts b/src/core/server/saved_objects/routes/integration_tests/export.test.ts index 7b342dde2febe..d47f7c6050d8f 100644 --- a/src/core/server/saved_objects/routes/integration_tests/export.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/export.test.ts @@ -29,7 +29,7 @@ import { SavedObjectConfig } from '../../saved_objects_config'; import { registerExportRoute } from '../export'; import { setupServer, createExportableType } from '../test_utils'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; const exportSavedObjectsToStream = exportMock.exportSavedObjectsToStream as jest.Mock; const allowedTypes = ['index-pattern', 'search']; const config = { @@ -38,9 +38,9 @@ const config = { } as SavedObjectConfig; describe('POST /api/saved_objects/_export', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; - let handlerContext: setupServerReturn['handlerContext']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let handlerContext: SetupServerReturn['handlerContext']; beforeEach(async () => { ({ server, httpSetup, handlerContext } = await setupServer()); diff --git a/src/core/server/saved_objects/routes/integration_tests/find.test.ts b/src/core/server/saved_objects/routes/integration_tests/find.test.ts index d5a7710f04b39..4fe9cbe415cd6 100644 --- a/src/core/server/saved_objects/routes/integration_tests/find.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/find.test.ts @@ -25,12 +25,12 @@ import { registerFindRoute } from '../find'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; describe('GET /api/saved_objects/_find', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; - let handlerContext: setupServerReturn['handlerContext']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let handlerContext: SetupServerReturn['handlerContext']; let savedObjectsClient: ReturnType; const clientResponse = { diff --git a/src/core/server/saved_objects/routes/integration_tests/import.test.ts b/src/core/server/saved_objects/routes/integration_tests/import.test.ts index c4e304a3f892f..61f32a420d92b 100644 --- a/src/core/server/saved_objects/routes/integration_tests/import.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/import.test.ts @@ -24,7 +24,7 @@ import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { SavedObjectConfig } from '../../saved_objects_config'; import { setupServer, createExportableType } from '../test_utils'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; const allowedTypes = ['index-pattern', 'visualization', 'dashboard']; const config = { @@ -33,9 +33,9 @@ const config = { } as SavedObjectConfig; describe('POST /internal/saved_objects/_import', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; - let handlerContext: setupServerReturn['handlerContext']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let handlerContext: SetupServerReturn['handlerContext']; let savedObjectsClient: ReturnType; const emptyResponse = { diff --git a/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts b/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts index 8d021580da36c..d86ac985d9da1 100644 --- a/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts @@ -23,11 +23,11 @@ import { registerLogLegacyImportRoute } from '../log_legacy_import'; import { loggingSystemMock } from '../../../logging/logging_system.mock'; import { setupServer } from '../test_utils'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; describe('POST /api/saved_objects/_log_legacy_import', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; let logger: ReturnType; beforeEach(async () => { diff --git a/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts b/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts index 27750ec692e5a..6a6976b513ca1 100644 --- a/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts @@ -24,7 +24,7 @@ import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer, createExportableType } from '../test_utils'; import { SavedObjectConfig } from '../../saved_objects_config'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; const allowedTypes = ['index-pattern', 'visualization', 'dashboard']; const config = { @@ -33,9 +33,9 @@ const config = { } as SavedObjectConfig; describe('POST /api/saved_objects/_resolve_import_errors', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; - let handlerContext: setupServerReturn['handlerContext']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let handlerContext: SetupServerReturn['handlerContext']; let savedObjectsClient: ReturnType; beforeEach(async () => { diff --git a/src/core/server/saved_objects/routes/integration_tests/update.test.ts b/src/core/server/saved_objects/routes/integration_tests/update.test.ts index eb6eb1cdb6bd9..dfccb651d72d7 100644 --- a/src/core/server/saved_objects/routes/integration_tests/update.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/update.test.ts @@ -23,12 +23,12 @@ import { registerUpdateRoute } from '../update'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { setupServer } from '../test_utils'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; describe('PUT /api/saved_objects/{type}/{id?}', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; - let handlerContext: setupServerReturn['handlerContext']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let handlerContext: SetupServerReturn['handlerContext']; let savedObjectsClient: ReturnType; beforeEach(async () => { diff --git a/src/core/server/saved_objects/serialization/serializer.ts b/src/core/server/saved_objects/serialization/serializer.ts index 3b19d494d8ecf..c0c09b6375bdf 100644 --- a/src/core/server/saved_objects/serialization/serializer.ts +++ b/src/core/server/saved_objects/serialization/serializer.ts @@ -17,8 +17,6 @@ * under the License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import uuid from 'uuid'; import { decodeVersion, encodeVersion } from '../version'; import { ISavedObjectTypeRegistry } from '../saved_objects_type_registry'; @@ -97,6 +95,7 @@ export class SavedObjectsSerializer { namespaces, attributes, migrationVersion, + // eslint-disable-next-line @typescript-eslint/naming-convention updated_at, version, references, diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 8b7b1d62c1b7d..d7e1ecba0370b 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -1242,6 +1242,7 @@ export class SavedObjectsRepository { response )[0] as any; + // eslint-disable-next-line @typescript-eslint/naming-convention const { [type]: attributes, references, updated_at } = documentToSave; if (error) { return { diff --git a/src/core/server/status/status_service.ts b/src/core/server/status/status_service.ts index 569b044a4fb27..aea335e64babf 100644 --- a/src/core/server/status/status_service.ts +++ b/src/core/server/status/status_service.ts @@ -17,8 +17,6 @@ * under the License. */ -/* eslint-disable max-classes-per-file */ - import { Observable, combineLatest } from 'rxjs'; import { map, distinctUntilChanged, shareReplay, take } from 'rxjs/operators'; import { isDeepStrictEqual } from 'util'; diff --git a/src/core/server/utils/package_json.ts b/src/core/server/utils/package_json.ts index ab1700e681a92..fcffa6593d599 100644 --- a/src/core/server/utils/package_json.ts +++ b/src/core/server/utils/package_json.ts @@ -22,6 +22,5 @@ import { dirname } from 'path'; export const pkg = { __filename: require.resolve('../../../../package.json'), __dirname: dirname(require.resolve('../../../../package.json')), - // eslint-disable no-var-requires ...require('../../../../package.json'), }; diff --git a/src/legacy/core_plugins/elasticsearch/index.d.ts b/src/legacy/core_plugins/elasticsearch/index.d.ts index df713160137a6..683f58b1a80ce 100644 --- a/src/legacy/core_plugins/elasticsearch/index.d.ts +++ b/src/legacy/core_plugins/elasticsearch/index.d.ts @@ -17,7 +17,6 @@ * under the License. */ -/* eslint-disable */ import { Client as ESClient, GenericParams, @@ -145,7 +144,6 @@ import { TasksGetParams, TasksListParams, } from 'elasticsearch'; -/* eslint-enable */ export class Cluster { public callWithRequest: CallClusterWithRequest; diff --git a/src/legacy/ui/public/new_platform/__mocks__/helpers.ts b/src/legacy/ui/public/new_platform/__mocks__/helpers.ts index e3aa49baeae0d..35aa8e4830428 100644 --- a/src/legacy/ui/public/new_platform/__mocks__/helpers.ts +++ b/src/legacy/ui/public/new_platform/__mocks__/helpers.ts @@ -17,7 +17,6 @@ * under the License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import { coreMock } from '../../../../../core/public/mocks'; import { dataPluginMock } from '../../../../../plugins/data/public/mocks'; import { embeddablePluginMock } from '../../../../../plugins/embeddable/public/mocks'; @@ -33,7 +32,6 @@ import { advancedSettingsMock } from '../../../../../plugins/advanced_settings/p import { savedObjectsManagementPluginMock } from '../../../../../plugins/saved_objects_management/public/mocks'; import { visualizationsPluginMock } from '../../../../../plugins/visualizations/public/mocks'; import { discoverPluginMock } from '../../../../../plugins/discover/public/mocks'; -/* eslint-enable @kbn/eslint/no-restricted-paths */ export const pluginsMock = { createSetup: () => ({ diff --git a/src/legacy/ui/public/new_platform/new_platform.ts b/src/legacy/ui/public/new_platform/new_platform.ts index ddf768495a9da..37787ffbde4fc 100644 --- a/src/legacy/ui/public/new_platform/new_platform.ts +++ b/src/legacy/ui/public/new_platform/new_platform.ts @@ -174,6 +174,7 @@ export const legacyAppRegister = (app: App) => { } legacyAppRegistered = true; + // eslint-disable-next-line @typescript-eslint/no-var-requires require('ui/chrome').setRootController(app.id, ($scope: IScope, $element: JQLite) => { const element = document.createElement('div'); $element[0].appendChild(element); diff --git a/src/legacy/ui/public/new_platform/set_services.test.ts b/src/legacy/ui/public/new_platform/set_services.test.ts index b7878954846fa..74e789ec220b1 100644 --- a/src/legacy/ui/public/new_platform/set_services.test.ts +++ b/src/legacy/ui/public/new_platform/set_services.test.ts @@ -18,9 +18,7 @@ */ import { __reset__, __setup__, __start__, PluginsSetup, PluginsStart } from './new_platform'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import * as dataServices from '../../../../plugins/data/public/services'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import * as visualizationsServices from '../../../../plugins/visualizations/public/services'; import { LegacyCoreSetup, LegacyCoreStart } from '../../../../core/public'; import { coreMock } from '../../../../core/public/mocks'; diff --git a/src/plugins/advanced_settings/public/management_app/components/field/field.tsx b/src/plugins/advanced_settings/public/management_app/components/field/field.tsx index 32bfc0826e7c4..45e359679056f 100644 --- a/src/plugins/advanced_settings/public/management_app/components/field/field.tsx +++ b/src/plugins/advanced_settings/public/management_app/components/field/field.tsx @@ -664,7 +664,9 @@ export class Field extends PureComponent { const isInvalid = unsavedChanges?.isInvalid; const className = classNames('mgtAdvancedSettings__field', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'mgtAdvancedSettings__field--unsaved': unsavedChanges, + // eslint-disable-next-line @typescript-eslint/naming-convention 'mgtAdvancedSettings__field--invalid': isInvalid, }); const id = setting.name; diff --git a/src/plugins/advanced_settings/public/management_app/components/form/form.tsx b/src/plugins/advanced_settings/public/management_app/components/form/form.tsx index 142ea06c7dce4..5533f684870d9 100644 --- a/src/plugins/advanced_settings/public/management_app/components/form/form.tsx +++ b/src/plugins/advanced_settings/public/management_app/components/form/form.tsx @@ -336,6 +336,7 @@ export class Form extends PureComponent { if (pageNav?.value === 'legacy') { bottomBarClasses = classNames('mgtAdvancedSettingsForm__bottomBar', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'mgtAdvancedSettingsForm__bottomBar--pushForNav': localStorage.getItem(NAV_IS_LOCKED_KEY) === 'true', }); diff --git a/src/plugins/console/public/application/containers/console_history/console_history.tsx b/src/plugins/console/public/application/containers/console_history/console_history.tsx index 433ad15990d77..e44d215775c69 100644 --- a/src/plugins/console/public/application/containers/console_history/console_history.tsx +++ b/src/plugins/console/public/application/containers/console_history/console_history.tsx @@ -160,7 +160,6 @@ export function ConsoleHistory({ close }: Props) { const isSelected = viewingReq === req; return ( // Ignore a11y issues on li's - // eslint-disable-next-line
  • { const aliasRules = { filter: {}, diff --git a/src/plugins/console/server/lib/spec_definitions/js/document.ts b/src/plugins/console/server/lib/spec_definitions/js/document.ts index f8214faab2681..f235860232cdc 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/document.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/document.ts @@ -18,7 +18,6 @@ */ import { SpecDefinitionsService } from '../../../services'; -/* eslint-disable @typescript-eslint/camelcase */ export const document = (specService: SpecDefinitionsService) => { specService.addEndpointDescription('update', { data_autocomplete_rules: { diff --git a/src/plugins/console/server/lib/spec_definitions/js/filter.ts b/src/plugins/console/server/lib/spec_definitions/js/filter.ts index b5e99e610b8ba..f43f62c9cf2ed 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/filter.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/filter.ts @@ -18,7 +18,6 @@ */ import { SpecDefinitionsService } from '../../../services'; -/* eslint-disable @typescript-eslint/camelcase */ const filters: Record = {}; filters.and = { diff --git a/src/plugins/console/server/lib/spec_definitions/js/globals.ts b/src/plugins/console/server/lib/spec_definitions/js/globals.ts index 9fef5c6dbf1e3..bf628e6b659a3 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/globals.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/globals.ts @@ -18,7 +18,6 @@ */ import { SpecDefinitionsService } from '../../../services'; -/* eslint-disable @typescript-eslint/camelcase */ const highlightOptions = { boundary_chars: {}, boundary_max_scan: 20, diff --git a/src/plugins/console/server/lib/spec_definitions/js/ingest.ts b/src/plugins/console/server/lib/spec_definitions/js/ingest.ts index 20dbeda5e0b3d..3450055804cf2 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/ingest.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/ingest.ts @@ -19,7 +19,6 @@ import { SpecDefinitionsService } from '../../../services'; -/* eslint-disable @typescript-eslint/camelcase */ const commonPipelineParams = { on_failure: [], ignore_failure: { diff --git a/src/plugins/console/server/lib/spec_definitions/js/mappings.ts b/src/plugins/console/server/lib/spec_definitions/js/mappings.ts index fbc9a822e509c..d09637b05a3cb 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/mappings.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/mappings.ts @@ -23,7 +23,6 @@ import { SpecDefinitionsService } from '../../../services'; import { BOOLEAN } from './shared'; -/* eslint-disable @typescript-eslint/camelcase */ export const mappings = (specService: SpecDefinitionsService) => { specService.addEndpointDescription('put_mapping', { priority: 10, // collides with put doc by id diff --git a/src/plugins/console/server/lib/spec_definitions/js/query/dsl.ts b/src/plugins/console/server/lib/spec_definitions/js/query/dsl.ts index d6e5030fb6928..b94809d38e1a8 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/query/dsl.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/query/dsl.ts @@ -36,7 +36,6 @@ import { regexpTemplate, } from './templates'; -/* eslint-disable @typescript-eslint/camelcase */ const matchOptions = { cutoff_frequency: 0.001, query: '', diff --git a/src/plugins/console/server/lib/spec_definitions/js/query/templates.ts b/src/plugins/console/server/lib/spec_definitions/js/query/templates.ts index 60192f81fec80..b1e636828c144 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/query/templates.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/query/templates.ts @@ -17,7 +17,6 @@ * under the License. */ -/* eslint-disable @typescript-eslint/camelcase */ export const regexpTemplate = { FIELD: 'REGEXP', }; diff --git a/src/plugins/console/server/lib/spec_definitions/js/reindex.ts b/src/plugins/console/server/lib/spec_definitions/js/reindex.ts index 862a4323f7bf3..e5b2904172096 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/reindex.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/reindex.ts @@ -19,7 +19,6 @@ import { SpecDefinitionsService } from '../../../services'; -/* eslint-disable @typescript-eslint/camelcase */ export const reindex = (specService: SpecDefinitionsService) => { specService.addEndpointDescription('reindex', { methods: ['POST'], diff --git a/src/plugins/console/server/lib/spec_definitions/js/search.ts b/src/plugins/console/server/lib/spec_definitions/js/search.ts index e319870d7be5c..f0e2813117574 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/search.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/search.ts @@ -18,7 +18,6 @@ */ import { SpecDefinitionsService } from '../../../services'; -/* eslint-disable @typescript-eslint/camelcase */ export const search = (specService: SpecDefinitionsService) => { specService.addEndpointDescription('search', { priority: 10, // collides with get doc by id diff --git a/src/plugins/console/server/lib/spec_definitions/js/settings.ts b/src/plugins/console/server/lib/spec_definitions/js/settings.ts index 88c58e618533b..9ffaad2e52b59 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/settings.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/settings.ts @@ -19,7 +19,6 @@ import { SpecDefinitionsService } from '../../../services'; import { BOOLEAN } from './shared'; -/* eslint-disable @typescript-eslint/camelcase */ export const settings = (specService: SpecDefinitionsService) => { specService.addEndpointDescription('put_settings', { data_autocomplete_rules: { diff --git a/src/plugins/console/server/lib/spec_definitions/js/shared.ts b/src/plugins/console/server/lib/spec_definitions/js/shared.ts index a884e1aebe2e7..ace189e2d0913 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/shared.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/shared.ts @@ -17,7 +17,6 @@ * under the License. */ -/* eslint-disable @typescript-eslint/camelcase */ export const BOOLEAN = Object.freeze({ __one_of: [true, false], }); diff --git a/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx b/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx index e7534fa09aa3f..b6bee5c3360b4 100644 --- a/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx +++ b/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx @@ -29,8 +29,6 @@ import { import { coreMock } from '../../../../../core/public/mocks'; import { CoreStart } from 'kibana/public'; import { ClonePanelAction } from '.'; - -// eslint-disable-next-line import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks'; const { setup, doStart } = embeddablePluginMock.createInstance(); diff --git a/src/plugins/dashboard/public/application/actions/expand_panel_action.test.tsx b/src/plugins/dashboard/public/application/actions/expand_panel_action.test.tsx index 0f4a92a1a7b7d..ff4e3ee5f06eb 100644 --- a/src/plugins/dashboard/public/application/actions/expand_panel_action.test.tsx +++ b/src/plugins/dashboard/public/application/actions/expand_panel_action.test.tsx @@ -28,8 +28,6 @@ import { ContactCardEmbeddableInput, ContactCardEmbeddableOutput, } from '../../embeddable_plugin_test_samples'; - -// eslint-disable-next-line import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks'; const { setup, doStart } = embeddablePluginMock.createInstance(); diff --git a/src/plugins/dashboard/public/application/actions/replace_panel_action.test.tsx b/src/plugins/dashboard/public/application/actions/replace_panel_action.test.tsx index cc06bd41379aa..38afc22670709 100644 --- a/src/plugins/dashboard/public/application/actions/replace_panel_action.test.tsx +++ b/src/plugins/dashboard/public/application/actions/replace_panel_action.test.tsx @@ -29,8 +29,6 @@ import { } from '../../embeddable_plugin_test_samples'; import { coreMock } from '../../../../../core/public/mocks'; import { CoreStart } from 'kibana/public'; - -// eslint-disable-next-line import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks'; const { setup, doStart } = embeddablePluginMock.createInstance(); diff --git a/src/plugins/dashboard/public/application/application.ts b/src/plugins/dashboard/public/application/application.ts index 08eeb19dcda93..21f423d009ee7 100644 --- a/src/plugins/dashboard/public/application/application.ts +++ b/src/plugins/dashboard/public/application/application.ts @@ -110,7 +110,7 @@ const thirdPartyAngularDependencies = ['ngSanitize', 'ngRoute', 'react']; function mountDashboardApp(appBasePath: string, element: HTMLElement) { const mountpoint = document.createElement('div'); mountpoint.setAttribute('class', 'dshAppContainer'); - // eslint-disable-next-line + // eslint-disable-next-line no-unsanitized/property mountpoint.innerHTML = mainTemplate(appBasePath); // bootstrap angular into detached element and attach it later to // make angular-within-angular possible diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx index 3cebe2b847155..a7226082d3dce 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx @@ -17,8 +17,6 @@ * under the License. */ -// @ts-ignore -import { findTestSubject } from '@elastic/eui/lib/test'; import { nextTick } from 'test_utils/enzyme_helpers'; import { isErrorEmbeddable, ViewMode } from '../../embeddable_plugin'; import { DashboardContainer, DashboardContainerOptions } from './dashboard_container'; @@ -30,7 +28,6 @@ import { ContactCardEmbeddable, ContactCardEmbeddableOutput, } from '../../embeddable_plugin_test_samples'; -// eslint-disable-next-line import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks'; const options: DashboardContainerOptions = { diff --git a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx index 493ae8eb51797..42d8f92de80aa 100644 --- a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx +++ b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx @@ -31,7 +31,6 @@ import { ContactCardEmbeddableFactory, } from '../../../embeddable_plugin_test_samples'; import { KibanaContextProvider } from '../../../../../kibana_react/public'; -// eslint-disable-next-line import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks'; let dashboardContainer: DashboardContainer | undefined; diff --git a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx index dcd07fe394c7d..d4d8fd0a4374b 100644 --- a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx +++ b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx @@ -256,7 +256,9 @@ class DashboardGridUi extends React.Component { expandedPanelId !== undefined && expandedPanelId === panel.explicitInput.id; const hidePanel = expandedPanelId !== undefined && expandedPanelId !== panel.explicitInput.id; const classes = classNames({ + // eslint-disable-next-line @typescript-eslint/naming-convention 'dshDashboardGrid__item--expanded': expandPanel, + // eslint-disable-next-line @typescript-eslint/naming-convention 'dshDashboardGrid__item--hidden': hidePanel, }); return ( diff --git a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx index 733ea11c1eb64..1e07c610b0ef2 100644 --- a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx +++ b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx @@ -32,7 +32,6 @@ import { ContactCardEmbeddableFactory, } from '../../../embeddable_plugin_test_samples'; import { KibanaContextProvider } from '../../../../../kibana_react/public'; -// eslint-disable-next-line import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks'; import { applicationServiceMock } from '../../../../../../core/public/mocks'; diff --git a/src/plugins/dashboard/public/embeddable_plugin_test_samples.ts b/src/plugins/dashboard/public/embeddable_plugin_test_samples.ts index 0e49a94278dfc..45759bf078911 100644 --- a/src/plugins/dashboard/public/embeddable_plugin_test_samples.ts +++ b/src/plugins/dashboard/public/embeddable_plugin_test_samples.ts @@ -17,5 +17,4 @@ * under the License. */ -// eslint-disable-next-line export * from '../../../plugins/embeddable/public/lib/test_samples'; diff --git a/src/plugins/dashboard/public/url_generator.test.ts b/src/plugins/dashboard/public/url_generator.test.ts index 0eeb8f26ed88b..208b229318a9e 100644 --- a/src/plugins/dashboard/public/url_generator.test.ts +++ b/src/plugins/dashboard/public/url_generator.test.ts @@ -19,7 +19,6 @@ import { createDashboardUrlGenerator } from './url_generator'; import { hashedItemStore } from '../../kibana_utils/public'; -// eslint-disable-next-line import { mockStorage } from '../../kibana_utils/public/storage/hashed_item_store/mock'; import { esFilters, Filter } from '../../data/public'; import { SavedObjectLoader } from '../../saved_objects/public'; diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts index a1842d31479c0..8223b31042124 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts @@ -17,7 +17,6 @@ * under the License. */ -// eslint-disable-next-line max-classes-per-file import { IndexPatternsService } from './index_patterns'; import { fieldFormatsMock } from '../../field_formats/mocks'; import { diff --git a/src/plugins/data/common/search/aggs/date_interval_utils/is_valid_interval.ts b/src/plugins/data/common/search/aggs/date_interval_utils/is_valid_interval.ts index 03d84c5e2c97b..cb8cb8e63f175 100644 --- a/src/plugins/data/common/search/aggs/date_interval_utils/is_valid_interval.ts +++ b/src/plugins/data/common/search/aggs/date_interval_utils/is_valid_interval.ts @@ -23,7 +23,7 @@ import { leastCommonInterval } from './least_common_interval'; // When base interval is set, check for least common interval and allow // input the value is the same. This means that the input interval is a // multiple of the base interval. -function _parseWithBase(value: string, baseInterval: string) { +function parseWithBase(value: string, baseInterval: string) { try { const interval = leastCommonInterval(baseInterval, value); return interval === value.replace(/\s/g, ''); @@ -34,7 +34,7 @@ function _parseWithBase(value: string, baseInterval: string) { export function isValidInterval(value: string, baseInterval?: string) { if (baseInterval) { - return _parseWithBase(value, baseInterval); + return parseWithBase(value, baseInterval); } else { return isValidEsInterval(value); } diff --git a/src/plugins/data/public/search/aggs/mocks.ts b/src/plugins/data/public/search/aggs/mocks.ts index 7a5dcc9be4592..2cad646067292 100644 --- a/src/plugins/data/public/search/aggs/mocks.ts +++ b/src/plugins/data/public/search/aggs/mocks.ts @@ -17,7 +17,6 @@ * under the License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { coreMock } from '../../../../../../src/core/public/mocks'; import { AggConfigs, diff --git a/src/plugins/data/public/search/search_source/normalize_sort_request.ts b/src/plugins/data/public/search/search_source/normalize_sort_request.ts index b00d28b38d670..3ec0a13282d3e 100644 --- a/src/plugins/data/public/search/search_source/normalize_sort_request.ts +++ b/src/plugins/data/public/search/search_source/normalize_sort_request.ts @@ -61,6 +61,7 @@ function normalize( } // Don't include unmapped_type for _score field + // eslint-disable-next-line @typescript-eslint/naming-convention const { unmapped_type, ...otherSortOptions } = defaultSortOptions; return { [sortField]: { ...order, ...(sortField === '_score' ? otherSortOptions : defaultSortOptions) }, diff --git a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx index 20e3fdae5ce5f..f187dcb804c79 100644 --- a/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx +++ b/src/plugins/data/public/ui/index_pattern_select/index_pattern_select.tsx @@ -189,12 +189,12 @@ export class IndexPatternSelect extends Component { render() { const { - fieldTypes, // eslint-disable-line no-unused-vars - onChange, // eslint-disable-line no-unused-vars - indexPatternId, // eslint-disable-line no-unused-vars + fieldTypes, + onChange, + indexPatternId, placeholder, - onNoIndexPatterns, // eslint-disable-line no-unused-vars - savedObjectsClient, // eslint-disable-line no-unused-vars + onNoIndexPatterns, + savedObjectsClient, ...rest } = this.props; diff --git a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx index 05249d46a1c50..e5d03e2a774f1 100644 --- a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx @@ -275,6 +275,7 @@ export function QueryBarTopRow(props: Props) { }); const wrapperClasses = classNames('kbnQueryBar__datePickerWrapper', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'kbnQueryBar__datePickerWrapper-isHidden': isQueryInputFocused, }); diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx index 2f740cc476087..b18b2fa9f0418 100644 --- a/src/plugins/data/public/ui/search_bar/search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx @@ -224,9 +224,7 @@ class SearchBarUI extends Component { }; // member-ordering rules conflict with use-before-declaration rules - /* eslint-disable */ public ro = new ResizeObserver(this.setFilterBarHeight); - /* eslint-enable */ public onSave = async (savedQueryMeta: SavedQueryMeta, saveAsNew = false) => { if (!this.state.query) return; @@ -411,6 +409,7 @@ class SearchBarUI extends Component { let filterBar; if (this.shouldRenderFilterBar()) { const filterGroupClasses = classNames('globalFilterGroup__wrapper', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'globalFilterGroup__wrapper-isVisible': this.state.isFiltersVisible, }); filterBar = ( diff --git a/src/plugins/data/public/ui/typeahead/suggestion_component.tsx b/src/plugins/data/public/ui/typeahead/suggestion_component.tsx index 951e47165819f..b859428e6ed7e 100644 --- a/src/plugins/data/public/ui/typeahead/suggestion_component.tsx +++ b/src/plugins/data/public/ui/typeahead/suggestion_component.tsx @@ -53,6 +53,7 @@ export function SuggestionComponent(props: Props) { // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus
    , field: IFieldType | string, query: string, diff --git a/src/plugins/discover/public/application/components/table/table_row.tsx b/src/plugins/discover/public/application/components/table/table_row.tsx index abb6e149b1bfd..5f7dd9f37dcd3 100644 --- a/src/plugins/discover/public/application/components/table/table_row.tsx +++ b/src/plugins/discover/public/application/components/table/table_row.tsx @@ -60,6 +60,7 @@ export function DocViewTableRow({ valueRaw, }: Props) { const valueClassName = classNames({ + // eslint-disable-next-line @typescript-eslint/naming-convention kbnDocViewer__value: true, 'truncate-by-height': isCollapsible && isCollapsed, }); diff --git a/src/plugins/discover/public/url_generator.test.ts b/src/plugins/discover/public/url_generator.test.ts index cf9beb246fea2..a18ee486ab007 100644 --- a/src/plugins/discover/public/url_generator.test.ts +++ b/src/plugins/discover/public/url_generator.test.ts @@ -19,7 +19,6 @@ import { DiscoverUrlGenerator } from './url_generator'; import { hashedItemStore, getStatesFromKbnUrl } from '../../kibana_utils/public'; -// eslint-disable-next-line import { mockStorage } from '../../kibana_utils/public/storage/hashed_item_store/mock'; import { FilterStateStore } from '../../data/common'; diff --git a/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.test.tsx b/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.test.tsx index e29e941e898fb..aa0b504b63fbe 100644 --- a/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.test.tsx +++ b/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.test.tsx @@ -28,7 +28,6 @@ import { ContactCardEmbeddableOutput, ContactCardEmbeddable, } from '../test_samples/embeddables/contact_card/contact_card_embeddable'; -// eslint-disable-next-line import { inspectorPluginMock } from '../../../../inspector/public/mocks'; import { mount } from 'enzyme'; import { embeddablePluginMock, createEmbeddablePanelMock } from '../../mocks'; diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx index ff9f466a8d553..341a51d7348b2 100644 --- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx +++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx @@ -40,7 +40,6 @@ import { ContactCardEmbeddableInput, ContactCardEmbeddableOutput, } from '../test_samples/embeddables/contact_card/contact_card_embeddable'; -// eslint-disable-next-line import { inspectorPluginMock } from '../../../../inspector/public/mocks'; import { EuiBadge } from '@elastic/eui'; import { embeddablePluginMock } from '../../mocks'; diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx index 74b08535bf27a..d8def3147e52c 100644 --- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx +++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/add_panel_action.test.tsx @@ -26,7 +26,6 @@ import { } from '../../../../test_samples/embeddables/filterable_embeddable'; import { FilterableEmbeddableFactory } from '../../../../test_samples/embeddables/filterable_embeddable_factory'; import { FilterableContainer } from '../../../../test_samples/embeddables/filterable_container'; -// eslint-disable-next-line import { coreMock } from '../../../../../../../../core/public/mocks'; import { ContactCardEmbeddable } from '../../../../test_samples'; import { esFilters, Filter } from '../../../../../../../../plugins/data/public'; diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/inspect_panel_action.test.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/inspect_panel_action.test.tsx index 491eaad9faefa..eb83641448986 100644 --- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/inspect_panel_action.test.tsx +++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/inspect_panel_action.test.tsx @@ -26,7 +26,6 @@ import { FilterableEmbeddable, ContactCardEmbeddable, } from '../../../test_samples'; -// eslint-disable-next-line import { inspectorPluginMock } from '../../../../../../../plugins/inspector/public/mocks'; import { EmbeddableOutput, isErrorEmbeddable, ErrorEmbeddable } from '../../../embeddables'; import { of } from '../../../../tests/helpers'; diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx index 7b66f29cc2726..2f086a3fb2c0c 100644 --- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx +++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx @@ -132,6 +132,7 @@ export function PanelHeader({ const showTitle = !isViewMode || (title && !hidePanelTitles) || viewDescription !== ''; const showPanelBar = badges.length > 0 || showTitle; const classes = classNames('embPanel__header', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'embPanel__header--floater': !showPanelBar, }); diff --git a/src/plugins/embeddable/public/mocks.tsx b/src/plugins/embeddable/public/mocks.tsx index 6b451e71522c5..94aa980e446ca 100644 --- a/src/plugins/embeddable/public/mocks.tsx +++ b/src/plugins/embeddable/public/mocks.tsx @@ -33,9 +33,7 @@ import { CoreStart } from '../../../core/public'; import { Start as InspectorStart } from '../../inspector/public'; import { dataPluginMock } from '../../data/public/mocks'; -// eslint-disable-next-line import { inspectorPluginMock } from '../../inspector/public/mocks'; -// eslint-disable-next-line import { uiActionsPluginMock } from '../../ui_actions/public/mocks'; export type Setup = jest.Mocked; diff --git a/src/plugins/embeddable/public/tests/apply_filter_action.test.ts b/src/plugins/embeddable/public/tests/apply_filter_action.test.ts index ec92f334267f5..9d765c9906443 100644 --- a/src/plugins/embeddable/public/tests/apply_filter_action.test.ts +++ b/src/plugins/embeddable/public/tests/apply_filter_action.test.ts @@ -30,7 +30,6 @@ import { FilterableContainerFactory, FilterableEmbeddableInput, } from '../lib/test_samples'; -// eslint-disable-next-line import { esFilters } from '../../../data/public'; test('ApplyFilterAction applies the filter to the root of the container tree', async () => { diff --git a/src/plugins/embeddable/public/tests/container.test.ts b/src/plugins/embeddable/public/tests/container.test.ts index e6162748fdb68..621ffe4c9dad6 100644 --- a/src/plugins/embeddable/public/tests/container.test.ts +++ b/src/plugins/embeddable/public/tests/container.test.ts @@ -43,7 +43,6 @@ import { FilterableContainer, FilterableContainerInput, } from '../lib/test_samples/embeddables/filterable_container'; -// eslint-disable-next-line import { coreMock } from '../../../../core/public/mocks'; import { testPlugin } from './test_plugin'; import { of } from './helpers'; diff --git a/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx b/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx index 311efae49f735..e094afe528498 100644 --- a/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx +++ b/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx @@ -31,7 +31,6 @@ import { ContactCardEmbeddableFactory, } from '../lib/test_samples/embeddables/contact_card/contact_card_embeddable_factory'; import { HelloWorldContainer } from '../lib/test_samples/embeddables/hello_world_container'; -// eslint-disable-next-line import { coreMock } from '../../../../core/public/mocks'; import { testPlugin } from './test_plugin'; import { CustomizePanelModal } from '../lib/panel/panel_header/panel_actions/customize_title/customize_panel_modal'; diff --git a/src/plugins/embeddable/public/tests/explicit_input.test.ts b/src/plugins/embeddable/public/tests/explicit_input.test.ts index cfddeec25b3b4..24785dd50a032 100644 --- a/src/plugins/embeddable/public/tests/explicit_input.test.ts +++ b/src/plugins/embeddable/public/tests/explicit_input.test.ts @@ -33,7 +33,6 @@ import { import { FilterableContainer } from '../lib/test_samples/embeddables/filterable_container'; import { isErrorEmbeddable } from '../lib'; import { HelloWorldContainer } from '../lib/test_samples/embeddables/hello_world_container'; -// eslint-disable-next-line import { coreMock } from '../../../../core/public/mocks'; import { esFilters, Filter } from '../../../../plugins/data/public'; import { createEmbeddablePanelMock } from '../mocks'; diff --git a/src/plugins/embeddable/public/tests/test_plugin.ts b/src/plugins/embeddable/public/tests/test_plugin.ts index bb12e3d7b9011..2c298b437a118 100644 --- a/src/plugins/embeddable/public/tests/test_plugin.ts +++ b/src/plugins/embeddable/public/tests/test_plugin.ts @@ -19,9 +19,7 @@ import { CoreSetup, CoreStart } from 'src/core/public'; import { UiActionsStart } from '../../../ui_actions/public'; -// eslint-disable-next-line import { uiActionsPluginMock } from '../../../ui_actions/public/mocks'; -// eslint-disable-next-line import { inspectorPluginMock } from '../../../inspector/public/mocks'; import { dataPluginMock } from '../../../data/public/mocks'; import { coreMock } from '../../../../core/public/mocks'; diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/ace/use_ui_ace_keyboard_mode.tsx b/src/plugins/es_ui_shared/__packages_do_not_import__/ace/use_ui_ace_keyboard_mode.tsx index d0d1aa1d8db15..4abb78c3bbc90 100644 --- a/src/plugins/es_ui_shared/__packages_do_not_import__/ace/use_ui_ace_keyboard_mode.tsx +++ b/src/plugins/es_ui_shared/__packages_do_not_import__/ace/use_ui_ace_keyboard_mode.tsx @@ -27,7 +27,6 @@ const OverlayText = () => ( // The point of this element is for accessibility purposes, so ignore eslint error // in this case // - // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions <> Press Enter to start editing. When you’re done, press Escape to stop editing. diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts index b2f00610a3d33..15ea99eb6cc3a 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts @@ -41,6 +41,7 @@ export const useField = ( serializer, deserializer, } = config; + const { getFormData, __removeField, __updateFormDataAt, __validateFields } = form; const initialValue = useMemo(() => { diff --git a/src/plugins/expressions/common/execution/container.ts b/src/plugins/expressions/common/execution/container.ts index 6302c0adb550b..d0867e7ec6b57 100644 --- a/src/plugins/expressions/common/execution/container.ts +++ b/src/plugins/expressions/common/execution/container.ts @@ -58,7 +58,6 @@ const executionDefaultState: ExecutionState = { }, }; -// eslint-disable-next-line export interface ExecutionPureTransitions { start: (state: ExecutionState) => () => ExecutionState; setResult: (state: ExecutionState) => (result: Output) => ExecutionState; diff --git a/src/plugins/expressions/public/mocks.tsx b/src/plugins/expressions/public/mocks.tsx index 3a5ece271c4ee..6e649c29ead7d 100644 --- a/src/plugins/expressions/public/mocks.tsx +++ b/src/plugins/expressions/public/mocks.tsx @@ -20,10 +20,8 @@ import React from 'react'; import { ExpressionsSetup, ExpressionsStart, plugin as pluginInitializer } from '.'; -/* eslint-disable */ import { coreMock } from '../../../core/public/mocks'; import { bfetchPluginMock } from '../../bfetch/public/mocks'; -/* eslint-enable */ export type Setup = jest.Mocked; export type Start = jest.Mocked; diff --git a/src/plugins/expressions/server/mocks.ts b/src/plugins/expressions/server/mocks.ts index 1ace19a1848b0..e6b883e38f244 100644 --- a/src/plugins/expressions/server/mocks.ts +++ b/src/plugins/expressions/server/mocks.ts @@ -20,10 +20,7 @@ import { ExpressionsServerSetup, ExpressionsServerStart } from '.'; import { plugin as pluginInitializer } from '.'; import { coreMock } from '../../../core/server/mocks'; - -/* eslint-disable */ import { bfetchPluginMock } from '../../bfetch/server/mocks'; -/* eslint-enable */ export type Setup = jest.Mocked; export type Start = jest.Mocked; diff --git a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts index f680329045625..4c31ccee1243a 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts @@ -18,7 +18,6 @@ */ /* eslint max-len: 0 */ -/* eslint-disable */ import { i18n } from '@kbn/i18n'; import { SavedObject } from 'kibana/server'; diff --git a/src/plugins/home/server/services/sample_data/data_sets/logs/saved_objects.ts b/src/plugins/home/server/services/sample_data/data_sets/logs/saved_objects.ts index 0620e93118b8d..97258c21bc8f0 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/logs/saved_objects.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/logs/saved_objects.ts @@ -18,7 +18,6 @@ */ /* eslint max-len: 0 */ -/* eslint-disable */ import { i18n } from '@kbn/i18n'; import { SavedObject } from 'kibana/server'; diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx index 5797149a51aea..fab638509313d 100644 --- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx @@ -106,6 +106,7 @@ export class StepIndexPattern extends Component { await updateComponent(component); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('handleOptionsChange - step', async () => { diff --git a/src/plugins/input_control_vis/public/components/vis/form_row.test.tsx b/src/plugins/input_control_vis/public/components/vis/form_row.test.tsx index e0f34113bd6a0..4a98acbe17bd1 100644 --- a/src/plugins/input_control_vis/public/components/vis/form_row.test.tsx +++ b/src/plugins/input_control_vis/public/components/vis/form_row.test.tsx @@ -28,7 +28,7 @@ test('renders enabled control', () => {
    My Control
    ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('renders control with warning', () => { @@ -37,7 +37,7 @@ test('renders control with warning', () => {
    My Control
    ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('renders disabled control with tooltip', () => { @@ -51,5 +51,5 @@ test('renders disabled control with tooltip', () => {
    My Control
    ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); diff --git a/src/plugins/input_control_vis/public/components/vis/input_control_vis.test.tsx b/src/plugins/input_control_vis/public/components/vis/input_control_vis.test.tsx index b0b674ad7b6ee..e0938f700428e 100644 --- a/src/plugins/input_control_vis/public/components/vis/input_control_vis.test.tsx +++ b/src/plugins/input_control_vis/public/components/vis/input_control_vis.test.tsx @@ -93,7 +93,7 @@ test('Renders list control', () => { refreshControl={refreshControlMock} /> ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('Renders range control', () => { @@ -114,7 +114,7 @@ test('Renders range control', () => { refreshControl={refreshControlMock} /> ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('Apply and Cancel change btns enabled when there are changes', () => { @@ -135,7 +135,7 @@ test('Apply and Cancel change btns enabled when there are changes', () => { refreshControl={refreshControlMock} /> ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('Clear btns enabled when there are values', () => { @@ -156,7 +156,7 @@ test('Clear btns enabled when there are values', () => { refreshControl={refreshControlMock} /> ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('clearControls', () => { diff --git a/src/plugins/input_control_vis/public/components/vis/list_control.test.tsx b/src/plugins/input_control_vis/public/components/vis/list_control.test.tsx index 79fe2e376863a..4944a9dacfed6 100644 --- a/src/plugins/input_control_vis/public/components/vis/list_control.test.tsx +++ b/src/plugins/input_control_vis/public/components/vis/list_control.test.tsx @@ -49,7 +49,7 @@ test('renders ListControl', () => { intl={{} as any} /> ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('disableMsg', () => { @@ -66,5 +66,5 @@ test('disableMsg', () => { intl={{} as any} /> ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); diff --git a/src/plugins/input_control_vis/public/components/vis/range_control.test.tsx b/src/plugins/input_control_vis/public/components/vis/range_control.test.tsx index ff5d572fa21c4..569d115c9dbda 100644 --- a/src/plugins/input_control_vis/public/components/vis/range_control.test.tsx +++ b/src/plugins/input_control_vis/public/components/vis/range_control.test.tsx @@ -46,7 +46,7 @@ test('renders RangeControl', () => { const component = shallowWithIntl( {}} /> ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('disabled', () => { @@ -69,7 +69,7 @@ test('disabled', () => { const component = shallowWithIntl( {}} /> ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('ceilWithPrecision', () => { diff --git a/src/plugins/input_control_vis/public/control/control.ts b/src/plugins/input_control_vis/public/control/control.ts index 1e1e05c96cc1a..91e8f1b26164b 100644 --- a/src/plugins/input_control_vis/public/control/control.ts +++ b/src/plugins/input_control_vis/public/control/control.ts @@ -17,8 +17,6 @@ * under the License. */ -/* eslint-disable no-multi-str*/ - import _ from 'lodash'; import { i18n } from '@kbn/i18n'; diff --git a/src/plugins/inspector/public/mocks.ts b/src/plugins/inspector/public/mocks.ts index 451daf4b8dc1a..ccddc0217831a 100644 --- a/src/plugins/inspector/public/mocks.ts +++ b/src/plugins/inspector/public/mocks.ts @@ -20,7 +20,6 @@ import { Setup as PluginSetup, Start as PluginStart } from '.'; import { InspectorViewRegistry } from './view_registry'; import { plugin as pluginInitializer } from '.'; -// eslint-disable-next-line import { coreMock } from '../../../core/public/mocks'; export type Setup = jest.Mocked; diff --git a/src/plugins/kibana_legacy/public/utils/inject_header_style.ts b/src/plugins/kibana_legacy/public/utils/inject_header_style.ts index b95e9721d5da4..0b953caeba8c4 100644 --- a/src/plugins/kibana_legacy/public/utils/inject_header_style.ts +++ b/src/plugins/kibana_legacy/public/utils/inject_header_style.ts @@ -36,6 +36,7 @@ export function injectHeaderStyle(uiSettings: IUiSettingsClient) { document.getElementsByTagName('head')[0].appendChild(style); uiSettings.get$('truncate:maxHeight').subscribe((value: number) => { + // eslint-disable-next-line no-unsanitized/property style.innerHTML = buildCSS(value); }); } diff --git a/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx b/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx index aefbd66e50fcf..cb8a9a4a2b65e 100644 --- a/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx +++ b/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx @@ -25,6 +25,7 @@ import { reactToUiComponent } from './react_to_ui_component'; const UiComp: UiComponent<{ cnt?: number }> = () => ({ render: (el, { cnt = 0 }) => { + // eslint-disable-next-line no-unsanitized/property el.innerHTML = `cnt: ${cnt}`; }, }); @@ -64,6 +65,7 @@ describe('uiToReactComponent', () => { test('does not crash if .unmount() not provided', () => { const UiComp2: UiComponent<{ cnt?: number }> = () => ({ render: (el, { cnt = 0 }) => { + // eslint-disable-next-line no-unsanitized/property el.innerHTML = `cnt: ${cnt}`; }, }); @@ -80,6 +82,7 @@ describe('uiToReactComponent', () => { const unmount = jest.fn(); const UiComp2: UiComponent<{ cnt?: number }> = () => ({ render: (el, { cnt = 0 }) => { + // eslint-disable-next-line no-unsanitized/property el.innerHTML = `cnt: ${cnt}`; }, unmount, @@ -100,6 +103,7 @@ describe('uiToReactComponent', () => { test('calls .render() method only once when components mounts, and once on every re-render', () => { const render = jest.fn((el, { cnt = 0 }) => { + // eslint-disable-next-line no-unsanitized/property el.innerHTML = `cnt: ${cnt}`; }); const UiComp2: UiComponent<{ cnt?: number }> = () => ({ diff --git a/src/plugins/kibana_react/public/markdown/markdown.test.tsx b/src/plugins/kibana_react/public/markdown/markdown.test.tsx index 5846b7a2d0dba..2fc0c6359fcc0 100644 --- a/src/plugins/kibana_react/public/markdown/markdown.test.tsx +++ b/src/plugins/kibana_react/public/markdown/markdown.test.tsx @@ -24,14 +24,14 @@ import { Markdown } from './markdown'; test('render', () => { const component = shallow(); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('should never render html tags', () => { const component = shallow( ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('should render links with parentheses correctly', () => { @@ -65,19 +65,19 @@ describe('props', () => { test('markdown', () => { const component = shallow(); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('openLinksInNewTab', () => { const component = shallow(); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('whiteListedRules', () => { const component = shallow( ); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); test('should update markdown when openLinksInNewTab prop change', () => { diff --git a/src/plugins/kibana_react/public/validated_range/validated_dual_range.tsx b/src/plugins/kibana_react/public/validated_range/validated_dual_range.tsx index 45592c8a703af..832ea70f0460e 100644 --- a/src/plugins/kibana_react/public/validated_range/validated_dual_range.tsx +++ b/src/plugins/kibana_react/public/validated_range/validated_dual_range.tsx @@ -100,9 +100,9 @@ export class ValidatedDualRange extends Component { fullWidth, label, formRowDisplay, - value, // eslint-disable-line no-unused-vars - onChange, // eslint-disable-line no-unused-vars - allowEmptyRange, // eslint-disable-line no-unused-vars + value, + onChange, + allowEmptyRange, ...rest // TODO: Consider alternatives for spread operator in component } = this.props; diff --git a/src/plugins/kibana_utils/public/state_sync/public.api.md b/src/plugins/kibana_utils/public/state_sync/public.api.md index c174ba798d01a..ae8c0e8e401b8 100644 --- a/src/plugins/kibana_utils/public/state_sync/public.api.md +++ b/src/plugins/kibana_utils/public/state_sync/public.api.md @@ -74,7 +74,7 @@ export interface IStateSyncConfig { +export interface ISyncStateRef { start: StartSyncStateFnType; stop: StopSyncStateFnType; } diff --git a/src/plugins/kibana_utils/public/state_sync/state_sync.ts b/src/plugins/kibana_utils/public/state_sync/state_sync.ts index bbcaaedd0d8bf..2ceacb5123513 100644 --- a/src/plugins/kibana_utils/public/state_sync/state_sync.ts +++ b/src/plugins/kibana_utils/public/state_sync/state_sync.ts @@ -38,7 +38,7 @@ export type StartSyncStateFnType = () => void; /** * @public */ -export interface ISyncStateRef { +export interface ISyncStateRef { /** * stop state syncing */ diff --git a/src/plugins/kibana_utils/public/storage/hashed_item_store/mock.ts b/src/plugins/kibana_utils/public/storage/hashed_item_store/mock.ts index e3360e0e3cf51..43a8856176c42 100644 --- a/src/plugins/kibana_utils/public/storage/hashed_item_store/mock.ts +++ b/src/plugins/kibana_utils/public/storage/hashed_item_store/mock.ts @@ -32,6 +32,7 @@ export const mockStorage = new StubBrowserStorage(); const mockHashedItemStore = new HashedItemStore(mockStorage); jest.mock('./', () => { return { + // eslint-disable-next-line @typescript-eslint/no-var-requires HashedItemStore: require('./hashed_item_store').HashedItemStore, hashedItemStore: mockHashedItemStore, }; diff --git a/src/plugins/saved_objects_management/public/plugin.test.ts b/src/plugins/saved_objects_management/public/plugin.test.ts index 09080f46a6869..8b1ee2cefe468 100644 --- a/src/plugins/saved_objects_management/public/plugin.test.ts +++ b/src/plugins/saved_objects_management/public/plugin.test.ts @@ -18,9 +18,7 @@ */ import { coreMock } from '../../../core/public/mocks'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { homePluginMock } from '../../home/public/mocks'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { managementPluginMock } from '../../management/public/mocks'; import { dataPluginMock } from '../../data/public/mocks'; import { SavedObjectsManagementPlugin } from './plugin'; diff --git a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts index 4d4031bb428ba..98c83a3394628 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts @@ -37,6 +37,7 @@ import { getDataTelemetry, DATA_TELEMETRY_ID, DataTelemetryPayload } from './get * @param {Object} kibana The Kibana Usage stats */ export function handleLocalStats( + // eslint-disable-next-line @typescript-eslint/naming-convention { cluster_name, cluster_uuid, version }: ESClusterInfo, { _nodes, cluster_name: clusterName, ...clusterStats }: any, kibana: KibanaUsageStats, diff --git a/src/plugins/timelion/public/application.ts b/src/plugins/timelion/public/application.ts index a398106d56f58..a4963ee6b1b03 100644 --- a/src/plugins/timelion/public/application.ts +++ b/src/plugins/timelion/public/application.ts @@ -100,7 +100,7 @@ const thirdPartyAngularDependencies = ['ngSanitize', 'ngRoute', 'react', 'angula function mountTimelionApp(appBasePath: string, element: HTMLElement, deps: RenderDeps) { const mountpoint = document.createElement('div'); mountpoint.setAttribute('class', 'timelionAppContainer'); - // eslint-disable-next-line + // eslint-disable-next-line no-unsanitized/property mountpoint.innerHTML = mainTemplate(appBasePath); // bootstrap angular into detached element and attach it later to // make angular-within-angular possible diff --git a/src/plugins/vis_type_metric/public/components/metric_vis_value.tsx b/src/plugins/vis_type_metric/public/components/metric_vis_value.tsx index 267d92abe2c75..5bc6c53d5a6a0 100644 --- a/src/plugins/vis_type_metric/public/components/metric_vis_value.tsx +++ b/src/plugins/vis_type_metric/public/components/metric_vis_value.tsx @@ -54,7 +54,9 @@ export class MetricVisValue extends Component { }; const containerClassName = classNames('mtrVis__container', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'mtrVis__container--light': metric.lightText, + // eslint-disable-next-line @typescript-eslint/naming-convention 'mtrVis__container-isfilterable': hasFilter, }); diff --git a/src/plugins/vis_type_table/public/table_vis_controller.test.ts b/src/plugins/vis_type_table/public/table_vis_controller.test.ts index e7d7f6726b0cd..56d17c187bd3f 100644 --- a/src/plugins/vis_type_table/public/table_vis_controller.test.ts +++ b/src/plugins/vis_type_table/public/table_vis_controller.test.ts @@ -28,14 +28,11 @@ import { getAngularModule } from './get_inner_angular'; import { initTableVisLegacyModule } from './table_vis_legacy_module'; import { getTableVisTypeDefinition } from './table_vis_type'; import { Vis } from '../../visualizations/public'; -// eslint-disable-next-line import { stubFields } from '../../data/public/stubs'; -// eslint-disable-next-line import { tableVisResponseHandler } from './table_vis_response_handler'; import { coreMock } from '../../../core/public/mocks'; import { IAggConfig, search } from '../../data/public'; // TODO: remove linting disable -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { searchServiceMock } from '../../data/public/search/mocks'; const { createAggConfigs } = searchServiceMock.createStartContract().aggs; diff --git a/src/plugins/vis_type_table/public/table_vis_fn.test.ts b/src/plugins/vis_type_table/public/table_vis_fn.test.ts index 6cb3f3e0f3779..2471522544fdf 100644 --- a/src/plugins/vis_type_table/public/table_vis_fn.test.ts +++ b/src/plugins/vis_type_table/public/table_vis_fn.test.ts @@ -20,7 +20,6 @@ import { createTableVisFn } from './table_vis_fn'; import { tableVisResponseHandler } from './table_vis_response_handler'; -// eslint-disable-next-line import { functionWrapper } from '../../expressions/common/expression_functions/specs/tests/utils'; jest.mock('./table_vis_response_handler', () => ({ diff --git a/src/plugins/vis_type_timeseries/common/vis_schema.ts b/src/plugins/vis_type_timeseries/common/vis_schema.ts index 7161c197b6940..a462e488c6732 100644 --- a/src/plugins/vis_type_timeseries/common/vis_schema.ts +++ b/src/plugins/vis_type_timeseries/common/vis_schema.ts @@ -233,6 +233,7 @@ export const panel = schema.object({ legend_position: stringOptionalNullable, markdown: stringOptionalNullable, markdown_scrollbars: numberIntegerOptional, + // eslint-disable-next-line @typescript-eslint/naming-convention markdown_openLinksInNewTab: numberIntegerOptional, markdown_vertical_align: stringOptionalNullable, markdown_less: stringOptionalNullable, diff --git a/src/plugins/vis_type_timeseries/public/application/components/color_picker.tsx b/src/plugins/vis_type_timeseries/public/application/components/color_picker.tsx index 444e5c90c7a6d..97069fa0c5e0c 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/color_picker.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/color_picker.tsx @@ -17,7 +17,7 @@ * under the License. */ -/* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ // The color picker is not yet accessible. import React, { useState } from 'react'; diff --git a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts index c867523d2b3b3..94d79071b8ef2 100644 --- a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts +++ b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts @@ -159,7 +159,6 @@ export class VegaParser { */ _compileVegaLite() { this.vlspec = this.spec; - // eslint-disable-next-line import/namespace const logger = vega.logger(vega.Warn); // note: eslint has a false positive here logger.warn = this._onWarning.bind(this); this.spec = vegaLite.compile(this.vlspec, logger).spec; diff --git a/src/plugins/vis_type_vislib/public/pie_fn.test.ts b/src/plugins/vis_type_vislib/public/pie_fn.test.ts index a8c03eba2b449..eb68353b7c0e2 100644 --- a/src/plugins/vis_type_vislib/public/pie_fn.test.ts +++ b/src/plugins/vis_type_vislib/public/pie_fn.test.ts @@ -17,7 +17,6 @@ * under the License. */ -// eslint-disable-next-line import { functionWrapper } from '../../expressions/common/expression_functions/specs/tests/utils'; import { createPieVisFn } from './pie_fn'; // @ts-ignore diff --git a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx index 129fdd2ade9bd..5a2db2d21c6fe 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx +++ b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx @@ -254,6 +254,7 @@ export class VisLegend extends PureComponent { type="button" onClick={this.toggleLegend} className={classNames('visLegend__toggle kbn-resetFocusState', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'visLegend__toggle--isOpen': open, })} aria-label={i18n.translate('visTypeVislib.vislib.legend.toggleLegendButtonAriaLabel', { diff --git a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend_item.tsx b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend_item.tsx index b440384899d5f..1bc41f9f61a1a 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend_item.tsx +++ b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend_item.tsx @@ -182,6 +182,7 @@ const VisLegendItemComponent = ({ onClick={setColor(item.label, color)} onKeyPress={setColor(item.label, color)} className={classNames('visLegend__valueColorPickerDot', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'visLegend__valueColorPickerDot-isSelected': color === getColor(item.label), })} style={{ color }} diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.ts b/src/plugins/visualizations/public/legacy/build_pipeline.ts index d3fe814f3b010..d52e2fcc13bff 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.ts @@ -52,16 +52,18 @@ export interface Schemas { [key: string]: any[] | undefined; } -type buildVisFunction = ( +type BuildVisFunction = ( params: VisParams, schemas: Schemas, uiState: any, meta?: { savedObjectId?: string } ) => string; + +// eslint-disable-next-line @typescript-eslint/naming-convention type buildVisConfigFunction = (schemas: Schemas, visParams?: VisParams) => VisParams; interface BuildPipelineVisFunction { - [key: string]: buildVisFunction; + [key: string]: BuildVisFunction; } interface BuildVisConfigFunction { diff --git a/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts b/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts index d44fc2f4a75af..94538b4081aef 100644 --- a/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts +++ b/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts @@ -43,7 +43,7 @@ export function createSavedVisLoader(services: SavedObjectKibanaServicesWithVisu typeName = JSON.parse(String(source.visState)).type; } catch (e) { /* missing typename handled below */ - } // eslint-disable-line no-empty + } } if (!typeName || !visTypes.get(typeName)) { diff --git a/src/test_utils/public/http_test_setup.ts b/src/test_utils/public/http_test_setup.ts index 4a71e912f0f9e..7c70f64887af1 100644 --- a/src/test_utils/public/http_test_setup.ts +++ b/src/test_utils/public/http_test_setup.ts @@ -17,11 +17,9 @@ * under the License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import { HttpService } from '../../core/public/http'; import { fatalErrorsServiceMock } from '../../core/public/fatal_errors/fatal_errors_service.mock'; import { injectedMetadataServiceMock } from '../../core/public/injected_metadata/injected_metadata_service.mock'; -/* eslint-enable @kbn/eslint/no-restricted-paths */ export type SetupTap = ( injectedMetadata: ReturnType, diff --git a/test/functional/apps/console/_console.ts b/test/functional/apps/console/_console.ts index 2c2528ab8c41d..6e524b2cd33df 100644 --- a/test/functional/apps/console/_console.ts +++ b/test/functional/apps/console/_console.ts @@ -31,7 +31,6 @@ GET _search `.trim(); -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); const log = getService('log'); diff --git a/test/functional/apps/home/_navigation.ts b/test/functional/apps/home/_navigation.ts index b8fa5b184cd1f..91ef444bc3a83 100644 --- a/test/functional/apps/home/_navigation.ts +++ b/test/functional/apps/home/_navigation.ts @@ -20,7 +20,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { const browser = getService('browser'); const PageObjects = getPageObjects(['common', 'header', 'home', 'timePicker']); diff --git a/test/functional/apps/visualize/_chart_types.ts b/test/functional/apps/visualize/_chart_types.ts index 8aa8b9c32e967..ecb7e9630c2c6 100644 --- a/test/functional/apps/visualize/_chart_types.ts +++ b/test/functional/apps/visualize/_chart_types.ts @@ -21,7 +21,6 @@ import _ from 'lodash'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { const log = getService('log'); const PageObjects = getPageObjects(['common', 'visualize']); diff --git a/test/functional/apps/visualize/_linked_saved_searches.ts b/test/functional/apps/visualize/_linked_saved_searches.ts index e7b2909afa5a1..4151e0e9b471c 100644 --- a/test/functional/apps/visualize/_linked_saved_searches.ts +++ b/test/functional/apps/visualize/_linked_saved_searches.ts @@ -19,7 +19,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { const browser = getService('browser'); const filterBar = getService('filterBar'); diff --git a/test/functional/apps/visualize/_tsvb_chart.ts b/test/functional/apps/visualize/_tsvb_chart.ts index f1082bf618b90..ab76598ae2ea5 100644 --- a/test/functional/apps/visualize/_tsvb_chart.ts +++ b/test/functional/apps/visualize/_tsvb_chart.ts @@ -20,7 +20,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const log = getService('log'); diff --git a/test/functional/apps/visualize/_tsvb_markdown.ts b/test/functional/apps/visualize/_tsvb_markdown.ts index fae60fe019433..ba60aa83d92da 100644 --- a/test/functional/apps/visualize/_tsvb_markdown.ts +++ b/test/functional/apps/visualize/_tsvb_markdown.ts @@ -20,7 +20,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getPageObjects, getService }: FtrProviderContext) { const { visualBuilder, timePicker } = getPageObjects(['visualBuilder', 'timePicker']); const retry = getService('retry'); diff --git a/test/functional/apps/visualize/_tsvb_time_series.ts b/test/functional/apps/visualize/_tsvb_time_series.ts index c048755fc5fbe..0b2a52b367a20 100644 --- a/test/functional/apps/visualize/_tsvb_time_series.ts +++ b/test/functional/apps/visualize/_tsvb_time_series.ts @@ -19,7 +19,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getPageObjects, getService }: FtrProviderContext) { const { visualize, visualBuilder } = getPageObjects(['visualBuilder', 'visualize']); const retry = getService('retry'); diff --git a/test/functional/apps/visualize/_vega_chart.ts b/test/functional/apps/visualize/_vega_chart.ts index 6c0b77411ae99..a1ed8460f1b22 100644 --- a/test/functional/apps/visualize/_vega_chart.ts +++ b/test/functional/apps/visualize/_vega_chart.ts @@ -20,7 +20,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getPageObjects, getService }: FtrProviderContext) { const PageObjects = getPageObjects([ 'timePicker', diff --git a/test/functional/apps/visualize/index.ts b/test/functional/apps/visualize/index.ts index 42b82486dc13f..a30517519820e 100644 --- a/test/functional/apps/visualize/index.ts +++ b/test/functional/apps/visualize/index.ts @@ -20,7 +20,6 @@ import { FtrProviderContext } from '../../ftr_provider_context.d'; import { UI_SETTINGS } from '../../../../src/plugins/data/common'; -// eslint-disable-next-line @typescript-eslint/no-namespace, import/no-default-export export default function ({ getService, getPageObjects, loadTestFile }: FtrProviderContext) { const browser = getService('browser'); const log = getService('log'); diff --git a/test/functional/apps/visualize/input_control_vis/input_control_range.ts b/test/functional/apps/visualize/input_control_vis/input_control_range.ts index f52a812d4d50c..b855a01427068 100644 --- a/test/functional/apps/visualize/input_control_vis/input_control_range.ts +++ b/test/functional/apps/visualize/input_control_vis/input_control_range.ts @@ -20,7 +20,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); diff --git a/test/mocha_decorations.d.ts b/test/mocha_decorations.d.ts index 4645faf3d5fe8..5ad289eb4f1a3 100644 --- a/test/mocha_decorations.d.ts +++ b/test/mocha_decorations.d.ts @@ -34,7 +34,6 @@ type Tags = | 'ciGroup12'; // We need to use the namespace here to match the Mocha definition -// eslint-disable-next-line @typescript-eslint/no-namespace declare module 'mocha' { interface Suite { /** diff --git a/test/plugin_functional/plugins/core_app_status/public/plugin.tsx b/test/plugin_functional/plugins/core_app_status/public/plugin.tsx index bdc08c03c1912..d8042f2c240dc 100644 --- a/test/plugin_functional/plugins/core_app_status/public/plugin.tsx +++ b/test/plugin_functional/plugins/core_app_status/public/plugin.tsx @@ -63,7 +63,7 @@ export class CoreAppStatusPlugin implements Plugin<{}, CoreAppStatusPluginStart> return core.application.navigateToApp(appId); }, }; - window.__coreAppStatus = startContract; + window._coreAppStatus = startContract; return startContract; } public stop() {} diff --git a/test/plugin_functional/plugins/core_app_status/public/types.ts b/test/plugin_functional/plugins/core_app_status/public/types.ts index 7c708e6c26d91..4f6070d130568 100644 --- a/test/plugin_functional/plugins/core_app_status/public/types.ts +++ b/test/plugin_functional/plugins/core_app_status/public/types.ts @@ -21,6 +21,6 @@ import { CoreAppStatusPluginStart } from './plugin'; declare global { interface Window { - __coreAppStatus: CoreAppStatusPluginStart; + _coreAppStatus: CoreAppStatusPluginStart; } } diff --git a/test/plugin_functional/plugins/core_provider_plugin/public/index.ts b/test/plugin_functional/plugins/core_provider_plugin/public/index.ts index ac2d63bb9fd75..c1dd56fb96700 100644 --- a/test/plugin_functional/plugins/core_provider_plugin/public/index.ts +++ b/test/plugin_functional/plugins/core_provider_plugin/public/index.ts @@ -31,7 +31,7 @@ class CoreProviderPlugin implements Plugin { } public start(core: CoreStart, plugins: Record) { - window.__coreProvider = { + window._coreProvider = { setup: this.setupDeps!, start: { core, diff --git a/test/plugin_functional/plugins/core_provider_plugin/types.ts b/test/plugin_functional/plugins/core_provider_plugin/types.ts index cae3b604ecd95..6edbaa59598f8 100644 --- a/test/plugin_functional/plugins/core_provider_plugin/types.ts +++ b/test/plugin_functional/plugins/core_provider_plugin/types.ts @@ -20,7 +20,7 @@ import { CoreSetup, CoreStart } from 'kibana/public'; declare global { interface Window { - __coreProvider: { + _coreProvider: { setup: { core: CoreSetup; plugins: Record; diff --git a/test/plugin_functional/test_suites/application_links/index.ts b/test/plugin_functional/test_suites/application_links/index.ts index 120b3fb49f138..ddacfebea96d2 100644 --- a/test/plugin_functional/test_suites/application_links/index.ts +++ b/test/plugin_functional/test_suites/application_links/index.ts @@ -18,7 +18,6 @@ */ import { PluginFunctionalProviderContext } from '../../services'; -// eslint-disable-next-line import/no-default-export export default function ({ loadTestFile }: PluginFunctionalProviderContext) { describe('application links', () => { loadTestFile(require.resolve('./redirect_app_links')); diff --git a/test/plugin_functional/test_suites/application_links/redirect_app_links.ts b/test/plugin_functional/test_suites/application_links/redirect_app_links.ts index 9120018958bda..2117e0e37f71d 100644 --- a/test/plugin_functional/test_suites/application_links/redirect_app_links.ts +++ b/test/plugin_functional/test_suites/application_links/redirect_app_links.ts @@ -24,7 +24,7 @@ import '../../plugins/core_app_status/public/types'; declare global { interface Window { - __nonReloadedFlag?: boolean; + _nonReloadedFlag?: boolean; } } @@ -33,7 +33,6 @@ const getPathWithHash = (absoluteUrl: string) => { return `${parsed.path}${parsed.hash ?? ''}`; }; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const PageObjects = getPageObjects(['common']); const browser = getService('browser'); @@ -41,13 +40,13 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide const setNonReloadedFlag = () => { return browser.executeAsync(async (cb) => { - window.__nonReloadedFlag = true; + window._nonReloadedFlag = true; cb(); }); }; const wasReloaded = () => { return browser.executeAsync(async (cb) => { - const reloaded = window.__nonReloadedFlag !== true; + const reloaded = window._nonReloadedFlag !== true; cb(reloaded); }); }; diff --git a/test/plugin_functional/test_suites/core_plugins/application_leave_confirm.ts b/test/plugin_functional/test_suites/core_plugins/application_leave_confirm.ts index d2e23f7d9572e..98c59717fcac0 100644 --- a/test/plugin_functional/test_suites/core_plugins/application_leave_confirm.ts +++ b/test/plugin_functional/test_suites/core_plugins/application_leave_confirm.ts @@ -29,7 +29,6 @@ const getKibanaUrl = (pathname?: string, search?: string) => search, }); -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const PageObjects = getPageObjects(['common']); const browser = getService('browser'); diff --git a/test/plugin_functional/test_suites/core_plugins/application_status.ts b/test/plugin_functional/test_suites/core_plugins/application_status.ts index f56a6e8d62fb1..b937ffdc7f5e6 100644 --- a/test/plugin_functional/test_suites/core_plugins/application_status.ts +++ b/test/plugin_functional/test_suites/core_plugins/application_status.ts @@ -36,7 +36,6 @@ const getKibanaUrl = (pathname?: string, search?: string) => search, }); -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const PageObjects = getPageObjects(['common']); const browser = getService('browser'); @@ -46,14 +45,14 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide const setAppStatus = async (s: Partial) => { return browser.executeAsync(async (status, cb) => { - window.__coreAppStatus.setAppStatus(status); + window._coreAppStatus.setAppStatus(status); cb(); }, s); }; const navigateToApp = async (id: string) => { return await browser.executeAsync(async (appId, cb) => { - await window.__coreAppStatus.navigateToApp(appId); + await window._coreAppStatus.navigateToApp(appId); cb(); }, id); }; diff --git a/test/plugin_functional/test_suites/core_plugins/applications.ts b/test/plugin_functional/test_suites/core_plugins/applications.ts index 6d31889a9cbe4..9306b62b9d521 100644 --- a/test/plugin_functional/test_suites/core_plugins/applications.ts +++ b/test/plugin_functional/test_suites/core_plugins/applications.ts @@ -20,7 +20,6 @@ import url from 'url'; import expect from '@kbn/expect'; import { PluginFunctionalProviderContext } from '../../services'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const PageObjects = getPageObjects(['common']); diff --git a/test/plugin_functional/test_suites/core_plugins/elasticsearch_client.ts b/test/plugin_functional/test_suites/core_plugins/elasticsearch_client.ts index 9b9efc261126f..a44db4193248d 100644 --- a/test/plugin_functional/test_suites/core_plugins/elasticsearch_client.ts +++ b/test/plugin_functional/test_suites/core_plugins/elasticsearch_client.ts @@ -19,7 +19,6 @@ import { PluginFunctionalProviderContext } from '../../services'; import '../../plugins/core_provider_plugin/types'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const supertest = getService('supertest'); describe('elasticsearch client', () => { diff --git a/test/plugin_functional/test_suites/core_plugins/index.ts b/test/plugin_functional/test_suites/core_plugins/index.ts index 99ac6dc9b8474..cc498fa10818f 100644 --- a/test/plugin_functional/test_suites/core_plugins/index.ts +++ b/test/plugin_functional/test_suites/core_plugins/index.ts @@ -18,7 +18,6 @@ */ import { PluginFunctionalProviderContext } from '../../services'; -// eslint-disable-next-line import/no-default-export export default function ({ loadTestFile }: PluginFunctionalProviderContext) { describe('core plugins', () => { loadTestFile(require.resolve('./applications')); diff --git a/test/plugin_functional/test_suites/core_plugins/legacy_plugins.ts b/test/plugin_functional/test_suites/core_plugins/legacy_plugins.ts index c9274c867df83..d03185796000f 100644 --- a/test/plugin_functional/test_suites/core_plugins/legacy_plugins.ts +++ b/test/plugin_functional/test_suites/core_plugins/legacy_plugins.ts @@ -20,7 +20,6 @@ import expect from '@kbn/expect'; import { PluginFunctionalProviderContext } from '../../services'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const PageObjects = getPageObjects(['common']); const testSubjects = getService('testSubjects'); diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index 7ae6865d45a97..08fd576c036a4 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -32,7 +32,6 @@ declare global { } } -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const PageObjects = getPageObjects(['common']); const appsMenu = getService('appsMenu'); diff --git a/test/plugin_functional/test_suites/core_plugins/server_plugins.ts b/test/plugin_functional/test_suites/core_plugins/server_plugins.ts index 00f242ccc62f6..f67474f3fe3b9 100644 --- a/test/plugin_functional/test_suites/core_plugins/server_plugins.ts +++ b/test/plugin_functional/test_suites/core_plugins/server_plugins.ts @@ -19,7 +19,6 @@ import { PluginFunctionalProviderContext } from '../../services'; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: PluginFunctionalProviderContext) { const supertest = getService('supertest'); diff --git a/test/plugin_functional/test_suites/core_plugins/top_nav.ts b/test/plugin_functional/test_suites/core_plugins/top_nav.ts index 6d2c6b7f85d28..c679ac89f2f61 100644 --- a/test/plugin_functional/test_suites/core_plugins/top_nav.ts +++ b/test/plugin_functional/test_suites/core_plugins/top_nav.ts @@ -19,7 +19,6 @@ import expect from '@kbn/expect'; import { PluginFunctionalProviderContext } from '../../services'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const PageObjects = getPageObjects(['common']); diff --git a/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts b/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts index 3a27be42a2a42..e17ce4059ad21 100644 --- a/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts +++ b/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts @@ -21,7 +21,6 @@ import expect from '@kbn/expect'; import { PluginFunctionalProviderContext } from '../../services'; import '../../../../test/plugin_functional/plugins/core_provider_plugin/types'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const PageObjects = getPageObjects(['common']); const browser = getService('browser'); @@ -36,7 +35,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide it('should run the new platform plugins', async () => { expect( await browser.execute(() => { - return window.__coreProvider.setup.plugins.core_plugin_b.sayHi(); + return window._coreProvider.setup.plugins.core_plugin_b.sayHi(); }) ).to.be('Plugin A said: Hello from Plugin A!'); }); @@ -50,7 +49,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide it('to start services via coreSetup.getStartServices', async () => { expect( await browser.executeAsync(async (cb) => { - const [coreStart] = await window.__coreProvider.setup.core.getStartServices(); + const [coreStart] = await window._coreProvider.setup.core.getStartServices(); cb(Boolean(coreStart.overlays)); }) ).to.be(true); @@ -77,7 +76,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide it('should send kbn-system-request header when asSystemRequest: true', async () => { expect( await browser.executeAsync(async (cb) => { - window.__coreProvider.start.plugins.core_plugin_b.sendSystemRequest(true).then(cb); + window._coreProvider.start.plugins.core_plugin_b.sendSystemRequest(true).then(cb); }) ).to.be('/core_plugin_b/system_request says: "System request? true"'); }); @@ -85,7 +84,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide it('should not send kbn-system-request header when asSystemRequest: false', async () => { expect( await browser.executeAsync(async (cb) => { - window.__coreProvider.start.plugins.core_plugin_b.sendSystemRequest(false).then(cb); + window._coreProvider.start.plugins.core_plugin_b.sendSystemRequest(false).then(cb); }) ).to.be('/core_plugin_b/system_request says: "System request? false"'); }); diff --git a/test/plugin_functional/test_suites/core_plugins/ui_settings.ts b/test/plugin_functional/test_suites/core_plugins/ui_settings.ts index 3a618ceaeb22f..2ff3072552b05 100644 --- a/test/plugin_functional/test_suites/core_plugins/ui_settings.ts +++ b/test/plugin_functional/test_suites/core_plugins/ui_settings.ts @@ -20,7 +20,6 @@ import expect from '@kbn/expect'; import { PluginFunctionalProviderContext } from '../../services'; import '../../plugins/core_provider_plugin/types'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const PageObjects = getPageObjects(['common']); const browser = getService('browser'); @@ -33,7 +32,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide it('client plugins have access to registered settings', async () => { const settings = await browser.execute(() => { - return window.__coreProvider.setup.core.uiSettings.getAll().ui_settings_plugin; + return window._coreProvider.setup.core.uiSettings.getAll().ui_settings_plugin; }); expect(settings).to.eql({ @@ -44,13 +43,13 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide }); const settingsValue = await browser.execute(() => { - return window.__coreProvider.setup.core.uiSettings.get('ui_settings_plugin'); + return window._coreProvider.setup.core.uiSettings.get('ui_settings_plugin'); }); expect(settingsValue).to.be('2'); const settingsValueViaObservables = await browser.executeAsync(async (callback) => { - window.__coreProvider.setup.core.uiSettings + window._coreProvider.setup.core.uiSettings .get$('ui_settings_plugin') .subscribe((v) => callback(v)); }); diff --git a/test/plugin_functional/test_suites/data_plugin/index_patterns.ts b/test/plugin_functional/test_suites/data_plugin/index_patterns.ts index 481e9d76e3acc..2db9eb733f805 100644 --- a/test/plugin_functional/test_suites/data_plugin/index_patterns.ts +++ b/test/plugin_functional/test_suites/data_plugin/index_patterns.ts @@ -20,7 +20,6 @@ import expect from '@kbn/expect'; import { PluginFunctionalProviderContext } from '../../services'; import '../../plugins/core_provider_plugin/types'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); diff --git a/test/plugin_functional/test_suites/doc_views/doc_views.ts b/test/plugin_functional/test_suites/doc_views/doc_views.ts index 87b4dc2a63d5a..d45be1c66149a 100644 --- a/test/plugin_functional/test_suites/doc_views/doc_views.ts +++ b/test/plugin_functional/test_suites/doc_views/doc_views.ts @@ -20,7 +20,6 @@ import expect from '@kbn/expect'; import { PluginFunctionalProviderContext } from '../../services'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) { const testSubjects = getService('testSubjects'); const find = getService('find'); diff --git a/test/typings/rison_node.d.ts b/test/typings/rison_node.d.ts index a0497f421c3fe..2c63488e6b6db 100644 --- a/test/typings/rison_node.d.ts +++ b/test/typings/rison_node.d.ts @@ -29,11 +29,11 @@ declare module 'rison-node' { export const decode: (input: string) => RisonValue; - // eslint-disable-next-line @typescript-eslint/camelcase + // eslint-disable-next-line @typescript-eslint/naming-convention export const decode_object: (input: string) => RisonObject; export const encode: (input: Input) => string; - // eslint-disable-next-line @typescript-eslint/camelcase + // eslint-disable-next-line @typescript-eslint/naming-convention export const encode_object: (input: Input) => string; } diff --git a/typings/rison_node.d.ts b/typings/rison_node.d.ts index a0497f421c3fe..2c63488e6b6db 100644 --- a/typings/rison_node.d.ts +++ b/typings/rison_node.d.ts @@ -29,11 +29,11 @@ declare module 'rison-node' { export const decode: (input: string) => RisonValue; - // eslint-disable-next-line @typescript-eslint/camelcase + // eslint-disable-next-line @typescript-eslint/naming-convention export const decode_object: (input: string) => RisonObject; export const encode: (input: Input) => string; - // eslint-disable-next-line @typescript-eslint/camelcase + // eslint-disable-next-line @typescript-eslint/naming-convention export const encode_object: (input: Input) => string; } diff --git a/x-pack/legacy/plugins/beats_management/common/io_ts_types.ts b/x-pack/legacy/plugins/beats_management/common/io_ts_types.ts index 7d71ea5ad8256..175aba82c8dac 100644 --- a/x-pack/legacy/plugins/beats_management/common/io_ts_types.ts +++ b/x-pack/legacy/plugins/beats_management/common/io_ts_types.ts @@ -8,7 +8,6 @@ import * as t from 'io-ts'; import { isRight } from 'fp-ts/lib/Either'; class DateFromStringType extends t.Type { - // eslint-disable-next-line public readonly _tag: 'DateFromISOStringType' = 'DateFromISOStringType'; constructor() { super( diff --git a/x-pack/legacy/plugins/beats_management/scripts/fake_env.ts b/x-pack/legacy/plugins/beats_management/scripts/fake_env.ts index 246f86c957174..65254d24863cd 100644 --- a/x-pack/legacy/plugins/beats_management/scripts/fake_env.ts +++ b/x-pack/legacy/plugins/beats_management/scripts/fake_env.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import Chance from 'chance'; // eslint-disable-line +import Chance from 'chance'; // @ts-ignore import request from 'request'; import uuidv4 from 'uuid/v4'; @@ -121,8 +121,8 @@ const start = async ( () => ({ type: configBlockSchemas[Math.floor(Math.random())].id, - description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sint ista Graecorum; -Nihil ad rem! Ne sit sane; Quod quidem nobis non saepe contingit. + description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sint ista Graecorum; +Nihil ad rem! Ne sit sane; Quod quidem nobis non saepe contingit. Duo Reges: constructio interrete. Itaque his sapiens semper vacabit.`.substring( 0, Math.floor(Math.random() * (0 - 115 + 1)) diff --git a/x-pack/legacy/plugins/beats_management/server/lib/beats.ts b/x-pack/legacy/plugins/beats_management/server/lib/beats.ts index 6b7053f40550b..e8a6e6f999ca3 100644 --- a/x-pack/legacy/plugins/beats_management/server/lib/beats.ts +++ b/x-pack/legacy/plugins/beats_management/server/lib/beats.ts @@ -93,8 +93,8 @@ export class CMBeatsDomain { remoteAddress: string, beat: Partial ): Promise<{ status: string; accessToken?: string }> { + // eslint-disable-next-line @typescript-eslint/naming-convention const { token, expires_on } = await this.tokens.getEnrollmentToken(enrollmentToken); - // eslint-disable-next-line @typescript-eslint/camelcase if (expires_on && moment(expires_on).isBefore(moment())) { return { status: BeatEnrollmentStatus.ExpiredEnrollmentToken }; } diff --git a/x-pack/plugins/actions/server/builtin_action_types/index.test.ts b/x-pack/plugins/actions/server/builtin_action_types/index.test.ts index 21efc05d49c38..acab6dd41b4b3 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/index.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/index.test.ts @@ -44,8 +44,6 @@ beforeEach(() => { describe('action is registered', () => { test('gets registered with builtin actions', () => { const { actionTypeRegistry } = createActionTypeRegistry(); - ACTION_TYPE_IDS.forEach((ACTION_TYPE_ID) => - expect(actionTypeRegistry.has(ACTION_TYPE_ID)).toEqual(true) - ); + ACTION_TYPE_IDS.forEach((id) => expect(actionTypeRegistry.has(id)).toEqual(true)); }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts index 7e659125af7b2..49b85f9254af9 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - import { TypeOf } from '@kbn/config-schema'; import { ExecutorSubActionGetIncidentParamsSchema, diff --git a/x-pack/plugins/alerts/server/alert_type_registry.test.ts b/x-pack/plugins/alerts/server/alert_type_registry.test.ts index 229847bda1836..60adde80e883f 100644 --- a/x-pack/plugins/alerts/server/alert_type_registry.test.ts +++ b/x-pack/plugins/alerts/server/alert_type_registry.test.ts @@ -57,7 +57,6 @@ describe('register()', () => { executor: jest.fn(), producer: 'alerts', }; - // eslint-disable-next-line @typescript-eslint/no-var-requires const registry = new AlertTypeRegistry(alertTypeRegistryParams); const invalidCharacters = [' ', ':', '*', '*', '/']; @@ -89,7 +88,6 @@ describe('register()', () => { executor: jest.fn(), producer: 'alerts', }; - // eslint-disable-next-line @typescript-eslint/no-var-requires const registry = new AlertTypeRegistry(alertTypeRegistryParams); expect(() => registry.register(alertType)).toThrowError( @@ -111,7 +109,6 @@ describe('register()', () => { executor: jest.fn(), producer: 'alerts', }; - // eslint-disable-next-line @typescript-eslint/no-var-requires const registry = new AlertTypeRegistry(alertTypeRegistryParams); registry.register(alertType); expect(taskManager.registerTaskDefinitions).toHaveBeenCalledTimes(1); diff --git a/x-pack/plugins/alerts/server/alerts_client.ts b/x-pack/plugins/alerts/server/alerts_client.ts index eec60f924bf38..256cae24e519f 100644 --- a/x-pack/plugins/alerts/server/alerts_client.ts +++ b/x-pack/plugins/alerts/server/alerts_client.ts @@ -295,6 +295,7 @@ export class AlertsClient { type: 'alert', }); + // eslint-disable-next-line @typescript-eslint/naming-convention const authorizedData = data.map(({ id, attributes, updated_at, references }) => { ensureAlertTypeIsAuthorized(attributes.alertTypeId, attributes.consumer); return this.getAlertFromRaw( diff --git a/x-pack/plugins/alerts/server/types.ts b/x-pack/plugins/alerts/server/types.ts index 154a9564518e8..71ab35f7f434b 100644 --- a/x-pack/plugins/alerts/server/types.ts +++ b/x-pack/plugins/alerts/server/types.ts @@ -23,7 +23,6 @@ import { export type State = Record; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type Context = Record; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export type AlertParams = Record; export type WithoutQueryAndParams = Pick>; export type GetServicesFunction = (request: KibanaRequest) => Services; diff --git a/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts b/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts index 5791dfe5b9463..1956f1c2d9f0d 100644 --- a/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts +++ b/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable import/no-extraneous-dependencies */ - const BASE_URL = Cypress.config().baseUrl; /** The default time in ms to wait for a Cypress command to complete */ diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/CytoscapeExampleData.stories.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/CytoscapeExampleData.stories.tsx index 44278b2846128..830e3719b11f9 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/CytoscapeExampleData.stories.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/CytoscapeExampleData.stories.tsx @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable no-console */ import { EuiButton, diff --git a/x-pack/plugins/apm/public/hooks/useFetcher.tsx b/x-pack/plugins/apm/public/hooks/useFetcher.tsx index b2cd217b6cdd2..68b197c46e888 100644 --- a/x-pack/plugins/apm/public/hooks/useFetcher.tsx +++ b/x-pack/plugins/apm/public/hooks/useFetcher.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable no-console */ - import React, { useContext, useEffect, useState, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { IHttpFetchError } from 'src/core/public'; diff --git a/x-pack/plugins/apm/public/utils/testHelpers.tsx b/x-pack/plugins/apm/public/utils/testHelpers.tsx index e750102de2baa..217e6a30a33b4 100644 --- a/x-pack/plugins/apm/public/utils/testHelpers.tsx +++ b/x-pack/plugins/apm/public/utils/testHelpers.tsx @@ -106,12 +106,14 @@ interface MockSetup { config: APMConfig; uiFiltersES: ESFilter[]; indices: { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': string; 'apm_oss.errorIndices': string; 'apm_oss.onboardingIndices': string; 'apm_oss.spanIndices': string; 'apm_oss.transactionIndices': string; 'apm_oss.metricsIndices': string; + /* eslint-enable @typescript-eslint/naming-convention */ apmAgentConfigurationIndex: string; apmCustomLinkIndex: string; }; @@ -152,12 +154,14 @@ export async function inspectSearchParams( config: new Proxy({}, { get: () => 'myIndex' }) as APMConfig, uiFiltersES: [{ term: { 'my.custom.ui.filter': 'foo-bar' } }], indices: { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': 'myIndex', 'apm_oss.errorIndices': 'myIndex', 'apm_oss.onboardingIndices': 'myIndex', 'apm_oss.spanIndices': 'myIndex', 'apm_oss.transactionIndices': 'myIndex', 'apm_oss.metricsIndices': 'myIndex', + /* eslint-enable @typescript-eslint/naming-convention */ apmAgentConfigurationIndex: 'myIndex', apmCustomLinkIndex: 'myIndex', }, diff --git a/x-pack/plugins/apm/scripts/shared/read-kibana-config.ts b/x-pack/plugins/apm/scripts/shared/read-kibana-config.ts index fe226c8ab27d2..aa269bd61d132 100644 --- a/x-pack/plugins/apm/scripts/shared/read-kibana-config.ts +++ b/x-pack/plugins/apm/scripts/shared/read-kibana-config.ts @@ -36,12 +36,14 @@ export const readKibanaConfig = () => { }; return { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.transactionIndices': 'apm-*', 'apm_oss.metricsIndices': 'apm-*', 'apm_oss.errorIndices': 'apm-*', 'apm_oss.spanIndices': 'apm-*', 'apm_oss.onboardingIndices': 'apm-*', 'apm_oss.sourcemapIndices': 'apm-*', + /* eslint-enable @typescript-eslint/naming-convention */ 'elasticsearch.hosts': 'http://localhost:9200', ...loadedKibanaConfig, ...cliEsCredentials, diff --git a/x-pack/plugins/apm/scripts/upload-telemetry-data/index.ts b/x-pack/plugins/apm/scripts/upload-telemetry-data/index.ts index 10651d97f3c3d..fd628f77eb519 100644 --- a/x-pack/plugins/apm/scripts/upload-telemetry-data/index.ts +++ b/x-pack/plugins/apm/scripts/upload-telemetry-data/index.ts @@ -19,7 +19,6 @@ import { stampLogger } from '../shared/stamp-logger'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { CollectTelemetryParams } from '../../server/lib/apm_telemetry/collect_data_telemetry'; import { downloadTelemetryTemplate } from '../shared/download-telemetry-template'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { mergeApmTelemetryMapping } from '../../common/apm_telemetry'; import { generateSampleDocuments } from './generate-sample-documents'; import { readKibanaConfig } from '../shared/read-kibana-config'; diff --git a/x-pack/plugins/apm/server/index.ts b/x-pack/plugins/apm/server/index.ts index 431210926c948..fa4b8b821f9f8 100644 --- a/x-pack/plugins/apm/server/index.ts +++ b/x-pack/plugins/apm/server/index.ts @@ -41,6 +41,7 @@ export function mergeConfigs( apmConfig: APMXPackConfig ) { return { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.transactionIndices': apmOssConfig.transactionIndices, 'apm_oss.spanIndices': apmOssConfig.spanIndices, 'apm_oss.errorIndices': apmOssConfig.errorIndices, @@ -48,6 +49,7 @@ export function mergeConfigs( 'apm_oss.sourcemapIndices': apmOssConfig.sourcemapIndices, 'apm_oss.onboardingIndices': apmOssConfig.onboardingIndices, 'apm_oss.indexPattern': apmOssConfig.indexPattern, + /* eslint-enable @typescript-eslint/naming-convention */ 'xpack.apm.serviceMapEnabled': apmConfig.serviceMapEnabled, 'xpack.apm.serviceMapFingerprintBucketSize': apmConfig.serviceMapFingerprintBucketSize, diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts index eafd0f04b9d10..9d06fc2ad9309 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts @@ -10,10 +10,12 @@ import { tasks } from './tasks'; describe('data telemetry collection tasks', () => { const indices = { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.errorIndices': 'apm-8.0.0-error', 'apm_oss.metricsIndices': 'apm-8.0.0-metric', 'apm_oss.spanIndices': 'apm-8.0.0-span', 'apm_oss.transactionIndices': 'apm-8.0.0-transaction', + /* eslint-enable @typescript-eslint/naming-convention */ } as ApmIndicesConfig; describe('aggregated_transactions', () => { diff --git a/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts b/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts index e0df4d7744610..1a83113de35f2 100644 --- a/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts +++ b/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts @@ -47,12 +47,14 @@ describe('timeseriesFetcher', () => { }, ], indices: { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': 'apm-*', 'apm_oss.errorIndices': 'apm-*', 'apm_oss.onboardingIndices': 'apm-*', 'apm_oss.spanIndices': 'apm-*', 'apm_oss.transactionIndices': 'apm-*', 'apm_oss.metricsIndices': 'apm-*', + /* eslint-enable @typescript-eslint/naming-convention */ apmAgentConfigurationIndex: '.apm-agent-configuration', apmCustomLinkIndex: '.apm-custom-link', }, diff --git a/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts b/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts index d8dbd8273f476..b7c9b178c7cd4 100644 --- a/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts +++ b/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts @@ -12,12 +12,14 @@ import { PROCESSOR_EVENT } from '../../../common/elasticsearch_fieldnames'; jest.mock('../settings/apm_indices/get_apm_indices', () => ({ getApmIndices: async () => ({ + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': 'apm-*', 'apm_oss.errorIndices': 'apm-*', 'apm_oss.onboardingIndices': 'apm-*', 'apm_oss.spanIndices': 'apm-*', 'apm_oss.transactionIndices': 'apm-*', 'apm_oss.metricsIndices': 'apm-*', + /* eslint-enable @typescript-eslint/naming-convention */ apmAgentConfigurationIndex: 'apm-*', }), })); diff --git a/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts b/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts index 430be3b96934b..2f3b2a602048c 100644 --- a/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts +++ b/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts @@ -18,12 +18,14 @@ import { APMRequestHandlerContext } from '../../../routes/typings'; type ISavedObjectsClient = Pick; export interface ApmIndicesConfig { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': string; 'apm_oss.errorIndices': string; 'apm_oss.onboardingIndices': string; 'apm_oss.spanIndices': string; 'apm_oss.transactionIndices': string; 'apm_oss.metricsIndices': string; + /* eslint-enable @typescript-eslint/naming-convention */ apmAgentConfigurationIndex: string; apmCustomLinkIndex: string; } @@ -46,12 +48,14 @@ async function getApmIndicesSavedObject( export function getApmIndicesConfig(config: APMConfig): ApmIndicesConfig { return { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': config['apm_oss.sourcemapIndices'], 'apm_oss.errorIndices': config['apm_oss.errorIndices'], 'apm_oss.onboardingIndices': config['apm_oss.onboardingIndices'], 'apm_oss.spanIndices': config['apm_oss.spanIndices'], 'apm_oss.transactionIndices': config['apm_oss.transactionIndices'], 'apm_oss.metricsIndices': config['apm_oss.metricsIndices'], + /* eslint-enable @typescript-eslint/naming-convention */ // system indices, not configurable apmAgentConfigurationIndex: '.apm-agent-configuration', apmCustomLinkIndex: '.apm-custom-link', diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts b/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts index 8fb2ceb30db85..d4e0bd1d54da1 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts @@ -74,10 +74,14 @@ export async function getErrorRate({ const erroneousTransactionsRate = resp.aggregations?.total_transactions.buckets.map( - ({ key, doc_count: totalTransactions, erroneous_transactions }) => { + ({ + key, + doc_count: totalTransactions, + erroneous_transactions: erroneousTransactions, + }) => { const errornousTransactionsCount = - // @ts-ignore - erroneous_transactions.doc_count; + // @ts-expect-error + erroneousTransactions.doc_count; return { x: key, y: errornousTransactionsCount / totalTransactions, diff --git a/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts b/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts index 9bb42d2fa7aad..3954d99cd52a8 100644 --- a/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts @@ -75,6 +75,7 @@ export async function getTransactionAvgDurationByCountry({ const buckets = resp.aggregations.country_code.buckets; const avgDurationsByCountry = buckets.map( + // eslint-disable-next-line @typescript-eslint/naming-convention ({ key, doc_count, avg_duration: { value } }) => ({ key: key as string, docCount: doc_count, diff --git a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts index 3c1618ed7715f..731f75226cbe4 100644 --- a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts +++ b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts @@ -11,12 +11,14 @@ import dataResponse from './mock_responses/data.json'; import { APMConfig } from '../../..'; const mockIndices = { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': 'myIndex', 'apm_oss.errorIndices': 'myIndex', 'apm_oss.onboardingIndices': 'myIndex', 'apm_oss.spanIndices': 'myIndex', 'apm_oss.transactionIndices': 'myIndex', 'apm_oss.metricsIndices': 'myIndex', + /* eslint-enable @typescript-eslint/naming-convention */ apmAgentConfigurationIndex: 'myIndex', apmCustomLinkIndex: 'myIndex', }; diff --git a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts index 09e1287f032f5..a7a740a239ea7 100644 --- a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts +++ b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts @@ -35,12 +35,14 @@ describe('timeseriesFetcher', () => { }, ], indices: { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': 'myIndex', 'apm_oss.errorIndices': 'myIndex', 'apm_oss.onboardingIndices': 'myIndex', 'apm_oss.spanIndices': 'myIndex', 'apm_oss.transactionIndices': 'myIndex', 'apm_oss.metricsIndices': 'myIndex', + /* eslint-enable @typescript-eslint/naming-convention */ apmAgentConfigurationIndex: 'myIndex', apmCustomLinkIndex: 'myIndex', }, diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices.ts index e52ce760e026a..1946bd1111d4b 100644 --- a/x-pack/plugins/apm/server/routes/settings/apm_indices.ts +++ b/x-pack/plugins/apm/server/routes/settings/apm_indices.ts @@ -42,12 +42,14 @@ export const saveApmIndicesRoute = createRoute(() => ({ }, params: { body: t.partial({ + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': t.string, 'apm_oss.errorIndices': t.string, 'apm_oss.onboardingIndices': t.string, 'apm_oss.spanIndices': t.string, 'apm_oss.transactionIndices': t.string, 'apm_oss.metricsIndices': t.string, + /* eslint-enable @typescript-eslint/naming-convention */ }), }, handler: async ({ context }) => { diff --git a/x-pack/plugins/apm/server/saved_objects/apm_indices.ts b/x-pack/plugins/apm/server/saved_objects/apm_indices.ts index b1473219ea45f..1137abdb474ac 100644 --- a/x-pack/plugins/apm/server/saved_objects/apm_indices.ts +++ b/x-pack/plugins/apm/server/saved_objects/apm_indices.ts @@ -11,6 +11,7 @@ export const apmIndices: SavedObjectsType = { namespaceType: 'agnostic', mappings: { properties: { + /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': { type: 'keyword', }, diff --git a/x-pack/plugins/beats_management/public/components/tag/tag_edit.tsx b/x-pack/plugins/beats_management/public/components/tag/tag_edit.tsx index 5ea4b643fb5a2..9fca9d3add5e7 100644 --- a/x-pack/plugins/beats_management/public/components/tag/tag_edit.tsx +++ b/x-pack/plugins/beats_management/public/components/tag/tag_edit.tsx @@ -67,6 +67,7 @@ export class TagEdit extends React.PureComponent { } public render() { + // eslint-disable-next-line @typescript-eslint/naming-convention const { tag, attachedBeats, configuration_blocks } = this.props; return ( @@ -151,9 +152,7 @@ export class TagEdit extends React.PureComponent {
    { if (action === 'delete') { this.props.onConfigRemoved(block); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts index 2a3741e15f467..ec640cfb5b299 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts @@ -13,7 +13,6 @@ import { EmbeddableExpression, } from '../../expression_types'; import { getFunctionHelp } from '../../../i18n'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { MapEmbeddableInput } from '../../../../../plugins/maps/public/embeddable'; interface Arguments { diff --git a/x-pack/plugins/canvas/public/application.tsx b/x-pack/plugins/canvas/public/application.tsx index 0bbf449ce11f9..90173a20500e5 100644 --- a/x-pack/plugins/canvas/public/application.tsx +++ b/x-pack/plugins/canvas/public/application.tsx @@ -26,7 +26,6 @@ import { getDocumentationLinks } from './lib/documentation_links'; import { HelpMenu } from './components/help_menu/help_menu'; import { createStore } from './store'; -/* eslint-enable */ import { init as initStatsReporter } from './lib/ui_metric'; import { CapabilitiesStrings } from '../i18n'; diff --git a/x-pack/plugins/canvas/public/components/confirm_modal/confirm_modal.tsx b/x-pack/plugins/canvas/public/components/confirm_modal/confirm_modal.tsx index 1be587c31528f..31a75acbba4ec 100644 --- a/x-pack/plugins/canvas/public/components/confirm_modal/confirm_modal.tsx +++ b/x-pack/plugins/canvas/public/components/confirm_modal/confirm_modal.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable react/forbid-elements */ import { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui'; import PropTypes from 'prop-types'; import React, { FunctionComponent } from 'react'; diff --git a/x-pack/plugins/canvas/public/components/custom_element_modal/custom_element_modal.tsx b/x-pack/plugins/canvas/public/components/custom_element_modal/custom_element_modal.tsx index ceb7c83f3cab5..e2bc81b39749f 100644 --- a/x-pack/plugins/canvas/public/components/custom_element_modal/custom_element_modal.tsx +++ b/x-pack/plugins/canvas/public/components/custom_element_modal/custom_element_modal.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable react/forbid-elements */ import React, { PureComponent } from 'react'; import { get } from 'lodash'; import PropTypes from 'prop-types'; diff --git a/x-pack/plugins/canvas/public/lib/aeroelastic/index.d.ts b/x-pack/plugins/canvas/public/lib/aeroelastic/index.d.ts index 3163e318b25dd..c21aac3fbfb25 100644 --- a/x-pack/plugins/canvas/public/lib/aeroelastic/index.d.ts +++ b/x-pack/plugins/canvas/public/lib/aeroelastic/index.d.ts @@ -7,15 +7,15 @@ /* eslint-disable @typescript-eslint/no-empty-interface */ // linear algebra -type f64 = number; // eventual AssemblyScript compatibility; doesn't hurt with vanilla TS either -type f = f64; // shorthand +type F64 = number; // eventual AssemblyScript compatibility; doesn't hurt with vanilla TS either +type F = F64; // shorthand -export type Vector2d = Readonly<[f, f, f]>; -export type Vector3d = Readonly<[f, f, f, f]>; +export type Vector2d = Readonly<[F, F, F]>; +export type Vector3d = Readonly<[F, F, F, F]>; -export type Matrix2d = [f, f, f, f, f, f, f, f, f]; +export type Matrix2d = [F, F, F, F, F, F, F, F, F]; export type TransformMatrix2d = Readonly; -export type Matrix3d = [f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f]; +export type Matrix3d = [F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F]; export type TransformMatrix3d = Readonly; // plain, JSON-bijective value diff --git a/x-pack/plugins/canvas/public/lib/elastic_logo.ts b/x-pack/plugins/canvas/public/lib/elastic_logo.ts index e73b8615045ae..5f0408ab01e29 100644 --- a/x-pack/plugins/canvas/public/lib/elastic_logo.ts +++ b/x-pack/plugins/canvas/public/lib/elastic_logo.ts @@ -4,6 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable */ export const elasticLogo = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmlld0JveD0iMCAwIDI3MC42MDAwMSAyNjkuNTQ2NjYiCiAgIGhlaWdodD0iMjY5LjU0NjY2IgogICB3aWR0aD0iMjcwLjYwMDAxIgogICB4bWw6c3BhY2U9InByZXNlcnZlIgogICBpZD0ic3ZnMiIKICAgdmVyc2lvbj0iMS4xIj48bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE4Ij48cmRmOlJERj48Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPjwvY2M6V29yaz48L3JkZjpSREY+PC9tZXRhZGF0YT48ZGVmcwogICAgIGlkPSJkZWZzNiIgLz48ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMzMzMzMzMywwLDAsLTEuMzMzMzMzMywwLDI2OS41NDY2NykiCiAgICAgaWQ9ImcxMCI+PGcKICAgICAgIHRyYW5zZm9ybT0ic2NhbGUoMC4xKSIKICAgICAgIGlkPSJnMTIiPjxwYXRoCiAgICAgICAgIGlkPSJwYXRoMTQiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiCiAgICAgICAgIGQ9Im0gMjAyOS40OCw5NjIuNDQxIGMgMCwxNzAuMDk5IC0xMDUuNDYsMzE4Ljc5OSAtMjY0LjE3LDM3Ni42NTkgNi45OCwzNS44NiAxMC42Miw3MS43MSAxMC42MiwxMDkuMDUgMCwzMTYuMTkgLTI1Ny4yNCw1NzMuNDMgLTU3My40Nyw1NzMuNDMgLTE4NC43MiwwIC0zNTYuNTU4LC04OC41OSAtNDY0LjUzLC0yMzcuODUgLTUzLjA5LDQxLjE4IC0xMTguMjg1LDYzLjc1IC0xODYuMzA1LDYzLjc1IC0xNjcuODM2LDAgLTMwNC4zODMsLTEzNi41NCAtMzA0LjM4MywtMzA0LjM4IDAsLTM3LjA4IDYuNjE3LC03Mi41OCAxOS4wMzEsLTEwNi4wOCBDIDEwOC40ODgsMTM4MC4wOSAwLDEyMjcuODkgMCwxMDU4Ljg4IDAsODg3LjkxIDEwNS45NzcsNzM4LjUzOSAyNjUuMzk4LDY4MS4wOSBjIC02Ljc2OSwtMzUuNDQyIC0xMC40NiwtNzIuMDIgLTEwLjQ2LC0xMDkgQyAyNTQuOTM4LDI1Ni42MjEgNTExLjU2NiwwIDgyNy4wMjcsMCAxMDEyLjIsMCAxMTgzLjk0LDg4Ljk0MTQgMTI5MS4zLDIzOC44MzIgYyA1My40NSwtNDEuOTYxIDExOC44LC02NC45OTIgMTg2LjU2LC02NC45OTIgMTY3LjgzLDAgMzA0LjM4LDEzNi40OTIgMzA0LjM4LDMwNC4zMzIgMCwzNy4wNzggLTYuNjIsNzIuNjI5IC0xOS4wMywxMDYuMTI5IDE1Ny43OCw1Ni44NzkgMjY2LjI3LDIwOS4xMjkgMjY2LjI3LDM3OC4xNCIgLz48cGF0aAogICAgICAgICBpZD0icGF0aDE2IgogICAgICAgICBzdHlsZT0iZmlsbDojZmFjZjA5O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIgogICAgICAgICBkPSJtIDc5Ny44OTgsMTE1MC45MyA0NDQuMDcyLC0yMDIuNDUgNDQ4LjA1LDM5Mi41OCBjIDYuNDksMzIuMzkgOS42Niw2NC42NyA5LjY2LDk4LjQ2IDAsMjc2LjIzIC0yMjQuNjgsNTAwLjk1IC01MDAuOSw1MDAuOTUgLTE2NS4yNCwwIC0zMTkuMzcsLTgxLjM2IC00MTMuMDUzLC0yMTcuNzkgbCAtNzQuNTI0LC0zODYuNjQgODYuNjk1LC0xODUuMTEiIC8+PHBhdGgKICAgICAgICAgaWQ9InBhdGgxOCIKICAgICAgICAgc3R5bGU9ImZpbGw6IzQ5YzFhZTtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIKICAgICAgICAgZD0ibSAzMzguMjIzLDY4MC42NzIgYyAtNi40ODksLTMyLjM4MyAtOS44MDksLTY1Ljk4MSAtOS44MDksLTk5Ljk3MyAwLC0yNzYuOTI5IDIyNS4zMzYsLTUwMi4yNTc2IDUwMi4zMTMsLTUwMi4yNTc2IDE2Ni41OTMsMCAzMjEuNDczLDgyLjExNzYgNDE1LjAxMywyMTkuOTQ5NiBsIDczLjk3LDM4NS4zNDcgLTk4LjcyLDE4OC42MjEgTCA3NzUuMTU2LDEwNzUuNTcgMzM4LjIyMyw2ODAuNjcyIiAvPjxwYXRoCiAgICAgICAgIGlkPSJwYXRoMjAiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNlZjI5OWI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiCiAgICAgICAgIGQ9Im0gMzM1LjQxLDE0NDkuMTggMzA0LjMzMiwtNzEuODYgNjYuNjgsMzQ2LjAyIGMgLTQxLjU4NiwzMS43OCAtOTIuOTMsNDkuMTggLTE0NS43MzEsNDkuMTggLTEzMi4yNSwwIC0yMzkuODEyLC0xMDcuNjEgLTIzOS44MTIsLTIzOS44NyAwLC0yOS4yMSA0Ljg3OSwtNTcuMjIgMTQuNTMxLC04My40NyIgLz48cGF0aAogICAgICAgICBpZD0icGF0aDIyIgogICAgICAgICBzdHlsZT0iZmlsbDojNGNhYmU0O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIgogICAgICAgICBkPSJNIDMwOC45OTIsMTM3Ni43IEMgMTczLjAyLDEzMzEuNjQgNzguNDgwNSwxMjAxLjMgNzguNDgwNSwxMDU3LjkzIDc4LjQ4MDUsOTE4LjM0IDE2NC44Miw3OTMuNjggMjk0LjQwNiw3NDQuMzUyIGwgNDI2Ljk4MSwzODUuOTM4IC03OC4zOTUsMTY3LjUxIC0zMzQsNzguOSIgLz48cGF0aAogICAgICAgICBpZD0icGF0aDI0IgogICAgICAgICBzdHlsZT0iZmlsbDojODVjZTI2O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIgogICAgICAgICBkPSJtIDEzMjMuOCwyOTguNDEgYyA0MS43NCwtMzIuMDkgOTIuODMsLTQ5LjU5IDE0NC45OCwtNDkuNTkgMTMyLjI1LDAgMjM5LjgxLDEwNy41NTkgMjM5LjgxLDIzOS44MjEgMCwyOS4xNiAtNC44OCw1Ny4xNjggLTE0LjUzLDgzLjQxOCBsIC0zMDQuMDgsNzEuMTYgLTY2LjE4LC0zNDQuODA5IiAvPjxwYXRoCiAgICAgICAgIGlkPSJwYXRoMjYiCiAgICAgICAgIHN0eWxlPSJmaWxsOiMzMTc3YTc7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiCiAgICAgICAgIGQ9Im0gMTM4NS42Nyw3MjIuOTMgMzM0Ljc2LC03OC4zMDEgYyAxMzYuMDIsNDQuOTYxIDIzMC41NiwxNzUuMzUxIDIzMC41NiwzMTguNzYyIDAsMTM5LjMzOSAtODYuNTQsMjYzLjg1OSAtMjE2LjM4LDMxMy4wMzkgbCAtNDM3Ljg0LC0zODMuNTkgODguOSwtMTY5LjkxIiAvPjwvZz48L2c+PC9zdmc+'; diff --git a/x-pack/plugins/canvas/public/state/selectors/workpad.ts b/x-pack/plugins/canvas/public/state/selectors/workpad.ts index b05615b7930c5..6eddca42e21c6 100644 --- a/x-pack/plugins/canvas/public/state/selectors/workpad.ts +++ b/x-pack/plugins/canvas/public/state/selectors/workpad.ts @@ -214,13 +214,13 @@ export function getGlobalFilters(state: State): string[] { }, []); } -type onValueFunction = ( +type OnValueFunction = ( argValue: ExpressionAstArgument, argNames?: string, args?: ExpressionAstFunction['arguments'] ) => ExpressionAstArgument | ExpressionAstArgument[] | undefined; -function buildGroupValues(args: ExpressionAstFunction['arguments'], onValue: onValueFunction) { +function buildGroupValues(args: ExpressionAstFunction['arguments'], onValue: OnValueFunction) { const argNames = Object.keys(args); return argNames.reduce((values, argName) => { @@ -495,7 +495,6 @@ export function getRenderedWorkpad(state: State) { const workpad = getWorkpad(state); - // eslint-disable-next-line no-unused-vars const { pages, variables, ...rest } = workpad; return { diff --git a/x-pack/plugins/canvas/server/routes/shareables/zip.test.ts b/x-pack/plugins/canvas/server/routes/shareables/zip.test.ts index 29dcb4268e618..0c19886f07e5c 100644 --- a/x-pack/plugins/canvas/server/routes/shareables/zip.test.ts +++ b/x-pack/plugins/canvas/server/routes/shareables/zip.test.ts @@ -6,6 +6,7 @@ jest.mock('archiver'); +// eslint-disable-next-line @typescript-eslint/no-var-requires const archiver = require('archiver') as jest.Mock; import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { httpServiceMock, httpServerMock, loggingSystemMock } from 'src/core/server/mocks'; diff --git a/x-pack/plugins/canvas/shareable_runtime/components/canvas.tsx b/x-pack/plugins/canvas/shareable_runtime/components/canvas.tsx index b1eb9af6fc4a1..e327f90e80aeb 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/canvas.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/canvas.tsx @@ -15,7 +15,9 @@ import { CanvasRenderedWorkpad, Stage, Settings, Refs } from '../types'; let timeout: number = 0; +// eslint-disable-next-line @typescript-eslint/naming-convention export type onSetPageFn = (page: number) => void; +// eslint-disable-next-line @typescript-eslint/naming-convention export type onSetScrubberVisibleFn = (visible: boolean) => void; type Workpad = Pick; diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/page_controls.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/page_controls.tsx index 836d10f9ee8f5..9f94ef4f24187 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/page_controls.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/page_controls.tsx @@ -14,19 +14,19 @@ import { setAutoplayAction, } from '../../context'; -type onSetPageNumberFn = (page: number) => void; -type onToggleScrubberFn = () => void; +type OnSetPageNumberFn = (page: number) => void; +type OnToggleScrubberFn = () => void; interface Props { /** * The handler to invoke when the current page number is set. */ - onSetPageNumber: onSetPageNumberFn; + onSetPageNumber: OnSetPageNumberFn; /** * The handler to invoke when the scrubber visibility is toggled. */ - onToggleScrubber: onToggleScrubberFn; + onToggleScrubber: OnToggleScrubberFn; /** * The current page number. diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/page_preview.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/page_preview.tsx index 7908b3edb981f..8c06a0a342c24 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/page_preview.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/page_preview.tsx @@ -12,7 +12,7 @@ import { setPageAction } from '../../context/actions'; import css from './page_preview.module.scss'; -type onClickFn = (index: number) => void; +type OnClickFn = (index: number) => void; export interface Props { /** @@ -28,7 +28,7 @@ export interface Props { /** * The handler to invoke if the preview is clicked. */ - onClick: onClickFn; + onClick: OnClickFn; /** * An object describing the page. diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/autoplay_settings.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/autoplay_settings.tsx index 4c7c65511698d..c20d9f6fc39e2 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/autoplay_settings.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/autoplay_settings.tsx @@ -14,7 +14,9 @@ import { import { createTimeInterval } from '../../../../public/lib/time_interval'; import { CustomInterval } from '../../../../public/components/workpad_header/view_menu/custom_interval'; +// eslint-disable-next-line @typescript-eslint/naming-convention export type onSetAutoplayFn = (autoplay: boolean) => void; +// eslint-disable-next-line @typescript-eslint/naming-convention export type onSetIntervalFn = (interval: string) => void; export interface Props { diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/toolbar_settings.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/toolbar_settings.tsx index 2c90c5c0ceded..8b545061a4185 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/toolbar_settings.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/toolbar_settings.tsx @@ -8,7 +8,7 @@ import React, { FC } from 'react'; import { EuiSwitch, EuiFormRow } from '@elastic/eui'; import { useCanvasShareableState, setToolbarAutohideAction } from '../../../context'; -export type onSetAutohideFn = (isAutohide: boolean) => void; +export type OnSetAutohideFn = (isAutohide: boolean) => void; export interface Props { /** @@ -20,7 +20,7 @@ export interface Props { /** * The handler to invoke when autohide is set. */ - onSetAutohide: onSetAutohideFn; + onSetAutohide: OnSetAutohideFn; } /** @@ -52,7 +52,7 @@ export const ToolbarSettings: FC> = ({ onSetAutohid const { toolbar } = settings; const { isAutohide } = toolbar; - const onSetAutohideFn: onSetAutohideFn = (autohide: boolean) => { + const onSetAutohideFn: OnSetAutohideFn = (autohide: boolean) => { onSetAutohide(autohide); dispatch(setToolbarAutohideAction(autohide)); }; diff --git a/x-pack/plugins/canvas/shareable_runtime/test/utils.ts b/x-pack/plugins/canvas/shareable_runtime/test/utils.ts index fe3c1be9ba154..5e65594972da2 100644 --- a/x-pack/plugins/canvas/shareable_runtime/test/utils.ts +++ b/x-pack/plugins/canvas/shareable_runtime/test/utils.ts @@ -15,6 +15,7 @@ export const tick = (ms = 0) => export const takeMountedSnapshot = (mountedComponent: ReactWrapper<{}, {}, Component>) => { const html = mountedComponent.html(); const template = document.createElement('template'); + // eslint-disable-next-line no-unsanitized/property template.innerHTML = html; return template.content.firstChild; }; diff --git a/x-pack/plugins/canvas/storybook/addon/src/register.tsx b/x-pack/plugins/canvas/storybook/addon/src/register.tsx index 3a5c4a6818ac1..4934438789b94 100644 --- a/x-pack/plugins/canvas/storybook/addon/src/register.tsx +++ b/x-pack/plugins/canvas/storybook/addon/src/register.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable import/no-extraneous-dependencies */ - import React from 'react'; import { addons, types } from '@storybook/addons'; import { AddonPanel } from '@storybook/components'; diff --git a/x-pack/plugins/case/server/routes/api/cases/comments/delete_all_comments.ts b/x-pack/plugins/case/server/routes/api/cases/comments/delete_all_comments.ts index e06b3a33dfc72..0bf8ad89ce470 100644 --- a/x-pack/plugins/case/server/routes/api/cases/comments/delete_all_comments.ts +++ b/x-pack/plugins/case/server/routes/api/cases/comments/delete_all_comments.ts @@ -24,6 +24,7 @@ export function initDeleteAllCommentsApi({ caseService, router, userActionServic async (context, request, response) => { try { const client = context.core.savedObjects.client; + // eslint-disable-next-line @typescript-eslint/naming-convention const { username, full_name, email } = await caseService.getUser({ request, response }); const deleteDate = new Date().toISOString(); diff --git a/x-pack/plugins/case/server/routes/api/cases/comments/delete_comment.ts b/x-pack/plugins/case/server/routes/api/cases/comments/delete_comment.ts index df08af025df03..70c0d8c2f84f9 100644 --- a/x-pack/plugins/case/server/routes/api/cases/comments/delete_comment.ts +++ b/x-pack/plugins/case/server/routes/api/cases/comments/delete_comment.ts @@ -27,6 +27,7 @@ export function initDeleteCommentApi({ caseService, router, userActionService }: async (context, request, response) => { try { const client = context.core.savedObjects.client; + // eslint-disable-next-line @typescript-eslint/naming-convention const { username, full_name, email } = await caseService.getUser({ request, response }); const deleteDate = new Date().toISOString(); diff --git a/x-pack/plugins/case/server/routes/api/cases/comments/patch_comment.ts b/x-pack/plugins/case/server/routes/api/cases/comments/patch_comment.ts index 1aca27bbf1853..85cc63b2f4d17 100644 --- a/x-pack/plugins/case/server/routes/api/cases/comments/patch_comment.ts +++ b/x-pack/plugins/case/server/routes/api/cases/comments/patch_comment.ts @@ -68,6 +68,7 @@ export function initPatchCommentApi({ ); } + // eslint-disable-next-line @typescript-eslint/naming-convention const { username, full_name, email } = await caseService.getUser({ request, response }); const updatedDate = new Date().toISOString(); const [updatedComment, updatedCase, myCaseConfigure] = await Promise.all([ diff --git a/x-pack/plugins/case/server/routes/api/cases/comments/post_comment.ts b/x-pack/plugins/case/server/routes/api/cases/comments/post_comment.ts index 486f709b1e7ed..dd6f06777fe98 100644 --- a/x-pack/plugins/case/server/routes/api/cases/comments/post_comment.ts +++ b/x-pack/plugins/case/server/routes/api/cases/comments/post_comment.ts @@ -48,6 +48,7 @@ export function initPostCommentApi({ caseId, }); + // eslint-disable-next-line @typescript-eslint/naming-convention const { username, full_name, email } = await caseService.getUser({ request, response }); const createdDate = new Date().toISOString(); diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.ts b/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.ts index 29df97c5f8476..06c99c8018cc0 100644 --- a/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.ts +++ b/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.ts @@ -49,6 +49,7 @@ export function initPatchCaseConfigure({ caseConfigureService, caseService, rout ); } + // eslint-disable-next-line @typescript-eslint/naming-convention const { username, full_name, email } = await caseService.getUser({ request, response }); const updateDate = new Date().toISOString(); diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.ts b/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.ts index a49a6c9ec5b76..3f02809cbd08f 100644 --- a/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.ts +++ b/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.ts @@ -43,6 +43,7 @@ export function initPostCaseConfigure({ caseConfigureService, caseService, route ) ); } + // eslint-disable-next-line @typescript-eslint/naming-convention const { email, full_name, username } = await caseService.getUser({ request, response }); const creationDate = new Date().toISOString(); diff --git a/x-pack/plugins/case/server/routes/api/cases/delete_cases.ts b/x-pack/plugins/case/server/routes/api/cases/delete_cases.ts index 9f57663c85f6f..db7bd6b9a76c8 100644 --- a/x-pack/plugins/case/server/routes/api/cases/delete_cases.ts +++ b/x-pack/plugins/case/server/routes/api/cases/delete_cases.ts @@ -55,6 +55,7 @@ export function initDeleteCasesApi({ caseService, router, userActionService }: R ) ); } + // eslint-disable-next-line @typescript-eslint/naming-convention const { username, full_name, email } = await caseService.getUser({ request, response }); const deleteDate = new Date().toISOString(); diff --git a/x-pack/plugins/case/server/routes/api/cases/patch_cases.ts b/x-pack/plugins/case/server/routes/api/cases/patch_cases.ts index 0c722cf56ada3..b70177b47ec97 100644 --- a/x-pack/plugins/case/server/routes/api/cases/patch_cases.ts +++ b/x-pack/plugins/case/server/routes/api/cases/patch_cases.ts @@ -87,6 +87,7 @@ export function initPatchCasesApi({ return Object.keys(updateCaseAttributes).length > 0; }); if (updateFilterCases.length > 0) { + // eslint-disable-next-line @typescript-eslint/naming-convention const { username, full_name, email } = await caseService.getUser({ request, response }); const updatedDt = new Date().toISOString(); const updatedCases = await caseService.patchCases({ diff --git a/x-pack/plugins/case/server/routes/api/cases/post_case.ts b/x-pack/plugins/case/server/routes/api/cases/post_case.ts index 05574698edd44..50883667a5047 100644 --- a/x-pack/plugins/case/server/routes/api/cases/post_case.ts +++ b/x-pack/plugins/case/server/routes/api/cases/post_case.ts @@ -38,6 +38,7 @@ export function initPostCaseApi({ fold(throwErrors(Boom.badRequest), identity) ); + // eslint-disable-next-line @typescript-eslint/naming-convention const { username, full_name, email } = await caseService.getUser({ request, response }); const createdDate = new Date().toISOString(); const myCaseConfigure = await caseConfigureService.find({ client }); diff --git a/x-pack/plugins/case/server/routes/api/cases/push_case.ts b/x-pack/plugins/case/server/routes/api/cases/push_case.ts index 3379bbd318d5b..f7990b861f815 100644 --- a/x-pack/plugins/case/server/routes/api/cases/push_case.ts +++ b/x-pack/plugins/case/server/routes/api/cases/push_case.ts @@ -49,6 +49,7 @@ export function initPushCaseUserActionApi({ throw Boom.notFound('Action client have not been found'); } + // eslint-disable-next-line @typescript-eslint/naming-convention const { username, full_name, email } = await caseService.getUser({ request, response }); const pushedDate = new Date().toISOString(); diff --git a/x-pack/plugins/case/server/routes/api/utils.ts b/x-pack/plugins/case/server/routes/api/utils.ts index ec2881807442f..074957ec69bca 100644 --- a/x-pack/plugins/case/server/routes/api/utils.ts +++ b/x-pack/plugins/case/server/routes/api/utils.ts @@ -29,6 +29,7 @@ export const transformNewCase = ({ connectorId, createdDate, email, + // eslint-disable-next-line @typescript-eslint/naming-convention full_name, newCase, username, @@ -63,6 +64,7 @@ export const transformNewComment = ({ comment, createdDate, email, + // eslint-disable-next-line @typescript-eslint/naming-convention full_name, username, }: NewCommentArgs): CommentAttributes => ({ diff --git a/x-pack/plugins/case/server/services/user_actions/helpers.ts b/x-pack/plugins/case/server/services/user_actions/helpers.ts index 228b42b4c638f..5b7d1f4618fed 100644 --- a/x-pack/plugins/case/server/services/user_actions/helpers.ts +++ b/x-pack/plugins/case/server/services/user_actions/helpers.ts @@ -23,6 +23,7 @@ export const transformNewUserAction = ({ action, actionAt, email, + // eslint-disable-next-line @typescript-eslint/naming-convention full_name, newValue = null, oldValue = null, diff --git a/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.ts b/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.ts index 265af0ede1462..2694f9038d6b2 100644 --- a/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.ts +++ b/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.ts @@ -11,15 +11,20 @@ export const deserializeAutoFollowPattern = ( ): AutoFollowPattern => { const { name, - pattern: { active, remote_cluster, leader_index_patterns, follow_index_pattern }, + pattern: { + active, + remote_cluster: remoteCluster, + leader_index_patterns: leaderIndexPatterns, + follow_index_pattern: followIndexPattern, + }, } = autoFollowPattern; return { name, active, - remoteCluster: remote_cluster, - leaderIndexPatterns: leader_index_patterns, - followIndexPattern: follow_index_pattern, + remoteCluster, + leaderIndexPatterns, + followIndexPattern, }; }; diff --git a/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.ts b/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.ts index df476a0b2db89..72aeaad3c2910 100644 --- a/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.ts +++ b/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.ts @@ -13,7 +13,7 @@ import { FollowerIndexAdvancedSettings, FollowerIndexAdvancedSettingsToEs, } from '../types'; - +/* eslint-disable @typescript-eslint/naming-convention */ export const deserializeShard = ({ remote_cluster, leader_index, @@ -106,7 +106,7 @@ export const deserializeFollowerIndex = ({ readPollTimeout: read_poll_timeout, shards: shards && shards.map(deserializeShard), }); - +/* eslint-enable @typescript-eslint/naming-convention */ export const deserializeListFollowerIndices = ( followerIndices: FollowerIndexFromEs[] ): FollowerIndex[] => followerIndices.map(deserializeFollowerIndex); diff --git a/x-pack/plugins/cross_cluster_replication/public/app/index.tsx b/x-pack/plugins/cross_cluster_replication/public/app/index.tsx index 8be3eb5c8b32a..3efe7ec842c73 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/index.tsx +++ b/x-pack/plugins/cross_cluster_replication/public/app/index.tsx @@ -36,8 +36,8 @@ export async function mountApp({ element, setBreadcrumbs, I18nContext, - ELASTIC_WEBSITE_URL, - DOC_LINK_VERSION, + ELASTIC_WEBSITE_URL, // eslint-disable-line @typescript-eslint/naming-convention + DOC_LINK_VERSION, // eslint-disable-line @typescript-eslint/naming-convention history, getUrlForApp, }: { diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts index 7e2b088919842..d6c3baa899d28 100644 --- a/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts +++ b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts @@ -12,7 +12,7 @@ import { AutoFollowStats, AutoFollowStatsFromEs, } from '../../common/types'; - +/* eslint-disable @typescript-eslint/naming-convention */ export const deserializeRecentAutoFollowErrors = ({ timestamp, leader_index, diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/format_es_error.ts b/x-pack/plugins/cross_cluster_replication/server/lib/format_es_error.ts index 9dde027cd6949..0f00bfb0c1e7c 100644 --- a/x-pack/plugins/cross_cluster_replication/server/lib/format_es_error.ts +++ b/x-pack/plugins/cross_cluster_replication/server/lib/format_es_error.ts @@ -8,13 +8,12 @@ function extractCausedByChain( causedBy: Record = {}, accumulator: string[] = [] ): string[] { - const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/camelcase + const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/naming-convention if (reason) { accumulator.push(reason); } - // eslint-disable-next-line @typescript-eslint/camelcase if (caused_by) { return extractCausedByChain(caused_by, accumulator); } @@ -36,8 +35,8 @@ export function wrapEsError( const { error: { - root_cause = [], // eslint-disable-line @typescript-eslint/camelcase - caused_by = undefined, // eslint-disable-line @typescript-eslint/camelcase + root_cause = [], // eslint-disable-line @typescript-eslint/naming-convention + caused_by = undefined, // eslint-disable-line @typescript-eslint/naming-convention } = {}, } = JSON.parse(response); diff --git a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts index d2a8384b1f882..0ed5485cfb6c9 100644 --- a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts @@ -119,6 +119,7 @@ async function asyncSearch( ...queryParams, }); + // eslint-disable-next-line @typescript-eslint/naming-convention const { id, response, is_partial, is_running } = (await caller( 'transport.request', { method, path, body, query }, diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts index cf35a458b4825..ee96f8099cf7c 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts @@ -5,6 +5,7 @@ */ jest.mock('node-fetch'); +// eslint-disable-next-line @typescript-eslint/no-var-requires const fetchMock = require('node-fetch') as jest.Mock; const { Response } = jest.requireActual('node-fetch'); diff --git a/x-pack/plugins/enterprise_search/server/routes/__mocks__/router.mock.ts b/x-pack/plugins/enterprise_search/server/routes/__mocks__/router.mock.ts index 1ca7755979f99..e3471d7268cb1 100644 --- a/x-pack/plugins/enterprise_search/server/routes/__mocks__/router.mock.ts +++ b/x-pack/plugins/enterprise_search/server/routes/__mocks__/router.mock.ts @@ -16,12 +16,12 @@ import { * Test helper that mocks Kibana's router and DRYs out various helper (callRoute, schema validation) */ -type methodType = 'get' | 'post' | 'put' | 'patch' | 'delete'; -type payloadType = 'params' | 'query' | 'body'; +type MethodType = 'get' | 'post' | 'put' | 'patch' | 'delete'; +type PayloadType = 'params' | 'query' | 'body'; interface IMockRouterProps { - method: methodType; - payload?: payloadType; + method: MethodType; + payload?: PayloadType; } interface IMockRouterRequest { body?: object; @@ -32,8 +32,8 @@ type TMockRouterRequest = KibanaRequest | IMockRouterRequest; export class MockRouter { public router!: jest.Mocked; - public method: methodType; - public payload?: payloadType; + public method: MethodType; + public payload?: PayloadType; public response = httpServerMock.createResponseFactory(); constructor({ method, payload }: IMockRouterProps) { diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts index d5b1bc5003456..968ecb95fd931 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.test.ts @@ -11,6 +11,7 @@ import { registerEnginesRoute } from './engines'; jest.mock('node-fetch'); const fetch = jest.requireActual('node-fetch'); const { Response } = fetch; +// eslint-disable-next-line @typescript-eslint/no-var-requires const fetchMock = require('node-fetch') as jest.Mocked; describe('engine routes', () => { diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/overview.test.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/overview.test.ts index b1b5539795357..3a4e28b0de5ff 100644 --- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/overview.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/overview.test.ts @@ -11,6 +11,7 @@ import { registerWSOverviewRoute } from './overview'; jest.mock('node-fetch'); const fetch = jest.requireActual('node-fetch'); const { Response } = fetch; +// eslint-disable-next-line @typescript-eslint/no-var-requires const fetchMock = require('node-fetch') as jest.Mocked; const ORG_ROUTE = 'http://localhost:3002/ws/org'; diff --git a/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts b/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts index f86e5d9ca0e32..8c3e6e11b75c5 100644 --- a/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts +++ b/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts @@ -133,6 +133,7 @@ export class ClusterClientAdapter { namespace: string | undefined, type: string, id: string, + // eslint-disable-next-line @typescript-eslint/naming-convention { page, per_page: perPage, start, end, sort_field, sort_order }: FindOptionsType ): Promise { const defaultNamespaceQuery = { diff --git a/x-pack/plugins/global_search/server/routes/integration_tests/find.test.ts b/x-pack/plugins/global_search/server/routes/integration_tests/find.test.ts index 878e4ac896b96..01bd68ca38b12 100644 --- a/x-pack/plugins/global_search/server/routes/integration_tests/find.test.ts +++ b/x-pack/plugins/global_search/server/routes/integration_tests/find.test.ts @@ -13,7 +13,7 @@ import { GlobalSearchFindError } from '../../../common/errors'; import { globalSearchPluginMock } from '../../mocks'; import { registerInternalFindRoute } from '../find'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; const pluginId = Symbol('globalSearch'); const createResult = (id: string): GlobalSearchResult => ({ @@ -31,8 +31,8 @@ const createBatch = (...ids: string[]): GlobalSearchBatchedResults => ({ const expectedResults = (...ids: string[]) => ids.map((id) => expect.objectContaining({ id })); describe('POST /internal/global_search/find', () => { - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; let globalSearchHandlerContext: ReturnType; beforeEach(async () => { diff --git a/x-pack/plugins/graph/public/application.ts b/x-pack/plugins/graph/public/application.ts index 0969b80bc38b0..b249fe2be32c7 100644 --- a/x-pack/plugins/graph/public/application.ts +++ b/x-pack/plugins/graph/public/application.ts @@ -115,7 +115,7 @@ const thirdPartyAngularDependencies = ['ngSanitize', 'ngRoute', 'react', 'ui.boo function mountGraphApp(appBasePath: string, element: HTMLElement) { const mountpoint = document.createElement('div'); mountpoint.setAttribute('class', 'gphAppWrapper'); - // eslint-disable-next-line + // eslint-disable-next-line no-unsanitized/property mountpoint.innerHTML = mainTemplate(appBasePath); // bootstrap angular into detached element and attach it later to // make angular-within-angular possible diff --git a/x-pack/plugins/graph/public/components/field_manager/field_editor.tsx b/x-pack/plugins/graph/public/components/field_manager/field_editor.tsx index cd2227bf6a18c..f4006d6bf142b 100644 --- a/x-pack/plugins/graph/public/components/field_manager/field_editor.tsx +++ b/x-pack/plugins/graph/public/components/field_manager/field_editor.tsx @@ -125,6 +125,7 @@ export function FieldEditor({ color={initialField.color} iconSide="right" className={classNames('gphFieldEditor__badge', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'gphFieldEditor__badge--disabled': isDisabled, })} onClickAriaLabel={badgeDescription} diff --git a/x-pack/plugins/graph/public/components/field_manager/field_picker.tsx b/x-pack/plugins/graph/public/components/field_manager/field_picker.tsx index ae32e8d2ce6d6..d59bbe92af98d 100644 --- a/x-pack/plugins/graph/public/components/field_manager/field_picker.tsx +++ b/x-pack/plugins/graph/public/components/field_manager/field_picker.tsx @@ -55,6 +55,7 @@ export function FieldPicker({ } className={classNames('gphUrlTemplateList__accordion', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'gphUrlTemplateList__accordion--isOpen': open, })} buttonClassName="gphUrlTemplateList__accordionbutton" diff --git a/x-pack/plugins/grokdebugger/server/lib/kibana_framework.ts b/x-pack/plugins/grokdebugger/server/lib/kibana_framework.ts index 015a2e250bb0e..ee7fa74022fd5 100644 --- a/x-pack/plugins/grokdebugger/server/lib/kibana_framework.ts +++ b/x-pack/plugins/grokdebugger/server/lib/kibana_framework.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/array-type */ - import { i18n } from '@kbn/i18n'; import { @@ -19,9 +17,9 @@ import { import { ILicense } from '../../../licensing/server'; -type GrokDebuggerRouteConfig = { +type GrokDebuggerRouteConfig = { method: RouteMethod; -} & RouteConfig; +} & RouteConfig; export class KibanaFramework { public router: IRouter; @@ -44,12 +42,12 @@ export class KibanaFramework { return this.license.isActive; } - public registerRoute( - config: GrokDebuggerRouteConfig, - handler: RequestHandler + public registerRoute( + config: GrokDebuggerRouteConfig, + handler: RequestHandler ) { // Automatically wrap all route registrations with license checking - const wrappedHandler: RequestHandler = async ( + const wrappedHandler: RequestHandler = async ( requestContext, request, response diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts index 942eec347341f..c8d02783864e1 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts @@ -31,7 +31,8 @@ function filterAndFormatTemplates(templates: any): any { const formattedTemplates = []; const templateNames = Object.keys(templates); for (const templateName of templateNames) { - const { settings, index_patterns } = templates[templateName]; // eslint-disable-line camelcase + // eslint-disable-next-line @typescript-eslint/naming-convention + const { settings, index_patterns } = templates[templateName]; if (isReservedSystemTemplate(templateName, index_patterns)) { continue; } diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx index e40cdc026210d..910d9be842da8 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import React from 'react'; import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts index 9397ce21ba827..db7541c93f9ac 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts @@ -14,8 +14,8 @@ import { findTestSubject, } from '../../../../../test_utils'; import { DataStream } from '../../../common'; -import { IndexManagementHome } from '../../../public/application/sections/home'; // eslint-disable-line @kbn/eslint/no-restricted-paths -import { indexManagementStore } from '../../../public/application/store'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { IndexManagementHome } from '../../../public/application/sections/home'; +import { indexManagementStore } from '../../../public/application/store'; import { WithAppDependencies, services, TestSubjects } from '../helpers'; export interface DataStreamsTabTestBed extends TestBed { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/home.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/home.helpers.ts index c58109364890a..27920ad8cdbdb 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/home.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/home.helpers.ts @@ -5,8 +5,8 @@ */ import { registerTestBed, TestBed, TestBedConfig } from '../../../../../test_utils'; -import { IndexManagementHome } from '../../../public/application/sections/home'; // eslint-disable-line @kbn/eslint/no-restricted-paths -import { indexManagementStore } from '../../../public/application/store'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { IndexManagementHome } from '../../../public/application/sections/home'; +import { indexManagementStore } from '../../../public/application/store'; import { WithAppDependencies, services, TestSubjects } from '../helpers'; const testBedConfig: TestBedConfig = { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts index 23b40f4cbd3d7..fe938bb087d2e 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts @@ -12,7 +12,7 @@ import { TestBedConfig, findTestSubject, } from '../../../../../test_utils'; -import { TemplateList } from '../../../public/application/sections/home/template_list'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { TemplateList } from '../../../public/application/sections/home/template_list'; import { TemplateDeserialized } from '../../../common'; import { WithAppDependencies, TestSubjects } from '../helpers'; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts index 11ea29fd9b78c..b660adb9eec08 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts @@ -13,8 +13,8 @@ import { TestBedConfig, findTestSubject, } from '../../../../../test_utils'; -import { IndexManagementHome } from '../../../public/application/sections/home'; // eslint-disable-line @kbn/eslint/no-restricted-paths -import { indexManagementStore } from '../../../public/application/store'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { IndexManagementHome } from '../../../public/application/sections/home'; +import { indexManagementStore } from '../../../public/application/store'; import { WithAppDependencies, services, TestSubjects } from '../helpers'; const testBedConfig: TestBedConfig = { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.helpers.ts index 1a58cfa8fb55e..62adb8c433366 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.helpers.ts @@ -5,7 +5,7 @@ */ import { registerTestBed, TestBedConfig } from '../../../../../test_utils'; -import { TemplateClone } from '../../../public/application/sections/template_clone'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { TemplateClone } from '../../../public/application/sections/template_clone'; import { WithAppDependencies } from '../helpers'; import { formSetup } from './template_form.helpers'; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.helpers.ts index ab0a7b8567607..9ad8d61e637e5 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.helpers.ts @@ -5,7 +5,7 @@ */ import { registerTestBed, TestBedConfig } from '../../../../../test_utils'; -import { TemplateCreate } from '../../../public/application/sections/template_create'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { TemplateCreate } from '../../../public/application/sections/template_create'; import { WithAppDependencies } from '../helpers'; import { formSetup, TestSubjects } from './template_form.helpers'; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.helpers.ts index 29ecd84e585ce..c3a139f89cb5f 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.helpers.ts @@ -5,7 +5,7 @@ */ import { registerTestBed, TestBedConfig } from '../../../../../test_utils'; -import { TemplateEdit } from '../../../public/application/sections/template_edit'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { TemplateEdit } from '../../../public/application/sections/template_edit'; import { WithAppDependencies } from '../helpers'; import { formSetup, TestSubjects } from './template_form.helpers'; diff --git a/x-pack/plugins/index_management/common/lib/data_stream_serialization.ts b/x-pack/plugins/index_management/common/lib/data_stream_serialization.ts index 51528ed9856ce..7832662aea494 100644 --- a/x-pack/plugins/index_management/common/lib/data_stream_serialization.ts +++ b/x-pack/plugins/index_management/common/lib/data_stream_serialization.ts @@ -7,12 +7,13 @@ import { DataStream, DataStreamFromEs } from '../types'; export function deserializeDataStream(dataStreamFromEs: DataStreamFromEs): DataStream { - const { name, timestamp_field, indices, generation } = dataStreamFromEs; + const { name, timestamp_field: timeStampField, indices, generation } = dataStreamFromEs; return { name, - timeStampField: timestamp_field, + timeStampField, indices: indices.map( + // eslint-disable-next-line @typescript-eslint/naming-convention ({ index_name, index_uuid }: { index_name: string; index_uuid: string }) => ({ name: index_name, uuid: index_uuid, diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx index 2f7317e3e656b..79e213229fc51 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/helpers/setup_environment.tsx @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import React from 'react'; import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_selector/component_templates.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_selector/component_templates.tsx index ea5632ac86192..b07279c57d2be 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_selector/component_templates.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_selector/component_templates.tsx @@ -171,6 +171,7 @@ export const ComponentTemplates = ({ isLoading, components, listItemProps }: Pro
    diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_selector/component_templates_selector.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_selector/component_templates_selector.tsx index ed570579d4e45..ccdfaad78fb6b 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_selector/component_templates_selector.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_selector/component_templates_selector.tsx @@ -157,6 +157,7 @@ export const ComponentTemplatesSelector = ({ {/* Selection */} diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/lib/documentation.ts b/x-pack/plugins/index_management/public/application/components/component_templates/lib/documentation.ts index db06877d6e81a..7bec03a5bade8 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/lib/documentation.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/lib/documentation.ts @@ -6,6 +6,7 @@ import { DocLinksStart } from 'src/core/public'; +// eslint-disable-next-line @typescript-eslint/naming-convention export const getDocumentation = ({ ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }: DocLinksStart) => { const docsBase = `${ELASTIC_WEBSITE_URL}guide/en`; const esDocsBase = `${docsBase}/elasticsearch/reference/${DOC_LINK_VERSION}`; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx index c03aa4805d27f..66989baa2dc67 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx @@ -307,8 +307,11 @@ describe.skip('Mappings editor: text datatype', () => { const indexSettings = { analysis: { analyzer: { + // eslint-disable-next-line @typescript-eslint/naming-convention customAnalyzer_1: {}, + // eslint-disable-next-line @typescript-eslint/naming-convention customAnalyzer_2: {}, + // eslint-disable-next-line @typescript-eslint/naming-convention customAnalyzer_3: {}, }, }, diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx index 20b2e11855029..3a3e19783d74d 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx @@ -24,9 +24,11 @@ const formSerializer: SerializerFunc = (formData) => { dynamicMapping: { enabled: dynamicMappingsEnabled, throwErrorsForUnmappedFields, + /* eslint-disable @typescript-eslint/naming-convention */ numeric_detection, date_detection, dynamic_date_formats, + /* eslint-enable @typescript-eslint/naming-convention */ }, sourceField, metaField, @@ -51,9 +53,11 @@ const formSerializer: SerializerFunc = (formData) => { const formDeserializer = (formData: GenericObject) => { const { dynamic, + /* eslint-disable @typescript-eslint/naming-convention */ numeric_detection, date_detection, dynamic_date_formats, + /* eslint-enable @typescript-eslint/naming-convention */ _source: { enabled, includes, excludes } = {} as { enabled?: boolean; includes?: string[]; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx index 05d871ccfac71..c5001740c26c6 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx @@ -55,6 +55,7 @@ export const DynamicMappingSection = () => ( {(formData) => { const { 'dynamicMapping.enabled': enabled, + // eslint-disable-next-line @typescript-eslint/naming-convention 'dynamicMapping.date_detection': dateDetection, } = formData; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/dynamic_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/dynamic_parameter.tsx index 1882802b27487..f8b7f90f983c5 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/dynamic_parameter.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/dynamic_parameter.tsx @@ -24,6 +24,7 @@ export const dynamicSerializer = (field: Field): Field => { const dynamic = field.dynamic_toggle === true ? true : field.dynamic_strict === true ? 'strict' : false; + // eslint-disable-next-line @typescript-eslint/naming-convention const { dynamic_toggle, dynamic_strict, ...rest } = field; return { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx index dc631b7dbf32d..ecaa40b398d08 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx @@ -164,8 +164,10 @@ export const CreateField = React.memo(function CreateFieldComponent({ >
    0, + // eslint-disable-next-line @typescript-eslint/naming-convention 'mappingsEditor__createFieldWrapper--multiField': isMultiField, })} style={{ diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx index c4d0a65905557..4ab0ea0fb355b 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx @@ -193,6 +193,7 @@ function FieldListItemComponent( return (
  • treeDepth, })} diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result_item.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result_item.tsx index 73d3e078f6ff3..a2d9a50f28394 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result_item.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result_item.tsx @@ -89,8 +89,11 @@ export const SearchResultItem = React.memo(function FieldListItemFlatComponent({
    @@ -99,7 +102,9 @@ export const SearchResultItem = React.memo(function FieldListItemFlatComponent({ gutterSize="s" alignItems="center" className={classNames('mappingsEditor__fieldsListItem__content', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'mappingsEditor__fieldsListItem__content--toggle': hasChildFields || hasMultiFields, + // eslint-disable-next-line @typescript-eslint/naming-convention 'mappingsEditor__fieldsListItem__content--multiField': isMultiField, })} > diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx index 44a809a7a01bf..9367eb6faee20 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx @@ -44,6 +44,7 @@ const formSerializer: SerializerFunc = (formData) }; const formDeserializer = (formData: { [key: string]: any }) => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { dynamic_templates } = formData; return { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx index 292882f1c5b4b..39451639bfb86 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx @@ -59,11 +59,13 @@ export const MappingsEditor = React.memo(({ onChange, value, indexSettings }: Pr _meta, _routing, dynamic, + /* eslint-disable @typescript-eslint/naming-convention */ numeric_detection, date_detection, dynamic_date_formats, properties, dynamic_templates, + /* eslint-enable @typescript-eslint/naming-convention */ } = mappingsDefinition; const parsed = { diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx index d01d8fa03a3fa..d1e093f1ffc83 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx @@ -42,7 +42,6 @@ export const DataStreamTable: React.FunctionComponent = ({ sortable: true, render: (name: DataStream['name'], item: DataStream) => { return ( - /* eslint-disable-next-line @elastic/eui/href-or-on-click */ { - const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/camelcase + const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/naming-convention if (reason) { accumulator.push(reason); } - // eslint-disable-next-line @typescript-eslint/camelcase if (caused_by) { return extractCausedByChain(caused_by, accumulator); } @@ -31,8 +30,8 @@ export const wrapEsError = (err: any, statusCodeToMessageMap: any = {}) => { const { error: { - root_cause = [], // eslint-disable-line @typescript-eslint/camelcase - caused_by = {}, // eslint-disable-line @typescript-eslint/camelcase + root_cause = [], // eslint-disable-line @typescript-eslint/naming-convention + caused_by = {}, // eslint-disable-line @typescript-eslint/naming-convention } = {}, } = JSON.parse(response); diff --git a/x-pack/plugins/infra/common/errors/metrics.ts b/x-pack/plugins/infra/common/errors/metrics.ts index 2acf2b741cec9..08d58a7db326e 100644 --- a/x-pack/plugins/infra/common/errors/metrics.ts +++ b/x-pack/plugins/infra/common/errors/metrics.ts @@ -5,6 +5,5 @@ */ export enum InfraMetricsErrorCodes { - // eslint-disable-next-line @typescript-eslint/camelcase invalid_node = 'METRICS_INVALID_NODE', } diff --git a/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx b/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx index b69078beec670..7ca17617871ff 100644 --- a/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx +++ b/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx @@ -39,7 +39,6 @@ import { import { IErrorObject } from '../../../../../triggers_actions_ui/public/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AlertsContextValue } from '../../../../../triggers_actions_ui/public/application/context/alerts_context'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { MetricsExplorerKueryBar } from '../../../pages/metrics/metrics_explorer/components/kuery_bar'; import { useSourceViaHttp } from '../../../containers/source/use_source_via_http'; import { sqsMetricTypes } from '../../../../common/inventory_models/aws_sqs/toolbar_items'; diff --git a/x-pack/plugins/infra/public/alerting/inventory/index.ts b/x-pack/plugins/infra/public/alerting/inventory/index.ts index 30f16ef137a17..b5f6e17cc2a13 100644 --- a/x-pack/plugins/infra/public/alerting/inventory/index.ts +++ b/x-pack/plugins/infra/public/alerting/inventory/index.ts @@ -10,7 +10,6 @@ import { METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID } from '../../../server/lib/al // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types'; import { validateMetricThreshold } from './components/validation'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths export function createInventoryMetricAlertType(): AlertTypeModel { return { diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx index 8bb8b3934b5fd..8031f7a03731a 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx @@ -20,7 +20,6 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { AlertPreview } from '../../common'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { Comparator, Aggregators, diff --git a/x-pack/plugins/infra/public/components/document_title.tsx b/x-pack/plugins/infra/public/components/document_title.tsx index 51f179760ec70..5ae3aa7ec8b42 100644 --- a/x-pack/plugins/infra/public/components/document_title.tsx +++ b/x-pack/plugins/infra/public/components/document_title.tsx @@ -6,10 +6,10 @@ import React from 'react'; -type titleProp = string | ((previousTitle: string) => string); +type TitleProp = string | ((previousTitle: string) => string); interface DocumentTitleProps { - title: titleProp; + title: TitleProp; } interface DocumentTitleState { @@ -47,7 +47,7 @@ const wrapWithSharedState = () => { return null; } - private getTitle(title: titleProp) { + private getTitle(title: TitleProp) { return typeof title === 'function' ? title(titles[this.state.index - 1]) : title; } diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/jump_to_tail.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/jump_to_tail.tsx index 78caa8054860f..50c26784bbdab 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/jump_to_tail.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/jump_to_tail.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable max-classes-per-file */ - import { EuiButtonEmpty, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import * as React from 'react'; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx index eb187a7af03f6..1dd6e0b23e6bc 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable max-classes-per-file */ - import { EuiText, EuiFlexGroup, diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx index 74d1878fc89c2..fc0c50b9044dc 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx @@ -326,8 +326,6 @@ export class ScrollableLogTextStreamView extends React.PureComponent< } }; - // this is actually a method but not recognized as such - // eslint-disable-next-line @typescript-eslint/member-ordering private handleVisibleChildrenChange = callWithoutRepeats( ({ topChild, diff --git a/x-pack/plugins/infra/public/components/navigation/routed_tabs.tsx b/x-pack/plugins/infra/public/components/navigation/routed_tabs.tsx index 29db3c893a460..d9340d804fb24 100644 --- a/x-pack/plugins/infra/public/components/navigation/routed_tabs.tsx +++ b/x-pack/plugins/infra/public/components/navigation/routed_tabs.tsx @@ -42,7 +42,6 @@ const Tab = ({ title, pathname, app }: TabConfiguration) => { children={({ match, history }) => { return ( - {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} {title} diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx index b9595548debf2..270ccac000637 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/charts.tsx @@ -19,13 +19,13 @@ import { NoData } from '../../../../components/empty_states/no_data'; import { MetricsExplorerChart } from './chart'; import { SourceQuery } from '../../../../graphql/types'; -type stringOrNull = string | null; +type StringOrNull = string | null; interface Props { loading: boolean; options: MetricsExplorerOptions; chartOptions: MetricsExplorerChartOptions; - onLoadMore: (afterKey: stringOrNull | Record) => void; + onLoadMore: (afterKey: StringOrNull | Record) => void; onRefetch: () => void; onFilter: (filter: string) => void; onTimeChange: (start: string, end: string) => void; diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts index 117749ae87bbe..1ecae84c54ffb 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts @@ -171,6 +171,6 @@ export interface InfraTSVBSeries { export type InfraTSVBDataPoint = [number, number]; -export type InfraRouteConfig = { +export type InfraRouteConfig = { method: RouteMethod; -} & RouteConfig; +} & RouteConfig; diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts index 453f01ef028f1..2dcab5b49dcdb 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/array-type */ - import { GraphQLSchema } from 'graphql'; import { runHttpQuery } from 'apollo-server-core'; import { schema, TypeOf } from '@kbn/config-schema'; @@ -43,9 +41,9 @@ export class KibanaFramework { this.plugins = plugins; } - public registerRoute( - config: InfraRouteConfig, - handler: RequestHandler + public registerRoute( + config: InfraRouteConfig, + handler: RequestHandler ) { const defaultOptions = { tags: ['access:infra'], diff --git a/x-pack/plugins/infra/server/lib/adapters/metrics/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/metrics/adapter_types.ts index 6659cb060b1a8..f786c043ee27c 100644 --- a/x-pack/plugins/infra/server/lib/adapters/metrics/adapter_types.ts +++ b/x-pack/plugins/infra/server/lib/adapters/metrics/adapter_types.ts @@ -40,12 +40,12 @@ export enum InfraMetricModelMetricType { min = 'min', calculation = 'calculation', cardinality = 'cardinality', - series_agg = 'series_agg', // eslint-disable-line @typescript-eslint/camelcase - positive_only = 'positive_only', // eslint-disable-line @typescript-eslint/camelcase + series_agg = 'series_agg', + positive_only = 'positive_only', derivative = 'derivative', count = 'count', sum = 'sum', - cumulative_sum = 'cumulative_sum', // eslint-disable-line @typescript-eslint/camelcase + cumulative_sum = 'cumulative_sum', } export interface InfraMetricModel { @@ -80,7 +80,7 @@ export interface InfraMetricModelBasicMetric { export interface InfraMetricModelSeriesAgg { id: string; function: string; - type: InfraMetricModelMetricType.series_agg; // eslint-disable-line @typescript-eslint/camelcase + type: InfraMetricModelMetricType.series_agg; } export interface InfraMetricModelDerivative { diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts index 5c2f76cea87c4..164f1ed6d18e5 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts @@ -68,6 +68,7 @@ export const emptyRateResponse = { buckets: [ { doc_count: 2, + // eslint-disable-next-line @typescript-eslint/naming-convention aggregatedValue_max: { value: null }, }, ], diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts index 950de4261bda0..a55958aee1285 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts @@ -246,6 +246,7 @@ async function fetchLogEntryAnomalies( const anomalies = hits.map((result) => { const { + // eslint-disable-next-line @typescript-eslint/naming-convention job_id, record_score: anomalyScore, typical, diff --git a/x-pack/plugins/infra/server/lib/log_analysis/queries/log_entry_categories.ts b/x-pack/plugins/infra/server/lib/log_analysis/queries/log_entry_categories.ts index c7ad60eeaabc2..3ef10d3378a66 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/queries/log_entry_categories.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/queries/log_entry_categories.ts @@ -46,4 +46,5 @@ export const logEntryCategoriesResponseRT = rt.intersection([ }), ]); +// eslint-disable-next-line @typescript-eslint/naming-convention export type logEntryCategoriesResponse = rt.TypeOf; diff --git a/x-pack/plugins/infra/server/lib/log_analysis/queries/log_entry_category_examples.ts b/x-pack/plugins/infra/server/lib/log_analysis/queries/log_entry_category_examples.ts index 2f4502f991dd9..6e2afa874b757 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/queries/log_entry_category_examples.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/queries/log_entry_category_examples.ts @@ -82,4 +82,5 @@ export const logEntryCategoryExamplesResponseRT = rt.intersection([ }), ]); +// eslint-disable-next-line @typescript-eslint/naming-convention export type logEntryCategoryExamplesResponse = rt.TypeOf; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/index.tsx index 0eaf785405590..443708ec6384f 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/index.tsx @@ -94,7 +94,6 @@ const IngestManagerRoutes = memo<{ history: AppMountParameters['history']; basep setPermissionsError('REQUEST_ERROR'); } })(); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); if (isPermissionsLoading || permissionsError) { diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/settings/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/settings/index.tsx index 6bb381e29ded2..dfdd63bd984dd 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/settings/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/settings/index.tsx @@ -74,6 +74,7 @@ export const ConfigSettingsView = memo<{ config: AgentConfig }>( const submitUpdateAgentConfig = async () => { setIsLoading(true); try { + // eslint-disable-next-line @typescript-eslint/naming-convention const { name, description, namespace, monitoring_enabled } = agentConfig; const { data, error } = await sendUpdateAgentConfig(agentConfig.id, { name, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/edit_package_config_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/edit_package_config_page/index.tsx index f4411a6057a15..3005f8d36f343 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/edit_package_config_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/edit_package_config_page/index.tsx @@ -100,10 +100,12 @@ export const EditPackageConfigPage: React.FunctionComponent = () => { id, revision, inputs, + /* eslint-disable @typescript-eslint/naming-convention */ created_by, created_at, updated_by, updated_at, + /* eslint-enable @typescript-eslint/naming-convention */ ...restOfPackageConfig } = packageConfigData.item; // Remove `compiled_stream` from all stream info, we assign this after saving @@ -114,6 +116,7 @@ export const EditPackageConfigPage: React.FunctionComponent = () => { return { ...restOfInput, streams: streams.map((stream) => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { compiled_stream, ...restOfStream } = stream; return restOfStream; }), diff --git a/x-pack/plugins/ingest_manager/server/services/agent_config.ts b/x-pack/plugins/ingest_manager/server/services/agent_config.ts index 63d4e6f012e07..10b5d9aa0b2f8 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_config.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_config.ts @@ -218,6 +218,7 @@ class AgentConfigService { if (!baseAgentConfig) { throw new Error('Agent config not found'); } + // eslint-disable-next-line @typescript-eslint/naming-convention const { namespace, monitoring_enabled } = baseAgentConfig; const newAgentConfig = await this.create( soClient, @@ -393,6 +394,7 @@ class AgentConfigService { outputs: { // TEMPORARY as we only support a default output ...[defaultOutput].reduce( + // eslint-disable-next-line @typescript-eslint/naming-convention (outputs, { config: outputConfig, name, type, hosts, ca_sha256, api_key }) => { outputs[name] = { type, diff --git a/x-pack/plugins/ingest_manager/server/services/agents/crud.ts b/x-pack/plugins/ingest_manager/server/services/agents/crud.ts index 4420135aec952..a57735e25ff7b 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/crud.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/crud.ts @@ -51,6 +51,7 @@ export async function listAgents( filters.push(`(${agentActiveCondition}) OR (${recentlySeenEphemeralAgent})`); } + // eslint-disable-next-line @typescript-eslint/naming-convention const { saved_objects, total } = await soClient.find({ type: AGENT_SAVED_OBJECT_TYPE, sortField, diff --git a/x-pack/plugins/ingest_manager/server/services/agents/events.ts b/x-pack/plugins/ingest_manager/server/services/agents/events.ts index 55970607c74ab..dfa599e4ffdfd 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/events.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/events.ts @@ -19,6 +19,7 @@ export async function getAgentEvents( ) { const { page, perPage, kuery } = options; + // eslint-disable-next-line @typescript-eslint/naming-convention const { total, saved_objects } = await soClient.find({ type: AGENT_EVENT_SAVED_OBJECT_TYPE, filter: diff --git a/x-pack/plugins/ingest_manager/server/services/api_keys/enrollment_api_key.ts b/x-pack/plugins/ingest_manager/server/services/api_keys/enrollment_api_key.ts index 02e2c8151fac7..e1266ac594164 100644 --- a/x-pack/plugins/ingest_manager/server/services/api_keys/enrollment_api_key.ts +++ b/x-pack/plugins/ingest_manager/server/services/api_keys/enrollment_api_key.ts @@ -24,6 +24,7 @@ export async function listEnrollmentApiKeys( ): Promise<{ items: EnrollmentAPIKey[]; total: any; page: any; perPage: any }> { const { page = 1, perPage = 20, kuery } = options; + // eslint-disable-next-line @typescript-eslint/naming-convention const { saved_objects, total } = await soClient.find({ type: ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE, page, diff --git a/x-pack/plugins/ingest_manager/server/services/package_config.ts b/x-pack/plugins/ingest_manager/server/services/package_config.ts index 5d1c5d1717714..a369aa5c41cd4 100644 --- a/x-pack/plugins/ingest_manager/server/services/package_config.ts +++ b/x-pack/plugins/ingest_manager/server/services/package_config.ts @@ -121,6 +121,7 @@ class PackageConfigService { options?: { user?: AuthenticatedUser; bumpConfigRevision?: boolean } ): Promise { const isoDate = new Date().toISOString(); + // eslint-disable-next-line @typescript-eslint/naming-convention const { saved_objects } = await soClient.bulkCreate( packageConfigs.map((packageConfig) => ({ type: SAVED_OBJECT_TYPE, diff --git a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_clone.helpers.ts b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_clone.helpers.ts index 2791ffc32c858..f369bfe66f642 100644 --- a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_clone.helpers.ts +++ b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_clone.helpers.ts @@ -6,7 +6,7 @@ import { registerTestBed, TestBedConfig, TestBed } from '../../../../../test_utils'; import { BASE_PATH } from '../../../common/constants'; -import { PipelinesClone } from '../../../public/application/sections/pipelines_clone'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { PipelinesClone } from '../../../public/application/sections/pipelines_clone'; import { getFormActions, PipelineFormTestSubjects } from './pipeline_form.helpers'; import { WithAppDependencies } from './setup_environment'; diff --git a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_create.helpers.ts b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_create.helpers.ts index 54a62a8357e52..ce5ab1faa01be 100644 --- a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_create.helpers.ts +++ b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_create.helpers.ts @@ -6,7 +6,7 @@ import { registerTestBed, TestBedConfig, TestBed } from '../../../../../test_utils'; import { BASE_PATH } from '../../../common/constants'; -import { PipelinesCreate } from '../../../public/application/sections/pipelines_create'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { PipelinesCreate } from '../../../public/application/sections/pipelines_create'; import { getFormActions, PipelineFormTestSubjects } from './pipeline_form.helpers'; import { WithAppDependencies } from './setup_environment'; diff --git a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_edit.helpers.ts b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_edit.helpers.ts index 12320f034a819..31c9630086178 100644 --- a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_edit.helpers.ts +++ b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/pipelines_edit.helpers.ts @@ -6,7 +6,7 @@ import { registerTestBed, TestBedConfig, TestBed } from '../../../../../test_utils'; import { BASE_PATH } from '../../../common/constants'; -import { PipelinesEdit } from '../../../public/application/sections/pipelines_edit'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { PipelinesEdit } from '../../../public/application/sections/pipelines_edit'; import { getFormActions, PipelineFormTestSubjects } from './pipeline_form.helpers'; import { WithAppDependencies } from './setup_environment'; diff --git a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/setup_environment.tsx index a5796c10f8d93..c380032bd9482 100644 --- a/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/setup_environment.tsx @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import React from 'react'; import { LocationDescriptorObject } from 'history'; import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; @@ -17,7 +16,6 @@ import { import { usageCollectionPluginMock } from '../../../../../../src/plugins/usage_collection/public/mocks'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { HttpService } from '../../../../../../src/core/public/http'; import { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/context_menu.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/context_menu.tsx index 5cee5311c62a9..1c2f2cc2f4843 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/context_menu.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/context_menu.tsx @@ -26,6 +26,7 @@ export const ContextMenu: FunctionComponent = (props) => { const [isOpen, setIsOpen] = useState(false); const containerClasses = classNames({ + // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__item--displayNone': hidden, }); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/inline_text_input.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/inline_text_input.tsx index ea936115f1ac9..e91974adca20a 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/inline_text_input.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/inline_text_input.tsx @@ -26,6 +26,7 @@ export const InlineTextInput: FunctionComponent = ({ const [textValue, setTextValue] = useState(text ?? ''); const containerClasses = classNames('pipelineProcessorsEditor__item__textContainer', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__item__textContainer--notEditing': !isShowingTextInput && !disabled, }); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx index 3fbef4c1b7898..b43e2bc1342c3 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx @@ -62,15 +62,19 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( const isDimmed = isEditingOtherProcessor || isMovingOtherProcessor; const panelClasses = classNames('pipelineProcessorsEditor__item', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__item--selected': isMovingThisProcessor || isEditingThisProcessor, + // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__item--dimmed': isDimmed, }); const actionElementClasses = classNames({ + // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__item--displayNone': isInMoveMode, }); const inlineTextInputContainerClasses = classNames({ + // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__item--displayNone': isInMoveMode && !processor.options.description, }); @@ -80,6 +84,7 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( : i18nTexts.cancelMoveButtonLabel; const dataTestSubj = !isMovingThisProcessor ? 'moveItemButton' : 'cancelMoveItemButton'; const moveButtonClasses = classNames('pipelineProcessorsEditor__item__moveButton', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__item__moveButton--cancel': isMovingThisProcessor, }); const icon = isMovingThisProcessor ? 'cross' : 'sortable'; @@ -143,7 +148,7 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( onChange={(nextDescription) => { let nextOptions: Record; if (!nextDescription) { - const { description: __, ...restOptions } = processor.options; + const { description: _description, ...restOptions } = processor.options; nextOptions = restOptions; } else { nextOptions = { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processors_tree/components/drop_zone_button.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processors_tree/components/drop_zone_button.tsx index 193b5b9afe447..57ecb6f7f1187 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processors_tree/components/drop_zone_button.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processors_tree/components/drop_zone_button.tsx @@ -32,10 +32,13 @@ export const DropZoneButton: FunctionComponent = (props) => { const { onClick, isDisabled, isVisible } = props; const isUnavailable = isVisible && isDisabled; const containerClasses = classNames({ + // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__tree__dropZoneContainer--visible': isVisible, + // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__tree__dropZoneContainer--unavailable': isUnavailable, }); const buttonClasses = classNames({ + // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__tree__dropZoneButton--visible': isVisible, }); diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts index c2328bcc9d0ab..4600580985b57 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts @@ -33,6 +33,7 @@ export const registerCreateRoute = ({ const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client; const pipeline = req.body as Pipeline; + // eslint-disable-next-line @typescript-eslint/naming-convention const { name, description, processors, version, on_failure } = pipeline; try { diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts index cd0e3568f0f60..82a5ccbc280d7 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts @@ -32,6 +32,7 @@ export const registerUpdateRoute = ({ license.guardApiRoute(async (ctx, req, res) => { const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client; const { name } = req.params; + // eslint-disable-next-line @typescript-eslint/naming-convention const { description, processors, version, on_failure } = req.body; try { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx index b06b316ec79aa..7efaecb125c8e 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx @@ -71,6 +71,7 @@ const PreviewRenderer = ({ return (
    @@ -123,6 +124,7 @@ const SuggestionPreview = ({ diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx index 35c510521b35b..b8f868a8694dd 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx @@ -100,7 +100,9 @@ export function FieldSelect({ label, value, className: classNames({ + // eslint-disable-next-line @typescript-eslint/naming-convention 'lnFieldSelect__option--incompatible': !compatible, + // eslint-disable-next-line @typescript-eslint/naming-convention 'lnFieldSelect__option--nonExistant': !exists, }), 'data-test-subj': `lns-fieldOption${compatible ? '' : 'Incompatible'}-${label}`, diff --git a/x-pack/plugins/lens/public/persistence/saved_object_store.ts b/x-pack/plugins/lens/public/persistence/saved_object_store.ts index 7632be3d82046..af90634874fb1 100644 --- a/x-pack/plugins/lens/public/persistence/saved_object_store.ts +++ b/x-pack/plugins/lens/public/persistence/saved_object_store.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { SavedObjectAttributes } from 'kibana/server'; import { Query, Filter } from '../../../../../src/plugins/data/public'; diff --git a/x-pack/plugins/lists/common/schemas/common/schemas.ts b/x-pack/plugins/lists/common/schemas/common/schemas.ts index 76aa896a741f6..0d52b075ebf12 100644 --- a/x-pack/plugins/lists/common/schemas/common/schemas.ts +++ b/x-pack/plugins/lists/common/schemas/common/schemas.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ +/* eslint-disable @typescript-eslint/naming-convention */ import * as t from 'io-ts'; diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_item_schema.ts index 8dc5a376d1495..8bc42d531768b 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts index be41e57f99421..347e1be03dc8c 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_item_schema.ts index 20187de535a8e..10302e529d2b9 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { esDataTypeUnion, metaOrUndefined, updated_at, updated_by } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_schema.ts index 80b9733908d39..5b2461156e81a 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_item_schema.ts index 76419587c5925..445c53116bc2b 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.ts index 6807201cf18d9..7252f3ca4987f 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts index 626b9e3e624ef..dacd9d515de51 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts index 039a38594a367..fd3390721d41e 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts index 7009fbd709e54..ffec974602714 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.ts index 351eae48a638d..8627d98bec5b8 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id, list_id, meta, value } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/delete_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/delete_endpoint_list_item_schema.ts index 5af5bcd17e744..6855261ee375f 100644 --- a/x-pack/plugins/lists/common/schemas/request/delete_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/delete_endpoint_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id, item_id } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/delete_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/delete_exception_list_item_schema.ts index da6516f4b6fe4..97abdcf730240 100644 --- a/x-pack/plugins/lists/common/schemas/request/delete_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/delete_exception_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id, item_id, namespace_type } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/delete_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/delete_exception_list_schema.ts index 0911a9342f7a9..4e12ac12e9e90 100644 --- a/x-pack/plugins/lists/common/schemas/request/delete_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/delete_exception_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id, list_id, namespace_type } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/delete_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/delete_list_item_schema.ts index 5e2425271c463..7012a9b723ed1 100644 --- a/x-pack/plugins/lists/common/schemas/request/delete_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/delete_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id, list_id, valueOrUndefined } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/delete_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/delete_list_schema.ts index 830e7fe695d1d..630c77bf80dd2 100644 --- a/x-pack/plugins/lists/common/schemas/request/delete_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/delete_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/export_list_item_query_schema.ts b/x-pack/plugins/lists/common/schemas/request/export_list_item_query_schema.ts index 8d14f015d3805..c393a9b7c0876 100644 --- a/x-pack/plugins/lists/common/schemas/request/export_list_item_query_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/export_list_item_query_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { list_id } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.ts index bc839ce1346f3..af94229c4ebd3 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { filter, sort_field, sort_order } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.ts index 634c080d70b75..4f9f8ef3632ad 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { sort_field, sort_order } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.ts index 7ce01c79bbe42..7765bbfbb29bd 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { filter, namespace_type, sort_field, sort_order } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.ts index ba3dfc6ee33ec..477b111af424d 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { cursor, filter, list_id, sort_field, sort_order } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/find_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/find_list_schema.ts index e5020cc8eff84..8bbe8003970ca 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { cursor, filter, sort_field, sort_order } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/import_list_item_query_schema.ts b/x-pack/plugins/lists/common/schemas/request/import_list_item_query_schema.ts index e45f77ca18ae1..6b0818fdcbe44 100644 --- a/x-pack/plugins/lists/common/schemas/request/import_list_item_query_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/import_list_item_query_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { RequiredKeepUndefined } from '../../types'; diff --git a/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts index 671aeda757eff..4b6f599ab013e 100644 --- a/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { file } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/patch_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/patch_list_item_schema.ts index 9c5284c15ca99..f61def1365f5f 100644 --- a/x-pack/plugins/lists/common/schemas/request/patch_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/patch_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { _version, id, meta, value } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts index c92abd2e912eb..394eab8ddb348 100644 --- a/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { _version, description, id, meta, name, version } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/read_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/read_endpoint_list_item_schema.ts index d6c54e289effe..01690f0a6b262 100644 --- a/x-pack/plugins/lists/common/schemas/request/read_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/read_endpoint_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id, item_id } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/read_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/read_exception_list_item_schema.ts index a2ba8126c7788..12e2e2dc278a7 100644 --- a/x-pack/plugins/lists/common/schemas/request/read_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/read_exception_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id, item_id, namespace_type } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/read_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/read_exception_list_schema.ts index f22eca6a8ab15..5db0d2d3662d8 100644 --- a/x-pack/plugins/lists/common/schemas/request/read_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/read_exception_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id, list_id, namespace_type } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/read_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/read_list_item_schema.ts index 063f430aa9cea..80d1321406113 100644 --- a/x-pack/plugins/lists/common/schemas/request/read_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/read_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id, list_id, value } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/read_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/read_list_schema.ts index e395875462cb4..b0de5f81514eb 100644 --- a/x-pack/plugins/lists/common/schemas/request/read_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/read_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { id } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts index 5bf0cb3b7984e..6ce5ad7858b78 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts index 7fbd5cd65f04d..659dde0b5b533 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts index dd1bc65d18230..54e0bbafe4981 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.ts index c6ed5ef0e9517..731c4f20a3ef3 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { _version, id, meta, value } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts index a9778f23f1302..cd0ed47cc3cb5 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { _version, description, id, meta, name, version } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.ts b/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.ts index 4653b73347f72..a2ee6adf9ead9 100644 --- a/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { exceptionListSchema } from './exception_list_schema'; diff --git a/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.ts index 54907f3f8a854..65a1a26eaa622 100644 --- a/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts index 2dbabb0e2bc3b..6597cb20508ca 100644 --- a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/response/found_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/response/found_exception_list_item_schema.ts index a58bf433017e6..8f30064c6aff9 100644 --- a/x-pack/plugins/lists/common/schemas/response/found_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/found_exception_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { page, per_page, total } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.ts index a2ea09a3263ae..c60a90dff5229 100644 --- a/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/found_exception_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { page, per_page, total } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/response/found_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/response/found_list_item_schema.ts index f792774cd0c12..5a64f4e6965e5 100644 --- a/x-pack/plugins/lists/common/schemas/response/found_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/found_list_item_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { cursor, page, per_page, total } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/response/found_list_schema.ts b/x-pack/plugins/lists/common/schemas/response/found_list_schema.ts index aaf4a721d050d..1f3f6571a712e 100644 --- a/x-pack/plugins/lists/common/schemas/response/found_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/found_list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { cursor, page, per_page, total } from '../common/schemas'; diff --git a/x-pack/plugins/lists/common/schemas/response/list_item_schema.ts b/x-pack/plugins/lists/common/schemas/response/list_item_schema.ts index 9ee801298f950..fbe66913f9818 100644 --- a/x-pack/plugins/lists/common/schemas/response/list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/list_item_schema.ts @@ -6,8 +6,6 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ - import { _versionOrUndefined, created_at, diff --git a/x-pack/plugins/lists/common/schemas/response/list_schema.ts b/x-pack/plugins/lists/common/schemas/response/list_schema.ts index 539c6221fcb0f..be0fe53f4d926 100644 --- a/x-pack/plugins/lists/common/schemas/response/list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/list_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { diff --git a/x-pack/plugins/lists/common/schemas/saved_objects/exceptions_list_so_schema.ts b/x-pack/plugins/lists/common/schemas/saved_objects/exceptions_list_so_schema.ts index 2bd2a51ca8c74..f4db77f4ee057 100644 --- a/x-pack/plugins/lists/common/schemas/saved_objects/exceptions_list_so_schema.ts +++ b/x-pack/plugins/lists/common/schemas/saved_objects/exceptions_list_so_schema.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { commentsArrayOrUndefined, entriesArrayOrUndefined } from '../types'; diff --git a/x-pack/plugins/lists/common/schemas/types/comment.ts b/x-pack/plugins/lists/common/schemas/types/comment.ts index 4d7aba3b3ad98..0c0d7543fea51 100644 --- a/x-pack/plugins/lists/common/schemas/types/comment.ts +++ b/x-pack/plugins/lists/common/schemas/types/comment.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { NonEmptyString } from '../../shared_imports'; diff --git a/x-pack/plugins/lists/common/schemas/types/entries.ts b/x-pack/plugins/lists/common/schemas/types/entries.ts index 4f20b9278d3ff..9f014a3e75c14 100644 --- a/x-pack/plugins/lists/common/schemas/types/entries.ts +++ b/x-pack/plugins/lists/common/schemas/types/entries.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { entriesMatchAny } from './entry_match_any'; diff --git a/x-pack/plugins/lists/common/schemas/types/entry_exists.ts b/x-pack/plugins/lists/common/schemas/types/entry_exists.ts index 4d9c09cc93574..50bf4ca776d52 100644 --- a/x-pack/plugins/lists/common/schemas/types/entry_exists.ts +++ b/x-pack/plugins/lists/common/schemas/types/entry_exists.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { NonEmptyString } from '../../shared_imports'; diff --git a/x-pack/plugins/lists/common/schemas/types/entry_list.ts b/x-pack/plugins/lists/common/schemas/types/entry_list.ts index fcfec5e0cccdf..edf93ebffada0 100644 --- a/x-pack/plugins/lists/common/schemas/types/entry_list.ts +++ b/x-pack/plugins/lists/common/schemas/types/entry_list.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { NonEmptyString } from '../../shared_imports'; diff --git a/x-pack/plugins/lists/common/schemas/types/entry_match.ts b/x-pack/plugins/lists/common/schemas/types/entry_match.ts index 247d64674e27d..50cf2138d1587 100644 --- a/x-pack/plugins/lists/common/schemas/types/entry_match.ts +++ b/x-pack/plugins/lists/common/schemas/types/entry_match.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { NonEmptyString } from '../../shared_imports'; diff --git a/x-pack/plugins/lists/common/schemas/types/entry_match_any.ts b/x-pack/plugins/lists/common/schemas/types/entry_match_any.ts index b6c4ef509c477..cff943b9a1275 100644 --- a/x-pack/plugins/lists/common/schemas/types/entry_match_any.ts +++ b/x-pack/plugins/lists/common/schemas/types/entry_match_any.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { NonEmptyString } from '../../shared_imports'; diff --git a/x-pack/plugins/lists/common/schemas/types/entry_nested.ts b/x-pack/plugins/lists/common/schemas/types/entry_nested.ts index f9e8e4356b811..96653eac81ae7 100644 --- a/x-pack/plugins/lists/common/schemas/types/entry_nested.ts +++ b/x-pack/plugins/lists/common/schemas/types/entry_nested.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ - import * as t from 'io-ts'; import { NonEmptyString } from '../../shared_imports'; diff --git a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.ts b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.ts index 8097a7b8c5898..50196a1a0bcc7 100644 --- a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.ts +++ b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.ts @@ -94,6 +94,7 @@ export const useExceptionList = ({ } setLoading(false); } else { + // eslint-disable-next-line @typescript-eslint/naming-convention const { page, per_page, total, data } = await fetchExceptionListsItemsByListIds({ filterOptions: filters, http, diff --git a/x-pack/plugins/lists/public/lists/api.ts b/x-pack/plugins/lists/public/lists/api.ts index 211b2445a0429..2b123280474df 100644 --- a/x-pack/plugins/lists/public/lists/api.ts +++ b/x-pack/plugins/lists/public/lists/api.ts @@ -44,6 +44,7 @@ const findLists = async ({ http, cursor, page, + // eslint-disable-next-line @typescript-eslint/naming-convention per_page, signal, }: ApiParams & FindListSchemaEncoded): Promise => { @@ -82,6 +83,7 @@ export { findListsWithValidation as findLists }; const importList = async ({ file, http, + // eslint-disable-next-line @typescript-eslint/naming-convention list_id, type, signal, @@ -154,6 +156,7 @@ export { deleteListWithValidation as deleteList }; const exportList = async ({ http, + // eslint-disable-next-line @typescript-eslint/naming-convention list_id, signal, }: ApiParams & ExportListItemQuerySchemaEncoded): Promise => diff --git a/x-pack/plugins/lists/server/services/exception_lists/utils.ts b/x-pack/plugins/lists/server/services/exception_lists/utils.ts index 836f642899086..2989a09b0ce00 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/utils.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/utils.ts @@ -70,6 +70,7 @@ export const transformSavedObjectToExceptionList = ({ const { version: _version, attributes: { + /* eslint-disable @typescript-eslint/naming-convention */ _tags, created_at, created_by, @@ -83,6 +84,7 @@ export const transformSavedObjectToExceptionList = ({ type, updated_by, version, + /* eslint-enable @typescript-eslint/naming-convention */ }, id, updated_at: updatedAt, @@ -168,6 +170,7 @@ export const transformSavedObjectToExceptionListItem = ({ const { version: _version, attributes: { + /* eslint-disable @typescript-eslint/naming-convention */ _tags, comments, created_at, @@ -182,6 +185,7 @@ export const transformSavedObjectToExceptionListItem = ({ tie_breaker_id, type, updated_by, + /* eslint-enable @typescript-eslint/naming-convention */ }, id, updated_at: updatedAt, diff --git a/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list_item.ts b/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list_item.ts index 26fe15e9106fe..14794870bf67a 100644 --- a/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list_item.ts +++ b/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list_item.ts @@ -25,6 +25,7 @@ export const transformElasticToListItem = ({ const { _id, _source: { + /* eslint-disable @typescript-eslint/naming-convention */ created_at, deserializer, serializer, @@ -34,6 +35,7 @@ export const transformElasticToListItem = ({ list_id, tie_breaker_id, meta, + /* eslint-enable @typescript-eslint/naming-convention */ }, } = hit; const value = findSourceValue(hit._source); diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 4914432f02de0..7191fb312b211 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -3,8 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/consistent-type-definitions */ - import { Dispatch } from 'redux'; import turfBboxPolygon from '@turf/bbox-polygon'; import turfBooleanContains from '@turf/boolean-contains'; diff --git a/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.test.ts b/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.test.ts index 7954d0c59d97f..2ddbd367baea5 100644 --- a/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.test.ts +++ b/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.test.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line max-classes-per-file import { ITileLayerArguments, TileLayer } from './tile_layer'; import { SOURCE_TYPES } from '../../../../common/constants'; import { XYZTMSSourceDescriptor } from '../../../../common/descriptor_types'; diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.test.ts b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.test.ts index e79d8e09fce9b..523cc86915010 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.test.ts @@ -53,6 +53,7 @@ describe('convertCompositeRespToGeoJson', () => { avg_of_bytes: 5359.2307692307695, doc_count: 65, 'terms_of_machine.os.keyword': 'win xp', + // eslint-disable-next-line @typescript-eslint/naming-convention 'terms_of_machine.os.keyword__percentage': 25, }, type: 'Feature', @@ -80,6 +81,7 @@ describe('convertCompositeRespToGeoJson', () => { avg_of_bytes: 5359.2307692307695, doc_count: 65, 'terms_of_machine.os.keyword': 'win xp', + // eslint-disable-next-line @typescript-eslint/naming-convention 'terms_of_machine.os.keyword__percentage': 25, }, type: 'Feature', @@ -127,6 +129,7 @@ describe('convertRegularRespToGeoJson', () => { avg_of_bytes: 5359.2307692307695, doc_count: 65, 'terms_of_machine.os.keyword': 'win xp', + // eslint-disable-next-line @typescript-eslint/naming-convention 'terms_of_machine.os.keyword__percentage': 25, }, type: 'Feature', @@ -154,6 +157,7 @@ describe('convertRegularRespToGeoJson', () => { avg_of_bytes: 5359.2307692307695, doc_count: 65, 'terms_of_machine.os.keyword': 'win xp', + // eslint-disable-next-line @typescript-eslint/naming-convention 'terms_of_machine.os.keyword__percentage': 25, }, type: 'Feature', diff --git a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/convert_to_lines.test.ts b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/convert_to_lines.test.ts index 14c62aa0207fe..23e6c25ac0d04 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/convert_to_lines.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/convert_to_lines.test.ts @@ -19,6 +19,7 @@ const esResponse = { { key: '4/9/3', doc_count: 1, + // eslint-disable-next-line @typescript-eslint/naming-convention terms_of_Carrier: { buckets: [ { @@ -34,6 +35,7 @@ const esResponse = { }, count: 1, }, + // eslint-disable-next-line @typescript-eslint/naming-convention avg_of_FlightDelayMin: { value: 3, }, @@ -59,9 +61,12 @@ it('Should convert elasticsearch aggregation response into feature collection of }, id: '10.39269994944334,43.68389896117151,4/9/3', properties: { + // eslint-disable-next-line @typescript-eslint/naming-convention avg_of_FlightDelayMin: 3, doc_count: 1, + // eslint-disable-next-line @typescript-eslint/naming-convention terms_of_Carrier: 'ES-Air', + // eslint-disable-next-line @typescript-eslint/naming-convention terms_of_Carrier__percentage: 100, }, type: 'Feature', diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index b2a93a4ef88ad..080138839ba2e 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/consistent-type-definitions */ import React, { ChangeEvent, Component, Fragment } from 'react'; import { diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx index 49487e96a4544..72fe2d9a90a71 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/consistent-type-definitions */ import React, { Component, ChangeEvent } from 'react'; import _ from 'lodash'; diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/symbol_icon.tsx b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/symbol_icon.tsx index c5d41ae2b1a9b..839f7a42eb9d6 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/symbol_icon.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/symbol_icon.tsx @@ -55,12 +55,7 @@ export class SymbolIcon extends Component { return null; } - const { - symbolId, // eslint-disable-line no-unused-vars - fill, // eslint-disable-line no-unused-vars - stroke, // eslint-disable-line no-unused-vars - ...rest - } = this.props; + const { symbolId, fill, stroke, ...rest } = this.props; return ( extends IStyleProperty { getValueSuggestions(query: string): Promise; } -type fieldFormatter = (value: string | number | undefined) => string | number; +type FieldFormatter = (value: string | number | undefined) => string | number; export class DynamicStyleProperty extends AbstractStyleProperty implements IDynamicStyleProperty { @@ -56,14 +55,14 @@ export class DynamicStyleProperty extends AbstractStyleProperty protected readonly _field: IField | null; protected readonly _layer: IVectorLayer; - protected readonly _getFieldFormatter: (fieldName: string) => null | fieldFormatter; + protected readonly _getFieldFormatter: (fieldName: string) => null | FieldFormatter; constructor( options: T, styleName: VECTOR_STYLES, field: IField | null, vectorLayer: IVectorLayer, - getFieldFormatter: (fieldName: string) => null | fieldFormatter + getFieldFormatter: (fieldName: string) => null | FieldFormatter ) { super(options, styleName); this._field = field; diff --git a/x-pack/plugins/maps/public/classes/util/es_agg_utils.test.ts b/x-pack/plugins/maps/public/classes/util/es_agg_utils.test.ts index 445a7621194b7..b51f48fe62157 100644 --- a/x-pack/plugins/maps/public/classes/util/es_agg_utils.test.ts +++ b/x-pack/plugins/maps/public/classes/util/es_agg_utils.test.ts @@ -34,6 +34,7 @@ describe('extractPropertiesFromBucket', () => { expect(properties).toEqual({ doc_count: 3, 'terms_of_machine.os.keyword': 'win xp', + // eslint-disable-next-line @typescript-eslint/naming-convention 'terms_of_machine.os.keyword__percentage': 33, }); }); diff --git a/x-pack/plugins/maps/public/components/tooltip_selector/tooltip_selector.tsx b/x-pack/plugins/maps/public/components/tooltip_selector/tooltip_selector.tsx index 6c07c322d5c49..84316a1b9105d 100644 --- a/x-pack/plugins/maps/public/components/tooltip_selector/tooltip_selector.tsx +++ b/x-pack/plugins/maps/public/components/tooltip_selector/tooltip_selector.tsx @@ -176,7 +176,9 @@ export class TooltipSelector extends Component { {(provided, state) => (
    diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx index 3f493ef7d4355..f7de84a9c1ad0 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx @@ -9,7 +9,6 @@ import { EuiButtonEmpty, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { LayerWizardSelect } from './layer_wizard_select'; import { LayerWizard, RenderWizardArguments } from '../../../classes/layers/layer_wizard_registry'; -/* eslint-disable @typescript-eslint/consistent-type-definitions */ type Props = RenderWizardArguments & { layerWizard: LayerWizard | null; diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/layer_wizard_select.test.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/layer_wizard_select.test.tsx index e802c5259e5ed..d64e38cf49dea 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/layer_wizard_select.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/layer_wizard_select.test.tsx @@ -17,6 +17,7 @@ const defaultProps = { describe('LayerWizardSelect', () => { beforeAll(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires require('../../../classes/layers/layer_wizard_registry').getLayerWizards = async () => { return [ { diff --git a/x-pack/plugins/maps/public/index_pattern_util.test.ts b/x-pack/plugins/maps/public/index_pattern_util.test.ts index 27b0a4aac9bf7..ffcc6da52677a 100644 --- a/x-pack/plugins/maps/public/index_pattern_util.test.ts +++ b/x-pack/plugins/maps/public/index_pattern_util.test.ts @@ -68,6 +68,7 @@ describe('Gold+ licensing', () => { describe('basic license', () => { beforeEach(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires require('./kibana_services').getIsGoldPlus = () => false; }); @@ -90,6 +91,7 @@ describe('Gold+ licensing', () => { describe('gold license', () => { beforeEach(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires require('./kibana_services').getIsGoldPlus = () => true; }); describe('getAggregatableGeoFieldTypes', () => { diff --git a/x-pack/plugins/maps_legacy_licensing/public/plugin.ts b/x-pack/plugins/maps_legacy_licensing/public/plugin.ts index 69c25efd96e75..eaf527f856bc5 100644 --- a/x-pack/plugins/maps_legacy_licensing/public/plugin.ts +++ b/x-pack/plugins/maps_legacy_licensing/public/plugin.ts @@ -13,7 +13,6 @@ import { LicensingPluginSetup, ILicense } from '../../licensing/public'; * @public */ -// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface MapsLegacyLicensingSetupDependencies { licensing: LicensingPluginSetup; mapsLegacy: any; diff --git a/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx b/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx index a354612a348dc..07e33a43d3ff9 100644 --- a/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx +++ b/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx @@ -69,7 +69,7 @@ const Tooltip: FC<{ service: ChartTooltipService }> = React.memo(({ service }) = .slice(1) .map(({ label, value, color, isHighlighted, seriesIdentifier, valueAccessor }) => { const classes = classNames('mlChartTooltip__item', { - /* eslint @typescript-eslint/camelcase:0 */ + // eslint-disable-next-line @typescript-eslint/naming-convention echTooltip__rowHighlighted: isHighlighted, }); return ( diff --git a/x-pack/plugins/ml/public/application/components/data_grid/column_chart.tsx b/x-pack/plugins/ml/public/application/components/data_grid/column_chart.tsx index 00e2d5b14a96b..a3a67fbb8bb75 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/column_chart.tsx +++ b/x-pack/plugins/ml/public/application/components/data_grid/column_chart.tsx @@ -61,6 +61,7 @@ export const ColumnChart: FC = ({ chartData, columnType, dataTestSubj }) )}
    { setVisibleColumns(defaultVisibleColumns); - // eslint-disable-next-line react-hooks/exhaustive-deps }, [defaultVisibleColumns.join()]); const [invalidSortingColumnns, setInvalidSortingColumnns] = useState([]); diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts b/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts index 3bc3b8c2c6dfd..e3da9b509e620 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts @@ -23,6 +23,5 @@ interface StartPlugins { } export type StartServices = CoreStart & StartPlugins & { kibanaVersion: string } & MlServicesContext; -// eslint-disable-next-line react-hooks/rules-of-hooks export const useMlKibana = () => useKibana(); export type MlKibanaReactContextValue = KibanaReactContextValue; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts index 1b28875a624f8..1b99aac812fcd 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts @@ -47,6 +47,7 @@ export const EXTENDED_NUMERICAL_TYPES = new Set([ ES_FIELD_TYPES.SCALED_FLOAT, ]); +// eslint-disable-next-line @typescript-eslint/naming-convention export const ML__ID_COPY = 'ml__id_copy'; export const isKeywordAndTextType = (fieldName: string): boolean => { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx index a229a79d316d7..a52cbb99d7f48 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx @@ -54,7 +54,7 @@ const columns = [ id: 'is_included', alignment: LEFT_ALIGNMENT, isSortable: true, - // eslint-disable-next-line @typescript-eslint/camelcase + // eslint-disable-next-line @typescript-eslint/naming-convention render: ({ is_included }: { is_included: boolean }) => (is_included ? 'Yes' : 'No'), }, { @@ -64,7 +64,7 @@ const columns = [ id: 'is_required', alignment: LEFT_ALIGNMENT, isSortable: true, - // eslint-disable-next-line @typescript-eslint/camelcase + // eslint-disable-next-line @typescript-eslint/naming-convention render: ({ is_required }: { is_required: boolean }) => (is_required ? 'Yes' : 'No'), }, { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts index 2cecffc993257..eab5165a42137 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts @@ -63,7 +63,6 @@ export const useIndexData = ( useEffect(() => { resetPagination(); // custom comparison - // eslint-disable-next-line react-hooks/exhaustive-deps }, [JSON.stringify(query)]); const getIndexData = async function () { @@ -103,7 +102,6 @@ export const useIndexData = ( useEffect(() => { getIndexData(); // custom comparison - // eslint-disable-next-line react-hooks/exhaustive-deps }, [indexPattern.title, JSON.stringify([query, pagination, sortingColumns])]); const dataLoader = useMemo(() => new DataLoader(indexPattern, toastNotifications), [ @@ -132,7 +130,6 @@ export const useIndexData = ( fetchColumnChartsData(); } // custom comparison - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ dataGrid.chartsVisible, indexPattern.title, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts index 98dd40986e32b..8d53214d23d47 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts @@ -70,7 +70,6 @@ export const useExplorationResults = ( useEffect(() => { getIndexData(jobConfig, dataGrid, searchQuery); // custom comparison - // eslint-disable-next-line react-hooks/exhaustive-deps }, [jobConfig && jobConfig.id, dataGrid.pagination, searchQuery, dataGrid.sortingColumns]); const dataLoader = useMemo( @@ -103,7 +102,6 @@ export const useExplorationResults = ( fetchColumnChartsData(); } // custom comparison - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ dataGrid.chartsVisible, jobConfig?.dest.index, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx index 4c4731d0dad5f..2b1c40f0eb734 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx @@ -56,7 +56,6 @@ export const OutlierExploration: FC = React.memo(({ jobId }) = const { columnsWithCharts, errorMessage, status, tableItems } = outlierData; - /* eslint-disable-next-line react-hooks/rules-of-hooks */ const colorRange = useColorRange( COLOR_RANGE.BLUE, COLOR_RANGE_SCALE.INFLUENCER, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts index 90294a09c0adc..24649ae5f1e71 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts @@ -77,7 +77,6 @@ export const useOutlierData = ( useEffect(() => { getIndexData(jobConfig, dataGrid, searchQuery); // custom comparison - // eslint-disable-next-line react-hooks/exhaustive-deps }, [jobConfig && jobConfig.id, dataGrid.pagination, searchQuery, dataGrid.sortingColumns]); const dataLoader = useMemo( @@ -112,7 +111,6 @@ export const useOutlierData = ( fetchColumnChartsData(); } // custom comparison - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ dataGrid.chartsVisible, jobConfig?.dest.index, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/evaluate_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/evaluate_panel.tsx index 75c41c097192e..895d217555ef4 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/evaluate_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/evaluate_panel.tsx @@ -94,6 +94,7 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, searchQuery }) genErrorEval.eval && isRegressionEvaluateResponse(genErrorEval.eval) ) { + // eslint-disable-next-line @typescript-eslint/naming-convention const { mse, msle, huber, r_squared } = getValuesFromResponse(genErrorEval.eval); setGeneralizationEval({ mse, @@ -131,6 +132,7 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, searchQuery }) trainingErrorEval.eval && isRegressionEvaluateResponse(trainingErrorEval.eval) ) { + // eslint-disable-next-line @typescript-eslint/naming-convention const { mse, msle, huber, r_squared } = getValuesFromResponse(trainingErrorEval.eval); setTrainingEval({ mse, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_button.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_button.tsx index 010aa7b8513b5..d78e1bcc1a913 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_button.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_button.tsx @@ -314,6 +314,7 @@ export type CloneDataFrameAnalyticsConfig = Omit< export function extractCloningConfig({ id, version, + // eslint-disable-next-line @typescript-eslint/naming-convention create_time, ...configToClone }: DeepReadonly): CloneDataFrameAnalyticsConfig { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row.tsx index 5276fedff0fde..645c6c276a6f9 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row.tsx @@ -95,6 +95,7 @@ export const ExpandedRow: FC = ({ item }) => { genErrorEval.eval && isRegressionEvaluateResponse(genErrorEval.eval) ) { + // eslint-disable-next-line @typescript-eslint/naming-convention const { mse, msle, huber, r_squared } = getValuesFromResponse(genErrorEval.eval); setGeneralizationEval({ mse, @@ -129,6 +130,7 @@ export const ExpandedRow: FC = ({ item }) => { trainingErrorEval.eval && isRegressionEvaluateResponse(trainingErrorEval.eval) ) { + // eslint-disable-next-line @typescript-eslint/naming-convention const { mse, msle, huber, r_squared } = getValuesFromResponse(trainingErrorEval.eval); setTrainingEval({ mse, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts index 69599f43ef297..f932e4d0db7d7 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts @@ -18,7 +18,6 @@ import { CloneDataFrameAnalyticsConfig } from '../../components/action_clone'; export enum DEFAULT_MODEL_MEMORY_LIMIT { regression = '100mb', - // eslint-disable-next-line @typescript-eslint/camelcase outlier_detection = '50mb', classification = '100mb', } diff --git a/x-pack/plugins/ml/public/application/services/results_service/index.ts b/x-pack/plugins/ml/public/application/services/results_service/index.ts index 6c508422e7063..5547c4096e3de 100644 --- a/x-pack/plugins/ml/public/application/services/results_service/index.ts +++ b/x-pack/plugins/ml/public/application/services/results_service/index.ts @@ -10,9 +10,9 @@ import { ml, MlApiServices } from '../ml_api_service'; export type MlResultsService = typeof mlResultsService; -type time = string; +type Time = string; export interface ModelPlotOutputResults { - results: Record; + results: Record; } export interface CriteriaField { diff --git a/x-pack/plugins/ml/public/application/util/custom_url_utils.test.ts b/x-pack/plugins/ml/public/application/util/custom_url_utils.test.ts index 428060dd2c31b..2912aad6819cf 100644 --- a/x-pack/plugins/ml/public/application/util/custom_url_utils.test.ts +++ b/x-pack/plugins/ml/public/application/util/custom_url_utils.test.ts @@ -211,7 +211,6 @@ describe('ML - custom URL utils', () => { ); }); - // eslint-disable-next-line ban/ban test('truncates long queries', () => { const TEST_DOC_WITH_METHOD: AnomalyRecordDoc = { ...TEST_DOC, diff --git a/x-pack/plugins/monitoring/public/alerts/panel.tsx b/x-pack/plugins/monitoring/public/alerts/panel.tsx index 91a426cc8798e..91604acf115fa 100644 --- a/x-pack/plugins/monitoring/public/alerts/panel.tsx +++ b/x-pack/plugins/monitoring/public/alerts/panel.tsx @@ -23,7 +23,6 @@ import { AlertMessage } from '../../server/alerts/types'; import { Legacy } from '../legacy_shims'; import { replaceTokens } from './lib/replace_tokens'; import { AlertsContextProvider } from '../../../triggers_actions_ui/public'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AlertEdit } from '../../../triggers_actions_ui/public'; import { isInSetupMode, hideBottomBar, showBottomBar } from '../lib/setup_mode'; import { BASE_ALERT_API_PATH } from '../../../alerts/common'; diff --git a/x-pack/plugins/monitoring/public/lib/setup_mode.tsx b/x-pack/plugins/monitoring/public/lib/setup_mode.tsx index b99093a3d8ad1..3425e0ee2a818 100644 --- a/x-pack/plugins/monitoring/public/lib/setup_mode.tsx +++ b/x-pack/plugins/monitoring/public/lib/setup_mode.tsx @@ -110,7 +110,7 @@ export const updateSetupModeData = async (uuid?: string, fetchWithoutClusterUuid text, }); }); - return toggleSetupMode(false); // eslint-disable-line no-use-before-define + return toggleSetupMode(false); } notifySetupModeDataChange(); @@ -160,7 +160,7 @@ export const toggleSetupMode = (inSetupMode: boolean) => { setupModeState.enabled = inSetupMode; globalState.inSetupMode = inSetupMode; globalState.save(); - setSetupModeMenuItem(); // eslint-disable-line no-use-before-define + setSetupModeMenuItem(); notifySetupModeDataChange(); if (inSetupMode) { diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_kibana_stats.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_kibana_stats.ts index 45df56b2139ff..e87c8398ad0b0 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_kibana_stats.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_kibana_stats.ts @@ -104,9 +104,11 @@ export function getUsageStats(rawStats: SearchResponse) { dashboard, visualization, search, + /* eslint-disable @typescript-eslint/naming-convention */ index_pattern, graph_workspace, timelion_sheet, + /* eslint-enable @typescript-eslint/naming-convention */ xpack, ...pluginsTop } = currUsage; diff --git a/x-pack/plugins/observability/public/data_handler.ts b/x-pack/plugins/observability/public/data_handler.ts index 834d7a52d767f..b0bdcf17b9066 100644 --- a/x-pack/plugins/observability/public/data_handler.ts +++ b/x-pack/plugins/observability/public/data_handler.ts @@ -40,7 +40,6 @@ export async function fetchHasData(): Promise> return result.value; } - // eslint-disable-next-line no-console console.error('Error while fetching has data', result.reason); return false; }); diff --git a/x-pack/plugins/observability/public/hooks/use_route_params.tsx b/x-pack/plugins/observability/public/hooks/use_route_params.tsx index 93a79bfda7fc1..1b32933eec3e6 100644 --- a/x-pack/plugins/observability/public/hooks/use_route_params.tsx +++ b/x-pack/plugins/observability/public/hooks/use_route_params.tsx @@ -36,12 +36,10 @@ export function useRouteParams(params: Params) { const queryResult = rts.queryRt.decode(queryParams); const pathResult = rts.pathRt.decode(pathParams); if (isLeft(queryResult)) { - // eslint-disable-next-line no-console console.error(PathReporter.report(queryResult)[0]); } if (isLeft(pathResult)) { - // eslint-disable-next-line no-console console.error(PathReporter.report(pathResult)[0]); } diff --git a/x-pack/plugins/observability/public/services/get_news_feed.ts b/x-pack/plugins/observability/public/services/get_news_feed.ts index 3a6e60fa74188..af8d062154e2d 100644 --- a/x-pack/plugins/observability/public/services/get_news_feed.ts +++ b/x-pack/plugins/observability/public/services/get_news_feed.ts @@ -20,7 +20,6 @@ export async function getNewsFeed({ core }: { core: AppMountContext['core'] }): try { return await core.http.get('https://feeds.elastic.co/observability-solution/v8.0.0.json'); } catch (e) { - // eslint-disable-next-line no-console console.error('Error while fetching news feed', e); return { items: [] }; } diff --git a/x-pack/plugins/observability/public/services/get_observability_alerts.ts b/x-pack/plugins/observability/public/services/get_observability_alerts.ts index fe5451597688a..602e4cf2bdd13 100644 --- a/x-pack/plugins/observability/public/services/get_observability_alerts.ts +++ b/x-pack/plugins/observability/public/services/get_observability_alerts.ts @@ -23,7 +23,6 @@ export async function getObservabilityAlerts({ core }: { core: AppMountContext[' return data.filter(({ consumer }) => allowedConsumers.includes(consumer)); } catch (e) { - // eslint-disable-next-line no-console console.error('Error while fetching alerts', e); return []; } diff --git a/x-pack/plugins/oss_telemetry/server/test_utils/index.ts b/x-pack/plugins/oss_telemetry/server/test_utils/index.ts index 3eee1978d4f1c..9201899d5a161 100644 --- a/x-pack/plugins/oss_telemetry/server/test_utils/index.ts +++ b/x-pack/plugins/oss_telemetry/server/test_utils/index.ts @@ -13,7 +13,6 @@ import { ConcreteTaskInstance, TaskStatus, TaskManagerStartContract, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths } from '../../../task_manager/server'; export const getMockTaskInstance = ( diff --git a/x-pack/plugins/painless_lab/public/application/components/main_controls.tsx b/x-pack/plugins/painless_lab/public/application/components/main_controls.tsx index 7018cfd27c509..4d44ae0176103 100644 --- a/x-pack/plugins/painless_lab/public/application/components/main_controls.tsx +++ b/x-pack/plugins/painless_lab/public/application/components/main_controls.tsx @@ -93,6 +93,7 @@ export function MainControls({ let classes = ''; if (isNavLegacy) { classes = classNames('painlessLab__bottomBar', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'painlessLab__bottomBar-isNavDrawerLocked': isNavDrawerLocked, }); } diff --git a/x-pack/plugins/painless_lab/public/links.ts b/x-pack/plugins/painless_lab/public/links.ts index 8f610140c3f34..c3a6ab5fafabf 100644 --- a/x-pack/plugins/painless_lab/public/links.ts +++ b/x-pack/plugins/painless_lab/public/links.ts @@ -8,6 +8,7 @@ import { DocLinksStart } from 'src/core/public'; export type Links = ReturnType; +// eslint-disable-next-line @typescript-eslint/naming-convention export const getLinks = ({ DOC_LINK_VERSION, ELASTIC_WEBSITE_URL }: DocLinksStart) => Object.freeze({ painlessExecuteAPI: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/painless/${DOC_LINK_VERSION}/painless-execute-api.html`, diff --git a/x-pack/plugins/reporting/public/lib/job_completion_notifications.ts b/x-pack/plugins/reporting/public/lib/job_completion_notifications.ts index 99f3773856325..06694361b757d 100644 --- a/x-pack/plugins/reporting/public/lib/job_completion_notifications.ts +++ b/x-pack/plugins/reporting/public/lib/job_completion_notifications.ts @@ -6,7 +6,7 @@ import { JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY } from '../../constants'; -type jobId = string; +type JobId = string; const set = (jobs: any) => { sessionStorage.setItem(JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY, JSON.stringify(jobs)); @@ -17,13 +17,13 @@ const getAll = () => { return sessionValue ? JSON.parse(sessionValue) : []; }; -export const add = (jobId: jobId) => { +export const add = (jobId: JobId) => { const jobs = getAll(); jobs.push(jobId); set(jobs); }; -export const remove = (jobId: jobId) => { +export const remove = (jobId: JobId) => { const jobs = getAll(); const index = jobs.indexOf(jobId); diff --git a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts index f07235742a1d3..b97a56c15fb4d 100644 --- a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts +++ b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts @@ -9,7 +9,7 @@ import { first } from 'rxjs/operators'; import { LicensingPluginSetup } from '../../../licensing/public'; import { GetCsvReportPanelAction } from './get_csv_panel_action'; -type licenseResults = 'valid' | 'invalid' | 'unavailable' | 'expired'; +type LicenseResults = 'valid' | 'invalid' | 'unavailable' | 'expired'; describe('GetCsvReportPanelAction', () => { let core: any; @@ -27,7 +27,7 @@ describe('GetCsvReportPanelAction', () => { }); beforeEach(() => { - mockLicense$ = (state: licenseResults = 'valid') => { + mockLicense$ = (state: LicenseResults = 'valid') => { return (of({ check: jest.fn().mockImplementation(() => ({ state })), }) as unknown) as LicensingPluginSetup['license$']; diff --git a/x-pack/plugins/reporting/server/export_types/common/validate_urls.test.ts b/x-pack/plugins/reporting/server/export_types/common/validate_urls.test.ts index 5e576e13c0227..5464f3d6dd505 100644 --- a/x-pack/plugins/reporting/server/export_types/common/validate_urls.test.ts +++ b/x-pack/plugins/reporting/server/export_types/common/validate_urls.test.ts @@ -35,6 +35,7 @@ describe('Validate URLS', () => { }); it(`throws for JS URLs`, () => { + // eslint-disable-next-line no-script-url expect(() => validateUrls(['javascript:alert(document.cookies)'])).toThrow(); }); diff --git a/x-pack/plugins/reporting/server/lib/screenshots/observable.test.ts b/x-pack/plugins/reporting/server/lib/screenshots/observable.test.ts index 0ad41cd904853..b25e8fab3abcf 100644 --- a/x-pack/plugins/reporting/server/lib/screenshots/observable.test.ts +++ b/x-pack/plugins/reporting/server/lib/screenshots/observable.test.ts @@ -16,7 +16,6 @@ jest.mock('../../browsers/chromium/puppeteer', () => ({ })); import * as Rx from 'rxjs'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; import { HeadlessChromiumDriver } from '../../browsers'; import { LevelLogger } from '../'; diff --git a/x-pack/plugins/reporting/server/routes/generation.test.ts b/x-pack/plugins/reporting/server/routes/generation.test.ts index c73c443d2390b..87a696948ad84 100644 --- a/x-pack/plugins/reporting/server/routes/generation.test.ts +++ b/x-pack/plugins/reporting/server/routes/generation.test.ts @@ -15,12 +15,12 @@ import { createMockReportingCore } from '../test_helpers'; import { createMockLevelLogger } from '../test_helpers/create_mock_levellogger'; import { registerJobGenerationRoutes } from './generation'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; describe('POST /api/reporting/generate', () => { const reportingSymbol = Symbol('reporting'); - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; let mockExportTypesRegistry: ExportTypesRegistry; let callClusterStub: any; let core: ReportingCore; diff --git a/x-pack/plugins/reporting/server/routes/jobs.test.ts b/x-pack/plugins/reporting/server/routes/jobs.test.ts index a0e3379da12be..2957bc76f4682 100644 --- a/x-pack/plugins/reporting/server/routes/jobs.test.ts +++ b/x-pack/plugins/reporting/server/routes/jobs.test.ts @@ -16,12 +16,12 @@ import { createMockReportingCore } from '../test_helpers'; import { ExportTypeDefinition } from '../types'; import { registerJobInfoRoutes } from './jobs'; -type setupServerReturn = UnwrapPromise>; +type SetupServerReturn = UnwrapPromise>; describe('GET /api/reporting/jobs/download', () => { const reportingSymbol = Symbol('reporting'); - let server: setupServerReturn['server']; - let httpSetup: setupServerReturn['httpSetup']; + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; let exportTypesRegistry: ExportTypesRegistry; let core: ReportingCore; diff --git a/x-pack/plugins/reporting/server/test_helpers/create_mock_server.ts b/x-pack/plugins/reporting/server/test_helpers/create_mock_server.ts index 01b9f6cbd9cd6..078d153cff18d 100644 --- a/x-pack/plugins/reporting/server/test_helpers/create_mock_server.ts +++ b/x-pack/plugins/reporting/server/test_helpers/create_mock_server.ts @@ -6,7 +6,6 @@ // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { createHttpServer, createCoreContext } from 'src/core/server/http/test_utils'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { coreMock } from 'src/core/server/mocks'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ContextService } from 'src/core/server/context/context_service'; diff --git a/x-pack/plugins/rollup/server/lib/format_es_error.ts b/x-pack/plugins/rollup/server/lib/format_es_error.ts index 9dde027cd6949..0f00bfb0c1e7c 100644 --- a/x-pack/plugins/rollup/server/lib/format_es_error.ts +++ b/x-pack/plugins/rollup/server/lib/format_es_error.ts @@ -8,13 +8,12 @@ function extractCausedByChain( causedBy: Record = {}, accumulator: string[] = [] ): string[] { - const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/camelcase + const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/naming-convention if (reason) { accumulator.push(reason); } - // eslint-disable-next-line @typescript-eslint/camelcase if (caused_by) { return extractCausedByChain(caused_by, accumulator); } @@ -36,8 +35,8 @@ export function wrapEsError( const { error: { - root_cause = [], // eslint-disable-line @typescript-eslint/camelcase - caused_by = undefined, // eslint-disable-line @typescript-eslint/camelcase + root_cause = [], // eslint-disable-line @typescript-eslint/naming-convention + caused_by = undefined, // eslint-disable-line @typescript-eslint/naming-convention } = {}, } = JSON.parse(response); diff --git a/x-pack/plugins/searchprofiler/public/application/components/percentage_badge.tsx b/x-pack/plugins/searchprofiler/public/application/components/percentage_badge.tsx index e39e37e8656db..700b6f85f4db8 100644 --- a/x-pack/plugins/searchprofiler/public/application/components/percentage_badge.tsx +++ b/x-pack/plugins/searchprofiler/public/application/components/percentage_badge.tsx @@ -24,7 +24,9 @@ export const PercentageBadge = ({ timePercentage, label, valueType = 'percent' } return ( { }); test('defaults max signals to 100', () => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { max_signals, ...noMaxSignals } = getAddPrepackagedRulesSchemaMock(); const payload: AddPrepackagedRulesSchema = { ...noMaxSignals, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts index c2c2f4784f2b5..56bc68a275ee4 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts @@ -1298,6 +1298,7 @@ describe('create rules schema', () => { }); test('defaults max signals to 100', () => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { max_signals, ...noMaxSignals } = getCreateRulesSchemaMock(); const payload: CreateRulesSchema = { ...noMaxSignals, @@ -1453,6 +1454,7 @@ describe('create rules schema', () => { }); test('it generates a uuid v4 whenever you omit the rule_id', () => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { rule_id, ...noRuleId } = getCreateRulesSchemaMock(); const decoded = createRulesSchema.decode(noRuleId); const checked = exactCheck(noRuleId, decoded); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.ts index 308b3c24010fb..7b6b98383cc33 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.ts @@ -6,7 +6,6 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { description, anomaly_threshold, @@ -47,7 +46,6 @@ import { RiskScoreMapping, SeverityMapping, } from '../common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ import { DefaultStringArray, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.ts index 75fa2da92b787..3874ff8ec90eb 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.ts @@ -6,9 +6,7 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { rule_id, FileName, ExcludeExportDetails } from '../common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ import { DefaultExportFileName } from '../types/default_export_file_name'; import { DefaultStringBooleanFalse } from '../types/default_string_boolean_false'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.ts index 87076803c9582..2e008c2b7401d 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.ts @@ -6,11 +6,9 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { queryFilter, fields, sort_field, sort_order, PerPage, Page } from '../common/schemas'; import { DefaultPerPage } from '../types/default_per_page'; import { DefaultPage } from '../types/default_page'; -/* eslint-enable @typescript-eslint/camelcase */ export const findRulesSchema = t.exact( t.partial({ diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts index 00a3f2126f44a..db2e9acc4615f 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts @@ -681,6 +681,7 @@ describe('import rules schema', () => { }); test('defaults max signals to 100', () => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { max_signals, ...noMaxSignals } = getImportRulesSchemaMock(); const payload: ImportRulesSchema = { ...noMaxSignals, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.ts index d141ca56828b6..698716fea696e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.ts @@ -6,7 +6,6 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { description, anomaly_threshold, @@ -53,7 +52,6 @@ import { RiskScoreMapping, SeverityMapping, } from '../common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ import { DefaultStringArray, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.ts index dd325c1a5034f..a674ac86af87b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.ts @@ -6,7 +6,6 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { description, anomaly_threshold, @@ -49,7 +48,6 @@ import { severity_mapping, } from '../common/schemas'; import { listArrayOrUndefined } from '../types/lists'; -/* eslint-enable @typescript-eslint/camelcase */ /** * All of the patch elements should default to undefined if not set diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.ts index cb8f21128b052..5d6bc5be6b75a 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.ts @@ -6,9 +6,7 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { rule_id, id } from '../common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ export const queryRulesSchema = t.exact( t.partial({ diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.ts index 0e922aeaf8cdf..1464896e50294 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.ts @@ -6,9 +6,7 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { signal_ids, signal_status_query, status } from '../common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ export const setSignalsStatusSchema = t.intersection([ t.type({ diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts index 024198d783048..1cbd3b99c27d7 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts @@ -664,6 +664,7 @@ describe('update rules schema', () => { }); test('defaults max signals to 100', () => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { max_signals, ...noMaxSignals } = getUpdateRulesSchemaMock(); const payload: UpdateRulesSchema = { ...noMaxSignals, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.ts index 4f284eedef3fd..1299dada065e1 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.ts @@ -6,7 +6,6 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { description, anomaly_threshold, @@ -49,7 +48,6 @@ import { RiskScoreMapping, SeverityMapping, } from '../common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ import { DefaultStringArray, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts index 986d3ad87ec85..b07fb9cc19b7b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts @@ -6,9 +6,7 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { rule_id, status_code, message } from '../common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ // We use id: t.string intentionally and _never_ the id from global schemas as // sometimes echo back out the id that the user gave us and it is not guaranteed diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.ts index adea77e7b933f..1131dee0aa8a2 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.ts @@ -6,10 +6,8 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { success, success_count } from '../common/schemas'; import { errorSchema } from './error_schema'; -/* eslint-enable @typescript-eslint/camelcase */ export const importRulesSchema = t.exact( t.type({ diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.ts index 73d144500e003..5e8da6bfcea0b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.ts @@ -6,14 +6,12 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { rules_installed, rules_updated, timelines_installed, timelines_updated, } from '../common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ const prePackagedRulesSchema = t.type({ rules_installed, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts index aabdbdd7300f4..889241d68eb2a 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts @@ -6,7 +6,6 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { rules_installed, rules_custom_installed, @@ -16,7 +15,6 @@ import { timelines_not_installed, timelines_not_updated, } from '../common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ export const prePackagedTimelinesStatusSchema = t.type({ timelines_installed, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.ts index 4bd18a13e4ebb..04df25d805f9e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase */ import * as t from 'io-ts'; import { isObject } from 'lodash/fp'; import { Either, left, fold } from 'fp-ts/lib/Either'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/type_timeline_only_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/type_timeline_only_schema.ts index d23d4ad2e83d4..c39edbbf76f45 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/type_timeline_only_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/type_timeline_only_schema.ts @@ -6,9 +6,7 @@ import * as t from 'io-ts'; -/* eslint-disable @typescript-eslint/camelcase */ import { timeline_id, type } from '../common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ /** * Special schema type that is only the type and the timeline_id. diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts index 518af32dcf2b4..642ee1cef9686 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts @@ -6,7 +6,6 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -// eslint-disable-next-line @typescript-eslint/camelcase import { max_signals } from '../common/schemas'; import { DEFAULT_MAX_SIGNALS } from '../../../constants'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_risk_score_mapping_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_risk_score_mapping_array.ts index bf88ece913767..d96323018dfec 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_risk_score_mapping_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_risk_score_mapping_array.ts @@ -6,7 +6,6 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -// eslint-disable-next-line @typescript-eslint/camelcase import { risk_score_mapping, RiskScoreMapping } from '../common/schemas'; /** diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_severity_mapping_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_severity_mapping_array.ts index 56b0ac1b75982..ec8f6b0a3739b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_severity_mapping_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_severity_mapping_array.ts @@ -6,7 +6,6 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -// eslint-disable-next-line @typescript-eslint/camelcase import { severity_mapping, SeverityMapping } from '../common/schemas'; /** diff --git a/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts b/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts index 7c15bc143e0fd..288ff46439645 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts @@ -10,7 +10,7 @@ import { RuleAlertAction } from './types'; export const transformRuleToAlertAction = ({ group, id, - action_type_id, + action_type_id, // eslint-disable-line @typescript-eslint/naming-convention params, }: RuleAlertAction): AlertAction => ({ group, diff --git a/x-pack/plugins/security_solution/common/types/timeline/index.ts b/x-pack/plugins/security_solution/common/types/timeline/index.ts index 98d17fc87f6ce..84a007e322f11 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/index.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @typescript-eslint/camelcase, @typescript-eslint/no-empty-interface */ - import * as runtimeTypes from 'io-ts'; import { stringEnum, unionWithNullType } from '../../utility_types'; @@ -257,9 +255,9 @@ export const SavedTimelineRuntimeType = runtimeTypes.partial({ updatedBy: unionWithNullType(runtimeTypes.string), }); -export interface SavedTimeline extends runtimeTypes.TypeOf {} +export type SavedTimeline = runtimeTypes.TypeOf; -export interface SavedTimelineNote extends runtimeTypes.TypeOf {} +export type SavedTimelineNote = runtimeTypes.TypeOf; /* * Timeline IDs @@ -317,8 +315,9 @@ export const TimelineSavedToReturnObjectRuntimeType = runtimeTypes.intersection( }), ]); -export interface TimelineSavedObject - extends runtimeTypes.TypeOf {} +export type TimelineSavedObject = runtimeTypes.TypeOf< + typeof TimelineSavedToReturnObjectRuntimeType +>; /** * All Timeline Saved object type with metadata @@ -342,9 +341,8 @@ export const TimelineErrorResponseType = runtimeTypes.type({ message: runtimeTypes.string, }); -export interface TimelineErrorResponse - extends runtimeTypes.TypeOf {} -export interface TimelineResponse extends runtimeTypes.TypeOf {} +export type TimelineErrorResponse = runtimeTypes.TypeOf; +export type TimelineResponse = runtimeTypes.TypeOf; /** * All Timeline Saved object type with metadata @@ -355,8 +353,7 @@ export const AllTimelineSavedObjectRuntimeType = runtimeTypes.type({ data: TimelineSavedToReturnObjectRuntimeType, }); -export interface AllTimelineSavedObject - extends runtimeTypes.TypeOf {} +export type AllTimelineSavedObject = runtimeTypes.TypeOf; /** * Import/export timelines diff --git a/x-pack/plugins/security_solution/public/app/index.tsx b/x-pack/plugins/security_solution/public/app/index.tsx index 0afd945af8597..69bf2549d7439 100644 --- a/x-pack/plugins/security_solution/public/app/index.tsx +++ b/x-pack/plugins/security_solution/public/app/index.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { Store, Action } from 'redux'; import { render, unmountComponentAtNode } from 'react-dom'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AppMountParameters } from '../../../../../src/core/public'; import { State } from '../common/store'; import { StartServices } from '../types'; diff --git a/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx index 43922462cd092..e2e3a600a95ff 100644 --- a/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx @@ -52,6 +52,7 @@ interface ConfigureCasesComponentProps { } const ConfigureCasesComponent: React.FC = ({ userCanCrud }) => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { http, triggers_actions_ui, notifications, application, docLinks } = useKibana().services; const [connectorIsValid, setConnectorIsValid] = useState(true); diff --git a/x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.tsx index a12611ea27035..66cfb0398b44c 100644 --- a/x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.tsx +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.tsx @@ -35,7 +35,6 @@ export const LinkToApp = memo( {children} ) : ( - // eslint-disable-next-line @elastic/eui/href-or-on-click {children} diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx index f6b703b7e622e..bea1eb8f0e17b 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx @@ -33,7 +33,6 @@ import { EmptyNestedEntry, } from '../types'; import { getEntryValue, getExceptionOperatorSelect } from '../helpers'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import exceptionableFields from '../exceptionable_fields.json'; /** diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx index 2b526ede12acf..18d2130dd3811 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx @@ -226,6 +226,7 @@ export const filterExceptionItems = ( export const formatExceptionItemForUpdate = ( exceptionItem: ExceptionListItemSchema ): UpdateExceptionListItemSchema => { + /* eslint-disable @typescript-eslint/naming-convention */ const { created_at, created_by, @@ -233,6 +234,7 @@ export const formatExceptionItemForUpdate = ( tie_breaker_id, updated_at, updated_by, + /* eslint-enable @typescript-eslint/naming-convention */ ...fieldsToUpdate } = exceptionItem; return { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.stories.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.stories.tsx index fec7354855935..a540a34b70677 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.stories.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.stories.tsx @@ -118,6 +118,7 @@ storiesOf('Components|ExceptionItem', module) ); }) .add('with loadingItemIds', () => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { id, namespace_type, ...rest } = getExceptionListItemSchemaMock(); return ( diff --git a/x-pack/plugins/security_solution/public/common/components/links/index.tsx b/x-pack/plugins/security_solution/public/common/components/links/index.tsx index 4a9ad94d8f36d..2f7aa1b14cfda 100644 --- a/x-pack/plugins/security_solution/public/common/components/links/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/links/index.tsx @@ -311,9 +311,11 @@ const ReputationLinkComponent: React.FC<{ ipReputationLinksSetting ?.slice(0, allItemsLimit) .filter( + // eslint-disable-next-line @typescript-eslint/naming-convention ({ url_template, name }) => !isNil(url_template) && !isNil(name) && !isUrlInvalid(url_template) ) + // eslint-disable-next-line @typescript-eslint/naming-convention .map(({ name, url_template }: { name: string; url_template: string }) => ({ name: isDefaultReputationLink(name) ? defaultNameMapping[name] : name, url_template: url_template.replace(`{{ip}}`, encodeURIComponent(domain)), diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts index 845ef580ddbe2..a10e4cf568dd1 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts @@ -6,7 +6,6 @@ import { getOr, omit } from 'lodash/fp'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ChromeBreadcrumb } from '../../../../../../../../src/core/public'; import { APP_NAME } from '../../../../../common/constants'; import { StartServices } from '../../../../types'; diff --git a/x-pack/plugins/security_solution/public/common/hooks/types.ts b/x-pack/plugins/security_solution/public/common/hooks/types.ts index 36b626b0ba9f1..301b8bd655333 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/types.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/types.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { SimpleSavedObject } from '../../../../../../src/core/public'; // eslint-disable-next-line @typescript-eslint/consistent-type-definitions diff --git a/x-pack/plugins/security_solution/public/common/lib/compose/kibana_compose.tsx b/x-pack/plugins/security_solution/public/common/lib/compose/kibana_compose.tsx index 342db7f43943d..30d3311a40b61 100644 --- a/x-pack/plugins/security_solution/public/common/lib/compose/kibana_compose.tsx +++ b/x-pack/plugins/security_solution/public/common/lib/compose/kibana_compose.tsx @@ -8,7 +8,6 @@ import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemo import ApolloClient from 'apollo-client'; import { ApolloLink } from 'apollo-link'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import introspectionQueryResultData from '../../../graphql/introspection.json'; import { AppFrontendLibs } from '../lib'; import { getLinks } from './helpers'; diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts index 8a8138691ba17..00f53ae273b4b 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { CoreStart } from '../../../../../../../src/core/public'; type GlobalServices = Pick; diff --git a/x-pack/plugins/security_solution/public/common/mock/kibana_core.ts b/x-pack/plugins/security_solution/public/common/mock/kibana_core.ts index e82c37e3a5b66..13b3c4b249bfe 100644 --- a/x-pack/plugins/security_solution/public/common/mock/kibana_core.ts +++ b/x-pack/plugins/security_solution/public/common/mock/kibana_core.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { coreMock } from '../../../../../../src/core/public/mocks'; import { dataPluginMock } from '../../../../../../src/plugins/data/public/mocks'; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/helpers.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/helpers.tsx index 0cbed86f18768..bb8cc2267249f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/helpers.tsx @@ -18,6 +18,7 @@ export const formatAlertsData = (alertsData: AlertSearchResponse<{}, AlertsAggre return [ ...acc, + // eslint-disable-next-line @typescript-eslint/naming-convention ...alertsBucket.map(({ key, doc_count }: AlertsBucket) => ({ x: key, y: doc_count, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx index be9725dac5ff3..5bab2e3c78970 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable react/display-name */ - import React from 'react'; import ApolloClient from 'apollo-client'; import { Dispatch } from 'redux'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.test.tsx index 4a2d17ec126fb..8b3d05ce5a574 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.test.tsx @@ -23,7 +23,6 @@ import { mockAboutStepRule, mockDefineStepRule, } from '../../../pages/detection_engine/rules/all/__mocks__/mock'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { coreMock } from '../../../../../../../../src/core/public/mocks'; import { DEFAULT_TIMELINE_TITLE } from '../../../../timelines/components/timeline/translations'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts index 1f75ff0210bd5..78d2e2a5b0c2f 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts @@ -7,7 +7,6 @@ import * as t from 'io-ts'; import { RuleTypeSchema } from '../../../../../common/detection_engine/types'; -/* eslint-disable @typescript-eslint/camelcase */ import { author, building_block_type, @@ -18,7 +17,6 @@ import { timestamp_override, threshold, } from '../../../../../common/detection_engine/schemas/common/schemas'; -/* eslint-enable @typescript-eslint/camelcase */ import { listArray, listArrayOrUndefined, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx index 6ba65ceca8fe9..70f278197b005 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx @@ -234,7 +234,6 @@ const CreateRulePageComponent: React.FC = () => { } }; - // eslint-disable-next-line react-hooks/rules-of-hooks const manageAccordions = useCallback( (id: RuleStep, isOpen: boolean) => { const activeRuleIdx = stepsRuleOrder.findIndex((step) => step === openAccordionId); @@ -256,7 +255,6 @@ const CreateRulePageComponent: React.FC = () => { [isStepRuleInReadOnlyView, openAccordionId, stepsData] ); - // eslint-disable-next-line react-hooks/rules-of-hooks const manageIsEditable = useCallback( async (id: RuleStep) => { const activeForm = await stepsForm.current[openAccordionId]?.submit(); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx index 4327ef96c93a7..016d0c7c67a9e 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable react-hooks/rules-of-hooks, complexity */ +/* eslint-disable complexity */ // TODO: Disabling complexity is temporary till this component is refactored as part of lists UI integration import { @@ -247,7 +247,6 @@ export const RuleDetailsPageComponent: FC = ({ ))} ), - // eslint-disable-next-line react-hooks/exhaustive-deps [ruleDetailTabs, ruleDetailTab, setRuleDetailTab] ); const ruleError = useMemo( @@ -318,13 +317,13 @@ export const RuleDetailsPageComponent: FC = ({ lists: ExceptionIdentifiers[]; allowedExceptionListTypes: ExceptionListTypeEnum[]; }>( - (acc, { id, list_id, namespace_type, type }) => { + (acc, { id, list_id: listId, namespace_type: namespaceType, type }) => { const { allowedExceptionListTypes, lists } = acc; const shouldAddEndpoint = type === ExceptionListTypeEnum.ENDPOINT && !allowedExceptionListTypes.includes(ExceptionListTypeEnum.ENDPOINT); return { - lists: [...lists, { id, listId: list_id, namespaceType: namespace_type, type }], + lists: [...lists, { id, listId, namespaceType, type }], allowedExceptionListTypes: shouldAddEndpoint ? [...allowedExceptionListTypes, ExceptionListTypeEnum.ENDPOINT] : allowedExceptionListTypes, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx index 3cc874b85ecf3..13855a4b81494 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable react-hooks/rules-of-hooks */ - import { EuiButton, EuiCallOut, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts index c1b4fa3e2b7d9..f862a06807e6f 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts @@ -6,7 +6,6 @@ import { isEmpty } from 'lodash/fp'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ChromeBreadcrumb } from '../../../../../../../../src/core/public'; import { getDetectionEngineTabUrl, diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/utils.ts b/x-pack/plugins/security_solution/public/hosts/pages/details/utils.ts index 5c5c7283eee47..9a24c61ae103d 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/utils.ts +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/utils.ts @@ -6,7 +6,6 @@ import { get, isEmpty } from 'lodash/fp'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ChromeBreadcrumb } from '../../../../../../../src/core/public'; import { hostsModel } from '../../store'; import { HostsTableType } from '../../store/model'; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx index 109392cb7a929..6a0a0cbb1014e 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx @@ -82,6 +82,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { }, [details]); const [policyResponseUri, policyResponseRoutePath] = useMemo(() => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { selected_host, show, ...currentUrlParams } = queryParams; return [ formatUrl( @@ -189,7 +190,6 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { description: details.agent.version, }, ]; - // eslint-disable-next-line react-hooks/exhaustive-deps }, [details.agent.version, details.host.hostname, details.host.ip]); return ( diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index 3e00a5cc33db1..bb6003f73714d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -313,6 +313,7 @@ describe('when on the hosts page', () => { beforeEach(async () => { const { + // eslint-disable-next-line @typescript-eslint/naming-convention host_status, metadata: { host, ...details }, } = mockHostDetailsApiResult(); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx index f91bba3e3125a..cdea4bfcf9f86 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx @@ -259,7 +259,6 @@ export const HostList = () => { name: i18n.translate('xpack.securitySolution.endpointList.policyStatus', { defaultMessage: 'Configuration Status', }), - // eslint-disable-next-line react/display-name render: (policy: HostInfo['metadata']['Endpoint']['policy']['applied'], item: HostInfo) => { const toRoutePath = getHostDetailsPath({ name: 'hostPolicyResponse', diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts b/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts index 7c67dffb8a663..4d32a9fbec694 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts @@ -48,12 +48,12 @@ export function clone(policyDetailsConfig: UIPolicyConfig): UIPolicyConfig { * Returns value from `configuration` */ export const getIn = (a: UIPolicyConfig) => (key: Key) => < - subKey extends keyof UIPolicyConfig[Key] + SubKey extends keyof UIPolicyConfig[Key] >( - subKey: subKey -) => ( + subKey: SubKey +) => ( leafKey: LeafKey -): UIPolicyConfig[Key][subKey][LeafKey] => { +): UIPolicyConfig[Key][SubKey][LeafKey] => { return a[key][subKey][leafKey]; }; @@ -61,11 +61,11 @@ export const getIn = (a: UIPolicyConfig) => (k * Returns cloned `configuration` with `value` set by the `keyPath`. */ export const setIn = (a: UIPolicyConfig) => (key: Key) => < - subKey extends keyof UIPolicyConfig[Key] + SubKey extends keyof UIPolicyConfig[Key] >( - subKey: subKey -) => (leafKey: LeafKey) => < - V extends UIPolicyConfig[Key][subKey][LeafKey] + subKey: SubKey +) => (leafKey: LeafKey) => < + V extends UIPolicyConfig[Key][SubKey][LeafKey] >( v: V ): UIPolicyConfig => { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors.ts index cce0adf36bcce..d780828fc8833 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors.ts @@ -29,6 +29,7 @@ export const policyDetails = (state: Immutable) => state.pol export const getPolicyDataForUpdate = ( policy: PolicyData | Immutable ): NewPolicyData | Immutable => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { id, revision, created_by, created_at, updated_by, updated_at, ...newPolicy } = policy; return newPolicy; }; diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/utils.ts b/x-pack/plugins/security_solution/public/network/pages/ip_details/utils.ts index 640b9d9818cdd..9284a808625a5 100644 --- a/x-pack/plugins/security_solution/public/network/pages/ip_details/utils.ts +++ b/x-pack/plugins/security_solution/public/network/pages/ip_details/utils.ts @@ -6,7 +6,6 @@ import { get, isEmpty } from 'lodash/fp'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ChromeBreadcrumb } from '../../../../../../../src/core/public'; import { decodeIpv6 } from '../../../common/lib/helpers'; import { getIPDetailsUrl } from '../../../common/components/link_to/redirect_to_network'; diff --git a/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx index f7f1fbc30aeb7..a35d85d1321f5 100644 --- a/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable react/display-name */ - import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json'; import { mount, ReactWrapper } from 'enzyme'; import React from 'react'; diff --git a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts index 628d0267754f2..060a014b8730f 100644 --- a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts +++ b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable no-shadow */ - import { uniquePidForProcess, uniqueParentPidForProcess, orderByTime } from '../process_event'; import { IndexedProcessTree } from '../../types'; import { ResolverEvent } from '../../../../common/endpoint/types'; diff --git a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts index 10ace895b3267..272d0aae7eef4 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts @@ -486,12 +486,7 @@ export const ariaFlowtoCandidate: ( const spatiallyIndexedLayout: (state: DataState) => rbush = createSelector( layout, - function ({ - /* eslint-disable no-shadow */ - processNodePositions, - edgeLineSegments, - /* eslint-enable no-shadow */ - }) { + function ({ processNodePositions, edgeLineSegments }) { const spatialIndex: rbush = new rbush(); const processesToIndex: IndexedProcessNode[] = []; const edgeLineSegmentsToIndex: IndexedEdgeLineSegment[] = []; diff --git a/x-pack/plugins/security_solution/public/resolver/store/middleware/resolver_tree_fetcher.ts b/x-pack/plugins/security_solution/public/resolver/store/middleware/resolver_tree_fetcher.ts index 2c98059d420e8..0ec340efbdac9 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/middleware/resolver_tree_fetcher.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/middleware/resolver_tree_fetcher.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable no-duplicate-imports */ - import { Dispatch, MiddlewareAPI } from 'redux'; import { ResolverTree, ResolverEntityIndex } from '../../../../common/endpoint/types'; diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/mock_resolver.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/mock_resolver.tsx index 36bb2a5ffc9fe..7de7cf48e6039 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/mock_resolver.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/mock_resolver.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable no-duplicate-imports */ /* eslint-disable react/display-name */ import React, { useMemo, useEffect, useState, useCallback } from 'react'; diff --git a/x-pack/plugins/security_solution/public/resolver/types.ts b/x-pack/plugins/security_solution/public/resolver/types.ts index 38e0cd0483559..c2871fdceb20a 100644 --- a/x-pack/plugins/security_solution/public/resolver/types.ts +++ b/x-pack/plugins/security_solution/public/resolver/types.ts @@ -245,14 +245,14 @@ export type Matrix3 = readonly [ number ]; -type eventSubtypeFull = +type EventSubtypeFull = | 'creation_event' | 'fork_event' | 'exec_event' | 'already_running' | 'termination_event'; -type eventTypeFull = 'process_event'; +type EventTypeFull = 'process_event'; /** * The 'events' which contain process data and are used to model Resolver. @@ -263,8 +263,8 @@ export interface ProcessEvent { readonly machine_id: string; readonly data_buffer: { timestamp_utc: string; - event_subtype_full: eventSubtypeFull; - event_type_full: eventTypeFull; + event_subtype_full: EventSubtypeFull; + event_type_full: EventTypeFull; node_id: number; source_id?: number; process_name: string; diff --git a/x-pack/plugins/security_solution/public/resolver/view/map.tsx b/x-pack/plugins/security_solution/public/resolver/view/map.tsx index 0ca71c5bf60ce..a965f06c04926 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/map.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/map.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable no-duplicate-imports */ - /* eslint-disable react/display-name */ import React, { useContext } from 'react'; diff --git a/x-pack/plugins/security_solution/public/resolver/view/resolver_without_providers.tsx b/x-pack/plugins/security_solution/public/resolver/view/resolver_without_providers.tsx index f444d5a25e1ef..e74502243ffc8 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/resolver_without_providers.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/resolver_without_providers.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable no-duplicate-imports */ - /* eslint-disable react/display-name */ import React, { useContext, useCallback } from 'react'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx index 3384165392dc8..a0678fb4a437a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx @@ -114,7 +114,7 @@ const AddressLinksComponent: React.FC<{ fieldName, address, })}`} - render={(_, __, snapshot) => + render={(_props, _provided, snapshot) => snapshot.isDragging ? ( ({ fetchPolicy: 'no-cache', variables: { id: timelineId }, }) - // eslint-disable-next-line .then((result) => { const timelineToOpen: TimelineResult = omitTypenameInTimeline( getOr({}, 'data.getOneTimeline', result) diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.tsx index aa4bb3f1e0467..b0e1eab25e7c7 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable react/display-name */ - import { ActionTimelineToShow, DeleteTimelines, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts index c79bcda71de9b..bcac559d61f79 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts @@ -87,6 +87,7 @@ export function handleEntities(): RequestHandler 0 && newPackageConfig.inputs[0].config !== undefined) { const oldManifest = newPackageConfig.inputs[0].config.artifact_manifest ?? { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts index 5f62ff426ecd0..3ab4775f890ac 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts @@ -28,13 +28,13 @@ export const querySignalsRoute = (router: IRouter) => { }, }, async (context, request, response) => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { query, aggs, _source, track_total_hits, size } = request.body; const siemResponse = buildSiemResponse(response); if ( query == null && aggs == null && _source == null && - // eslint-disable-next-line @typescript-eslint/camelcase track_total_hits == null && size == null ) { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts index c36f6ca831c57..f469aa8634c5a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts @@ -26,6 +26,7 @@ export const getRuleActionsSavedObject = async ({ ruleAlertId, savedObjectsClient, }: GetRuleActionsSavedObject): Promise => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { saved_objects } = await savedObjectsClient.find< IRuleActionsAttributesSavedObjectAttributes >({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.ts index e2f3d16bd6d03..bdcddbf2ed21b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.ts @@ -134,6 +134,7 @@ const getTransformedHits = ( } return results.aggregations.threshold.buckets.map( + // eslint-disable-next-line @typescript-eslint/naming-convention ({ key, doc_count }: { key: string; doc_count: number }) => { const source = { '@timestamp': new Date().toISOString(), diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts index bfc72a169566e..dd0698b8d1124 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts @@ -12,6 +12,7 @@ import { RuleTypeParams } from '../types'; import { SearchResponse } from '../../types'; // used for gap detection code +// eslint-disable-next-line @typescript-eslint/naming-convention export type unitType = 's' | 'm' | 'h'; export const isValidUnit = (unitParam: string): unitParam is unitType => ['s', 'm', 'h'].includes(unitParam); diff --git a/x-pack/plugins/security_solution/server/lib/framework/types.ts b/x-pack/plugins/security_solution/server/lib/framework/types.ts index 03c82ceb02e68..68b40b72866b1 100644 --- a/x-pack/plugins/security_solution/server/lib/framework/types.ts +++ b/x-pack/plugins/security_solution/server/lib/framework/types.ts @@ -40,7 +40,7 @@ export interface FrameworkAdapter { callWithRequest( req: FrameworkRequest, method: 'indices.getMapping', - options?: IndicesGetMappingParams // eslint-disable-line + options?: IndicesGetMappingParams ): Promise; getIndexPatternsService(req: FrameworkRequest): FrameworkIndexPatternsService; } diff --git a/x-pack/plugins/security_solution/server/lib/matrix_histogram/utils.ts b/x-pack/plugins/security_solution/server/lib/matrix_histogram/utils.ts index 67568b96fee90..4a6a38421f42a 100644 --- a/x-pack/plugins/security_solution/server/lib/matrix_histogram/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/matrix_histogram/utils.ts @@ -16,6 +16,7 @@ export const getDnsParsedData = ( data.forEach((bucketData: unknown) => { const time = get('key', bucketData); const histData = getOr([], keyBucket, bucketData).map( + // eslint-disable-next-line @typescript-eslint/naming-convention ({ key, doc_count }: DnsHistogramSubBucket) => ({ x: time, y: doc_count, @@ -35,6 +36,7 @@ export const getGenericData = ( data.forEach((bucketData: unknown) => { const group = get('key', bucketData); const histData = getOr([], keyBucket, bucketData).map( + // eslint-disable-next-line @typescript-eslint/naming-convention ({ key, doc_count }: HistogramBucket) => ({ x: key, y: doc_count, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/create_timelines.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/create_timelines.ts index 6bdecb5d80ecc..dc0caaf67d738 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/create_timelines.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/create_timelines.ts @@ -191,7 +191,6 @@ export const getTemplateTimeline = async ( frameworkRequest, templateTimelineId ); - // eslint-disable-next-line no-empty } catch (e) { return null; } diff --git a/x-pack/plugins/security_solution/server/lib/tls/elasticsearch_adapter.ts b/x-pack/plugins/security_solution/server/lib/tls/elasticsearch_adapter.ts index 10929c3d03641..ab9175951a8f5 100644 --- a/x-pack/plugins/security_solution/server/lib/tls/elasticsearch_adapter.ts +++ b/x-pack/plugins/security_solution/server/lib/tls/elasticsearch_adapter.ts @@ -69,7 +69,7 @@ export const formatTlsEdges = (buckets: TlsBuckets[]): TlsEdges[] => { subjects: bucket.subjects.buckets.map(({ key }) => key), ja3: bucket.ja3.buckets.map(({ key }) => key), issuers: bucket.issuers.buckets.map(({ key }) => key), - // eslint-disable-next-line @typescript-eslint/camelcase + // eslint-disable-next-line @typescript-eslint/naming-convention notAfter: bucket.not_after.buckets.map(({ key_as_string }) => key_as_string), }, cursor: { diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/home.helpers.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/home.helpers.ts index bff66b7068145..917c41b998dec 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/home.helpers.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/home.helpers.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import { act } from 'react-dom/test-utils'; import { diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_add.helpers.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_add.helpers.ts index bdc2f76224361..e8528889eb231 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_add.helpers.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_add.helpers.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import { registerTestBed, TestBedConfig } from '../../../../../test_utils'; import { PolicyAdd } from '../../../public/application/sections/policy_add'; diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_edit.helpers.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_edit.helpers.ts index ca53f9306445e..f009afbb2eacc 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_edit.helpers.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_edit.helpers.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import { registerTestBed, TestBedConfig } from '../../../../../test_utils'; import { PolicyEdit } from '../../../public/application/sections/policy_edit'; diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_add.helpers.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_add.helpers.ts index 2f7c47dbf544c..fa4421988740b 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_add.helpers.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_add.helpers.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import { registerTestBed, TestBed } from '../../../../../test_utils'; import { RepositoryType } from '../../../common/types'; diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_edit.helpers.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_edit.helpers.ts index 4127fd0546580..043b21270cc8d 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_edit.helpers.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/repository_edit.helpers.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import { registerTestBed, TestBedConfig } from '../../../../../test_utils'; import { RepositoryEdit } from '../../../public/application/sections/repository_edit'; diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/restore_snapshot.helpers.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/restore_snapshot.helpers.ts index 0cfb6fbc97975..cfe3027b6d43f 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/restore_snapshot.helpers.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/restore_snapshot.helpers.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import { registerTestBed, TestBed, TestBedConfig } from '../../../../../test_utils'; import { RestoreSnapshot } from '../../../public/application/sections/restore_snapshot'; import { WithAppDependencies } from './setup_environment'; diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/setup_environment.tsx index 2cfffb3572dde..c7ee0648b5c3b 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/setup_environment.tsx @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import React from 'react'; import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_table/policy_table.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_table/policy_table.tsx index 5f0a208348785..d55bbf0b324cf 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_table/policy_table.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_table/policy_table.tsx @@ -64,7 +64,6 @@ export const PolicyTable: React.FunctionComponent = ({ return ( - {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} uiMetricService.trackUiMetric(UIM_POLICY_SHOW_DETAILS_CLICK) diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/repository_list/repository_table/repository_table.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/repository_list/repository_table/repository_table.tsx index 70d83846cd74e..d435ff4524ea2 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/repository_list/repository_table/repository_table.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/repository_list/repository_table/repository_table.tsx @@ -55,7 +55,6 @@ export const RepositoryTable: React.FunctionComponent = ({ render: (name: Repository['name']) => { return ( - {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} uiMetricService.trackUiMetric(UIM_REPOSITORY_SHOW_DETAILS_CLICK) diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/snapshot_list/snapshot_table/snapshot_table.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/snapshot_list/snapshot_table/snapshot_table.tsx index 4910bf909ce3a..46bd5bab53d2b 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/snapshot_list/snapshot_table/snapshot_table.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/snapshot_list/snapshot_table/snapshot_table.tsx @@ -74,7 +74,6 @@ export const SnapshotTable: React.FunctionComponent = ({ truncateText: true, sortable: true, render: (snapshotId: string, snapshot: SnapshotDetails) => ( - /* eslint-disable-next-line @elastic/eui/href-or-on-click */ { - const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/camelcase + const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/naming-convention if (reason) { accumulator.push(reason); } - // eslint-disable-next-line @typescript-eslint/camelcase if (caused_by) { return extractCausedByChain(caused_by, accumulator); } @@ -31,8 +30,8 @@ export const wrapEsError = (err: any, statusCodeToMessageMap: any = {}) => { const { error: { - root_cause = [], // eslint-disable-line @typescript-eslint/camelcase - caused_by = {}, // eslint-disable-line @typescript-eslint/camelcase + root_cause = [], // eslint-disable-line @typescript-eslint/naming-convention + caused_by = {}, // eslint-disable-line @typescript-eslint/naming-convention } = {}, } = JSON.parse(response); diff --git a/x-pack/plugins/snapshot_restore/test/fixtures/policy.ts b/x-pack/plugins/snapshot_restore/test/fixtures/policy.ts index 435ae27e8dd46..a293f505147e4 100644 --- a/x-pack/plugins/snapshot_restore/test/fixtures/policy.ts +++ b/x-pack/plugins/snapshot_restore/test/fixtures/policy.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ import { getRandomString, getRandomNumber } from '../../../../test_utils'; import { SlmPolicy } from '../../common/types'; diff --git a/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.ts b/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.ts index b4b0057a2f5a5..dd2e0d40f31ed 100644 --- a/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.ts +++ b/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.ts @@ -66,6 +66,7 @@ export class SpacesClient { if (this.useRbac()) { const privilegeFactory = PURPOSE_PRIVILEGE_MAP[purpose]; + // eslint-disable-next-line @typescript-eslint/naming-convention const { saved_objects } = await this.internalSavedObjectRepository.find({ type: 'space', page: 1, @@ -111,6 +112,7 @@ export class SpacesClient { } else { this.debugLogger(`SpacesClient.getAll(), NOT USING RBAC. querying all spaces`); + // eslint-disable-next-line @typescript-eslint/naming-convention const { saved_objects } = await this.callWithRequestSavedObjectRepository.find({ type: 'space', page: 1, diff --git a/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts b/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts index 4ab309cc6015c..3ea4693d9e9d7 100644 --- a/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts +++ b/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts @@ -92,6 +92,7 @@ async function getSpacesUsage( ); const disabledFeatures: Record = disabledFeatureBuckets.reduce( + // eslint-disable-next-line @typescript-eslint/naming-convention (acc, { key, doc_count }) => { return { ...acc, diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index 7ec3db5c99aa7..cac37db72202d 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -443,6 +443,7 @@ export class TaskStore { private async updateByQuery( opts: UpdateByQuerySearchOpts = {}, + // eslint-disable-next-line @typescript-eslint/naming-convention { max_docs }: UpdateByQueryOpts = {} ): Promise { const { query } = ensureQueryOnlyReturnsTaskObjects(opts); @@ -458,6 +459,7 @@ export class TaskStore { }, }); + // eslint-disable-next-line @typescript-eslint/naming-convention const { total, updated, version_conflicts } = result as UpdateDocumentByQueryResponse; return { total, diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx index f3e96736e40fc..50064274cf98e 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx @@ -103,7 +103,6 @@ export const PopoverForm: React.FC = ({ defaultData, otherAggNames, onCha setAggName(name); } } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [aggConfigDef]); const availableFields: EuiSelectOption[] = []; diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/group_by_list/popover_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/group_by_list/popover_form.tsx index ba1bf915afd19..0452638e90dfb 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/group_by_list/popover_form.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/group_by_list/popover_form.tsx @@ -37,7 +37,7 @@ import { } from '../../../../common'; export function isIntervalValid( - interval: optionalInterval, + interval: OptionalInterval, intervalType: PivotSupportedGroupByAggsWithInterval ) { if (interval !== '' && interval !== undefined) { @@ -73,7 +73,7 @@ interface SelectOption { text: string; } -type optionalInterval = string | undefined; +type OptionalInterval = string | undefined; function getDefaultInterval(defaultData: PivotGroupByConfig): string | undefined { if (isGroupByDateHistogram(defaultData)) { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx index ee19b6124da05..009f582424765 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx @@ -65,6 +65,7 @@ type PromptErrorProps = Pick & { }; const TlsAndEncryptionError = ({ + // eslint-disable-next-line @typescript-eslint/naming-convention docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, className, }: PromptErrorProps) => ( @@ -107,6 +108,7 @@ const TlsAndEncryptionError = ({ ); const EncryptionError = ({ + // eslint-disable-next-line @typescript-eslint/naming-convention docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, className, }: PromptErrorProps) => ( @@ -158,6 +160,7 @@ const EncryptionError = ({ ); const TlsError = ({ + // eslint-disable-next-line @typescript-eslint/naming-convention docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, className, }: PromptErrorProps) => ( diff --git a/x-pack/plugins/ui_actions_enhanced/public/custom_time_range_action.test.ts b/x-pack/plugins/ui_actions_enhanced/public/custom_time_range_action.test.ts index 0d6e9743f0f4b..440bbd4242fa5 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/custom_time_range_action.test.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/custom_time_range_action.test.ts @@ -12,9 +12,7 @@ import { mount } from 'enzyme'; import { TimeRangeEmbeddable, TimeRangeContainer, TIME_RANGE_EMBEDDABLE } from './test_helpers'; import { CustomTimeRangeAction } from './custom_time_range_action'; -/* eslint-disable */ import { HelloWorldContainer } from '../../../../src/plugins/embeddable/public/lib/test_samples'; -/* eslint-enable */ import { HelloWorldEmbeddable, diff --git a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx index cd8452ff74ab4..0b0339a625c50 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx @@ -8,11 +8,7 @@ import * as React from 'react'; import { EuiFlyout } from '@elastic/eui'; import { storiesOf } from '@storybook/react'; import { createFlyoutManageDrilldowns } from './connected_flyout_manage_drilldowns'; -import { - dashboardFactory, - urlFactory, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../components/action_wizard/test_data'; +import { dashboardFactory, urlFactory } from '../../../components/action_wizard/test_data'; import { Storage } from '../../../../../../../src/plugins/kibana_utils/public'; import { StubBrowserStorage } from '../../../../../../../src/test_utils/public/stub_browser_storage'; import { mockDynamicActionManager } from './test_data'; diff --git a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx index 2069a83ab8ba0..01e2a457889ca 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx @@ -4,17 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable no-console */ - import * as React from 'react'; import { EuiFlyout } from '@elastic/eui'; import { storiesOf } from '@storybook/react'; import { FlyoutDrilldownWizard } from './index'; -import { - dashboardFactory, - urlFactory, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../components/action_wizard/test_data'; +import { dashboardFactory, urlFactory } from '../../../components/action_wizard/test_data'; import { ActionFactory } from '../../../dynamic_actions'; storiesOf('components/FlyoutDrilldownWizard', module) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx index be4138b7a29f3..8f318e8113ea1 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx @@ -43,6 +43,7 @@ interface ReindexFlyoutState { currentFlyoutStep: ReindexFlyoutStep; } +// eslint-disable-next-line @typescript-eslint/naming-convention const getOpenAndCloseIndexDocLink = ({ ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }: DocLinksStart) => ( = ({ idx, }) => { const titleClassName = classNames('upgStepProgress__title', { + // eslint-disable-next-line @typescript-eslint/naming-convention 'upgStepProgress__title--currentStep': status === 'inProgress' || status === 'paused' || diff --git a/x-pack/plugins/uptime/server/lib/alerts/status_check.ts b/x-pack/plugins/uptime/server/lib/alerts/status_check.ts index a34d7eb292eef..8ca2e857a52c9 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/status_check.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/status_check.ts @@ -36,6 +36,7 @@ const { MONITOR_STATUS } = ACTION_GROUP_DEFINITIONS; * @param items to reduce */ export const uniqueMonitorIds = (items: GetMonitorStatusResult[]): Set => + // eslint-disable-next-line @typescript-eslint/naming-convention items.reduce((acc, { monitor_id }) => { acc.add(monitor_id); return acc; diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts index 1783cb3c28522..f12f1527fb56c 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts @@ -27,9 +27,11 @@ interface BucketItem { } const genBucketItem = ({ + // eslint-disable-next-line @typescript-eslint/naming-convention monitor_id, status, location, + // eslint-disable-next-line @typescript-eslint/naming-convention doc_count, }: BucketItemCriteria): BucketItem => ({ key: { diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/helper.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/helper.ts index 0eb46e17c6324..878569b5d390f 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/helper.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/helper.ts @@ -33,6 +33,7 @@ export const setupMockEsCompositeQuery = ( ): [MockCallES, jest.Mocked>] => { const esMock = elasticsearchServiceMock.createLegacyScopedClusterClient(); + // eslint-disable-next-line @typescript-eslint/naming-convention criteria.forEach(({ after_key, bucketCriteria }) => { const mockResponse = { aggregations: { diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.ts index eafc0df431f77..798cefc404e1f 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.ts @@ -23,6 +23,7 @@ export interface GetMonitorAvailabilityResult { } export const formatBuckets = async (buckets: any[]): Promise => + // eslint-disable-next-line @typescript-eslint/naming-convention buckets.map(({ key, fields, up_sum, down_sum, ratio }: any) => ({ ...key, name: fields?.hits?.hits?.[0]?._source?.monitor.name, diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts index 17d79002e6f7d..f52e965d488ea 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts @@ -115,6 +115,7 @@ export const getMonitorLocations: UMElasticsearchQueryFn< let totalDowns = 0; const monLocs: MonitorLocation[] = []; + // eslint-disable-next-line @typescript-eslint/naming-convention locations.forEach(({ most_recent: mostRecent, up_history, down_history }: any) => { const mostRecentLocation = mostRecent.hits.hits[0]._source; totalUps += up_history.value; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts index 33f18b7a94069..a52bbfc8f2442 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts @@ -32,7 +32,7 @@ const formatBuckets = async ( ): Promise => { return buckets .filter((monitor: any) => monitor?.doc_count > numTimes) - .map(({ key, doc_count }: any) => ({ ...key, count: doc_count })); + .map(({ key, doc_count: count }: any) => ({ ...key, count })); }; const getLocationClause = (locations: string[]) => ({ diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/app_context.mock.tsx b/x-pack/plugins/watcher/__jest__/client_integration/helpers/app_context.mock.tsx index 3db3cf5c66011..7caa8b8bc0859 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/app_context.mock.tsx +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/app_context.mock.tsx @@ -15,7 +15,6 @@ import { httpServiceMock, scopedHistoryMock, } from '../../../../../../src/core/public/mocks'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AppContextProvider } from '../../../public/application/app_context'; import { LicenseStatus } from '../../../common/types/license_status'; diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/setup_environment.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/setup_environment.ts index 2fc8d430208f6..3cac3eb40d894 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/setup_environment.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/setup_environment.ts @@ -7,7 +7,6 @@ import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; import { init as initHttpRequests } from './http_requests'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { setHttpClient, setSavedObjectsClient } from '../../../public/application/lib/api'; const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_json.helpers.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_json.helpers.ts index 19217729aafd6..caef4b378cf0a 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_json.helpers.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_json.helpers.ts @@ -5,9 +5,7 @@ */ import { withAppContext } from './app_context.mock'; import { registerTestBed, TestBed, TestBedConfig } from '../../../../../test_utils'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { WatchEdit } from '../../../public/application/sections/watch_edit/components/watch_edit'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { registerRouter } from '../../../public/application/lib/navigation'; import { ROUTES, WATCH_TYPES } from '../../../common/constants'; diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_threshold.helpers.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_threshold.helpers.ts index 54ba39ee7eaa6..c76f31e744f8d 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_threshold.helpers.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_threshold.helpers.ts @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { registerTestBed, TestBed, TestBedConfig } from '../../../../../test_utils'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { WatchEdit } from '../../../public/application/sections/watch_edit/components/watch_edit'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { registerRouter } from '../../../public/application/lib/navigation'; import { ROUTES, WATCH_TYPES } from '../../../common/constants'; import { withAppContext } from './app_context.mock'; diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_edit.helpers.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_edit.helpers.ts index 290204d1878ea..5e6dbd0a40bfb 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_edit.helpers.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_edit.helpers.ts @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { registerTestBed, TestBed, TestBedConfig } from '../../../../../test_utils'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { WatchEdit } from '../../../public/application/sections/watch_edit/components/watch_edit'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { registerRouter } from '../../../public/application/lib/navigation'; import { ROUTES } from '../../../common/constants'; import { WATCH_ID } from './constants'; diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_list.helpers.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_list.helpers.ts index b5cf3df9509fc..e511dcdc58606 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_list.helpers.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_list.helpers.ts @@ -13,7 +13,6 @@ import { TestBedConfig, nextTick, } from '../../../../../test_utils'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { WatchList } from '../../../public/application/sections/watch_list/components/watch_list'; import { ROUTES } from '../../../common/constants'; import { withAppContext } from './app_context.mock'; diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_status.helpers.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_status.helpers.ts index e116c1bde3677..b869e55aa3464 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_status.helpers.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_status.helpers.ts @@ -13,7 +13,6 @@ import { TestBedConfig, nextTick, } from '../../../../../test_utils'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { WatchStatus } from '../../../public/application/sections/watch_status/components/watch_status'; import { ROUTES } from '../../../common/constants'; import { WATCH_ID } from './constants'; diff --git a/x-pack/plugins/watcher/public/application/app_context.tsx b/x-pack/plugins/watcher/public/application/app_context.tsx index e5cf4c33b477a..e8546a1517097 100644 --- a/x-pack/plugins/watcher/public/application/app_context.tsx +++ b/x-pack/plugins/watcher/public/application/app_context.tsx @@ -15,6 +15,7 @@ interface ContextValue extends Omit { const AppContext = createContext(null as any); +// eslint-disable-next-line @typescript-eslint/naming-convention const generateDocLinks = ({ ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }: DocLinksStart) => { const elasticDocLinkBase = `${ELASTIC_WEBSITE_URL}guide/en/`; const esBase = `${elasticDocLinkBase}elasticsearch/reference/${DOC_LINK_VERSION}`; diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index 946b3d2f2591b..4947cdbf55484 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -36,7 +36,6 @@ const enabledActionTypes = [ 'test.throw', ]; -// eslint-disable-next-line import/no-default-export export function createTestConfig(name: string, options: CreateTestConfigOptions) { const { license = 'trial', disabledPlugins = [], ssl = false } = options; diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts_base.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts_base.ts index 8ffe65a8ebb48..b94a547452377 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts_base.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts_base.ts @@ -19,7 +19,6 @@ import { TaskManagerUtils, } from '../../../common/lib'; -// eslint-disable-next-line import/no-default-export export function alertTests({ getService }: FtrProviderContext, space: Space) { const supertestWithoutAuth = getService('supertestWithoutAuth'); const es = getService('legacyEs'); diff --git a/x-pack/test/api_integration/apis/lens/existing_fields.ts b/x-pack/test/api_integration/apis/lens/existing_fields.ts index b3810cf468b55..92336f2892f43 100644 --- a/x-pack/test/api_integration/apis/lens/existing_fields.ts +++ b/x-pack/test/api_integration/apis/lens/existing_fields.ts @@ -129,7 +129,6 @@ const metricBeatData = [ 'system.cpu.user.pct', ]; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/lens/field_stats.ts b/x-pack/test/api_integration/apis/lens/field_stats.ts index 2d394e35725c2..87c9d97be9b60 100644 --- a/x-pack/test/api_integration/apis/lens/field_stats.ts +++ b/x-pack/test/api_integration/apis/lens/field_stats.ts @@ -14,7 +14,6 @@ const COMMON_HEADERS = { 'kbn-xsrf': 'some-xsrf-token', }; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/lens/telemetry.ts b/x-pack/test/api_integration/apis/lens/telemetry.ts index bd6144a2690b0..2c05b02cf470f 100644 --- a/x-pack/test/api_integration/apis/lens/telemetry.ts +++ b/x-pack/test/api_integration/apis/lens/telemetry.ts @@ -18,7 +18,6 @@ const COMMON_HEADERS = { 'kbn-xsrf': 'some-xsrf-token', }; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); const es: Client = getService('legacyEs'); diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_analysis.ts b/x-pack/test/api_integration/apis/metrics_ui/log_analysis.ts index 7bcea4c17cdcd..e40a9f77e2c18 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/log_analysis.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/log_analysis.ts @@ -23,7 +23,6 @@ const COMMON_HEADERS = { 'kbn-xsrf': 'some-xsrf-token', }; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/ml/annotations/create_annotations.ts b/x-pack/test/api_integration/apis/ml/annotations/create_annotations.ts index 14ecf1bfe524e..aff1150997496 100644 --- a/x-pack/test/api_integration/apis/ml/annotations/create_annotations.ts +++ b/x-pack/test/api_integration/apis/ml/annotations/create_annotations.ts @@ -11,7 +11,6 @@ import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/commo import { USER } from '../../../../functional/services/ml/security_common'; import { Annotation } from '../../../../../plugins/ml/common/types/annotations'; import { createJobConfig, createAnnotationRequestBody } from './common_jobs'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/annotations/delete_annotations.ts b/x-pack/test/api_integration/apis/ml/annotations/delete_annotations.ts index 4fbb26e9b5a3e..d3451c4d7da0c 100644 --- a/x-pack/test/api_integration/apis/ml/annotations/delete_annotations.ts +++ b/x-pack/test/api_integration/apis/ml/annotations/delete_annotations.ts @@ -10,7 +10,6 @@ import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/commo import { USER } from '../../../../functional/services/ml/security_common'; import { testSetupJobConfigs, jobIds, testSetupAnnotations } from './common_jobs'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/annotations/get_annotations.ts b/x-pack/test/api_integration/apis/ml/annotations/get_annotations.ts index 710473eed6901..29ad905bd3f2d 100644 --- a/x-pack/test/api_integration/apis/ml/annotations/get_annotations.ts +++ b/x-pack/test/api_integration/apis/ml/annotations/get_annotations.ts @@ -11,7 +11,6 @@ import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/commo import { USER } from '../../../../functional/services/ml/security_common'; import { testSetupJobConfigs, jobIds, testSetupAnnotations } from './common_jobs'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/annotations/update_annotations.ts b/x-pack/test/api_integration/apis/ml/annotations/update_annotations.ts index ba73617151120..bcfb7ab0825b8 100644 --- a/x-pack/test/api_integration/apis/ml/annotations/update_annotations.ts +++ b/x-pack/test/api_integration/apis/ml/annotations/update_annotations.ts @@ -12,7 +12,6 @@ import { ANNOTATION_TYPE } from '../../../../../plugins/ml/common/constants/anno import { Annotation } from '../../../../../plugins/ml/common/types/annotations'; import { testSetupJobConfigs, jobIds, testSetupAnnotations } from './common_jobs'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/anomaly_detectors/create.ts b/x-pack/test/api_integration/apis/ml/anomaly_detectors/create.ts index 9c2b1046cc124..71703ed019dc5 100644 --- a/x-pack/test/api_integration/apis/ml/anomaly_detectors/create.ts +++ b/x-pack/test/api_integration/apis/ml/anomaly_detectors/create.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/calendars/create_calendars.ts b/x-pack/test/api_integration/apis/ml/calendars/create_calendars.ts index f163df0109ffd..82f4eee8cc328 100644 --- a/x-pack/test/api_integration/apis/ml/calendars/create_calendars.ts +++ b/x-pack/test/api_integration/apis/ml/calendars/create_calendars.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); const ml = getService('ml'); diff --git a/x-pack/test/api_integration/apis/ml/calendars/delete_calendars.ts b/x-pack/test/api_integration/apis/ml/calendars/delete_calendars.ts index 5c5d5a3c432fa..eef8479b811b4 100644 --- a/x-pack/test/api_integration/apis/ml/calendars/delete_calendars.ts +++ b/x-pack/test/api_integration/apis/ml/calendars/delete_calendars.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); const ml = getService('ml'); diff --git a/x-pack/test/api_integration/apis/ml/calendars/get_calendars.ts b/x-pack/test/api_integration/apis/ml/calendars/get_calendars.ts index e115986b2f092..0b4f4a8f73ede 100644 --- a/x-pack/test/api_integration/apis/ml/calendars/get_calendars.ts +++ b/x-pack/test/api_integration/apis/ml/calendars/get_calendars.ts @@ -9,7 +9,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); const ml = getService('ml'); diff --git a/x-pack/test/api_integration/apis/ml/calendars/update_calendars.ts b/x-pack/test/api_integration/apis/ml/calendars/update_calendars.ts index 5194370b19e66..65832ac9ca81e 100644 --- a/x-pack/test/api_integration/apis/ml/calendars/update_calendars.ts +++ b/x-pack/test/api_integration/apis/ml/calendars/update_calendars.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); const ml = getService('ml'); diff --git a/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_histograms.ts b/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_histograms.ts index 8b21c367d29f6..1a71894f8423d 100644 --- a/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_histograms.ts +++ b/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_histograms.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts b/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts index 92776e297f1a2..5373da6a794c7 100644 --- a/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts +++ b/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/data_visualizer/get_overall_stats.ts b/x-pack/test/api_integration/apis/ml/data_visualizer/get_overall_stats.ts index c6acf37cb9b3a..d87ab16d71c18 100644 --- a/x-pack/test/api_integration/apis/ml/data_visualizer/get_overall_stats.ts +++ b/x-pack/test/api_integration/apis/ml/data_visualizer/get_overall_stats.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/fields_service/field_cardinality.ts b/x-pack/test/api_integration/apis/ml/fields_service/field_cardinality.ts index 647874c1cd5fb..ced4d937863ee 100644 --- a/x-pack/test/api_integration/apis/ml/fields_service/field_cardinality.ts +++ b/x-pack/test/api_integration/apis/ml/fields_service/field_cardinality.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/fields_service/time_field_range.ts b/x-pack/test/api_integration/apis/ml/fields_service/time_field_range.ts index 247bfe89fea1d..2128b1fe8d9e1 100644 --- a/x-pack/test/api_integration/apis/ml/fields_service/time_field_range.ts +++ b/x-pack/test/api_integration/apis/ml/fields_service/time_field_range.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/filters/create_filters.ts b/x-pack/test/api_integration/apis/ml/filters/create_filters.ts index c175d3a9a3d9c..233c95b190f02 100644 --- a/x-pack/test/api_integration/apis/ml/filters/create_filters.ts +++ b/x-pack/test/api_integration/apis/ml/filters/create_filters.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); const ml = getService('ml'); diff --git a/x-pack/test/api_integration/apis/ml/filters/delete_filters.ts b/x-pack/test/api_integration/apis/ml/filters/delete_filters.ts index bb83a7f720692..d0323360400be 100644 --- a/x-pack/test/api_integration/apis/ml/filters/delete_filters.ts +++ b/x-pack/test/api_integration/apis/ml/filters/delete_filters.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); const ml = getService('ml'); diff --git a/x-pack/test/api_integration/apis/ml/filters/get_filters.ts b/x-pack/test/api_integration/apis/ml/filters/get_filters.ts index 3dd6093a9917f..f0aa7aac7b9e4 100644 --- a/x-pack/test/api_integration/apis/ml/filters/get_filters.ts +++ b/x-pack/test/api_integration/apis/ml/filters/get_filters.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); const ml = getService('ml'); diff --git a/x-pack/test/api_integration/apis/ml/filters/update_filters.ts b/x-pack/test/api_integration/apis/ml/filters/update_filters.ts index eb58d545093c4..87eec99906c34 100644 --- a/x-pack/test/api_integration/apis/ml/filters/update_filters.ts +++ b/x-pack/test/api_integration/apis/ml/filters/update_filters.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); const ml = getService('ml'); diff --git a/x-pack/test/api_integration/apis/ml/job_validation/bucket_span_estimator.ts b/x-pack/test/api_integration/apis/ml/job_validation/bucket_span_estimator.ts index be03311303288..c556a6c28554b 100644 --- a/x-pack/test/api_integration/apis/ml/job_validation/bucket_span_estimator.ts +++ b/x-pack/test/api_integration/apis/ml/job_validation/bucket_span_estimator.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const esSupertest = getService('esSupertest'); diff --git a/x-pack/test/api_integration/apis/ml/job_validation/calculate_model_memory_limit.ts b/x-pack/test/api_integration/apis/ml/job_validation/calculate_model_memory_limit.ts index 076be816e0693..409bd161e601b 100644 --- a/x-pack/test/api_integration/apis/ml/job_validation/calculate_model_memory_limit.ts +++ b/x-pack/test/api_integration/apis/ml/job_validation/calculate_model_memory_limit.ts @@ -8,7 +8,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/job_validation/cardinality.ts b/x-pack/test/api_integration/apis/ml/job_validation/cardinality.ts index ca7b8c332ede3..ed61f234a671d 100644 --- a/x-pack/test/api_integration/apis/ml/job_validation/cardinality.ts +++ b/x-pack/test/api_integration/apis/ml/job_validation/cardinality.ts @@ -8,7 +8,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/job_validation/validate.ts b/x-pack/test/api_integration/apis/ml/job_validation/validate.ts index fc8f837744221..5e9b2d68bd6df 100644 --- a/x-pack/test/api_integration/apis/ml/job_validation/validate.ts +++ b/x-pack/test/api_integration/apis/ml/job_validation/validate.ts @@ -9,7 +9,6 @@ import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; import pkg from '../../../../../../package.json'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/jobs/categorization_field_examples.ts b/x-pack/test/api_integration/apis/ml/jobs/categorization_field_examples.ts index 8ae4beafa525a..b99a4965adb9d 100644 --- a/x-pack/test/api_integration/apis/ml/jobs/categorization_field_examples.ts +++ b/x-pack/test/api_integration/apis/ml/jobs/categorization_field_examples.ts @@ -72,7 +72,6 @@ const defaultRequestBody = { analyzer, }; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts b/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts index 2bf6c3f29468c..f411595aca995 100644 --- a/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts +++ b/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts @@ -12,7 +12,6 @@ import { USER } from '../../../../functional/services/ml/security_common'; import { JOB_STATE, DATAFEED_STATE } from '../../../../../plugins/ml/common/constants/states'; import { MULTI_METRIC_JOB_CONFIG, SINGLE_METRIC_JOB_CONFIG, DATAFEED_CONFIG } from './common_jobs'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/jobs/delete_jobs.ts b/x-pack/test/api_integration/apis/ml/jobs/delete_jobs.ts index b93d3bbce0cec..4976b6441c37a 100644 --- a/x-pack/test/api_integration/apis/ml/jobs/delete_jobs.ts +++ b/x-pack/test/api_integration/apis/ml/jobs/delete_jobs.ts @@ -11,7 +11,6 @@ import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/commo import { USER } from '../../../../functional/services/ml/security_common'; import { MULTI_METRIC_JOB_CONFIG, SINGLE_METRIC_JOB_CONFIG } from './common_jobs'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts b/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts index e9696eeffb6dc..0a6e1ed75020a 100644 --- a/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts +++ b/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts @@ -11,7 +11,6 @@ import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/commo import { USER } from '../../../../functional/services/ml/security_common'; import { MULTI_METRIC_JOB_CONFIG, SINGLE_METRIC_JOB_CONFIG } from './common_jobs'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/modules/get_module.ts b/x-pack/test/api_integration/apis/ml/modules/get_module.ts index cfb3c17ac7f21..e2a5d3cd425dc 100644 --- a/x-pack/test/api_integration/apis/ml/modules/get_module.ts +++ b/x-pack/test/api_integration/apis/ml/modules/get_module.ts @@ -32,7 +32,6 @@ const moduleIds = [ 'uptime_heartbeat', ]; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertestWithoutAuth'); const ml = getService('ml'); diff --git a/x-pack/test/api_integration/apis/ml/modules/recognize_module.ts b/x-pack/test/api_integration/apis/ml/modules/recognize_module.ts index d217a83efe948..6634c4e2ed16c 100644 --- a/x-pack/test/api_integration/apis/ml/modules/recognize_module.ts +++ b/x-pack/test/api_integration/apis/ml/modules/recognize_module.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts index 10c0f00234abc..6c3eda197f892 100644 --- a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts +++ b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts @@ -14,7 +14,6 @@ import { Job } from '../../../../../plugins/ml/common/types/anomaly_detection_jo import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/ml/results/get_anomalies_table_data.ts b/x-pack/test/api_integration/apis/ml/results/get_anomalies_table_data.ts index 01afacea645d6..f769d0d878cb2 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_anomalies_table_data.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_anomalies_table_data.ts @@ -9,7 +9,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { Datafeed, Job } from '../../../../../plugins/ml/common/types/anomaly_detection_jobs'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/transform/delete_transforms.ts b/x-pack/test/api_integration/apis/transform/delete_transforms.ts index 8e5d7354bcaf4..136bb85dd5ac2 100644 --- a/x-pack/test/api_integration/apis/transform/delete_transforms.ts +++ b/x-pack/test/api_integration/apis/transform/delete_transforms.ts @@ -15,7 +15,6 @@ async function asyncForEach(array: any[], callback: Function) { } } -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/case_api_integration/common/lib/mock.ts b/x-pack/test/case_api_integration/common/lib/mock.ts index 728eaf88617e9..cfa4a0ae977f4 100644 --- a/x-pack/test/case_api_integration/common/lib/mock.ts +++ b/x-pack/test/case_api_integration/common/lib/mock.ts @@ -36,6 +36,7 @@ export const postCaseResp = (id: string): Partial => ({ export const removeServerGeneratedPropertiesFromCase = ( config: Partial ): Partial => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { closed_at, created_at, updated_at, version, ...rest } = config; return rest; }; diff --git a/x-pack/test/case_api_integration/common/lib/utils.ts b/x-pack/test/case_api_integration/common/lib/utils.ts index fe9cb48178633..a24e17f9e5efb 100644 --- a/x-pack/test/case_api_integration/common/lib/utils.ts +++ b/x-pack/test/case_api_integration/common/lib/utils.ts @@ -7,6 +7,7 @@ import { Client } from '@elastic/elasticsearch'; import { CasesConfigureRequest, CasesConfigureResponse } from '../../../../plugins/case/common/api'; +// eslint-disable-next-line @typescript-eslint/naming-convention export const getConfiguration = (connector_id: string = 'connector-1'): CasesConfigureRequest => { return { connector_id, @@ -89,6 +90,7 @@ export const getJiraConnector = () => ({ export const removeServerGeneratedPropertiesFromConfigure = ( config: Partial ): Partial => { + // eslint-disable-next-line @typescript-eslint/naming-convention const { created_at, updated_at, version, ...rest } = config; return rest; }; diff --git a/x-pack/test/detection_engine_api_integration/common/config.ts b/x-pack/test/detection_engine_api_integration/common/config.ts index 3e444bcab319a..bb9b3d9e96664 100644 --- a/x-pack/test/detection_engine_api_integration/common/config.ts +++ b/x-pack/test/detection_engine_api_integration/common/config.ts @@ -31,7 +31,6 @@ const enabledActionTypes = [ 'test.rate-limit', ]; -// eslint-disable-next-line import/no-default-export export function createTestConfig(name: string, options: CreateTestConfigOptions) { const { license = 'trial', disabledPlugins = [], ssl = false } = options; diff --git a/x-pack/test/detection_engine_api_integration/utils.ts b/x-pack/test/detection_engine_api_integration/utils.ts index 102a1577a7eaf..604133a1c2dc7 100644 --- a/x-pack/test/detection_engine_api_integration/utils.ts +++ b/x-pack/test/detection_engine_api_integration/utils.ts @@ -24,6 +24,7 @@ export const removeServerGeneratedProperties = ( rule: Partial ): Partial => { const { + /* eslint-disable @typescript-eslint/naming-convention */ created_at, updated_at, id, @@ -33,6 +34,7 @@ export const removeServerGeneratedProperties = ( last_success_message, status, status_date, + /* eslint-enable @typescript-eslint/naming-convention */ ...removedProperties } = rule; return removedProperties; @@ -46,6 +48,7 @@ export const removeServerGeneratedPropertiesIncludingRuleId = ( rule: Partial ): Partial => { const ruleWithRemovedProperties = removeServerGeneratedProperties(rule); + // eslint-disable-next-line @typescript-eslint/naming-convention const { rule_id, ...additionalRuledIdRemoved } = ruleWithRemovedProperties; return additionalRuledIdRemoved; }; @@ -153,6 +156,7 @@ export const getSignalStatusEmptyResponse = () => ({ */ export const getSimpleRuleWithoutRuleId = (): CreateRulesSchema => { const simpleRule = getSimpleRule(); + // eslint-disable-next-line @typescript-eslint/naming-convention const { rule_id, ...ruleWithoutId } = simpleRule; return ruleWithoutId; }; @@ -215,6 +219,7 @@ export const getSimpleRuleOutput = (ruleId = 'rule-1'): Partial => */ export const getSimpleRuleOutputWithoutRuleId = (ruleId = 'rule-1'): Partial => { const rule = getSimpleRuleOutput(ruleId); + // eslint-disable-next-line @typescript-eslint/naming-convention const { rule_id, ...ruleWithoutRuleId } = rule; return ruleWithoutRuleId; }; diff --git a/x-pack/test/functional/apps/lens/index.ts b/x-pack/test/functional/apps/lens/index.ts index 9e04f6e9df22b..b17b7d856841c 100644 --- a/x-pack/test/functional/apps/lens/index.ts +++ b/x-pack/test/functional/apps/lens/index.ts @@ -6,7 +6,6 @@ import { FtrProviderContext } from '../../ftr_provider_context.d'; -// eslint-disable-next-line @typescript-eslint/no-namespace, import/no-default-export export default function ({ getService, loadTestFile }: FtrProviderContext) { const browser = getService('browser'); const log = getService('log'); diff --git a/x-pack/test/functional/apps/lens/lens_reporting.ts b/x-pack/test/functional/apps/lens/lens_reporting.ts index 5fa2bd1a049a7..3e3d217b9d8d7 100644 --- a/x-pack/test/functional/apps/lens/lens_reporting.ts +++ b/x-pack/test/functional/apps/lens/lens_reporting.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['common', 'dashboard', 'reporting']); const esArchiver = getService('esArchiver'); diff --git a/x-pack/test/functional/apps/lens/persistent_context.ts b/x-pack/test/functional/apps/lens/persistent_context.ts index 9146ec7334625..b57a9884dd11f 100644 --- a/x-pack/test/functional/apps/lens/persistent_context.ts +++ b/x-pack/test/functional/apps/lens/persistent_context.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['visualize', 'lens', 'header', 'timePicker']); const browser = getService('browser'); diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index 23d4cc972675b..1e93636161067 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects([ 'header', diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/advanced_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection/advanced_job.ts index b574c67daf7a4..a8836a463e652 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/advanced_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/advanced_job.ts @@ -87,7 +87,6 @@ const isPickFieldsConfigWithSummaryCountField = ( return arg.hasOwnProperty('summaryCountField'); }; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/anomaly_explorer.ts b/x-pack/test/functional/apps/ml/anomaly_detection/anomaly_explorer.ts index c23abead458f1..89308938cfab0 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/anomaly_explorer.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/anomaly_explorer.ts @@ -51,7 +51,6 @@ const testDataList = [ }, ]; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/categorization_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection/categorization_job.ts index 0f8aad36ed372..1581bd54f5c44 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/categorization_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/categorization_job.ts @@ -8,7 +8,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../../plugins/ml/common/constants/categorization_job'; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/date_nanos_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection/date_nanos_job.ts index da56d96d3d59e..50622604c4e5c 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/date_nanos_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/date_nanos_job.ts @@ -81,7 +81,6 @@ const isPickFieldsConfigWithSummaryCountField = ( return arg.hasOwnProperty('summaryCountField'); }; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/multi_metric_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection/multi_metric_job.ts index 945717a694aac..85477b105abe9 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/multi_metric_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/multi_metric_job.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/population_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection/population_job.ts index 8084856aa7c6b..c6de7f8a2bd39 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/population_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/population_job.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/saved_search_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection/saved_search_job.ts index c1276c158eb64..6f40ec5427b74 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/saved_search_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/saved_search_job.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/single_metric_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection/single_metric_job.ts index 58d7d7c3ad359..58f3960153bc6 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/single_metric_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/single_metric_job.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/single_metric_viewer.ts b/x-pack/test/functional/apps/ml/anomaly_detection/single_metric_viewer.ts index b9c40d319dea5..db511c5d75f39 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/single_metric_viewer.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/single_metric_viewer.ts @@ -34,7 +34,6 @@ const DATAFEED_CONFIG: Datafeed = { query: { bool: { must: [{ match_all: {} }] } }, }; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); diff --git a/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts b/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts index fc561a7a93c2d..3c9111c246630 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts @@ -8,7 +8,6 @@ import path from 'path'; import { FtrProviderContext } from '../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const ml = getService('ml'); diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts index aec9153640636..eb76a8b4298af 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts @@ -38,7 +38,6 @@ function getFieldTypes(cards: FieldVisConfig[]) { return fieldTypes.sort(); } -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); diff --git a/x-pack/test/functional_with_es_ssl/config.ts b/x-pack/test/functional_with_es_ssl/config.ts index 43192d906336d..5df5a4155efd3 100644 --- a/x-pack/test/functional_with_es_ssl/config.ts +++ b/x-pack/test/functional_with_es_ssl/config.ts @@ -25,7 +25,6 @@ const enabledActionTypes = [ 'test.rate-limit', ]; -// eslint-disable-next-line import/no-default-export export default async function ({ readConfigFile }: FtrConfigProviderContext) { const xpackFunctionalConfig = await readConfigFile(require.resolve('../functional/config.js')); diff --git a/x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/public/plugin.ts b/x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/public/plugin.ts index 503c328017a9a..b612f54120d42 100644 --- a/x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/public/plugin.ts +++ b/x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/public/plugin.ts @@ -19,6 +19,7 @@ export interface AlertingExamplePublicSetupDeps { } export class AlertingFixturePlugin implements Plugin { + // eslint-disable-next-line @typescript-eslint/naming-convention public setup(core: CoreSetup, { alerts, triggers_actions_ui }: AlertingExamplePublicSetupDeps) { alerts.registerNavigation( 'alerting_fixture', diff --git a/x-pack/test/ingest_manager_api_integration/apis/agent_config/agent_config.ts b/x-pack/test/ingest_manager_api_integration/apis/agent_config/agent_config.ts index 89258600c85e1..6526dc63e212c 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/agent_config/agent_config.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/agent_config/agent_config.ts @@ -59,6 +59,7 @@ export default function ({ getService }: FtrProviderContext) { description: 'Test', }) .expect(200); + // eslint-disable-next-line @typescript-eslint/naming-convention const { id, updated_at, ...newConfig } = item; expect(success).to.be(true); diff --git a/x-pack/test/licensing_plugin/public/updates.ts b/x-pack/test/licensing_plugin/public/updates.ts index 4604cfe032b0b..b939bd7a0f9eb 100644 --- a/x-pack/test/licensing_plugin/public/updates.ts +++ b/x-pack/test/licensing_plugin/public/updates.ts @@ -28,7 +28,7 @@ export default function (ftrContext: FtrProviderContext) { expect( await browser.executeAsync(async (cb) => { - const { setup, testUtils } = window.__coreProvider; + const { setup, testUtils } = window._coreProvider; // this call enforces signature check to detect license update // and causes license re-fetch await setup.core.http.get('/'); @@ -44,7 +44,7 @@ export default function (ftrContext: FtrProviderContext) { expect( await browser.executeAsync(async (cb) => { - const { setup, testUtils } = window.__coreProvider; + const { setup, testUtils } = window._coreProvider; // this call enforces signature check to detect license update // and causes license re-fetch await setup.core.http.get('/'); @@ -60,7 +60,7 @@ export default function (ftrContext: FtrProviderContext) { expect( await browser.executeAsync(async (cb) => { - const { setup, testUtils } = window.__coreProvider; + const { setup, testUtils } = window._coreProvider; // this call enforces signature check to detect license update // and causes license re-fetch await setup.core.http.get('/'); @@ -76,7 +76,7 @@ export default function (ftrContext: FtrProviderContext) { expect( await browser.executeAsync(async (cb) => { - const { setup, testUtils } = window.__coreProvider; + const { setup, testUtils } = window._coreProvider; // this call enforces signature check to detect license update // and causes license re-fetch await setup.core.http.get('/'); diff --git a/x-pack/test/mocha_decorations.d.ts b/x-pack/test/mocha_decorations.d.ts index 3574e717ef649..44f43a22de1f9 100644 --- a/x-pack/test/mocha_decorations.d.ts +++ b/x-pack/test/mocha_decorations.d.ts @@ -7,7 +7,6 @@ import { Suite } from 'mocha'; // We need to use the namespace here to match the Mocha definition -// eslint-disable-next-line @typescript-eslint/no-namespace declare module 'mocha' { interface Suite { /** diff --git a/x-pack/test/oidc_api_integration/apis/implicit_flow/index.ts b/x-pack/test/oidc_api_integration/apis/implicit_flow/index.ts index 1c2f634f8054b..0acae074f129f 100644 --- a/x-pack/test/oidc_api_integration/apis/implicit_flow/index.ts +++ b/x-pack/test/oidc_api_integration/apis/implicit_flow/index.ts @@ -6,7 +6,6 @@ import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ loadTestFile }: FtrProviderContext) { describe('apis', function () { this.tags('ciGroup6'); diff --git a/x-pack/test/oidc_api_integration/apis/implicit_flow/oidc_auth.ts b/x-pack/test/oidc_api_integration/apis/implicit_flow/oidc_auth.ts index f35c72ea135c9..fbfb4df7fac63 100644 --- a/x-pack/test/oidc_api_integration/apis/implicit_flow/oidc_auth.ts +++ b/x-pack/test/oidc_api_integration/apis/implicit_flow/oidc_auth.ts @@ -11,7 +11,6 @@ import { format as formatURL } from 'url'; import { createTokens, getStateAndNonce } from '../../fixtures/oidc_tools'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertestWithoutAuth'); const config = getService('config'); diff --git a/x-pack/test/oidc_api_integration/implicit_flow.config.ts b/x-pack/test/oidc_api_integration/implicit_flow.config.ts index a3d87e809f887..992115d05c5a8 100644 --- a/x-pack/test/oidc_api_integration/implicit_flow.config.ts +++ b/x-pack/test/oidc_api_integration/implicit_flow.config.ts @@ -6,7 +6,6 @@ import { FtrConfigProviderContext } from '@kbn/test/types/ftr'; -// eslint-disable-next-line import/no-default-export export default async function ({ readConfigFile }: FtrConfigProviderContext) { const oidcAPITestsConfig = await readConfigFile(require.resolve('./config.ts')); diff --git a/x-pack/test/plugin_api_integration/test_suites/licensed_feature_usage/feature_usage.ts b/x-pack/test/plugin_api_integration/test_suites/licensed_feature_usage/feature_usage.ts index e16d55f8fad2c..770b51fb922ff 100644 --- a/x-pack/test/plugin_api_integration/test_suites/licensed_feature_usage/feature_usage.ts +++ b/x-pack/test/plugin_api_integration/test_suites/licensed_feature_usage/feature_usage.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); diff --git a/x-pack/test/plugin_functional/config.ts b/x-pack/test/plugin_functional/config.ts index a766e22a34a1d..40a3b3cf1877f 100644 --- a/x-pack/test/plugin_functional/config.ts +++ b/x-pack/test/plugin_functional/config.ts @@ -13,7 +13,6 @@ import { pageObjects } from './page_objects'; // the default export of config files must be a config provider // that returns an object with the projects config values -/* eslint-disable import/no-default-export */ export default async function ({ readConfigFile }: FtrConfigProviderContext) { const xpackFunctionalConfig = await readConfigFile( require.resolve('../security_solution_endpoint/config.ts') diff --git a/x-pack/test/plugin_functional/test_suites/global_search/global_search_api.ts b/x-pack/test/plugin_functional/test_suites/global_search/global_search_api.ts index 841c4d2967e21..146c4297fc2c8 100644 --- a/x-pack/test/plugin_functional/test_suites/global_search/global_search_api.ts +++ b/x-pack/test/plugin_functional/test_suites/global_search/global_search_api.ts @@ -15,7 +15,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const findResultsWithAPI = async (t: string): Promise => { return browser.executeAsync(async (term, cb) => { - const { start } = window.__coreProvider; + const { start } = window._coreProvider; const globalSearchTestApi: GlobalSearchTestApi = start.plugins.globalSearchTest; globalSearchTestApi.findTest(term).then(cb); }, t); diff --git a/x-pack/test/plugin_functional/test_suites/global_search/global_search_providers.ts b/x-pack/test/plugin_functional/test_suites/global_search/global_search_providers.ts index 4e4f42578d11a..726115958d027 100644 --- a/x-pack/test/plugin_functional/test_suites/global_search/global_search_providers.ts +++ b/x-pack/test/plugin_functional/test_suites/global_search/global_search_providers.ts @@ -16,7 +16,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const findResultsWithAPI = async (t: string): Promise => { return browser.executeAsync(async (term, cb) => { - const { start } = window.__coreProvider; + const { start } = window._coreProvider; const globalSearchTestApi: GlobalSearchTestApi = start.plugins.globalSearchTest; globalSearchTestApi.findReal(term).then(cb); }, t); diff --git a/x-pack/test/security_solution_cypress/runner.ts b/x-pack/test/security_solution_cypress/runner.ts index e3bea8b9bbbcf..11c960389e25f 100644 --- a/x-pack/test/security_solution_cypress/runner.ts +++ b/x-pack/test/security_solution_cypress/runner.ts @@ -26,6 +26,7 @@ export async function SiemCypressTestRunner({ getService }: FtrProviderContext) cwd: resolve(__dirname, '../../plugins/security_solution'), env: { FORCE_COLOR: '1', + // eslint-disable-next-line @typescript-eslint/naming-convention CYPRESS_baseUrl: Url.format(config.get('servers.kibana')), CYPRESS_ELASTICSEARCH_URL: Url.format(config.get('servers.elasticsearch')), CYPRESS_ELASTICSEARCH_USERNAME: config.get('servers.elasticsearch.username'), diff --git a/x-pack/test/spaces_api_integration/security_and_spaces/apis/get_all.ts b/x-pack/test/spaces_api_integration/security_and_spaces/apis/get_all.ts index 1420cb35de143..e64f721825089 100644 --- a/x-pack/test/spaces_api_integration/security_and_spaces/apis/get_all.ts +++ b/x-pack/test/spaces_api_integration/security_and_spaces/apis/get_all.ts @@ -20,6 +20,7 @@ export default function getAllSpacesTestSuite({ getService }: TestInvoker) { ); describe('get all', () => { + /* eslint-disable @typescript-eslint/naming-convention */ [ { spaceId: SPACES.DEFAULT.spaceId, @@ -73,6 +74,7 @@ export default function getAllSpacesTestSuite({ getService }: TestInvoker) { monitoringUser: AUTHENTICATION.MONITORING_USER, }, }, + /* eslint-enable @typescript-eslint/naming-convention */ ].forEach((scenario) => { getAllTest(`user with no access can't access any spaces from ${scenario.spaceId}`, { spaceId: scenario.spaceId, diff --git a/x-pack/test/ui_capabilities/common/config.ts b/x-pack/test/ui_capabilities/common/config.ts index 068974386acd7..477a3f702ffbf 100644 --- a/x-pack/test/ui_capabilities/common/config.ts +++ b/x-pack/test/ui_capabilities/common/config.ts @@ -14,7 +14,6 @@ interface CreateTestConfigOptions { disabledPlugins?: string[]; } -// eslint-disable-next-line import/no-default-export export function createTestConfig(name: string, options: CreateTestConfigOptions) { const { license = 'trial', disabledPlugins = [] } = options; diff --git a/x-pack/test/ui_capabilities/common/nav_links_builder.ts b/x-pack/test/ui_capabilities/common/nav_links_builder.ts index 04ab08e08a2ba..886318be8e758 100644 --- a/x-pack/test/ui_capabilities/common/nav_links_builder.ts +++ b/x-pack/test/ui_capabilities/common/nav_links_builder.ts @@ -5,7 +5,7 @@ */ import { Features } from './features'; -type buildCallback = (featureId: string) => boolean; +type BuildCallback = (featureId: string) => boolean; export class NavLinksBuilder { private readonly features: Features; constructor(features: Features) { @@ -38,7 +38,7 @@ export class NavLinksBuilder { return this.build((featureId) => feature.includes(featureId)); } - private build(callback: buildCallback): Record { + private build(callback: BuildCallback): Record { const navLinks = {} as Record; for (const [featureId, feature] of Object.entries(this.features)) { feature.app.forEach((app) => { diff --git a/x-pack/typings/rison_node.d.ts b/x-pack/typings/rison_node.d.ts index f830adc897445..295392af2e05b 100644 --- a/x-pack/typings/rison_node.d.ts +++ b/x-pack/typings/rison_node.d.ts @@ -16,11 +16,11 @@ declare module 'rison-node' { export const decode: (input: string) => RisonValue; - // eslint-disable-next-line @typescript-eslint/camelcase + // eslint-disable-next-line @typescript-eslint/naming-convention export const decode_object: (input: string) => RisonObject; export const encode: (input: Input) => string; - // eslint-disable-next-line @typescript-eslint/camelcase + // eslint-disable-next-line @typescript-eslint/naming-convention export const encode_object: (input: Input) => string; } diff --git a/yarn.lock b/yarn.lock index 0638267afd256..7aff34fab23ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5798,23 +5798,26 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg== -"@typescript-eslint/eslint-plugin@^2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9" - integrity sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ== +"@typescript-eslint/eslint-plugin@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.7.1.tgz#d144c49a9a0ffe8dd704bb179c243df76c111bc9" + integrity sha512-3DB9JDYkMrc8Au00rGFiJLK2Ja9CoMP6Ut0sHsXp3ZtSugjNxvSSHTnKLfo4o+QmjYBJqEznDqsG1zj4F2xnsg== dependencies: - "@typescript-eslint/experimental-utils" "2.34.0" + "@typescript-eslint/experimental-utils" "3.7.1" + debug "^4.1.1" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" + semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" - integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA== +"@typescript-eslint/experimental-utils@3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.7.1.tgz#ab036caaed4c870d22531d41f9352f3147364d61" + integrity sha512-TqE97pv7HrqWcGJbLbZt1v59tcqsSVpWTOf1AqrWK7n8nok2sGgVtYRuGXeNeLw3wXlLEbY1MKP3saB2HsO/Ng== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.34.0" + "@typescript-eslint/types" "3.7.1" + "@typescript-eslint/typescript-estree" "3.7.1" eslint-scope "^5.0.0" eslint-utils "^2.0.0" @@ -5827,16 +5830,22 @@ "@typescript-eslint/typescript-estree" "2.15.0" eslint-scope "^5.0.0" -"@typescript-eslint/parser@^2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.34.0.tgz#50252630ca319685420e9a39ca05fe185a256bc8" - integrity sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA== +"@typescript-eslint/parser@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.7.1.tgz#5d9ccecb116d12d9c6073e9861c57c9b1aa88128" + integrity sha512-W4QV/gXvfIsccN8225784LNOorcm7ch68Fi3V4Wg7gmkWSQRKevO4RrRqWo6N/Z/myK1QAiGgeaXN57m+R/8iQ== dependencies: "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.34.0" - "@typescript-eslint/typescript-estree" "2.34.0" + "@typescript-eslint/experimental-utils" "3.7.1" + "@typescript-eslint/types" "3.7.1" + "@typescript-eslint/typescript-estree" "3.7.1" eslint-visitor-keys "^1.1.0" +"@typescript-eslint/types@3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.7.1.tgz#90375606b2fd73c1224fe9e397ee151e28fa1e0c" + integrity sha512-PZe8twm5Z4b61jt7GAQDor6KiMhgPgf4XmUb9zdrwTbgtC/Sj29gXP1dws9yEn4+aJeyXrjsD9XN7AWFhmnUfg== + "@typescript-eslint/typescript-estree@2.15.0": version "2.15.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.15.0.tgz#79ae52eed8701b164d91e968a65d85a9105e76d3" @@ -5850,13 +5859,14 @@ semver "^6.3.0" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" - integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg== +"@typescript-eslint/typescript-estree@3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.7.1.tgz#ce1ffbd0fa53f34d4ce851a7a364e392432f6eb3" + integrity sha512-m97vNZkI08dunYOr2lVZOHoyfpqRs0KDpd6qkGaIcLGhQ2WPtgHOd/eVbsJZ0VYCQvupKrObAGTOvk3tfpybYA== dependencies: + "@typescript-eslint/types" "3.7.1" + "@typescript-eslint/visitor-keys" "3.7.1" debug "^4.1.1" - eslint-visitor-keys "^1.1.0" glob "^7.1.6" is-glob "^4.0.1" lodash "^4.17.15" @@ -5871,6 +5881,13 @@ lodash.unescape "4.0.1" semver "5.5.0" +"@typescript-eslint/visitor-keys@3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.7.1.tgz#b90191e74efdee656be8c5a30f428ed16dda46d1" + integrity sha512-xn22sQbEya+Utj2IqJHGLA3i1jDzR43RzWupxojbSWnj3nnPLavaQmWe5utw03CwYao3r00qzXfgJMGNkrzrAA== + dependencies: + eslint-visitor-keys "^1.1.0" + "@webassemblyjs/ast@1.8.5": version "1.8.5" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" @@ -13070,6 +13087,14 @@ eslint-plugin-es@^3.0.0: eslint-utils "^2.0.0" regexpp "^3.0.0" +eslint-plugin-eslint-comments@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz#9e1cd7b4413526abb313933071d7aba05ca12ffa" + integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ== + dependencies: + escape-string-regexp "^1.0.5" + ignore "^5.0.5" + eslint-plugin-import@^2.19.1: version "2.19.1" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.19.1.tgz#5654e10b7839d064dd0d46cd1b88ec2133a11448" @@ -16946,7 +16971,7 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.1, ignore@^5.1.4: +ignore@^5.0.5, ignore@^5.1.1, ignore@^5.1.4: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== From 549c256390383ee08bcbe3744c42eb226acc18b5 Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Wed, 5 Aug 2020 17:45:30 +0200 Subject: [PATCH 010/106] [SIEM] Adds rule override Cypress tests (#74367) * implements rule override test * refactors the code --- .../alerts_detection_rules_override.spec.ts | 196 ++++++++++++++++++ .../security_solution/cypress/objects/rule.ts | 50 +++++ .../cypress/screens/create_new_rule.ts | 16 ++ .../cypress/screens/rule_details.ts | 18 ++ .../cypress/tasks/create_new_rule.ts | 76 ++++++- .../rules/risk_score_mapping/index.tsx | 2 +- .../rules/severity_mapping/index.tsx | 8 +- .../rules/step_about_rule/index.tsx | 4 +- 8 files changed, 364 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/security_solution/cypress/integration/alerts_detection_rules_override.spec.ts diff --git a/x-pack/plugins/security_solution/cypress/integration/alerts_detection_rules_override.spec.ts b/x-pack/plugins/security_solution/cypress/integration/alerts_detection_rules_override.spec.ts new file mode 100644 index 0000000000000..e3526c63e2310 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/integration/alerts_detection_rules_override.spec.ts @@ -0,0 +1,196 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { newOverrideRule } from '../objects/rule'; + +import { + CUSTOM_RULES_BTN, + RISK_SCORE, + RULE_NAME, + RULES_ROW, + RULES_TABLE, + SEVERITY, +} from '../screens/alerts_detection_rules'; +import { + ABOUT_INVESTIGATION_NOTES, + ABOUT_OVERRIDE_FALSE_POSITIVES, + ABOUT_OVERRIDE_MITRE, + ABOUT_OVERRIDE_NAME_OVERRIDE, + ABOUT_OVERRIDE_RISK, + ABOUT_OVERRIDE_RISK_OVERRIDE, + ABOUT_OVERRIDE_SEVERITY_OVERRIDE, + ABOUT_OVERRIDE_TAGS, + ABOUT_OVERRIDE_TIMESTAMP_OVERRIDE, + ABOUT_OVERRIDE_URLS, + ABOUT_RULE_DESCRIPTION, + ABOUT_SEVERITY, + ABOUT_STEP, + DEFINITION_CUSTOM_QUERY, + DEFINITION_INDEX_PATTERNS, + DEFINITION_TIMELINE, + DEFINITION_STEP, + INVESTIGATION_NOTES_MARKDOWN, + INVESTIGATION_NOTES_TOGGLE, + RULE_ABOUT_DETAILS_HEADER_TOGGLE, + RULE_NAME_HEADER, + SCHEDULE_LOOPBACK, + SCHEDULE_RUNS, + SCHEDULE_STEP, +} from '../screens/rule_details'; + +import { + goToManageAlertsDetectionRules, + waitForAlertsIndexToBeCreated, + waitForAlertsPanelToBeLoaded, +} from '../tasks/alerts'; +import { + changeToThreeHundredRowsPerPage, + filterByCustomRules, + goToCreateNewRule, + goToRuleDetails, + waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded, + waitForRulesToBeLoaded, +} from '../tasks/alerts_detection_rules'; +import { + createAndActivateRule, + fillAboutRuleWithOverrideAndContinue, + fillDefineCustomRuleWithImportedQueryAndContinue, +} from '../tasks/create_new_rule'; +import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver'; +import { loginAndWaitForPageWithoutDateRange } from '../tasks/login'; + +import { DETECTIONS_URL } from '../urls/navigation'; + +describe('Detection rules, override', () => { + before(() => { + esArchiverLoad('timeline'); + }); + + after(() => { + esArchiverUnload('timeline'); + }); + + it('Creates and activates a new custom rule with override option', () => { + loginAndWaitForPageWithoutDateRange(DETECTIONS_URL); + waitForAlertsPanelToBeLoaded(); + waitForAlertsIndexToBeCreated(); + goToManageAlertsDetectionRules(); + waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded(); + goToCreateNewRule(); + fillDefineCustomRuleWithImportedQueryAndContinue(newOverrideRule); + fillAboutRuleWithOverrideAndContinue(newOverrideRule); + createAndActivateRule(); + + cy.get(CUSTOM_RULES_BTN).invoke('text').should('eql', 'Custom rules (1)'); + + changeToThreeHundredRowsPerPage(); + waitForRulesToBeLoaded(); + + const expectedNumberOfRules = 1; + cy.get(RULES_TABLE).then(($table) => { + cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRules); + }); + + filterByCustomRules(); + + cy.get(RULES_TABLE).then(($table) => { + cy.wrap($table.find(RULES_ROW).length).should('eql', 1); + }); + cy.get(RULE_NAME).invoke('text').should('eql', newOverrideRule.name); + cy.get(RISK_SCORE).invoke('text').should('eql', newOverrideRule.riskScore); + cy.get(SEVERITY).invoke('text').should('eql', newOverrideRule.severity); + cy.get('[data-test-subj="rule-switch"]').should('have.attr', 'aria-checked', 'true'); + + goToRuleDetails(); + + let expectedUrls = ''; + newOverrideRule.referenceUrls.forEach((url) => { + expectedUrls = expectedUrls + url; + }); + let expectedFalsePositives = ''; + newOverrideRule.falsePositivesExamples.forEach((falsePositive) => { + expectedFalsePositives = expectedFalsePositives + falsePositive; + }); + let expectedTags = ''; + newOverrideRule.tags.forEach((tag) => { + expectedTags = expectedTags + tag; + }); + let expectedMitre = ''; + newOverrideRule.mitre.forEach((mitre) => { + expectedMitre = expectedMitre + mitre.tactic; + mitre.techniques.forEach((technique) => { + expectedMitre = expectedMitre + technique; + }); + }); + const expectedIndexPatterns = [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ]; + + cy.get(RULE_NAME_HEADER).invoke('text').should('eql', `${newOverrideRule.name} Beta`); + + cy.get(ABOUT_RULE_DESCRIPTION).invoke('text').should('eql', newOverrideRule.description); + + const expectedOverrideSeverities = ['Low', 'Medium', 'High', 'Critical']; + + cy.get(ABOUT_STEP).eq(ABOUT_SEVERITY).invoke('text').should('eql', newOverrideRule.severity); + newOverrideRule.severityOverride.forEach((severity, i) => { + cy.get(ABOUT_STEP) + .eq(ABOUT_OVERRIDE_SEVERITY_OVERRIDE + i) + .invoke('text') + .should( + 'eql', + `${severity.sourceField}:${severity.sourceValue}${expectedOverrideSeverities[i]}` + ); + }); + + cy.get(ABOUT_STEP) + .eq(ABOUT_OVERRIDE_RISK) + .invoke('text') + .should('eql', newOverrideRule.riskScore); + cy.get(ABOUT_STEP) + .eq(ABOUT_OVERRIDE_RISK_OVERRIDE) + .invoke('text') + .should('eql', `${newOverrideRule.riskOverride}signal.rule.risk_score`); + cy.get(ABOUT_STEP).eq(ABOUT_OVERRIDE_URLS).invoke('text').should('eql', expectedUrls); + cy.get(ABOUT_STEP) + .eq(ABOUT_OVERRIDE_FALSE_POSITIVES) + .invoke('text') + .should('eql', expectedFalsePositives); + cy.get(ABOUT_STEP) + .eq(ABOUT_OVERRIDE_NAME_OVERRIDE) + .invoke('text') + .should('eql', newOverrideRule.nameOverride); + cy.get(ABOUT_STEP).eq(ABOUT_OVERRIDE_MITRE).invoke('text').should('eql', expectedMitre); + cy.get(ABOUT_STEP) + .eq(ABOUT_OVERRIDE_TIMESTAMP_OVERRIDE) + .invoke('text') + .should('eql', newOverrideRule.timestampOverride); + cy.get(ABOUT_STEP).eq(ABOUT_OVERRIDE_TAGS).invoke('text').should('eql', expectedTags); + + cy.get(RULE_ABOUT_DETAILS_HEADER_TOGGLE).eq(INVESTIGATION_NOTES_TOGGLE).click({ force: true }); + cy.get(ABOUT_INVESTIGATION_NOTES).invoke('text').should('eql', INVESTIGATION_NOTES_MARKDOWN); + + cy.get(DEFINITION_INDEX_PATTERNS).then((patterns) => { + cy.wrap(patterns).each((pattern, index) => { + cy.wrap(pattern).invoke('text').should('eql', expectedIndexPatterns[index]); + }); + }); + cy.get(DEFINITION_STEP) + .eq(DEFINITION_CUSTOM_QUERY) + .invoke('text') + .should('eql', `${newOverrideRule.customQuery} `); + cy.get(DEFINITION_STEP).eq(DEFINITION_TIMELINE).invoke('text').should('eql', 'None'); + + cy.get(SCHEDULE_STEP).eq(SCHEDULE_RUNS).invoke('text').should('eql', '5m'); + cy.get(SCHEDULE_STEP).eq(SCHEDULE_LOOPBACK).invoke('text').should('eql', '1m'); + }); +}); diff --git a/x-pack/plugins/security_solution/cypress/objects/rule.ts b/x-pack/plugins/security_solution/cypress/objects/rule.ts index aeadc34c6e49c..df6b792296f9d 100644 --- a/x-pack/plugins/security_solution/cypress/objects/rule.ts +++ b/x-pack/plugins/security_solution/cypress/objects/rule.ts @@ -18,6 +18,11 @@ interface Mitre { techniques: string[]; } +interface SeverityOverride { + sourceField: string; + sourceValue: string; +} + export interface CustomRule { customQuery: string; name: string; @@ -38,6 +43,13 @@ export interface ThresholdRule extends CustomRule { threshold: string; } +export interface OverrideRule extends CustomRule { + severityOverride: SeverityOverride[]; + riskOverride: string; + nameOverride: string; + timestampOverride: string; +} + export interface MachineLearningRule { machineLearningJob: string; anomalyScoreThreshold: string; @@ -63,6 +75,26 @@ const mitre2: Mitre = { techniques: ['CMSTP (T1191)'], }; +const severityOverride1: SeverityOverride = { + sourceField: 'host.name', + sourceValue: 'host', +}; + +const severityOverride2: SeverityOverride = { + sourceField: 'agent.type', + sourceValue: 'endpoint', +}; + +const severityOverride3: SeverityOverride = { + sourceField: 'host.geo.name', + sourceValue: 'atack', +}; + +const severityOverride4: SeverityOverride = { + sourceField: '@timestamp', + sourceValue: '10/02/2020', +}; + export const newRule: CustomRule = { customQuery: 'host.name:*', name: 'New Rule Test', @@ -77,6 +109,24 @@ export const newRule: CustomRule = { timelineId: '0162c130-78be-11ea-9718-118a926974a4', }; +export const newOverrideRule: OverrideRule = { + customQuery: 'host.name:*', + name: 'New Rule Test', + description: 'The new rule description.', + severity: 'High', + riskScore: '17', + tags: ['test', 'newRule'], + referenceUrls: ['https://www.google.com/', 'https://elastic.co/'], + falsePositivesExamples: ['False1', 'False2'], + mitre: [mitre1, mitre2], + note: '# test markdown', + timelineId: '0162c130-78be-11ea-9718-118a926974a4', + severityOverride: [severityOverride1, severityOverride2, severityOverride3, severityOverride4], + riskOverride: 'destination.port', + nameOverride: 'agent.type', + timestampOverride: '@timestamp', +}; + export const newThresholdRule: ThresholdRule = { customQuery: 'host.name:*', name: 'New Rule Test', diff --git a/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts index af4fe7257ae5b..83ace877cd51d 100644 --- a/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts +++ b/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts @@ -18,6 +18,8 @@ export const MITRE_BTN = '[data-test-subj="addMitre"]'; export const ADVANCED_SETTINGS_BTN = '[data-test-subj="advancedSettings"] .euiAccordion__button'; +export const COMBO_BOX_INPUT = '[data-test-subj="comboBoxInput"]'; + export const CREATE_AND_ACTIVATE_BTN = '[data-test-subj="create-activate"]'; export const CUSTOM_QUERY_INPUT = '[data-test-subj="queryInput"]'; @@ -53,17 +55,31 @@ export const REFERENCE_URLS_INPUT = export const RISK_INPUT = '.euiRangeInput'; +export const RISK_MAPPING_OVERRIDE_OPTION = '#risk_score-mapping-override'; + +export const RISK_OVERRIDE = + '[data-test-subj="detectionEngineStepAboutRuleRiskScore-riskOverride"]'; + export const RULE_DESCRIPTION_INPUT = '[data-test-subj="detectionEngineStepAboutRuleDescription"] [data-test-subj="input"]'; export const RULE_NAME_INPUT = '[data-test-subj="detectionEngineStepAboutRuleName"] [data-test-subj="input"]'; +export const RULE_NAME_OVERRIDE = '[data-test-subj="detectionEngineStepAboutRuleRuleNameOverride"]'; + +export const RULE_TIMESTAMP_OVERRIDE = + '[data-test-subj="detectionEngineStepAboutRuleTimestampOverride"]'; + export const SCHEDULE_CONTINUE_BUTTON = '[data-test-subj="schedule-continue"]'; export const SEVERITY_DROPDOWN = '[data-test-subj="detectionEngineStepAboutRuleSeverity"] [data-test-subj="select"]'; +export const SEVERITY_MAPPING_OVERRIDE_OPTION = '#severity-mapping-override'; + +export const SEVERITY_OVERRIDE_ROW = '[data-test-subj="severityOverrideRow"]'; + export const TAGS_INPUT = '[data-test-subj="detectionEngineStepAboutRuleTags"] [data-test-subj="comboBoxSearchInput"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/rule_details.ts b/x-pack/plugins/security_solution/cypress/screens/rule_details.ts index 1c0102382ab6b..b221709966943 100644 --- a/x-pack/plugins/security_solution/cypress/screens/rule_details.ts +++ b/x-pack/plugins/security_solution/cypress/screens/rule_details.ts @@ -10,6 +10,24 @@ export const ABOUT_INVESTIGATION_NOTES = '[data-test-subj="stepAboutDetailsNoteC export const ABOUT_MITRE = 4; +export const ABOUT_OVERRIDE_FALSE_POSITIVES = 8; + +export const ABOUT_OVERRIDE_MITRE = 10; + +export const ABOUT_OVERRIDE_NAME_OVERRIDE = 9; + +export const ABOUT_OVERRIDE_RISK = 5; + +export const ABOUT_OVERRIDE_RISK_OVERRIDE = 6; + +export const ABOUT_OVERRIDE_SEVERITY_OVERRIDE = 1; + +export const ABOUT_OVERRIDE_TAGS = 12; + +export const ABOUT_OVERRIDE_TIMESTAMP_OVERRIDE = 11; + +export const ABOUT_OVERRIDE_URLS = 7; + export const ABOUT_RULE_DESCRIPTION = '[data-test-subj=stepAboutRuleDetailsToggleDescriptionText]'; export const ABOUT_RISK = 1; diff --git a/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts index de9d343bc91f7..1cce72a48e0f0 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts @@ -8,6 +8,7 @@ import { CustomRule, MachineLearningRule, machineLearningRule, + OverrideRule, ThresholdRule, } from '../objects/rule'; import { @@ -16,6 +17,7 @@ import { ADD_FALSE_POSITIVE_BTN, ADD_REFERENCE_URL_BTN, ADVANCED_SETTINGS_BTN, + COMBO_BOX_INPUT, CREATE_AND_ACTIVATE_BTN, CUSTOM_QUERY_INPUT, DEFINE_CONTINUE_BUTTON, @@ -32,10 +34,16 @@ import { MITRE_TECHNIQUES_INPUT, RISK_INPUT, REFERENCE_URLS_INPUT, + RISK_MAPPING_OVERRIDE_OPTION, + RISK_OVERRIDE, RULE_DESCRIPTION_INPUT, RULE_NAME_INPUT, + RULE_NAME_OVERRIDE, + RULE_TIMESTAMP_OVERRIDE, SCHEDULE_CONTINUE_BUTTON, SEVERITY_DROPDOWN, + SEVERITY_MAPPING_OVERRIDE_OPTION, + SEVERITY_OVERRIDE_ROW, TAGS_INPUT, THRESHOLD_FIELD_SELECTION, THRESHOLD_INPUT_AREA, @@ -92,7 +100,73 @@ export const fillAboutRuleAndContinue = ( cy.get(ABOUT_CONTINUE_BTN).should('exist').click({ force: true }); }; -export const fillDefineCustomRuleWithImportedQueryAndContinue = (rule: CustomRule) => { +export const fillAboutRuleWithOverrideAndContinue = (rule: OverrideRule) => { + cy.get(RULE_NAME_INPUT).type(rule.name, { force: true }); + cy.get(RULE_DESCRIPTION_INPUT).type(rule.description, { force: true }); + + cy.get(SEVERITY_MAPPING_OVERRIDE_OPTION).click(); + rule.severityOverride.forEach((severity, i) => { + cy.get(SEVERITY_OVERRIDE_ROW) + .eq(i) + .within(() => { + cy.get(COMBO_BOX_INPUT).eq(0).type(`${severity.sourceField}{enter}`); + cy.get(COMBO_BOX_INPUT).eq(1).type(`${severity.sourceValue}{enter}`); + }); + }); + + cy.get(SEVERITY_DROPDOWN).click({ force: true }); + cy.get(`#${rule.severity.toLowerCase()}`).click(); + + cy.get(RISK_MAPPING_OVERRIDE_OPTION).click(); + cy.get(RISK_OVERRIDE).within(() => { + cy.get(COMBO_BOX_INPUT).type(`${rule.riskOverride}{enter}`); + }); + + cy.get(RISK_INPUT).clear({ force: true }).type(`${rule.riskScore}`, { force: true }); + + rule.tags.forEach((tag) => { + cy.get(TAGS_INPUT).type(`${tag}{enter}`, { force: true }); + }); + + cy.get(ADVANCED_SETTINGS_BTN).click({ force: true }); + + rule.referenceUrls.forEach((url, index) => { + cy.get(REFERENCE_URLS_INPUT).eq(index).type(url, { force: true }); + cy.get(ADD_REFERENCE_URL_BTN).click({ force: true }); + }); + + rule.falsePositivesExamples.forEach((falsePositive, index) => { + cy.get(FALSE_POSITIVES_INPUT).eq(index).type(falsePositive, { force: true }); + cy.get(ADD_FALSE_POSITIVE_BTN).click({ force: true }); + }); + + rule.mitre.forEach((mitre, index) => { + cy.get(MITRE_TACTIC_DROPDOWN).eq(index).click({ force: true }); + cy.contains(MITRE_TACTIC, mitre.tactic).click(); + + mitre.techniques.forEach((technique) => { + cy.get(MITRE_TECHNIQUES_INPUT).eq(index).type(`${technique}{enter}`, { force: true }); + }); + + cy.get(MITRE_BTN).click({ force: true }); + }); + + cy.get(INVESTIGATION_NOTES_TEXTAREA).type(rule.note, { force: true }); + + cy.get(RULE_NAME_OVERRIDE).within(() => { + cy.get(COMBO_BOX_INPUT).type(`${rule.nameOverride}{enter}`); + }); + + cy.get(RULE_TIMESTAMP_OVERRIDE).within(() => { + cy.get(COMBO_BOX_INPUT).type(`${rule.timestampOverride}{enter}`); + }); + + cy.get(ABOUT_CONTINUE_BTN).should('exist').click({ force: true }); +}; + +export const fillDefineCustomRuleWithImportedQueryAndContinue = ( + rule: CustomRule | OverrideRule +) => { cy.get(IMPORT_QUERY_FROM_SAVED_TIMELINE_LINK).click(); cy.get(TIMELINE(rule.timelineId)).click(); cy.get(CUSTOM_QUERY_INPUT).invoke('text').should('eq', rule.customQuery); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx index 0f16cb99862a5..a0384ef52a841 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx @@ -179,7 +179,7 @@ export const RiskScoreField = ({ error={'errorMessage'} isInvalid={false} fullWidth - data-test-subj={dataTestSubj} + data-test-subj={`${dataTestSubj}-riskOverride`} describedByIds={idAria ? [idAria] : undefined} > diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx index 54d505a4d867f..733e701cff204 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx @@ -220,7 +220,7 @@ export const SeverityField = ({ error={'errorMessage'} isInvalid={false} fullWidth - data-test-subj={dataTestSubj} + data-test-subj={`${dataTestSubj}-severityOverride`} describedByIds={idAria ? [idAria] : undefined} > @@ -245,7 +245,11 @@ export const SeverityField = ({ {(field.value as AboutStepSeverity).mapping.map( (severityMappingItem: SeverityMappingItem, index) => ( - + = ({ path="severity" component={SeverityField} componentProps={{ - 'data-test-subj': 'detectionEngineStepAboutRuleSeverityField', + dataTestSubj: 'detectionEngineStepAboutRuleSeverityField', idAria: 'detectionEngineStepAboutRuleSeverityField', isDisabled: isLoading || indexPatternLoading, options: severityOptions, @@ -158,7 +158,7 @@ const StepAboutRuleComponent: FC = ({ path="riskScore" component={RiskScoreField} componentProps={{ - 'data-test-subj': 'detectionEngineStepAboutRuleRiskScore', + dataTestSubj: 'detectionEngineStepAboutRuleRiskScore', idAria: 'detectionEngineStepAboutRuleRiskScore', isDisabled: isLoading || indexPatternLoading, indices: indexPatterns, From e23c5eafa1171bc074d1aa33fa7e24b99cbb131c Mon Sep 17 00:00:00 2001 From: Yara Tercero Date: Wed, 5 Aug 2020 12:10:28 -0400 Subject: [PATCH 011/106] [Security Solution][Exceptions] - Fixes builder overflow and updates ux for nested entries (#74262) ## Summary - updates the builder nested entries so that the children do not display the parent path - so instead of `parent.child` it just shows `child` - updates the builder to fix overflow issue --- .../common/components/autocomplete/field.tsx | 10 ++++--- .../common/components/autocomplete/helpers.ts | 5 ++-- .../exceptions/builder/entry_item.tsx | 9 +++++-- .../exceptions/builder/exception_item.tsx | 13 +++++++--- .../exceptions/builder/helpers.test.tsx | 11 +++----- .../components/exceptions/builder/helpers.tsx | 26 +++++++++++++------ .../exceptions/viewer/index.test.tsx | 2 ++ 7 files changed, 50 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field.tsx index fab2b1e4a7463..48b24a79bd7c0 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field.tsx @@ -36,11 +36,11 @@ export const FieldComponent: React.FC = ({ onChange, }): JSX.Element => { const [touched, setIsTouched] = useState(false); - const getLabel = useCallback((field): string => field.name, []); + const getLabel = useCallback(({ name }): string => name, []); const optionsMemo = useMemo((): IFieldType[] => { if (indexPattern != null) { if (fieldTypeFilter.length > 0) { - return indexPattern.fields.filter((f) => fieldTypeFilter.includes(f.type)); + return indexPattern.fields.filter(({ type }) => fieldTypeFilter.includes(type)); } else { return indexPattern.fields; } @@ -68,6 +68,10 @@ export const FieldComponent: React.FC = ({ onChange(newValues); }; + const handleTouch = useCallback((): void => { + setIsTouched(true); + }, [setIsTouched]); + return ( = ({ isDisabled={isDisabled} isClearable={isClearable} isInvalid={isRequired ? touched && selectedField == null : false} - onFocus={() => setIsTouched(true)} + onFocus={handleTouch} singleSelection={{ asPlainText: true }} data-test-subj="fieldAutocompleteComboBox" style={{ width: `${fieldInputWidth}px` }} diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts index 3dcaf612da649..8bbc022181475 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts @@ -69,11 +69,12 @@ export function getGenericComboBoxProps({ const newLabels = options.map(getLabel); const newComboOptions: EuiComboBoxOptionOption[] = newLabels.map((label) => ({ label })); const newSelectedComboOptions = selectedOptions + .map(getLabel) .filter((option) => { - return options.indexOf(option) !== -1; + return newLabels.indexOf(option) !== -1; }) .map((option) => { - return newComboOptions[options.indexOf(option)]; + return newComboOptions[newLabels.indexOf(option)]; }); return { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.tsx index 3044f6d01b745..450b48a793e4e 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.tsx @@ -5,6 +5,7 @@ */ import React, { useCallback } from 'react'; import { EuiFormRow, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import styled from 'styled-components'; import { IFieldType, IIndexPattern } from '../../../../../../../../src/plugins/data/common'; import { FieldComponent } from '../../autocomplete/field'; @@ -29,6 +30,10 @@ import { } from './helpers'; import { EXCEPTION_OPERATORS_ONLY_LISTS } from '../../autocomplete/operators'; +const MyValuesInput = styled(EuiFlexItem)` + overflow: hidden; +`; + interface EntryItemProps { entry: FormattedBuilderEntry; indexPattern: IIndexPattern; @@ -257,12 +262,12 @@ export const BuilderEntryItem: React.FC = ({ > {renderFieldInput(showLabel)} {renderOperatorInput(showLabel)} - + {renderFieldValueInput( showLabel, entry.nested === 'parent' ? OperatorTypeEnum.EXISTS : entry.operator.type )} - + ); }; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.tsx index cd8b66acd223a..49a159cdfe623 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.tsx @@ -26,6 +26,11 @@ const MyBeautifulLine = styled(EuiFlexItem)` } `; +const MyOverflowContainer = styled(EuiFlexItem)` + overflow: hidden; + width: 100%; +`; + interface BuilderExceptionListItemProps { exceptionItem: ExceptionsBuilderExceptionItem; exceptionId: string; @@ -98,13 +103,13 @@ export const BuilderExceptionListItemComponent = React.memo )} - + {entries.map((item, index) => ( {item.nested === 'child' && } - + - + ))} - + ); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx index a3c5d09a0fb64..04ab9ee7216f7 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx @@ -161,10 +161,7 @@ describe('Exception builder helpers', () => { const payloadItem: FormattedBuilderEntry = getMockNestedBuilderEntry(); const output = getFilteredIndexPatterns(payloadIndexPattern, payloadItem, 'detection'); const expected: IIndexPattern = { - fields: [ - { ...getField('nestedField.child') }, - { ...getField('nestedField.nestedChild.doublyNestedChild') }, - ], + fields: [{ ...getField('nestedField.child'), name: 'child' }], id: '1234', title: 'logstash-*', }; @@ -243,7 +240,7 @@ describe('Exception builder helpers', () => { }; const output = getFilteredIndexPatterns(payloadIndexPattern, payloadItem, 'endpoint'); const expected: IIndexPattern = { - fields: [getEndpointField('file.Ext.code_signature.status')], + fields: [{ ...getEndpointField('file.Ext.code_signature.status'), name: 'status' }], id: '1234', title: 'logstash-*', }; @@ -405,7 +402,7 @@ describe('Exception builder helpers', () => { aggregatable: false, count: 0, esTypes: ['text'], - name: 'nestedField.child', + name: 'child', readFromDocValues: false, scripted: false, searchable: true, @@ -600,7 +597,7 @@ describe('Exception builder helpers', () => { aggregatable: false, count: 0, esTypes: ['text'], - name: 'nestedField.child', + name: 'child', readFromDocValues: false, scripted: false, searchable: true, diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx index bea1eb8f0e17b..2fda14dfa04d7 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx @@ -60,13 +60,20 @@ export const getFilteredIndexPatterns = ( // when user has selected a nested entry, only fields with the common parent are shown return { ...indexPatterns, - fields: indexPatterns.fields.filter( - (field) => - field.subType != null && - field.subType.nested != null && - item.parent != null && - field.subType.nested.path.startsWith(item.parent.parent.field) - ), + fields: indexPatterns.fields + .filter((indexField) => { + const fieldHasCommonParentPath = + indexField.subType != null && + indexField.subType.nested != null && + item.parent != null && + indexField.subType.nested.path === item.parent.parent.field; + + return fieldHasCommonParentPath; + }) + .map((f) => { + const fieldNameWithoutParentPath = f.name.split('.').slice(-1)[0]; + return { ...f, name: fieldNameWithoutParentPath }; + }), }; } else if (item.nested === 'parent' && item.field != null) { // when user has selected a nested entry, right above it we show the common parent @@ -145,7 +152,10 @@ export const getFormattedBuilderEntry = ( if (parent != null && parentIndex != null) { return { - field: foundField, + field: + foundField != null + ? { ...foundField, name: foundField.name.split('.').slice(-1)[0] } + : foundField, correspondingKeywordField, operator: getExceptionOperatorSelect(item), value: getEntryValue(item), diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx index 84613d1c73536..4c60f3ba5ccce 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx @@ -17,6 +17,7 @@ import { useApi, } from '../../../../../public/lists_plugin_deps'; import { getExceptionListSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_schema.mock'; +import { getFoundExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/found_exception_list_item_schema.mock'; jest.mock('../../../../common/lib/kibana'); jest.mock('../../../../../public/lists_plugin_deps'); @@ -36,6 +37,7 @@ describe('ExceptionsViewer', () => { (useApi as jest.Mock).mockReturnValue({ deleteExceptionItem: jest.fn().mockResolvedValue(true), + getExceptionListsItems: jest.fn().mockResolvedValue(getFoundExceptionListItemSchemaMock()), }); (useExceptionList as jest.Mock).mockReturnValue([ From cf6413ab2f97493a808ebd16f2a29ed6a5fc75a5 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 5 Aug 2020 18:25:16 +0200 Subject: [PATCH 012/106] [Lens] fix chart switching when on VisualizationDimensionEditor (#70689) --- .../config_panel/layer_panel.test.tsx | 75 ++++++++++++++++--- .../editor_frame/config_panel/layer_panel.tsx | 37 +++++---- 2 files changed, 82 insertions(+), 30 deletions(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx index 9545bd3c840da..b100c885466ab 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx @@ -24,6 +24,7 @@ jest.mock('../../../id_generator'); describe('LayerPanel', () => { let mockVisualization: jest.Mocked; + let mockVisualization2: jest.Mocked; let mockDatasource: DatasourceMock; function getDefaultProps() { @@ -36,6 +37,7 @@ describe('LayerPanel', () => { activeVisualizationId: 'vis1', visualizationMap: { vis1: mockVisualization, + vis2: mockVisualization2, }, activeDatasourceId: 'ds1', datasourceMap: { @@ -72,6 +74,18 @@ describe('LayerPanel', () => { ], }; + mockVisualization2 = { + ...createMockVisualization(), + id: 'testVis2', + visualizationTypes: [ + { + icon: 'empty', + id: 'testVis2', + label: 'TEST2', + }, + ], + }; + mockVisualization.getLayerIds.mockReturnValue(['first']); mockDatasource = createMockDatasource('ds1'); }); @@ -209,16 +223,6 @@ describe('LayerPanel', () => { const panel = mount(group.prop('panel')); expect(panel.find('EuiTabbedContent').prop('tabs')).toHaveLength(2); - act(() => { - panel.find('EuiTab#visualization').simulate('click'); - }); - expect(mockVisualization.renderDimensionEditor).toHaveBeenCalledWith( - expect.any(Element), - expect.objectContaining({ - groupId: 'a', - accessor: 'newid', - }) - ); }); it('should keep the popover open when configuring a new dimension', () => { @@ -267,5 +271,56 @@ describe('LayerPanel', () => { expect(component.find(EuiPopover).prop('isOpen')).toBe(true); }); + it('should close the popover when the active visualization changes', () => { + /** + * The ID generation system for new dimensions has been messy before, so + * this tests that the ID used in the first render is used to keep the popover + * open in future renders + */ + + (generateId as jest.Mock).mockReturnValueOnce(`newid`); + (generateId as jest.Mock).mockReturnValueOnce(`bad`); + mockVisualization.getConfiguration.mockReturnValueOnce({ + groups: [ + { + groupLabel: 'A', + groupId: 'a', + accessors: [], + filterOperations: () => true, + supportsMoreColumns: true, + dataTestSubj: 'lnsGroup', + }, + ], + }); + // Normally the configuration would change in response to a state update, + // but this test is updating it directly + mockVisualization.getConfiguration.mockReturnValueOnce({ + groups: [ + { + groupLabel: 'A', + groupId: 'a', + accessors: ['newid'], + filterOperations: () => true, + supportsMoreColumns: false, + dataTestSubj: 'lnsGroup', + }, + ], + }); + + const component = mountWithIntl(); + + const group = component.find('DimensionPopover'); + const triggerButton = mountWithIntl(group.prop('trigger')); + act(() => { + triggerButton.find('[data-test-subj="lns-empty-dimension"]').first().simulate('click'); + }); + component.update(); + expect(component.find(EuiPopover).prop('isOpen')).toBe(true); + act(() => { + component.setProps({ activeVisualizationId: 'vis2' }); + }); + component.update(); + expect(component.find(EuiPopover).prop('isOpen')).toBe(false); + }); }); }); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index f72b1429967d2..a384e339e8fbd 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext, useState } from 'react'; +import React, { useContext, useState, useEffect } from 'react'; import { EuiPanel, EuiSpacer, @@ -26,6 +26,13 @@ import { generateId } from '../../../id_generator'; import { ConfigPanelWrapperProps, DimensionPopoverState } from './types'; import { DimensionPopover } from './dimension_popover'; +const initialPopoverState = { + isOpen: false, + openId: null, + addingToGroupId: null, + tabId: null, +}; + export function LayerPanel( props: Exclude & { layerId: string; @@ -41,15 +48,15 @@ export function LayerPanel( } ) { const dragDropContext = useContext(DragContext); - const [popoverState, setPopoverState] = useState({ - isOpen: false, - openId: null, - addingToGroupId: null, - tabId: null, - }); + const [popoverState, setPopoverState] = useState(initialPopoverState); const { framePublicAPI, layerId, isOnlyLayer, onRemoveLayer } = props; const datasourcePublicAPI = framePublicAPI.datasourceLayers[layerId]; + + useEffect(() => { + setPopoverState(initialPopoverState); + }, [props.activeVisualizationId]); + if ( !datasourcePublicAPI || !props.activeVisualizationId || @@ -243,12 +250,7 @@ export function LayerPanel( suggestedPriority: group.suggestedPriority, togglePopover: () => { if (popoverState.isOpen) { - setPopoverState({ - isOpen: false, - openId: null, - addingToGroupId: null, - tabId: null, - }); + setPopoverState(initialPopoverState); } else { setPopoverState({ isOpen: true, @@ -264,7 +266,7 @@ export function LayerPanel( panel={ t.id === popoverState.tabId)} + selectedTab={tabs.find((t) => t.id === popoverState.tabId) || tabs[0]} size="s" onTabClick={(tab) => { setPopoverState({ @@ -358,12 +360,7 @@ export function LayerPanel( })} onClick={() => { if (popoverState.isOpen) { - setPopoverState({ - isOpen: false, - openId: null, - addingToGroupId: null, - tabId: null, - }); + setPopoverState(initialPopoverState); } else { setPopoverState({ isOpen: true, From 5c770e5930f3302ded04a62d4f3f0125bb4ce7fb Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Wed, 5 Aug 2020 17:35:38 +0100 Subject: [PATCH 013/106] [Task Manager] Correctly handle `running` tasks when calling RunNow and reduce flakiness in related tests (#73244) This PR addresses two issues which caused several tests to be flaky in TM. When `runNow` was introduced to TM we added a pinned query which returned specific tasks by ID. This query does not have the filter applied to it which causes task to return when they're already marked as `running` but we didn't address these correctly which caused flakyness in the tests. This didn't cause a broken beahviour, but it did cause beahviour that was hard to reason about - we now address them correctly. It seems that sometimes, especially if the ES queue is overworked, it can take some time for the update to the underlying task to be visible (we don't user `refresh:true` on purpose), so adding a wait for the index to refresh to make sure the task is updated in time for the next stage of the test. --- x-pack/plugins/alerts/server/alerts_client.ts | 17 ++- .../task_manager/server/task_events.ts | 6 +- .../task_manager/server/task_manager.test.ts | 31 ++-- .../task_manager/server/task_manager.ts | 104 +++++++------ .../task_manager/server/task_store.test.ts | 142 +++++++++++++++--- .../plugins/task_manager/server/task_store.ts | 37 ++++- .../task_manager_fixture/server/plugin.ts | 20 ++- .../sample_task_plugin/server/init_routes.ts | 15 ++ .../task_manager/task_manager_integration.js | 34 ++++- 9 files changed, 316 insertions(+), 90 deletions(-) diff --git a/x-pack/plugins/alerts/server/alerts_client.ts b/x-pack/plugins/alerts/server/alerts_client.ts index 256cae24e519f..dd66ccc7a0256 100644 --- a/x-pack/plugins/alerts/server/alerts_client.ts +++ b/x-pack/plugins/alerts/server/alerts_client.ts @@ -387,11 +387,18 @@ export class AlertsClient { updateResult.scheduledTaskId && !isEqual(alertSavedObject.attributes.schedule, updateResult.schedule) ) { - this.taskManager.runNow(updateResult.scheduledTaskId).catch((err: Error) => { - this.logger.error( - `Alert update failed to run its underlying task. TaskManager runNow failed with Error: ${err.message}` - ); - }); + this.taskManager + .runNow(updateResult.scheduledTaskId) + .then(() => { + this.logger.debug( + `Alert update has rescheduled the underlying task: ${updateResult.scheduledTaskId}` + ); + }) + .catch((err: Error) => { + this.logger.error( + `Alert update failed to run its underlying task. TaskManager runNow failed with Error: ${err.message}` + ); + }); } })(), ]); diff --git a/x-pack/plugins/task_manager/server/task_events.ts b/x-pack/plugins/task_manager/server/task_events.ts index b17a3636c1730..e1dd85f868cdd 100644 --- a/x-pack/plugins/task_manager/server/task_events.ts +++ b/x-pack/plugins/task_manager/server/task_events.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Option } from 'fp-ts/lib/Option'; + import { ConcreteTaskInstance } from './task'; import { Result, Err } from './lib/result_type'; @@ -22,7 +24,7 @@ export interface TaskEvent { } export type TaskMarkRunning = TaskEvent; export type TaskRun = TaskEvent; -export type TaskClaim = TaskEvent; +export type TaskClaim = TaskEvent>; export type TaskRunRequest = TaskEvent; export function asTaskMarkRunningEvent( @@ -46,7 +48,7 @@ export function asTaskRunEvent(id: string, event: Result + event: Result> ): TaskClaim { return { id, diff --git a/x-pack/plugins/task_manager/server/task_manager.test.ts b/x-pack/plugins/task_manager/server/task_manager.test.ts index 80215ffa7abba..7035971ad6061 100644 --- a/x-pack/plugins/task_manager/server/task_manager.test.ts +++ b/x-pack/plugins/task_manager/server/task_manager.test.ts @@ -7,6 +7,7 @@ import _ from 'lodash'; import sinon from 'sinon'; import { Subject } from 'rxjs'; +import { none } from 'fp-ts/lib/Option'; import { asTaskMarkRunningEvent, @@ -297,7 +298,9 @@ describe('TaskManager', () => { events$.next(asTaskMarkRunningEvent(id, asOk(task))); events$.next(asTaskRunEvent(id, asErr(new Error('some thing gone wrong')))); - return expect(result).rejects.toEqual(new Error('some thing gone wrong')); + return expect(result).rejects.toMatchInlineSnapshot( + `[Error: Failed to run task "01ddff11-e88a-4d13-bc4e-256164e755e2": Error: some thing gone wrong]` + ); }); test('rejects when the task mark as running fails', () => { @@ -311,7 +314,9 @@ describe('TaskManager', () => { events$.next(asTaskClaimEvent(id, asOk(task))); events$.next(asTaskMarkRunningEvent(id, asErr(new Error('some thing gone wrong')))); - return expect(result).rejects.toEqual(new Error('some thing gone wrong')); + return expect(result).rejects.toMatchInlineSnapshot( + `[Error: Failed to run task "01ddff11-e88a-4d13-bc4e-256164e755e2": Error: some thing gone wrong]` + ); }); test('when a task claim fails we ensure the task exists', async () => { @@ -321,7 +326,7 @@ describe('TaskManager', () => { const result = awaitTaskRunResult(id, events$, getLifecycle); - events$.next(asTaskClaimEvent(id, asErr(new Error('failed to claim')))); + events$.next(asTaskClaimEvent(id, asErr(none))); await expect(result).rejects.toEqual( new Error(`Failed to run task "${id}" as it does not exist`) @@ -337,7 +342,7 @@ describe('TaskManager', () => { const result = awaitTaskRunResult(id, events$, getLifecycle); - events$.next(asTaskClaimEvent(id, asErr(new Error('failed to claim')))); + events$.next(asTaskClaimEvent(id, asErr(none))); await expect(result).rejects.toEqual( new Error(`Failed to run task "${id}" as it is currently running`) @@ -353,7 +358,7 @@ describe('TaskManager', () => { const result = awaitTaskRunResult(id, events$, getLifecycle); - events$.next(asTaskClaimEvent(id, asErr(new Error('failed to claim')))); + events$.next(asTaskClaimEvent(id, asErr(none))); await expect(result).rejects.toEqual( new Error(`Failed to run task "${id}" as it is currently running`) @@ -386,9 +391,11 @@ describe('TaskManager', () => { const result = awaitTaskRunResult(id, events$, getLifecycle); - events$.next(asTaskClaimEvent(id, asErr(new Error('failed to claim')))); + events$.next(asTaskClaimEvent(id, asErr(none))); - await expect(result).rejects.toEqual(new Error('failed to claim')); + await expect(result).rejects.toMatchInlineSnapshot( + `[Error: Failed to run task "01ddff11-e88a-4d13-bc4e-256164e755e2" for unknown reason (Current Task Lifecycle is "idle")]` + ); expect(getLifecycle).toHaveBeenCalledWith(id); }); @@ -400,9 +407,11 @@ describe('TaskManager', () => { const result = awaitTaskRunResult(id, events$, getLifecycle); - events$.next(asTaskClaimEvent(id, asErr(new Error('failed to claim')))); + events$.next(asTaskClaimEvent(id, asErr(none))); - await expect(result).rejects.toEqual(new Error('failed to claim')); + await expect(result).rejects.toMatchInlineSnapshot( + `[Error: Failed to run task "01ddff11-e88a-4d13-bc4e-256164e755e2" for unknown reason (Current Task Lifecycle is "failed")]` + ); expect(getLifecycle).toHaveBeenCalledWith(id); }); @@ -424,7 +433,9 @@ describe('TaskManager', () => { events$.next(asTaskRunEvent(id, asErr(new Error('some thing gone wrong')))); - return expect(result).rejects.toEqual(new Error('some thing gone wrong')); + return expect(result).rejects.toMatchInlineSnapshot( + `[Error: Failed to run task "01ddff11-e88a-4d13-bc4e-256164e755e2": Error: some thing gone wrong]` + ); }); }); }); diff --git a/x-pack/plugins/task_manager/server/task_manager.ts b/x-pack/plugins/task_manager/server/task_manager.ts index 35ca439bb9130..7165fd28678c1 100644 --- a/x-pack/plugins/task_manager/server/task_manager.ts +++ b/x-pack/plugins/task_manager/server/task_manager.ts @@ -9,13 +9,14 @@ import { filter } from 'rxjs/operators'; import { performance } from 'perf_hooks'; import { pipe } from 'fp-ts/lib/pipeable'; -import { Option, some, map as mapOptional } from 'fp-ts/lib/Option'; +import { Option, some, map as mapOptional, getOrElse } from 'fp-ts/lib/Option'; + import { SavedObjectsSerializer, ILegacyScopedClusterClient, ISavedObjectsRepository, } from '../../../../src/core/server'; -import { Result, asErr, either, map, mapErr, promiseResult } from './lib/result_type'; +import { Result, asOk, asErr, either, map, mapErr, promiseResult } from './lib/result_type'; import { TaskManagerConfig } from './config'; import { Logger } from './types'; @@ -405,7 +406,9 @@ export async function claimAvailableTasks( if (docs.length !== claimedTasks) { logger.warn( - `[Task Ownership error]: (${claimedTasks}) tasks were claimed by Kibana, but (${docs.length}) tasks were fetched` + `[Task Ownership error]: ${claimedTasks} tasks were claimed by Kibana, but ${ + docs.length + } task(s) were fetched (${docs.map((doc) => doc.id).join(', ')})` ); } return docs; @@ -437,48 +440,65 @@ export async function awaitTaskRunResult( // listen for all events related to the current task .pipe(filter(({ id }: TaskLifecycleEvent) => id === taskId)) .subscribe((taskEvent: TaskLifecycleEvent) => { - either( - taskEvent.event, - (taskInstance: ConcreteTaskInstance) => { - // resolve if the task has run sucessfully - if (isTaskRunEvent(taskEvent)) { - subscription.unsubscribe(); - resolve({ id: taskInstance.id }); - } - }, - async (error: Error) => { + if (isTaskClaimEvent(taskEvent)) { + mapErr(async (error: Option) => { // reject if any error event takes place for the requested task subscription.unsubscribe(); - if (isTaskRunRequestEvent(taskEvent)) { - return reject( - new Error( - `Failed to run task "${taskId}" as Task Manager is at capacity, please try again later` - ) - ); - } else if (isTaskClaimEvent(taskEvent)) { - reject( - map( - // if the error happened in the Claim phase - we try to provide better insight - // into why we failed to claim by getting the task's current lifecycle status - await promiseResult(getLifecycle(taskId)), - (taskLifecycleStatus: TaskLifecycle) => { - if (taskLifecycleStatus === TaskLifecycleResult.NotFound) { - return new Error(`Failed to run task "${taskId}" as it does not exist`); - } else if ( - taskLifecycleStatus === TaskStatus.Running || - taskLifecycleStatus === TaskStatus.Claiming - ) { - return new Error(`Failed to run task "${taskId}" as it is currently running`); - } - return error; - }, - () => error - ) - ); + return reject( + map( + await pipe( + error, + mapOptional(async (taskReturnedBySweep) => asOk(taskReturnedBySweep.status)), + getOrElse(() => + // if the error happened in the Claim phase - we try to provide better insight + // into why we failed to claim by getting the task's current lifecycle status + promiseResult(getLifecycle(taskId)) + ) + ), + (taskLifecycleStatus: TaskLifecycle) => { + if (taskLifecycleStatus === TaskLifecycleResult.NotFound) { + return new Error(`Failed to run task "${taskId}" as it does not exist`); + } else if ( + taskLifecycleStatus === TaskStatus.Running || + taskLifecycleStatus === TaskStatus.Claiming + ) { + return new Error(`Failed to run task "${taskId}" as it is currently running`); + } + return new Error( + `Failed to run task "${taskId}" for unknown reason (Current Task Lifecycle is "${taskLifecycleStatus}")` + ); + }, + (getLifecycleError: Error) => + new Error( + `Failed to run task "${taskId}" and failed to get current Status:${getLifecycleError}` + ) + ) + ); + }, taskEvent.event); + } else { + either>( + taskEvent.event, + (taskInstance: ConcreteTaskInstance) => { + // resolve if the task has run sucessfully + if (isTaskRunEvent(taskEvent)) { + subscription.unsubscribe(); + resolve({ id: taskInstance.id }); + } + }, + async (error: Error | Option) => { + // reject if any error event takes place for the requested task + subscription.unsubscribe(); + if (isTaskRunRequestEvent(taskEvent)) { + return reject( + new Error( + `Failed to run task "${taskId}" as Task Manager is at capacity, please try again later` + ) + ); + } + return reject(new Error(`Failed to run task "${taskId}": ${error}`)); } - return reject(error); - } - ); + ); + } }); }); } diff --git a/x-pack/plugins/task_manager/server/task_store.test.ts b/x-pack/plugins/task_manager/server/task_store.test.ts index 771b4e2d7d9cb..d65c39f4f454d 100644 --- a/x-pack/plugins/task_manager/server/task_store.test.ts +++ b/x-pack/plugins/task_manager/server/task_store.test.ts @@ -8,6 +8,7 @@ import _ from 'lodash'; import sinon from 'sinon'; import uuid from 'uuid'; import { filter } from 'rxjs/operators'; +import { Option, some, none } from 'fp-ts/lib/Option'; import { TaskDictionary, @@ -972,7 +973,7 @@ if (doc['task.runAt'].size()!=0) { const runAt = new Date(); const tasks = [ { - _id: 'aaa', + _id: 'claimed-by-id', _source: { type: 'task', task: { @@ -980,7 +981,7 @@ if (doc['task.runAt'].size()!=0) { taskType: 'foo', schedule: undefined, attempts: 0, - status: 'idle', + status: 'claiming', params: '{ "hello": "world" }', state: '{ "baby": "Henhen" }', user: 'jimbo', @@ -996,7 +997,31 @@ if (doc['task.runAt'].size()!=0) { sort: ['a', 1], }, { - _id: 'bbb', + _id: 'claimed-by-schedule', + _source: { + type: 'task', + task: { + runAt, + taskType: 'bar', + schedule: { interval: '5m' }, + attempts: 2, + status: 'claiming', + params: '{ "shazm": 1 }', + state: '{ "henry": "The 8th" }', + user: 'dabo', + scope: ['reporting', 'ceo'], + ownerId: taskManagerId, + startedAt: null, + retryAt: null, + scheduledAt: new Date(), + }, + }, + _seq_no: 3, + _primary_term: 4, + sort: ['b', 2], + }, + { + _id: 'already-running', _source: { type: 'task', task: { @@ -1045,19 +1070,24 @@ if (doc['task.runAt'].size()!=0) { }); const sub = store.events - .pipe(filter((event: TaskEvent) => event.id === 'aaa')) + .pipe( + filter( + (event: TaskEvent>) => + event.id === 'claimed-by-id' + ) + ) .subscribe({ - next: (event: TaskEvent) => { + next: (event: TaskEvent>) => { expect(event).toMatchObject( asTaskClaimEvent( - 'aaa', + 'claimed-by-id', asOk({ - id: 'aaa', + id: 'claimed-by-id', runAt, taskType: 'foo', schedule: undefined, attempts: 0, - status: 'idle' as TaskStatus, + status: 'claiming' as TaskStatus, params: { hello: 'world' }, state: { baby: 'Henhen' }, user: 'jimbo', @@ -1075,7 +1105,7 @@ if (doc['task.runAt'].size()!=0) { }); await store.claimAvailableTasks({ - claimTasksById: ['aaa'], + claimTasksById: ['claimed-by-id'], claimOwnershipUntil: new Date(), size: 10, }); @@ -1102,19 +1132,24 @@ if (doc['task.runAt'].size()!=0) { }); const sub = store.events - .pipe(filter((event: TaskEvent) => event.id === 'bbb')) + .pipe( + filter( + (event: TaskEvent>) => + event.id === 'claimed-by-schedule' + ) + ) .subscribe({ - next: (event: TaskEvent) => { + next: (event: TaskEvent>) => { expect(event).toMatchObject( asTaskClaimEvent( - 'bbb', + 'claimed-by-schedule', asOk({ - id: 'bbb', + id: 'claimed-by-schedule', runAt, taskType: 'bar', schedule: { interval: '5m' }, attempts: 2, - status: 'running' as TaskStatus, + status: 'claiming' as TaskStatus, params: { shazm: 1 }, state: { henry: 'The 8th' }, user: 'dabo', @@ -1132,14 +1167,14 @@ if (doc['task.runAt'].size()!=0) { }); await store.claimAvailableTasks({ - claimTasksById: ['aaa'], + claimTasksById: ['claimed-by-id'], claimOwnershipUntil: new Date(), size: 10, }); }); test('emits an event when the store fails to claim a required task by id', async (done) => { - const { taskManagerId, tasks } = generateTasks(); + const { taskManagerId, runAt, tasks } = generateTasks(); const callCluster = sinon.spy(async (name: string, params?: unknown) => name === 'updateByQuery' ? { @@ -1159,11 +1194,36 @@ if (doc['task.runAt'].size()!=0) { }); const sub = store.events - .pipe(filter((event: TaskEvent) => event.id === 'ccc')) + .pipe( + filter( + (event: TaskEvent>) => + event.id === 'already-running' + ) + ) .subscribe({ - next: (event: TaskEvent) => { + next: (event: TaskEvent>) => { expect(event).toMatchObject( - asTaskClaimEvent('ccc', asErr(new Error(`failed to claim task 'ccc'`))) + asTaskClaimEvent( + 'already-running', + asErr( + some({ + id: 'already-running', + runAt, + taskType: 'bar', + schedule: { interval: '5m' }, + attempts: 2, + status: 'running' as TaskStatus, + params: { shazm: 1 }, + state: { henry: 'The 8th' }, + user: 'dabo', + scope: ['reporting', 'ceo'], + ownerId: taskManagerId, + startedAt: null, + retryAt: null, + scheduledAt: new Date(), + }) + ) + ) ); sub.unsubscribe(); done(); @@ -1171,7 +1231,49 @@ if (doc['task.runAt'].size()!=0) { }); await store.claimAvailableTasks({ - claimTasksById: ['ccc'], + claimTasksById: ['already-running'], + claimOwnershipUntil: new Date(), + size: 10, + }); + }); + + test('emits an event when the store fails to find a task which was required by id', async (done) => { + const { taskManagerId, tasks } = generateTasks(); + const callCluster = sinon.spy(async (name: string, params?: unknown) => + name === 'updateByQuery' + ? { + total: tasks.length, + updated: tasks.length, + } + : { hits: { hits: tasks } } + ); + const store = new TaskStore({ + callCluster, + maxAttempts: 2, + definitions: taskDefinitions, + serializer, + savedObjectsRepository: savedObjectsClient, + taskManagerId, + index: '', + }); + + const sub = store.events + .pipe( + filter( + (event: TaskEvent>) => + event.id === 'unknown-task' + ) + ) + .subscribe({ + next: (event: TaskEvent>) => { + expect(event).toMatchObject(asTaskClaimEvent('unknown-task', asErr(none))); + sub.unsubscribe(); + done(); + }, + }); + + await store.claimAvailableTasks({ + claimTasksById: ['unknown-task'], claimOwnershipUntil: new Date(), size: 10, }); diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index cac37db72202d..a18fb57b35b3d 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -9,7 +9,9 @@ */ import apm from 'elastic-apm-node'; import { Subject, Observable } from 'rxjs'; -import { omit, difference, defaults } from 'lodash'; +import { omit, difference, partition, map, defaults } from 'lodash'; + +import { some, none } from 'fp-ts/lib/Option'; import { SearchResponse, UpdateDocumentByQueryResponse } from 'elasticsearch'; import { @@ -31,6 +33,7 @@ import { TaskLifecycle, TaskLifecycleResult, SerializedConcreteTaskInstance, + TaskStatus, } from './task'; import { TaskClaim, asTaskClaimEvent } from './task_events'; @@ -221,13 +224,35 @@ export class TaskStore { // emit success/fail events for claimed tasks by id if (claimTasksById && claimTasksById.length) { - this.emitEvents(docs.map((doc) => asTaskClaimEvent(doc.id, asOk(doc)))); + const [documentsReturnedById, documentsClaimedBySchedule] = partition(docs, (doc) => + claimTasksById.includes(doc.id) + ); + + const [documentsClaimedById, documentsRequestedButNotClaimed] = partition( + documentsReturnedById, + // we filter the schduled tasks down by status is 'claiming' in the esearch, + // but we do not apply this limitation on tasks claimed by ID so that we can + // provide more detailed error messages when we fail to claim them + (doc) => doc.status === TaskStatus.Claiming + ); + + const documentsRequestedButNotReturned = difference( + claimTasksById, + map(documentsReturnedById, 'id') + ); + + this.emitEvents( + [...documentsClaimedById, ...documentsClaimedBySchedule].map((doc) => + asTaskClaimEvent(doc.id, asOk(doc)) + ) + ); + + this.emitEvents( + documentsRequestedButNotClaimed.map((doc) => asTaskClaimEvent(doc.id, asErr(some(doc)))) + ); this.emitEvents( - difference( - claimTasksById, - docs.map((doc) => doc.id) - ).map((id) => asTaskClaimEvent(id, asErr(new Error(`failed to claim task '${id}'`)))) + documentsRequestedButNotReturned.map((id) => asTaskClaimEvent(id, asErr(none))) ); } diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts index 18fdd5f9c3ac3..0833dd0425894 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts @@ -51,7 +51,8 @@ export class SampleTaskManagerFixturePlugin .toPromise(); public setup(core: CoreSetup) { - core.http.createRouter().get( + const router = core.http.createRouter(); + router.get( { path: '/api/alerting_tasks/{taskId}', validate: { @@ -77,6 +78,23 @@ export class SampleTaskManagerFixturePlugin } } ); + + router.get( + { + path: `/api/ensure_tasks_index_refreshed`, + validate: {}, + }, + async function ( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + await core.elasticsearch.legacy.client.callAsInternalUser('indices.refresh', { + index: '.kibana_task_manager', + }); + return res.ok({ body: {} }); + } + ); } public start(core: CoreStart, { taskManager }: SampleTaskManagerFixtureStartDeps) { diff --git a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts index f35d6baac8f5a..266e66b5a1a45 100644 --- a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts +++ b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts @@ -223,6 +223,21 @@ export function initRoutes( } ); + router.get( + { + path: `/api/ensure_tasks_index_refreshed`, + validate: {}, + }, + async function ( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + await ensureIndexIsRefreshed(); + return res.ok({ body: {} }); + } + ); + router.delete( { path: `/api/sample_tasks`, diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js index 165e79fb311ea..c87a5039360b8 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js @@ -28,8 +28,7 @@ export default function ({ getService }) { const testHistoryIndex = '.kibana_task_manager_test_result'; const supertest = supertestAsPromised(url.format(config.get('servers.kibana'))); - // FLAKY: https://github.com/elastic/kibana/issues/71390 - describe.skip('scheduling and running tasks', () => { + describe('scheduling and running tasks', () => { beforeEach( async () => await supertest.delete('/api/sample_tasks').set('kbn-xsrf', 'xxx').expect(200) ); @@ -69,6 +68,14 @@ export default function ({ getService }) { .then((response) => response.body); } + function ensureTasksIndexRefreshed() { + return supertest + .get(`/api/ensure_tasks_index_refreshed`) + .send({}) + .expect(200) + .then((response) => response.body); + } + function historyDocs(taskId) { return es .search({ @@ -404,7 +411,7 @@ export default function ({ getService }) { const originalTask = await scheduleTask({ taskType: 'sampleTask', schedule: { interval: `30m` }, - params: { failWith: 'error on run now', failOn: 3 }, + params: { failWith: 'this task was meant to fail!', failOn: 3 }, }); await retry.try(async () => { @@ -415,11 +422,14 @@ export default function ({ getService }) { const task = await currentTask(originalTask.id); expect(task.state.count).to.eql(1); + expect(task.status).to.eql('idle'); // ensure this task shouldnt run for another half hour expectReschedule(Date.parse(originalTask.runAt), task, 30 * 60000); }); + await ensureTasksIndexRefreshed(); + // second run should still be successful const successfulRunNowResult = await runTaskNow({ id: originalTask.id, @@ -429,14 +439,20 @@ export default function ({ getService }) { await retry.try(async () => { const task = await currentTask(originalTask.id); expect(task.state.count).to.eql(2); + expect(task.status).to.eql('idle'); }); + await ensureTasksIndexRefreshed(); + // third run should fail const failedRunNowResult = await runTaskNow({ id: originalTask.id, }); - expect(failedRunNowResult).to.eql({ id: originalTask.id, error: `Error: error on run now` }); + expect(failedRunNowResult).to.eql({ + id: originalTask.id, + error: `Error: Failed to run task \"${originalTask.id}\": Error: this task was meant to fail!`, + }); await retry.try(async () => { expect( @@ -479,8 +495,13 @@ export default function ({ getService }) { expect( docs.filter((taskDoc) => taskDoc._source.taskId === longRunningTask.id).length ).to.eql(1); + + const task = await currentTask(longRunningTask.id); + expect(task.status).to.eql('running'); }); + await ensureTasksIndexRefreshed(); + // first runNow should fail const failedRunNowResult = await runTaskNow({ id: longRunningTask.id, @@ -496,8 +517,13 @@ export default function ({ getService }) { await retry.try(async () => { const tasks = (await currentTasks()).docs; expect(getTaskById(tasks, longRunningTask.id).state.count).to.eql(1); + + const task = await currentTask(longRunningTask.id); + expect(task.status).to.eql('idle'); }); + await ensureTasksIndexRefreshed(); + // second runNow should be successful const successfulRunNowResult = runTaskNow({ id: longRunningTask.id, From 4150a234c8f4517725b79ead280285b49890e17c Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Wed, 5 Aug 2020 12:43:58 -0400 Subject: [PATCH 014/106] update empty prompt in analytics list (#74174) --- .../components/analytics_list/analytics_list.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx index 7b5c714c236b3..90e24f6da5d0a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import { Direction, - EuiButtonEmpty, + EuiButton, EuiCallOut, EuiEmptyPrompt, EuiFlexGroup, @@ -147,25 +147,29 @@ export const DataFrameAnalyticsList: FC = ({ return ( <> {i18n.translate('xpack.ml.dataFrame.analyticsList.emptyPromptTitle', { - defaultMessage: 'No data frame analytics jobs found', + defaultMessage: 'Create your first data frame analytics job', })} } actions={ !isManagementTable ? [ - setIsSourceIndexModalVisible(true)} isDisabled={disabled} + color="primary" + iconType="plusInCircle" + fill data-test-subj="mlAnalyticsCreateFirstButton" > {i18n.translate('xpack.ml.dataFrame.analyticsList.emptyPromptButtonText', { - defaultMessage: 'Create your first data frame analytics job', + defaultMessage: 'Create job', })} - , + , ] : [] } From 47b9aba3bf0ce6a5a867fa144701ad1841020f7c Mon Sep 17 00:00:00 2001 From: Constance Date: Wed, 5 Aug 2020 10:12:25 -0700 Subject: [PATCH 015/106] [Enterprise Search] Fix/DRY out plugin i18n strings (#74323) * i18n refactor - DRY out plugin details to constants and correctly i18n-ize front-end-facing strings * DRY out new i18n constants - refactor instances of i18n.translate to use new constants * Fix non-i18n'd breadcrumb strings * PR feedback: swap out more plugin ID strings for constants --- .../enterprise_search/common/constants.ts | 34 +++++++++++++++++++ .../components/setup_guide/setup_guide.tsx | 11 +++--- .../generate_breadcrumbs.ts | 18 ++++++++-- .../components/error_state/error_state.tsx | 8 ++--- .../components/setup_guide/setup_guide.tsx | 12 ++++--- .../enterprise_search/public/plugin.ts | 31 ++++++++--------- .../enterprise_search/server/plugin.ts | 15 +++++--- 7 files changed, 90 insertions(+), 39 deletions(-) diff --git a/x-pack/plugins/enterprise_search/common/constants.ts b/x-pack/plugins/enterprise_search/common/constants.ts index fc9a47717871b..c5839df4c603b 100644 --- a/x-pack/plugins/enterprise_search/common/constants.ts +++ b/x-pack/plugins/enterprise_search/common/constants.ts @@ -4,6 +4,40 @@ * you may not use this file except in compliance with the Elastic License. */ +import { i18n } from '@kbn/i18n'; + +export const ENTERPRISE_SEARCH_PLUGIN = { + ID: 'enterpriseSearch', + NAME: i18n.translate('xpack.enterpriseSearch.productName', { + defaultMessage: 'Enterprise Search', + }), + URL: '/app/enterprise_search', +}; + +export const APP_SEARCH_PLUGIN = { + ID: 'appSearch', + NAME: i18n.translate('xpack.enterpriseSearch.appSearch.productName', { + defaultMessage: 'App Search', + }), + DESCRIPTION: i18n.translate('xpack.enterpriseSearch.appSearch.productDescription', { + defaultMessage: + 'Leverage dashboards, analytics, and APIs for advanced application search made simple.', + }), + URL: '/app/enterprise_search/app_search', +}; + +export const WORKPLACE_SEARCH_PLUGIN = { + ID: 'workplaceSearch', + NAME: i18n.translate('xpack.enterpriseSearch.workplaceSearch.productName', { + defaultMessage: 'Workplace Search', + }), + DESCRIPTION: i18n.translate('xpack.enterpriseSearch.workplaceSearch.productDescription', { + defaultMessage: + 'Search all documents, files, and sources available across your virtual workplace.', + }), + URL: '/app/enterprise_search/workplace_search', +}; + export const JSON_HEADER = { 'Content-Type': 'application/json' }; // This needs specific casing or Chrome throws a 415 error export const ENGINES_PAGE_SIZE = 10; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx index df278bf938a69..f899423319afc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx @@ -9,6 +9,7 @@ import { EuiSpacer, EuiTitle, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; +import { APP_SEARCH_PLUGIN } from '../../../../../common/constants'; import { SetupGuide as SetupGuideLayout } from '../../../shared/setup_guide'; import { SetAppSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; @@ -16,14 +17,16 @@ import GettingStarted from '../../assets/getting_started.png'; export const SetupGuide: React.FC = () => ( - + ( breadcrumbs: TBreadcrumbs = [] ) => [ - generateBreadcrumb({ text: 'Enterprise Search' }), + generateBreadcrumb({ text: ENTERPRISE_SEARCH_PLUGIN.NAME }), ...breadcrumbs.map(({ text, path }: IGenerateBreadcrumbProps) => generateBreadcrumb({ text, path, history }) ), ]; export const appSearchBreadcrumbs = (history: History) => (breadcrumbs: TBreadcrumbs = []) => - enterpriseSearchBreadcrumbs(history)([{ text: 'App Search', path: '/' }, ...breadcrumbs]); + enterpriseSearchBreadcrumbs(history)([ + { text: APP_SEARCH_PLUGIN.NAME, path: '/' }, + ...breadcrumbs, + ]); export const workplaceSearchBreadcrumbs = (history: History) => (breadcrumbs: TBreadcrumbs = []) => - enterpriseSearchBreadcrumbs(history)([{ text: 'Workplace Search', path: '/' }, ...breadcrumbs]); + enterpriseSearchBreadcrumbs(history)([ + { text: WORKPLACE_SEARCH_PLUGIN.NAME, path: '/' }, + ...breadcrumbs, + ]); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx index 9fa508d599425..a1bc17e05dc05 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx @@ -6,8 +6,8 @@ import React from 'react'; import { EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; +import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; import { ErrorStatePrompt } from '../../../shared/error_state'; import { SetWorkplaceSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; @@ -20,11 +20,7 @@ export const ErrorState: React.FC = () => { - + diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx index 5b5d067d23eb8..e96d114c67c5d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx @@ -9,8 +9,8 @@ import { EuiSpacer, EuiTitle, EuiText, EuiButton } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; +import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; import { SetupGuide as SetupGuideLayout } from '../../../shared/setup_guide'; - import { SetWorkplaceSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import GettingStarted from '../../assets/getting_started.png'; @@ -21,14 +21,16 @@ const GETTING_STARTED_LINK_URL = export const SetupGuide: React.FC = () => { return ( - + diff --git a/x-pack/plugins/enterprise_search/public/plugin.ts b/x-pack/plugins/enterprise_search/public/plugin.ts index fc95828a3f4a4..66d2ae82fe3ce 100644 --- a/x-pack/plugins/enterprise_search/public/plugin.ts +++ b/x-pack/plugins/enterprise_search/public/plugin.ts @@ -20,6 +20,7 @@ import { import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public'; import { LicensingPluginSetup } from '../../licensing/public'; +import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../common/constants'; import { getPublicUrl } from './applications/shared/enterprise_search_url'; import AppSearchLogo from './applications/app_search/assets/logo.svg'; import WorkplaceSearchLogo from './applications/workplace_search/assets/logo.svg'; @@ -44,9 +45,9 @@ export class EnterpriseSearchPlugin implements Plugin { const config = { host: this.config.host }; core.application.register({ - id: 'appSearch', - title: 'App Search', - appRoute: '/app/enterprise_search/app_search', + id: APP_SEARCH_PLUGIN.ID, + title: APP_SEARCH_PLUGIN.NAME, + appRoute: APP_SEARCH_PLUGIN.URL, category: DEFAULT_APP_CATEGORIES.enterpriseSearch, mount: async (params: AppMountParameters) => { const [coreStart] = await core.getStartServices(); @@ -61,9 +62,9 @@ export class EnterpriseSearchPlugin implements Plugin { }); core.application.register({ - id: 'workplaceSearch', - title: 'Workplace Search', - appRoute: '/app/enterprise_search/workplace_search', + id: WORKPLACE_SEARCH_PLUGIN.ID, + title: WORKPLACE_SEARCH_PLUGIN.NAME, + appRoute: WORKPLACE_SEARCH_PLUGIN.URL, category: DEFAULT_APP_CATEGORIES.enterpriseSearch, mount: async (params: AppMountParameters) => { const [coreStart] = await core.getStartServices(); @@ -76,23 +77,21 @@ export class EnterpriseSearchPlugin implements Plugin { }); plugins.home.featureCatalogue.register({ - id: 'appSearch', - title: 'App Search', + id: APP_SEARCH_PLUGIN.ID, + title: APP_SEARCH_PLUGIN.NAME, icon: AppSearchLogo, - description: - 'Leverage dashboards, analytics, and APIs for advanced application search made simple.', - path: '/app/enterprise_search/app_search', + description: APP_SEARCH_PLUGIN.DESCRIPTION, + path: APP_SEARCH_PLUGIN.URL, category: FeatureCatalogueCategory.DATA, showOnHomePage: true, }); plugins.home.featureCatalogue.register({ - id: 'workplaceSearch', - title: 'Workplace Search', + id: WORKPLACE_SEARCH_PLUGIN.ID, + title: WORKPLACE_SEARCH_PLUGIN.NAME, icon: WorkplaceSearchLogo, - description: - 'Search all documents, files, and sources available across your virtual workplace.', - path: '/app/enterprise_search/workplace_search', + description: WORKPLACE_SEARCH_PLUGIN.DESCRIPTION, + path: WORKPLACE_SEARCH_PLUGIN.URL, category: FeatureCatalogueCategory.DATA, showOnHomePage: true, }); diff --git a/x-pack/plugins/enterprise_search/server/plugin.ts b/x-pack/plugins/enterprise_search/server/plugin.ts index a7bd68f92f78b..6de6671337797 100644 --- a/x-pack/plugins/enterprise_search/server/plugin.ts +++ b/x-pack/plugins/enterprise_search/server/plugin.ts @@ -19,6 +19,11 @@ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { SecurityPluginSetup } from '../../security/server'; import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server'; +import { + ENTERPRISE_SEARCH_PLUGIN, + APP_SEARCH_PLUGIN, + WORKPLACE_SEARCH_PLUGIN, +} from '../common/constants'; import { ConfigType } from './'; import { checkAccess } from './lib/check_access'; import { registerPublicUrlRoute } from './routes/enterprise_search/public_url'; @@ -64,13 +69,13 @@ export class EnterpriseSearchPlugin implements Plugin { * Register space/feature control */ features.registerFeature({ - id: 'enterpriseSearch', - name: 'Enterprise Search', + id: ENTERPRISE_SEARCH_PLUGIN.ID, + name: ENTERPRISE_SEARCH_PLUGIN.NAME, order: 0, icon: 'logoEnterpriseSearch', - navLinkId: 'appSearch', // TODO - remove this once functional tests no longer rely on navLinkId - app: ['kibana', 'appSearch', 'workplaceSearch'], // TODO: 'enterpriseSearch' - catalogue: ['appSearch', 'workplaceSearch'], // TODO: 'enterpriseSearch' + navLinkId: APP_SEARCH_PLUGIN.ID, // TODO - remove this once functional tests no longer rely on navLinkId + app: ['kibana', APP_SEARCH_PLUGIN.ID, WORKPLACE_SEARCH_PLUGIN.ID], + catalogue: [APP_SEARCH_PLUGIN.ID, WORKPLACE_SEARCH_PLUGIN.ID], privileges: null, }); From 41e3128ecd2ec33c4823aa98b9ae0b3a31125564 Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Wed, 5 Aug 2020 18:48:09 +0100 Subject: [PATCH 016/106] [Alerting] Reload the Alerts List when alerts are deleted (#73715) Reloads the entire Alerts list when alerts are deleted through the UI. --- .../alerts_list/components/alerts_list.tsx | 19 ++++++--------- .../apps/triggers_actions_ui/alerts.ts | 24 +++++++++++++++---- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx index 2b2897a2181b1..3d55c51e45281 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx @@ -152,6 +152,10 @@ export const AlertsList: React.FunctionComponent = () => { data: alertsResponse.data, totalItemCount: alertsResponse.total, }); + + if (!alertsResponse.data?.length && page.index > 0) { + setPage({ ...page, index: 0 }); + } } catch (e) { toastNotifications.addDanger({ title: i18n.translate( @@ -399,18 +403,9 @@ export const AlertsList: React.FunctionComponent = () => { return (
    { - if (selectedIds.length === 0 || selectedIds.length === deleted.length) { - const updatedAlerts = alertsState.data.filter( - (alert) => alert.id && !alertsToDelete.includes(alert.id) - ); - setAlertsState({ - isLoading: false, - data: updatedAlerts, - totalItemCount: alertsState.totalItemCount - deleted.length, - }); - setSelectedIds([]); - } + onDeleted={async (deleted: string[]) => { + loadAlertsData(); + setSelectedIds([]); setAlertsToDelete([]); }} onErrors={async () => { diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts.ts index fa714e8374ec7..56952919e416a 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts.ts @@ -5,6 +5,7 @@ */ import uuid from 'uuid'; +import { times } from 'lodash'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; @@ -361,11 +362,22 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); it('should delete all selection', async () => { - const createdAlert = await createAlert(); + const namePrefix = generateUniqueKey(); + let count = 0; + const createdAlertsFirstPage = await Promise.all( + times(10, () => createAlert({ name: `${namePrefix}-0${count++}` })) + ); + + const createdAlertsSecondPage = await Promise.all( + times(2, () => createAlert({ name: `${namePrefix}-1${count++}` })) + ); + await pageObjects.common.navigateToApp('triggersActions'); - await pageObjects.triggersActionsUI.searchAlerts(createdAlert.name); + await pageObjects.triggersActionsUI.searchAlerts(namePrefix); - await testSubjects.click(`checkboxSelectRow-${createdAlert.id}`); + for (const createdAlert of createdAlertsFirstPage) { + await testSubjects.click(`checkboxSelectRow-${createdAlert.id}`); + } await testSubjects.click('bulkAction'); @@ -377,9 +389,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await pageObjects.common.closeToast(); await pageObjects.common.navigateToApp('triggersActions'); - await pageObjects.triggersActionsUI.searchAlerts(createdAlert.name); + await pageObjects.triggersActionsUI.searchAlerts(namePrefix); const searchResultsAfterDelete = await pageObjects.triggersActionsUI.getAlertsList(); - expect(searchResultsAfterDelete.length).to.eql(0); + expect(searchResultsAfterDelete).to.have.length(2); + expect(searchResultsAfterDelete[0].name).to.eql(createdAlertsSecondPage[0].name); + expect(searchResultsAfterDelete[1].name).to.eql(createdAlertsSecondPage[1].name); }); }); }; From c8597ec84bebcd7c51a760bd1a13455aad8d8612 Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Wed, 5 Aug 2020 19:52:00 +0200 Subject: [PATCH 017/106] Change experimental message for visualizations (#74354) --- .../components/experimental_vis_info.tsx | 20 +++++++++++++------ .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/plugins/visualize/public/application/components/experimental_vis_info.tsx b/src/plugins/visualize/public/application/components/experimental_vis_info.tsx index 51abb3ca530a4..5f08bea60e538 100644 --- a/src/plugins/visualize/public/application/components/experimental_vis_info.tsx +++ b/src/plugins/visualize/public/application/components/experimental_vis_info.tsx @@ -26,12 +26,20 @@ export const InfoComponent = () => { <> {' '} - - GitHub - - {'.'} + defaultMessage="This visualization is experimental and is not subject to the support SLA of official GA features. + For feedback, please create an issue in {githubLink}." + values={{ + githubLink: ( + + GitHub + + ), + }} + /> ); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 7e1ce610a1948..8218904f77df9 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4529,7 +4529,6 @@ "visualize.createVisualization.noVisTypeErrorMessage": "有効なビジュアライゼーションタイプを指定してください", "visualize.editor.createBreadcrumb": "作成", "visualize.error.title": "ビジュアライゼーションエラー", - "visualize.experimentalVisInfoText": "このビジュアライゼーションは実験的なものです。フィードバックがありますか?で問題を報告してください。", "visualize.helpMenu.appName": "可視化", "visualize.linkedToSearch.unlinkSuccessNotificationText": "保存された検索「{searchTitle}」からリンクが解除されました", "visualize.listing.betaTitle": "ベータ", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e82ba7cc1d60f..21a42362bcdd3 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -4530,7 +4530,6 @@ "visualize.createVisualization.noVisTypeErrorMessage": "必须提供有效的可视化类型", "visualize.editor.createBreadcrumb": "创建", "visualize.error.title": "可视化错误", - "visualize.experimentalVisInfoText": "此可视化标记为“实验性”。想反馈?请在以下位置创建问题:", "visualize.helpMenu.appName": "Visualize", "visualize.linkedToSearch.unlinkSuccessNotificationText": "已取消与已保存搜索“{searchTitle}”的链接", "visualize.listing.betaTitle": "公测版", From c0bb5375e037e5c1b83d354fa3835731cd3e2337 Mon Sep 17 00:00:00 2001 From: Nicolas Ruflin Date: Wed, 5 Aug 2020 20:01:52 +0200 Subject: [PATCH 018/106] [Ingest Manager] Update package registry for testing to f6b01d (#74341) Many changes went into the registry and the packages recently. This is updating to the most recent version of the registry distribution currently in production. Co-authored-by: Sonja Krause-Harder --- .../ingest_manager_api_integration/apis/epm/list.ts | 2 +- .../0.1.0/dataset/test_logs/fields/fields.yml | 12 ++++++------ .../0.1.0/dataset/test_metrics/fields/fields.yml | 12 ++++++------ .../0.1.0/dataset/test/fields/fields.yml | 12 ++++++------ .../0.2.0/dataset/test/fields/fields.yml | 12 ++++++------ .../0.3.0/dataset/test/fields/fields.yml | 12 ++++++------ .../overrides/0.1.0/dataset/test/fields/fields.yml | 12 ++++++------ .../apis/package_config/create.ts | 4 ++-- x-pack/test/ingest_manager_api_integration/config.ts | 2 +- 9 files changed, 40 insertions(+), 40 deletions(-) diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts index 20414fcb90521..0b6a37d77387e 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts @@ -29,7 +29,7 @@ export default function ({ getService }: FtrProviderContext) { return response.body; }; const listResponse = await fetchPackageList(); - expect(listResponse.response.length).to.be(14); + expect(listResponse.response.length).to.be(8); } else { warnAndSkipTest(this, log); } diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/fields.yml index 12a9a03c1337b..6e003ed0ad147 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/fields.yml +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/fields.yml @@ -1,15 +1,15 @@ -- name: dataset.type +- name: data_stream.type type: constant_keyword description: > - Dataset type. -- name: dataset.name + Data stream type. +- name: data_stream.dataset type: constant_keyword description: > - Dataset name. -- name: dataset.namespace + Data stream dataset. +- name: data_stream.namespace type: constant_keyword description: > - Dataset namespace. + Data stream namespace. - name: '@timestamp' type: date description: > diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/fields.yml index 12a9a03c1337b..6e003ed0ad147 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/fields.yml +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/fields.yml @@ -1,15 +1,15 @@ -- name: dataset.type +- name: data_stream.type type: constant_keyword description: > - Dataset type. -- name: dataset.name + Data stream type. +- name: data_stream.dataset type: constant_keyword description: > - Dataset name. -- name: dataset.namespace + Data stream dataset. +- name: data_stream.namespace type: constant_keyword description: > - Dataset namespace. + Data stream namespace. - name: '@timestamp' type: date description: > diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.1.0/dataset/test/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.1.0/dataset/test/fields/fields.yml index 12a9a03c1337b..6e003ed0ad147 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.1.0/dataset/test/fields/fields.yml +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.1.0/dataset/test/fields/fields.yml @@ -1,15 +1,15 @@ -- name: dataset.type +- name: data_stream.type type: constant_keyword description: > - Dataset type. -- name: dataset.name + Data stream type. +- name: data_stream.dataset type: constant_keyword description: > - Dataset name. -- name: dataset.namespace + Data stream dataset. +- name: data_stream.namespace type: constant_keyword description: > - Dataset namespace. + Data stream namespace. - name: '@timestamp' type: date description: > diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.2.0/dataset/test/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.2.0/dataset/test/fields/fields.yml index 12a9a03c1337b..6e003ed0ad147 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.2.0/dataset/test/fields/fields.yml +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.2.0/dataset/test/fields/fields.yml @@ -1,15 +1,15 @@ -- name: dataset.type +- name: data_stream.type type: constant_keyword description: > - Dataset type. -- name: dataset.name + Data stream type. +- name: data_stream.dataset type: constant_keyword description: > - Dataset name. -- name: dataset.namespace + Data stream dataset. +- name: data_stream.namespace type: constant_keyword description: > - Dataset namespace. + Data stream namespace. - name: '@timestamp' type: date description: > diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.3.0/dataset/test/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.3.0/dataset/test/fields/fields.yml index 12a9a03c1337b..6e003ed0ad147 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.3.0/dataset/test/fields/fields.yml +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.3.0/dataset/test/fields/fields.yml @@ -1,15 +1,15 @@ -- name: dataset.type +- name: data_stream.type type: constant_keyword description: > - Dataset type. -- name: dataset.name + Data stream type. +- name: data_stream.dataset type: constant_keyword description: > - Dataset name. -- name: dataset.namespace + Data stream dataset. +- name: data_stream.namespace type: constant_keyword description: > - Dataset namespace. + Data stream namespace. - name: '@timestamp' type: date description: > diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/overrides/0.1.0/dataset/test/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/overrides/0.1.0/dataset/test/fields/fields.yml index 12a9a03c1337b..6e003ed0ad147 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/overrides/0.1.0/dataset/test/fields/fields.yml +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/overrides/0.1.0/dataset/test/fields/fields.yml @@ -1,15 +1,15 @@ -- name: dataset.type +- name: data_stream.type type: constant_keyword description: > - Dataset type. -- name: dataset.name + Data stream type. +- name: data_stream.dataset type: constant_keyword description: > - Dataset name. -- name: dataset.namespace + Data stream dataset. +- name: data_stream.namespace type: constant_keyword description: > - Dataset namespace. + Data stream namespace. - name: '@timestamp' type: date description: > diff --git a/x-pack/test/ingest_manager_api_integration/apis/package_config/create.ts b/x-pack/test/ingest_manager_api_integration/apis/package_config/create.ts index cae4ff79bdef6..a2c2b99364d50 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/package_config/create.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/package_config/create.ts @@ -100,7 +100,7 @@ export default function ({ getService }: FtrProviderContext) { package: { name: 'endpoint', title: 'Endpoint', - version: '0.8.0', + version: '0.13.0', }, }) .expect(200); @@ -118,7 +118,7 @@ export default function ({ getService }: FtrProviderContext) { package: { name: 'endpoint', title: 'Endpoint', - version: '0.8.0', + version: '0.13.0', }, }) .expect(500); diff --git a/x-pack/test/ingest_manager_api_integration/config.ts b/x-pack/test/ingest_manager_api_integration/config.ts index 85d1c20c7f155..08d5da148b51e 100644 --- a/x-pack/test/ingest_manager_api_integration/config.ts +++ b/x-pack/test/ingest_manager_api_integration/config.ts @@ -12,7 +12,7 @@ import { defineDockerServersConfig } from '@kbn/test'; // Docker image to use for Ingest Manager API integration tests. // This hash comes from the commit hash here: https://github.com/elastic/package-storage/commit export const dockerImage = - 'docker.elastic.co/package-registry/distribution:80e93ade87f65e18d487b1c407406825915daba8'; + 'docker.elastic.co/package-registry/distribution:f6b01daec8cfe355101e366de9941d35a4c3763e'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { const xPackAPITestsConfig = await readConfigFile(require.resolve('../api_integration/config.ts')); From 1c428ffed780495a327c15fcd33dcf3759e6087c Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Wed, 5 Aug 2020 14:11:27 -0400 Subject: [PATCH 019/106] fixing encoding issue with \ for enroll command (#74379) --- .../components/enrollment_instructions/manual/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx index 8ea236b2dd6c3..9efc95b0a04cf 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx @@ -36,8 +36,8 @@ export const ManualInstructions: React.FunctionComponent = ({ systemctl enable elastic-agent systemctl start elastic-agent`; - const windowsCommand = `.\elastic-agent enroll ${enrollArgs} -./install-service-elastic-agent.ps1`; + const windowsCommand = `.\\elastic-agent enroll ${enrollArgs} +.\\install-service-elastic-agent.ps1`; return ( <> From 0737241decd6bfc30e3c98abd47344befa856ee7 Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Wed, 5 Aug 2020 13:13:22 -0500 Subject: [PATCH 020/106] [Metrics UI] Fix validating Metrics Explorer URL (#74311) --- ...metrics_explorer_options_url_state.test.ts | 70 ++++++++++++++ ...ith_metrics_explorer_options_url_state.tsx | 65 ++----------- .../hooks/use_metrics_explorer_options.ts | 94 +++++++++++++------ 3 files changed, 140 insertions(+), 89 deletions(-) create mode 100644 x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.test.ts diff --git a/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.test.ts b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.test.ts new file mode 100644 index 0000000000000..8be34b4498c3f --- /dev/null +++ b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.test.ts @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { omit } from 'lodash'; +import { mapToUrlState } from './with_metrics_explorer_options_url_state'; + +describe('WithMetricsExplorerOptionsUrlState', () => { + describe('mapToUrlState', () => { + it('loads a valid URL state', () => { + expect(mapToUrlState(validState)).toEqual(validState); + }); + it('discards invalid properties and loads valid properties into the URL', () => { + expect(mapToUrlState(invalidState)).toEqual(omit(invalidState, 'options')); + }); + }); +}); + +const validState = { + chartOptions: { + stack: false, + type: 'line', + yAxisMode: 'fromZero', + }, + options: { + aggregation: 'avg', + filterQuery: '', + groupBy: ['host.hostname'], + metrics: [ + { + aggregation: 'avg', + color: 'color0', + field: 'system.cpu.user.pct', + }, + { + aggregation: 'avg', + color: 'color1', + field: 'system.load.1', + }, + ], + source: 'url', + }, + timerange: { + from: 'now-1h', + interval: '>=10s', + to: 'now', + }, +}; + +const invalidState = { + chartOptions: { + stack: false, + type: 'line', + yAxisMode: 'fromZero', + }, + options: { + aggregation: 'avg', + filterQuery: '', + groupBy: ['host.hostname'], + metrics: 'this is the wrong data type', + source: 'url', + }, + timerange: { + from: 'now-1h', + interval: '>=10s', + to: 'now', + }, +}; diff --git a/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx index 35fb66b2620d6..c263d0f68a45e 100644 --- a/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx +++ b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx @@ -5,19 +5,17 @@ */ import { set } from '@elastic/safer-lodash-set'; -import { values } from 'lodash'; import React, { useContext, useMemo } from 'react'; -import * as t from 'io-ts'; import { ThrowReporter } from 'io-ts/lib/ThrowReporter'; -import { MetricsExplorerColor } from '../../../common/color_palette'; import { UrlStateContainer } from '../../utils/url_state'; import { MetricsExplorerOptions, MetricsExplorerOptionsContainer, MetricsExplorerTimeOptions, - MetricsExplorerYAxisMode, - MetricsExplorerChartType, MetricsExplorerChartOptions, + metricExplorerOptionsRT, + metricsExplorerChartOptionsRT, + metricsExplorerTimeOptionsRT, } from '../../pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options'; interface MetricsExplorerUrlState { @@ -74,36 +72,7 @@ export const WithMetricsExplorerOptionsUrlState = () => { }; function isMetricExplorerOptions(subject: any): subject is MetricsExplorerOptions { - const MetricRequired = t.type({ - aggregation: t.string, - }); - - const MetricOptional = t.partial({ - field: t.string, - rate: t.boolean, - color: t.keyof( - Object.fromEntries(values(MetricsExplorerColor).map((c) => [c, null])) as Record - ), - label: t.string, - }); - - const Metric = t.intersection([MetricRequired, MetricOptional]); - - const OptionsRequired = t.type({ - aggregation: t.string, - metrics: t.array(Metric), - }); - - const OptionsOptional = t.partial({ - limit: t.number, - groupBy: t.string, - filterQuery: t.string, - source: t.string, - }); - - const Options = t.intersection([OptionsRequired, OptionsOptional]); - - const result = Options.decode(subject); + const result = metricExplorerOptionsRT.decode(subject); try { ThrowReporter.report(result); @@ -114,22 +83,7 @@ function isMetricExplorerOptions(subject: any): subject is MetricsExplorerOption } function isMetricExplorerChartOptions(subject: any): subject is MetricsExplorerChartOptions { - const ChartOptions = t.type({ - yAxisMode: t.keyof( - Object.fromEntries(values(MetricsExplorerYAxisMode).map((v) => [v, null])) as Record< - string, - null - > - ), - type: t.keyof( - Object.fromEntries(values(MetricsExplorerChartType).map((v) => [v, null])) as Record< - string, - null - > - ), - stack: t.boolean, - }); - const result = ChartOptions.decode(subject); + const result = metricsExplorerChartOptionsRT.decode(subject); try { ThrowReporter.report(result); @@ -140,12 +94,7 @@ function isMetricExplorerChartOptions(subject: any): subject is MetricsExplorerC } function isMetricExplorerTimeOption(subject: any): subject is MetricsExplorerTimeOptions { - const TimeRange = t.type({ - from: t.string, - to: t.string, - interval: t.string, - }); - const result = TimeRange.decode(subject); + const result = metricsExplorerTimeOptionsRT.decode(subject); try { ThrowReporter.report(result); return true; @@ -154,7 +103,7 @@ function isMetricExplorerTimeOption(subject: any): subject is MetricsExplorerTim } } -const mapToUrlState = (value: any): MetricsExplorerUrlState | undefined => { +export const mapToUrlState = (value: any): MetricsExplorerUrlState | undefined => { const finalState = {}; if (value) { if (value.options && isMetricExplorerOptions(value.options)) { diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts index fa103ce15e3e8..299231f1821f0 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts @@ -4,19 +4,29 @@ * you may not use this file except in compliance with the Elastic License. */ +import * as t from 'io-ts'; +import { values } from 'lodash'; import createContainer from 'constate'; import { useState, useEffect, useMemo, Dispatch, SetStateAction } from 'react'; import { useAlertPrefillContext } from '../../../../alerting/use_alert_prefill'; import { MetricsExplorerColor } from '../../../../../common/color_palette'; -import { - MetricsExplorerAggregation, - MetricsExplorerMetric, -} from '../../../../../common/http_api/metrics_explorer'; - -export type MetricsExplorerOptionsMetric = MetricsExplorerMetric & { - color?: MetricsExplorerColor; - label?: string; -}; +import { metricsExplorerMetricRT } from '../../../../../common/http_api/metrics_explorer'; + +const metricsExplorerOptionsMetricRT = t.intersection([ + metricsExplorerMetricRT, + t.partial({ + rate: t.boolean, + color: t.keyof( + Object.fromEntries(values(MetricsExplorerColor).map((c) => [c, null])) as Record< + MetricsExplorerColor, + null + > + ), + label: t.string, + }), +]); + +export type MetricsExplorerOptionsMetric = t.TypeOf; export enum MetricsExplorerChartType { line = 'line', @@ -29,28 +39,50 @@ export enum MetricsExplorerYAxisMode { auto = 'auto', } -export interface MetricsExplorerChartOptions { - type: MetricsExplorerChartType; - yAxisMode: MetricsExplorerYAxisMode; - stack: boolean; -} - -export interface MetricsExplorerOptions { - metrics: MetricsExplorerOptionsMetric[]; - limit?: number; - groupBy?: string | string[]; - filterQuery?: string; - aggregation: MetricsExplorerAggregation; - forceInterval?: boolean; - dropLastBucket?: boolean; - source?: string; -} - -export interface MetricsExplorerTimeOptions { - from: string; - to: string; - interval: string; -} +export const metricsExplorerChartOptionsRT = t.type({ + yAxisMode: t.keyof( + Object.fromEntries(values(MetricsExplorerYAxisMode).map((v) => [v, null])) as Record< + MetricsExplorerYAxisMode, + null + > + ), + type: t.keyof( + Object.fromEntries(values(MetricsExplorerChartType).map((v) => [v, null])) as Record< + MetricsExplorerChartType, + null + > + ), + stack: t.boolean, +}); + +export type MetricsExplorerChartOptions = t.TypeOf; + +const metricExplorerOptionsRequiredRT = t.type({ + aggregation: t.string, + metrics: t.array(metricsExplorerOptionsMetricRT), +}); + +const metricExplorerOptionsOptionalRT = t.partial({ + limit: t.number, + groupBy: t.union([t.string, t.array(t.string)]), + filterQuery: t.string, + source: t.string, + forceInterval: t.boolean, + dropLastBucket: t.boolean, +}); +export const metricExplorerOptionsRT = t.intersection([ + metricExplorerOptionsRequiredRT, + metricExplorerOptionsOptionalRT, +]); + +export type MetricsExplorerOptions = t.TypeOf; + +export const metricsExplorerTimeOptionsRT = t.type({ + from: t.string, + to: t.string, + interval: t.string, +}); +export type MetricsExplorerTimeOptions = t.TypeOf; export const DEFAULT_TIMERANGE: MetricsExplorerTimeOptions = { from: 'now-1h', From 057cab725c1e5c09d2a3aa531221fffc826e7090 Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 5 Aug 2020 12:05:17 -0700 Subject: [PATCH 021/106] [Jenkins] run CI when plugin readmes change (#74388) Co-authored-by: spalger --- .ci/pipeline-library/src/test/prChanges.groovy | 13 +++++++++++++ vars/prChanges.groovy | 2 ++ 2 files changed, 15 insertions(+) diff --git a/.ci/pipeline-library/src/test/prChanges.groovy b/.ci/pipeline-library/src/test/prChanges.groovy index f149340517ff0..0f354e7687246 100644 --- a/.ci/pipeline-library/src/test/prChanges.groovy +++ b/.ci/pipeline-library/src/test/prChanges.groovy @@ -97,4 +97,17 @@ class PrChangesTest extends KibanaBasePipelineTest { assertFalse(prChanges.areChangesSkippable()) } + + @Test + void 'areChangesSkippable() with plugin readme changes'() { + props([ + githubPrs: [ + getChanges: { [ + [filename: 'src/plugins/foo/README.asciidoc'], + ] }, + ], + ]) + + assertFalse(prChanges.areChangesSkippable()) + } } diff --git a/vars/prChanges.groovy b/vars/prChanges.groovy index adaacf952b5b6..a7fe46e7bf014 100644 --- a/vars/prChanges.groovy +++ b/vars/prChanges.groovy @@ -22,6 +22,8 @@ def getNotSkippablePaths() { return [ // this file is auto-generated and changes to it need to be validated with CI /^docs\/developer\/architecture\/code-exploration.asciidoc$/, + // don't skip CI on prs with changes to plugin readme files (?i) is for case-insensitive matching + /(?i)\/plugins\/[^\/]+\/readme\.(md|asciidoc)$/, ] } From c655f50950693f3d0ec32dcf8167135d0c9781ec Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Wed, 5 Aug 2020 12:51:58 -0700 Subject: [PATCH 022/106] Rename agent configs SO to agent policies (#74397) --- .../ingest_manager/common/constants/agent_config.ts | 2 +- .../test/functional/es_archives/fleet/agents/data.json | 6 +++--- .../functional/es_archives/fleet/agents/mappings.json | 4 ++-- x-pack/test/functional/es_archives/lists/mappings.json | 6 +++--- .../reporting/canvas_disallowed_url/mappings.json | 9 ++++----- .../es_archives/export_rule/mappings.json | 4 ++-- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/constants/agent_config.ts b/x-pack/plugins/ingest_manager/common/constants/agent_config.ts index 30ca92f5f32f3..aa6399b73f14e 100644 --- a/x-pack/plugins/ingest_manager/common/constants/agent_config.ts +++ b/x-pack/plugins/ingest_manager/common/constants/agent_config.ts @@ -5,7 +5,7 @@ */ import { AgentConfigStatus, DefaultPackages } from '../types'; -export const AGENT_CONFIG_SAVED_OBJECT_TYPE = 'ingest-agent-configs'; +export const AGENT_CONFIG_SAVED_OBJECT_TYPE = 'ingest-agent-policies'; export const DEFAULT_AGENT_CONFIG = { name: 'Default config', diff --git a/x-pack/test/functional/es_archives/fleet/agents/data.json b/x-pack/test/functional/es_archives/fleet/agents/data.json index b3d49199b0d9e..c94b87f6ad1ec 100644 --- a/x-pack/test/functional/es_archives/fleet/agents/data.json +++ b/x-pack/test/functional/es_archives/fleet/agents/data.json @@ -203,11 +203,11 @@ { "type": "doc", "value": { - "id": "ingest-agent-configs:config1", + "id": "ingest-agent-policies:config1", "index": ".kibana", "source": { - "type": "ingest-agent-configs", - "ingest-agent-configs": { + "type": "ingest-agent-policies", + "ingest-agent-policies": { "name": "Test config", "namespace": "default", "description": "Config 1", diff --git a/x-pack/test/functional/es_archives/fleet/agents/mappings.json b/x-pack/test/functional/es_archives/fleet/agents/mappings.json index 1f0aa2f24d6df..acc32c3e2cbb5 100644 --- a/x-pack/test/functional/es_archives/fleet/agents/mappings.json +++ b/x-pack/test/functional/es_archives/fleet/agents/mappings.json @@ -58,7 +58,7 @@ "siem-ui-timeline": "f2d929253ecd06ffbac78b4047f45a86", "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", "ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3", - "ingest-agent-configs": "f4bdc17427437537ca1754d5d5057ad5", + "ingest-agent-policies": "f4bdc17427437537ca1754d5d5057ad5", "url": "b675c3be8d76ecf029294d51dc7ec65d", "migrationVersion": "4a1746014a75ade3a714e1db5763276f", "index-pattern": "66eccb05066c5a89924f48a9e9736499", @@ -1797,7 +1797,7 @@ } } }, - "ingest-agent-configs": { + "ingest-agent-policies": { "properties": { "package_configs": { "type": "keyword" diff --git a/x-pack/test/functional/es_archives/lists/mappings.json b/x-pack/test/functional/es_archives/lists/mappings.json index c1b277b8183a3..2fc1f1a3111a7 100644 --- a/x-pack/test/functional/es_archives/lists/mappings.json +++ b/x-pack/test/functional/es_archives/lists/mappings.json @@ -61,7 +61,7 @@ "siem-ui-timeline": "94bc38c7a421d15fbfe8ea565370a421", "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", "ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3", - "ingest-agent-configs": "9326f99c977fd2ef5ab24b6336a0675c", + "ingest-agent-policies": "9326f99c977fd2ef5ab24b6336a0675c", "url": "c7f66a0df8b1b52f17c28c4adb111105", "endpoint:user-artifact-manifest": "67c28185da541c1404e7852d30498cd6", "migrationVersion": "4a1746014a75ade3a714e1db5763276f", @@ -1210,7 +1210,7 @@ } } }, - "ingest-agent-configs": { + "ingest-agent-policies": { "properties": { "description": { "type": "text" @@ -2488,4 +2488,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json b/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json index 1432a53b45461..1fd338fbb0ffb 100644 --- a/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json +++ b/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json @@ -2,8 +2,7 @@ "type": "index", "value": { "aliases": { - ".kibana": { - } + ".kibana": {} }, "index": ".kibana_1", "mappings": { @@ -38,7 +37,7 @@ "fleet-enrollment-api-keys": "28b91e20b105b6f928e2012600085d8f", "graph-workspace": "cd7ba1330e6682e9cc00b78850874be1", "index-pattern": "66eccb05066c5a89924f48a9e9736499", - "ingest-agent-configs": "9326f99c977fd2ef5ab24b6336a0675c", + "ingest-agent-policies": "9326f99c977fd2ef5ab24b6336a0675c", "ingest-outputs": "8aa988c376e65443fefc26f1075e93a3", "ingest-package-configs": "48e8bd97e488008e21c0b5a2367b83ad", "ingest_manager_settings": "012cf278ec84579495110bb827d1ed09", @@ -1149,7 +1148,7 @@ } } }, - "ingest-agent-configs": { + "ingest-agent-policies": { "properties": { "description": { "type": "text" @@ -2213,4 +2212,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json b/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json index 2cfa0bde4e977..dc92d23a618d3 100644 --- a/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json +++ b/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json @@ -39,7 +39,7 @@ "graph-workspace": "cd7ba1330e6682e9cc00b78850874be1", "index-pattern": "66eccb05066c5a89924f48a9e9736499", "infrastructure-ui-source": "2b2809653635caf490c93f090502d04c", - "ingest-agent-configs": "9326f99c977fd2ef5ab24b6336a0675c", + "ingest-agent-policies": "9326f99c977fd2ef5ab24b6336a0675c", "ingest-outputs": "8aa988c376e65443fefc26f1075e93a3", "ingest-package-configs": "48e8bd97e488008e21c0b5a2367b83ad", "ingest_manager_settings": "012cf278ec84579495110bb827d1ed09", @@ -1222,7 +1222,7 @@ } } }, - "ingest-agent-configs": { + "ingest-agent-policies": { "properties": { "description": { "type": "text" From af358c94a3e17aeb2c78c0edd50c233a4e3558c0 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Wed, 5 Aug 2020 17:58:40 -0400 Subject: [PATCH 023/106] [ML] DF Analytics: adds functional tests for edit form (#73885) * add edit analytics functional test * adds edit test service * update edit test wording for clarity * check flyout closes after edit * rename testSubj for consitency --- .../action_edit/edit_button_flyout.tsx | 4 +- .../components/analytics_list/use_columns.tsx | 1 + .../classification_creation.ts | 31 ++++++++ .../outlier_detection_creation.ts | 31 ++++++++ .../regression_creation.ts | 31 ++++++++ .../services/ml/data_frame_analytics_edit.ts | 71 +++++++++++++++++++ .../services/ml/data_frame_analytics_table.ts | 6 ++ x-pack/test/functional/services/ml/index.ts | 3 + 8 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 x-pack/test/functional/services/ml/data_frame_analytics_edit.ts diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_button_flyout.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_button_flyout.tsx index 86b1c879417bb..14b743997f30a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_button_flyout.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_button_flyout.tsx @@ -133,7 +133,7 @@ export const EditButtonFlyout: FC> = ({ closeFlyout, item } onClose={closeFlyout} hideCloseButton aria-labelledby="analyticsEditFlyoutTitle" - data-test-subj="analyticsEditFlyout" + data-test-subj="mlAnalyticsEditFlyout" > @@ -297,7 +297,7 @@ export const EditButtonFlyout: FC> = ({ closeFlyout, item } { @@ -179,6 +180,36 @@ export default function ({ getService }: FtrProviderContext) { }); }); + it('should open the edit form for the created job in the analytics table', async () => { + await ml.dataFrameAnalyticsTable.openEditFlyout(testData.jobId); + }); + + it('should input the description in the edit form', async () => { + await ml.dataFrameAnalyticsEdit.assertJobDescriptionEditInputExists(); + await ml.dataFrameAnalyticsEdit.setJobDescriptionEdit(editedDescription); + }); + + it('should input the model memory limit in the edit form', async () => { + await ml.dataFrameAnalyticsEdit.assertJobMmlEditInputExists(); + await ml.dataFrameAnalyticsEdit.setJobMmlEdit('21mb'); + }); + + it('should submit the edit job form', async () => { + await ml.dataFrameAnalyticsEdit.updateAnalyticsJob(); + }); + + it('displays details for the edited job in the analytics table', async () => { + await ml.dataFrameAnalyticsTable.assertAnalyticsRowFields(testData.jobId, { + id: testData.jobId, + description: editedDescription, + sourceIndex: testData.source, + destinationIndex: testData.destinationIndex, + type: testData.expected.row.type, + status: testData.expected.row.status, + progress: testData.expected.row.progress, + }); + }); + it('creates the destination index and writes results to it', async () => { await ml.api.assertIndicesExist(testData.destinationIndex); await ml.api.assertIndicesNotEmpty(testData.destinationIndex); diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts index 0320354b99ff0..5b89cec49db3e 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts @@ -10,6 +10,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); + const editedDescription = 'Edited description'; describe('outlier detection creation', function () { before(async () => { @@ -197,6 +198,36 @@ export default function ({ getService }: FtrProviderContext) { }); }); + it('should open the edit form for the created job in the analytics table', async () => { + await ml.dataFrameAnalyticsTable.openEditFlyout(testData.jobId); + }); + + it('should input the description in the edit form', async () => { + await ml.dataFrameAnalyticsEdit.assertJobDescriptionEditInputExists(); + await ml.dataFrameAnalyticsEdit.setJobDescriptionEdit(editedDescription); + }); + + it('should input the model memory limit in the edit form', async () => { + await ml.dataFrameAnalyticsEdit.assertJobMmlEditInputExists(); + await ml.dataFrameAnalyticsEdit.setJobMmlEdit('21mb'); + }); + + it('should submit the edit job form', async () => { + await ml.dataFrameAnalyticsEdit.updateAnalyticsJob(); + }); + + it('displays details for the edited job in the analytics table', async () => { + await ml.dataFrameAnalyticsTable.assertAnalyticsRowFields(testData.jobId, { + id: testData.jobId, + description: editedDescription, + sourceIndex: testData.source, + destinationIndex: testData.destinationIndex, + type: testData.expected.row.type, + status: testData.expected.row.status, + progress: testData.expected.row.progress, + }); + }); + it('creates the destination index and writes results to it', async () => { await ml.api.assertIndicesExist(testData.destinationIndex); await ml.api.assertIndicesNotEmpty(testData.destinationIndex); diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts index 1aa505e26e1e9..a67a348323347 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts @@ -10,6 +10,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); + const editedDescription = 'Edited description'; describe('regression creation', function () { before(async () => { @@ -179,6 +180,36 @@ export default function ({ getService }: FtrProviderContext) { }); }); + it('should open the edit form for the created job in the analytics table', async () => { + await ml.dataFrameAnalyticsTable.openEditFlyout(testData.jobId); + }); + + it('should input the description in the edit form', async () => { + await ml.dataFrameAnalyticsEdit.assertJobDescriptionEditInputExists(); + await ml.dataFrameAnalyticsEdit.setJobDescriptionEdit(editedDescription); + }); + + it('should input the model memory limit in the edit form', async () => { + await ml.dataFrameAnalyticsEdit.assertJobMmlEditInputExists(); + await ml.dataFrameAnalyticsEdit.setJobMmlEdit('21mb'); + }); + + it('should submit the edit job form', async () => { + await ml.dataFrameAnalyticsEdit.updateAnalyticsJob(); + }); + + it('displays details for the edited job in the analytics table', async () => { + await ml.dataFrameAnalyticsTable.assertAnalyticsRowFields(testData.jobId, { + id: testData.jobId, + description: editedDescription, + sourceIndex: testData.source, + destinationIndex: testData.destinationIndex, + type: testData.expected.row.type, + status: testData.expected.row.status, + progress: testData.expected.row.progress, + }); + }); + it('creates the destination index and writes results to it', async () => { await ml.api.assertIndicesExist(testData.destinationIndex); await ml.api.assertIndicesNotEmpty(testData.destinationIndex); diff --git a/x-pack/test/functional/services/ml/data_frame_analytics_edit.ts b/x-pack/test/functional/services/ml/data_frame_analytics_edit.ts new file mode 100644 index 0000000000000..fd06dd24d6f8b --- /dev/null +++ b/x-pack/test/functional/services/ml/data_frame_analytics_edit.ts @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../ftr_provider_context'; +import { MlCommon } from './common'; + +export function MachineLearningDataFrameAnalyticsEditProvider( + { getService }: FtrProviderContext, + mlCommon: MlCommon +) { + const testSubjects = getService('testSubjects'); + const retry = getService('retry'); + + return { + async assertJobDescriptionEditInputExists() { + await testSubjects.existOrFail('mlAnalyticsEditFlyoutDescriptionInput'); + }, + async assertJobDescriptionEditValue(expectedValue: string) { + const actualJobDescription = await testSubjects.getAttribute( + 'mlAnalyticsEditFlyoutDescriptionInput', + 'value' + ); + expect(actualJobDescription).to.eql( + expectedValue, + `Job description edit should be '${expectedValue}' (got '${actualJobDescription}')` + ); + }, + async assertJobMmlEditInputExists() { + await testSubjects.existOrFail('mlAnalyticsEditFlyoutmodelMemoryLimitInput'); + }, + async assertJobMmlEditValue(expectedValue: string) { + const actualMml = await testSubjects.getAttribute( + 'mlAnalyticsEditFlyoutmodelMemoryLimitInput', + 'value' + ); + expect(actualMml).to.eql( + expectedValue, + `Job model memory limit edit should be '${expectedValue}' (got '${actualMml}')` + ); + }, + async setJobDescriptionEdit(jobDescription: string) { + await mlCommon.setValueWithChecks('mlAnalyticsEditFlyoutDescriptionInput', jobDescription, { + clearWithKeyboard: true, + }); + await this.assertJobDescriptionEditValue(jobDescription); + }, + + async setJobMmlEdit(mml: string) { + await mlCommon.setValueWithChecks('mlAnalyticsEditFlyoutmodelMemoryLimitInput', mml, { + clearWithKeyboard: true, + }); + await this.assertJobMmlEditValue(mml); + }, + + async assertAnalyticsEditFlyoutMissing() { + await testSubjects.missingOrFail('mlAnalyticsEditFlyout'); + }, + + async updateAnalyticsJob() { + await testSubjects.existOrFail('mlAnalyticsEditFlyoutUpdateButton'); + await testSubjects.click('mlAnalyticsEditFlyoutUpdateButton'); + await retry.tryForTime(5000, async () => { + await this.assertAnalyticsEditFlyoutMissing(); + }); + }, + }; +} diff --git a/x-pack/test/functional/services/ml/data_frame_analytics_table.ts b/x-pack/test/functional/services/ml/data_frame_analytics_table.ts index d315f9eb77210..608a1f2bee3e1 100644 --- a/x-pack/test/functional/services/ml/data_frame_analytics_table.ts +++ b/x-pack/test/functional/services/ml/data_frame_analytics_table.ts @@ -88,6 +88,12 @@ export function MachineLearningDataFrameAnalyticsTableProvider({ getService }: F await testSubjects.existOrFail('mlAnalyticsJobViewButton'); } + public async openEditFlyout(analyticsId: string) { + await this.openRowActions(analyticsId); + await testSubjects.click('mlAnalyticsJobEditButton'); + await testSubjects.existOrFail('mlAnalyticsEditFlyout', { timeout: 5000 }); + } + async assertAnalyticsSearchInputValue(expectedSearchValue: string) { const searchBarInput = await this.getAnalyticsSearchInput(); const actualSearchValue = await searchBarInput.getAttribute('value'); diff --git a/x-pack/test/functional/services/ml/index.ts b/x-pack/test/functional/services/ml/index.ts index fbf31e40a242a..fd36bb0f47f95 100644 --- a/x-pack/test/functional/services/ml/index.ts +++ b/x-pack/test/functional/services/ml/index.ts @@ -13,6 +13,7 @@ import { MachineLearningCommonProvider } from './common'; import { MachineLearningCustomUrlsProvider } from './custom_urls'; import { MachineLearningDataFrameAnalyticsProvider } from './data_frame_analytics'; import { MachineLearningDataFrameAnalyticsCreationProvider } from './data_frame_analytics_creation'; +import { MachineLearningDataFrameAnalyticsEditProvider } from './data_frame_analytics_edit'; import { MachineLearningDataFrameAnalyticsTableProvider } from './data_frame_analytics_table'; import { MachineLearningDataVisualizerProvider } from './data_visualizer'; import { MachineLearningDataVisualizerFileBasedProvider } from './data_visualizer_file_based'; @@ -47,6 +48,7 @@ export function MachineLearningProvider(context: FtrProviderContext) { common, api ); + const dataFrameAnalyticsEdit = MachineLearningDataFrameAnalyticsEditProvider(context, common); const dataFrameAnalyticsTable = MachineLearningDataFrameAnalyticsTableProvider(context); const dataVisualizer = MachineLearningDataVisualizerProvider(context); const dataVisualizerFileBased = MachineLearningDataVisualizerFileBasedProvider(context, common); @@ -76,6 +78,7 @@ export function MachineLearningProvider(context: FtrProviderContext) { customUrls, dataFrameAnalytics, dataFrameAnalyticsCreation, + dataFrameAnalyticsEdit, dataFrameAnalyticsTable, dataVisualizer, dataVisualizerFileBased, From b001301f5ad44757fa83bffc7f4dac1f007c18b6 Mon Sep 17 00:00:00 2001 From: spalger Date: Thu, 16 Jul 2020 08:47:23 -0700 Subject: [PATCH 024/106] skip flaky suite (#71390) (cherry picked from commit d0afbd887dc547ebbc564f77edf2ef04750fc653) --- .../test_suites/task_manager/task_manager_integration.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js index c87a5039360b8..ea95eb42dd6ff 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js @@ -28,7 +28,8 @@ export default function ({ getService }) { const testHistoryIndex = '.kibana_task_manager_test_result'; const supertest = supertestAsPromised(url.format(config.get('servers.kibana'))); - describe('scheduling and running tasks', () => { + // FLAKY: https://github.com/elastic/kibana/issues/71390 + describe.skip('scheduling and running tasks', () => { beforeEach( async () => await supertest.delete('/api/sample_tasks').set('kbn-xsrf', 'xxx').expect(200) ); From 4b3326d6fbafb09bb6eb8552c0a17505af50aabe Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Wed, 5 Aug 2020 15:08:38 -0700 Subject: [PATCH 025/106] [DOCS] Add Kibana alerts to Stack Monitoring (#73762) Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com> --- .../images/monitoring-kibana-alerts.png | Bin 0 -> 113426 bytes docs/user/monitoring/index.asciidoc | 1 + docs/user/monitoring/kibana-alerts.asciidoc | 36 ++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 docs/user/monitoring/images/monitoring-kibana-alerts.png create mode 100644 docs/user/monitoring/kibana-alerts.asciidoc diff --git a/docs/user/monitoring/images/monitoring-kibana-alerts.png b/docs/user/monitoring/images/monitoring-kibana-alerts.png new file mode 100644 index 0000000000000000000000000000000000000000..43edcb45041400ea128a9b6ee397df9188dff82f GIT binary patch literal 113426 zcmZs@byQnj(+658MT-=7C{l`3w0Q9X#hu{p?pjKV7PkV$ic4^ZAjKVu6C8pB2^u8G z<@xS?@A|&?=^t6^th3MAXZD`iW51b1sw&H2W0GS&d-e=l{-d<|vu7yZpFKnBMn`?R zgH=M?`gDWLR!U0MUP?~N*}>UO!^PCxQqI!J(#_UfT~6}Zv-dGET81{1T7+V4?$-1S z;~EaU-#kjhu^F+Gw0ZODTZ30t_?=Sa`IqSSEa1oEKZeHN^R(UPsmQ1Xyn|*E_I5UX zrhR*f3l^*AOu=ManxTCwR(~C;x))t^kS@%VZrfV3YIz)Ro(0SHKW?#xz1V9h(@jkv zL?X_pWGCU?bPtb<5M_=38lFpnnx~^i#cEjk37KC7%ew)vCiUCjcyV^+AqUtbOGQNM zN@G^HQ-T!{hjdb`HR6Tjcbh;X4%MfIo9#8d`_Rkj*Sujq-{US86k}_(&9*rm@j^?( zE+P#tZnW=O_9fz7^_+38lHEbs9^{uNN*pzQc{QV|=oL)bpaP6m){#>HY>0XtwELC+ zoNbdmVnSedSfhKPyez5jXSY{x6QBOsnJ`LMWGf)!bifVasF8iP3xV=wjQIOX-`%$R zeuM|Q

    __2kf1HO=U;BD@;ocCF%{02+ot0fbVWT)GRCDJtwmxhsXzWBbGt`RTTl!oGeI)%JANlW3=SHH z-ZYQbvsi?SeIc$Tzl*IPp0+$K|7KuLARfdffGqxoj23?}bi#;R9-iRJjYQ`gC87jR zqO2vbfZZ-AILH`@2+ZBLf9Fvz%9L3VtZ&OTdE{aFWS}u$!G_ZqMnA%gcwq>->o=}3 z*k=<^YuqHuYSkIPF}^vtIdsr<_tqkJMBO4jnM&`A z?4vq&J>Ay9l?_TAO5d%zFci^q=D?AyNPBT>ccV?F93x$E5qc3`&jw-&e0$#y8Vei_ z919!|>^4MB5FW|e>e%3Lp>a3vhufW#>#z9}`;sVD7>b3AfhIA`^~?hX3BlW z^b*}%Qf(n56?lLk&f&}!rNS|%*(pXCbZ}@RMIvgDFO(j%v^4i!l9{Qrot55qNDzEy zkh1um%&&RXtaF}6m!bkux5d*C)*vXYnUTN^uPgG(bwozoQO%Y*)v81Pn6CyR>rD$e z9bk_Uc`N=&G9$0zXGzU~?nRW4h7Ep-wb2M)a@41I0b9L@yU65j!zBQ4$o)jT?CKCd zJw$M9#@0VerTiQ+K<`94F^snQ;{Ey8rCM+|Rl>&rto50zLwM&cw@=Xh%>Ht(d&MsM z=LP}ctj;x<$DG)Q$MR>^F~LZ=IRRSF4X|KOy5ha1uDq3!(leH)YxHMG;kM6Ep01Fd ze&kQTXU~vxk^gfC<$Lb)|6C(=|1$^>6qbGV?87s8X$egqq(hMPcLNZZ4_}39UQn_c{Hk3FW|M!LeOhZemhWhX6{u%9m z^?{2#Je2c4PyXNcr|e&UR8g$^$T0S2I?+Dn8bJ5Xj-Eb$e(A9BE;T#*7{N~=e=R0g zzw6I~p~Rc$l>flFVIa$yi*ZQ#Gc~4w*l2)RI)DPg+$&JK;%N~$QeJ?lk!k<*5^>qQ zs&O`ZFC;|M`BgF>rV!Z+@>fcd^MP~4-_CO8%d1_=nc^ z$DjtiKQsGOQ3FTIi#&6alY3NaU$wNf7AqF(*oB4tf6L@&A3K3t+;he<1qOD;fjGZM zKwjMifxVmbUS%x<3g>kd?Od$rES05tk0#4Yt!TiCw_r>+9`S^uYdq}QgzfyM+XsUtlHU6JDJ!#pLu?{3oNOgR8SZZOPKyKc7y)k zoW^TrLYIEHR(ZIffOf?x)yD3@XsV^cal!pDnGVxC-VU(r=c^c%O%Z^HQI~F7{Fqjv zz5%KrNWyLQ?aw#%WT5`-D$nF#J3YJ1nTM24ZSmmB)rb9@hgpRY1&5);7v1{wwkrws ztCP3G^p^^OG?{A)Yw9;^))Grh7qsu5&VX=!1l zYxdqWv?Gg6ut=$@e(gG@s+n=%aDANcYTVD*IHwI68!*#Xc6S%RjFm?~b9!%iUHb#z zHP}ke!^2aNKM^TSrz;&pl=xfOxrb&A)E6e_xVFy$_NpElKI1+-R~f}x`Vc${tkXv< z|FL<0XiJ-2o&8|i#7kb|K%#I~n;$f~-wi5vHd(k0$LEJS>0deqO1O}_5xcolMBI2~ z%Po(kp4HK(!nEb^DK|SR&!Q22!%PCgJ+*g%l8G>tIq5(UXl`bPkj8%1um#nTnxM0_{zl1>i z1tYA!9;|`qVG!F%%Oc*9@u9}{WrIfxey&Ma6%r>J#+r31Z2DU{ZKKj)dfbTS{PA)N zYPqmKf3oF`BHV*%q^|eZ&!3bdBO~YMG>vuEcRyF?s(>KTMBqhOWea>%c3_kP*L9=r!DjsRKSkcHq`jU7Qp2n>~OS?X?NRI}2y$RWn%oxf9-V z_>s7YJ&mq8ZY97mT$!?I>;aslBDzueUWTM15su25SlDqt!r4iQ@_F8P%?5Er<1v!= z$E0*-b=5Q{@N&A*t&iLL%GT{5Ch#>3GLi=747w}=UEgVF^OPWxp^Nc{{% z2Ad`VA9%F)oRsC_sNL<;kO2*LEskp)(>OGOX1KuMNn#EI6aTAY+|A$lablYY*7I1z z?AG}5=!*oIxb`wPw_n6$W7S)`tqv14Rsc}0hy_!E%%dOLCcMAW4{;;6%f9h@s(n}l zu^cAYXyz2j*LVq55ihH2iu2TMF^*C8HV5pFSV~N<^4T~Cc#Jnv+Sk>AT>Tv+BJYh4 ztQQZ51Hj&8Jr7&=JjcKJZM6Cp;fGK%_+bW%tqrsJ&rHF>a%cL6HwE=w7ii+woK1vw z?(aBwn%TxHGG2Y{OXsm(S`9=T0h{>IT$!i8b+y**Iwr{Am{W73LKQ?(I8DnU*Iaa7)~8O=u0IO`^Yk7sF>JK(nmjrQ}a z>*NB#4*`fx5^;N;fHiy?@gW%wPgDT}2d+qDL2D7dzyTC`R4k4t%o6hbGxDJk2xyu! z@`Vs}qSpRWYyvvPc5g+o#je?VviFjeyK8Vln8;HrH?7%Q{PBu)EF%+a%H3 zy|76#j&oA>a_!3MI_rrSHP$_0atLU-1DZ5Szyh|gqHRMg>KLVh>! zXlQ`OU9o@{_TIT^x>yAfWVN)fQGE0x8U*py~pR0Njf- z6#SM&4L<~eu#dl_S|96@Y?AE?XRAXdDZF?Tjr3WeUKN$o)P@G8D%%#Q-VHfzCl`g-vyBHX`9xMliy5=i z>|?mUA@~$t5}%NondpZ8$UQPz#5CJ4s&y*k%Vq~3Gnc>RJg;@>RsLCmJ;&$o1@lyT zyU{6XjvX`Bcoe$Ak7ozUs3dy+z*Td;qlKCtyPa|DRF~TC`YmpH)$R5kIKtjX^@WOQOZF53ZJtxP zpp!eEZplyD?tYfdDa2pY5_y7O|CbB5evIGzNj~A*@QI5^uX#dOJ`6va7o4^nlZ=Wm z*EZ0!sk0vQAgK)!K9&qIh_|!bLAm0@Ky{l)7Xyl*t0*b4=h3&@%_<~yF$gs27zJ@O z)Ay}deliPX;~H}}Ukb|G}92is#dSazXl#9CliBgOL z*4HoK9InB%nH_`JYG@T&yv&LX0_>ce8q$pXhTPoG47!>pw>o3msg!;UIZP_4>}V3{ z%UJdD9|N0$5xL`YZ7K0)FR>9pxIbZyLEeUlGXi(f_g+Ou@Bdi94ojO>IOr~KVOYcN zM*`U;7-kct?o_62*{iS1Mb~VZ$o(q(^g~j1WREI>Qz@2M?ZerHSk4^s*UIYV z@t?xLPnp`b-;8i9i3HS`x7jO$Vj3t~o&A_y(5cZb4u$pyrk@jRb%t3lJ4feeb%m+ zC*E@JY}sYBM^68kl?ECC(;n zqFws^q{BdqiBXd1W#-_($+EdGqMc*pII|H?r-s?AE@!NF)K9F;w2C-Keqdx|lpw^E zWnUG9o%`^+8QR14FbC+P6K#2l!1colBo6r9wN{;I8rd6__UtQ{6R&9=(&;COkB@^xu%;@Pn0bKt5HSaiO@M~vCCg=g&>&Z z{*-FY_PnmXK0Y+wTItKb!nS2kvxE~{1yIICtj44)D#sdDG>0A zR08^vQ@6S+c+C<9>YUZC(uYuO=&-G0_1K6B?eOt(y#gLYR2w}8g2Qhcgm6&|d^k-8f8%gVQ-wlacbUJK?_GNK!gNM$y;SEBGYtQm4MAe%QFEBVo(bBvQaBfCpW8AZ~t%XM$x;sReLvam%|k^j;XBl-GZWKCYta@!T6+QBg6tMaZt1 z`-4`}M;!d3NDa{7S32vv>%Wzm>9C(DKPSD!tdoLf0Qt!6`GNB)P_R7w-vP@7Tj?)7st1Nrf}{^0g9b8eL2Or zKv+!v#ufVj_z0s(cB#5{xRK`S^Bncn9tl7N&HfkFfUqRj;V{1UJNJ7J=7$YKTK?v7=ve5rOA4k3%(u;H3upPzvLQ0gP!j zcZUDU0O5V^0!h+3(h}2PBX|9vPuv}=M&oz#I*45H$NAbdTiYDpFut6TVS>ScMH8u* zQFs^-7>MVR$_^kGI$kj}^t!u_!@Cp^XIkI2(r3Xqvz4mmZx05p zJ?FRYum5$&CcL37GaxFKfD-!sCmTStYShZ#R%~`WH)4f4>kKiDSb>A706NWZ) zQ^DP3TBE%@iQ2ks75JUEubnNntbF(DwRVP*k}FVurB$vjfrx};@hoK|GzFY3idZ=+ zpMEYaS1|*OC7dyE`aX2#fwDtk~Rs<2&<>mMU&| z!Gq+T4#FYOReZ;=4gO;s;Azn{;t)x*l`+e@!p$sE9u&cV-vS3wkO|bojyVsa&)l$ET%-vkB}jI+UI+kg|N(gS!hE#VJ{h1s|d3h9njv z2Xm}y)r1ox2}57*(AXHpfr3vwZGn$$?VTF+Fy~I4th}l^ll~fHv*4N!Ds69wp?gm~ z^6{NpeXK!_#nCTaZj48zx>n|F<<{N23HlCWV6l1nAV)J>nOUeK!EpPeBkPUbb)K_61J$8Zw?a4k>zf>lmIIs} z^{ABOU2S0&cl<%k$}oac6UZAyfs~ZUk3vR_7{-Pir1FQ;HG?c1S`Un=mwxxEKPx12 z(p7$?8(fB&NtpsLe!9tP1kmekGpj_F2%)9iP~r||!+gWspu2K^aRIPUDp^Piag^z# zGd{(NlqOZY=QnR_fbOB@Np{BUpV;~SXc!UD3O35}gWwDGlboq%E9i4{%Yzl!6c{ny zFuN*@&~c~^ev!3j5HV7+3*I2TBh_&AxG?m!1I-9Mxc*k}z1n>h5MWFLqoYh37j=>6 zh?7oKHb@jm+)Xh!&P4d`Mowr#gWCPXWeTr;FG$%x)p@?eW_IEbq`Ggk^R z8J^b!3n+0*h1n)o)~f#Htk}d02o2+1xy{Xq4dk1QAw) zEm=cv3o0e-jJKfSH0Dr|1_LHij`Cp5fWjGPl5+y|0lKLqlz*q$($E8bnRswgu?-;q zYw(}^HrFYN7(eXCbzlwJzZBp<9##nA^Rq8gfi4N}rT;eW!h}Ifx+1@Hi1oj-=l_Y- zm(fu0z8{B1_rCsb7yW;x7M6e3y{G)g%J@Ie|8GmZE=K#=#Dm6w0q50Ur`?D?a_?3$nBF&?naoIjVRvmEk|};lJnlM2&1K8dx)x%$4YuQ)}wD z%*VNLY}3<2Pf~fZP57O#>Fr8SmK^;nlA-M=0bfjB>%WLV7m(m1MMR$=mx6NYo6ro+ z_xXT{Td^_IM13N|OS@cRLn3VP|IL>F7ak~L3E5j9Nb}-?#3N&O2qpyhgj z!Jrgfv>xd`{I@-QhOG1EiNls0Y~TL1vZpU-Gmp~VJ&qk{eJe#7fO=oYL1Mr^I01I)}&9Hti$M%zCXD)7!mU(-;khj zuWaEO>2F8zlhHqva1hILnmN@E`A-S*{FPpI(f|F*AB%&~aG zrOcHv$~4>}@o$NG%JCS`JTd-Yt5^STB4sj+_kk;eJ1v9YuOc=7gxu}jzONzv8_Rxh z|06V`g*(!J-Mh;t^sZG*x#Gp&v}n=GC!(0$O9j>by7EAjU-L~%M~1BLxXtn(qGai; zY;Bta+}%RE0za5|cwB6%6&aR1AF|ZX-kJU4=lTkd=D)XQJ(i$3|I5^g%kPZLOkiF4 zw5$Qw@c3}eK2MRJkyGU*9InTZ=+yFXV`uB*vk(>*#wIKb{xkh9ww0VIbq#^y=kE`! ztDB~qD$&x`)SX!agTYE>c50@1mX?-=^YSnI&G-{P8q}>C=*U)}gxKRv-uoSj>TDJn z;qzC?Ew@iyR=K{tLkXdvbK$X6ffz!BHmHn(`|i(>kToJcL*>rWbA?hUXO!mhJz$-( zmF4Unj0QSo-Z}uzhC9C{!&1+xi|l3VKUQ1X=dJ1wY?%Ql$3IL86lP~;EIP0I?B^yI z_NcbMpLF>_AS4c}?d1MfE5OvWG;0;n%O92&7P<yxCY5ID4 zdd=jwqO;Z0Z5@g~q6WePTAVXeY+v;j4(YhT&Uu7`6r_fRLO(-QMZ^wc1o+kyvo1jh99Jxq-A?N!$XE>3?%N5_YD zQywNJCf>^95REOoH-aGv32GFir0ABM;^J$Vn3!Ux-#ynH?d{KNGtBSrpPM2C-FLns z0accN5Yf7zp_fcAEidDvW`q&+dp3L9pvCNg|oC(8;8*=Ir*>#Wt#j=LHxNv=4M8mhE%Zf{Z9c0wD< zEXc^zMlSisURDL)itv|aRXWb#bf)IcEGes_FjZhp<0RhzA;!CnV^VLL53(9}{m+i?kmE!LP1I36!&Ofn1l9sU44KJW`0 z8#~`{FkH6C^dC64Tf*8A*_OK&ZNh*s0ORGY>zm*2vIPOwq0d7lB7_2OzdNp-s^JyQ ze9#OJi#^9SVAIZWL54Zqbgc#)II>=xwJg6-6?KWF6t#Q4Dv_?IWx3CBedzwqW*|0e zqgzu`b1y5K8r&J&nRRv+czdxpX|jC1W5szO4C2tzS5r%%67>^tpl9tshAp!iw3zXz~k2LQU$dA9Bwa$Cr?X&qL$7bEki|GWy?fi{?+8X%&&PaKTUCipa&D-h)(HI z$);S5t$n)#CVVkB4hh1%M{N!Yun-b9Z9ipNyCFMV;w=Ca{3&XF1AA=np?!NJl z9Y~i2w%_Nkz{i~LGja8Sm`5&DI}<^tVe{ea@JXoyNh$@OOn~p(Lg?pV|6%fpv@nQ% zY8jf}d~4}tPyby=SD@^NP+YlK%7(20m8IZ-N2W$=SkTCD#8>{-CD}6Ly!*}F!di}r z^ygylm$w47E~OxXE;W_kO9`AiZW;sEJ+DLfSf!}t+5Ez;M-J-#RO1rU2>Xp*h(t-# zi(Mzsq!vSyp#{+O66Yj+{zjazl>4~UeZi(R1PRnwF(9!<_RN>B!>G7%g9@3B%Lpgy z!y7+ZBEoGw$D{Pg(=5?C7LQ~tvetlYz0O^qZmr$?z83}0(Qv{sU5}SE?ij=2}kjGn12~vK{pM36r$;-Xk#t4GnqUNr;ITcgA2hHYU+yB^gec z?eskUa0fuMNk|GI$<5#gD^iTKZ-3HxiXGP;o=d!i9v?TDuf`iZPKKIOf0*}-cv9Z3 zD7=`3vcomzOcl+|3q}DOdNi)bO@5qB?_kX(pXRegY{PM=aUfSnP4VR=Z*gN%dx9Q; zKvA+`A7kU-w{3PP`yCt-9$fr3<=Vh{@}_mt%h*US2J^m0_2mxRss<(Pdn2{xcL?a)Fa91MJb`eq=v+iiMhQ zO57{Me8SuCV0SigY4>7)T8kQXKqEsv5AUSsXe+_xep?0xg> zL+GyH{9J_*nRa=(@b1kK#-+trhL+Ll?l+<0Zg78pkx6=iU$x7|7tO|Ysr3%}T%@WN zcl$ddV=HGTzjQ48o|%-z**XWvFj2S7#?yJKi4!eYEYAt*n>T#5 zbmk8~#D4xi0JGItSuH=VoEprL4U(V`8Y<ix_FuRo^i@&rL`ds+v`pm=;?3VG7mPgbi(eKJb-jdh4*xf`y(8S0Hn~x zf_vC%gTRHLcB@2q>b`+I9;xDbEQYL`1fbp~4=A`sItubWTBVTwh1Nb@LCWFQttOJM z=LBCmq^D0$C)>Ed8ToFmyM$Lqe*kyPOtFKwvIQa zXBQorK#bZ)dwUu6H`5}F2a-%$Rx52G*9X}^|LG>sS-IK z-i=1Hl*$fkiSH0=)`Vu4op~JxgaW#bFheyBFAYt5-$V18$$up3uC1=_YZJr#2A07T zLAc_so6>mFq6a1$c_Q@=9=xxFb_UuLs&E3eWv$-AYRfbRKBI(yWj-YJ@A0jnX@rM| zw^O-xp(!ceQTwszQk0J^?_aH)onhL0k|?e?7pvs#Xk#)RZV&M|K|0~TEW7*6&k(-B z##N>HWbW^b=kTehj#6QvE#$ePK6??tFm$tnrxcl#@Ljhju1_&sI)Za)ah6Kt#mwT& z{oNBBpE5h6iKwF=fZv*YHb_e2Fr+-bBDoquLtkb>(X525?khiA#m#z!YR%^}IX`a= zZVa|i!dB{5+|AGOuQ)acWjEqon;6}qDwJ7fdAkzxdTCjBy&gBY?>CRt6KwZDsYjEo zLT0yneJ(BkoT|<12*=ScQb`mf`ud^j7FTHuXiD`B)5gID-BVOtd;;x+e3_1a$FsJl zHPGbdW;f?lBHC~@6?z)7PnJj3FpVIJ3Ht8$#!glGms{Gr9(L+XmN3b8esYlx#e!_ngxN=&#&FCr=GmB3-TI$rjIVd^;gPBL9y_l|<1p zRzYPS$}0RyUl%JB4Ch1a>c72uMPh9|_7jq_h}9ZA7m@pwfp6y{UNZ@L$tRjK+4)k9 zV$f)D_%-R1$~?vK)M<_^Ux#i?udcpw+QES3vKh5^Q5e=4@{%|FIpYSbOC~|%oZw{? zezwVKR=cyuLa#@JUQAM-BzO)#fLvx_=jJE=rQ{4bH>0d#Y7(hf*@&J!*DzePO3b9)Ofb& zZocVC9)X6Y!QR!QMSCUUCv|x6JO%?`17Bd4)Cp!&cZpkxWqGzeG%bMwEHB48iXzDl zooIs)Fb8lm=DAnr}>l|M?pBE)nWsZ!?EHhE4%+R|V zIwYo>WCeA#tmNGgXxW@bbEK*B{0J3q52CYn4sbxcV7E1*57H}<3SSB(bXzlb$2wrn$WWVdBzl^A+Z0H5ibGpm zQR$t0{LE+?H_)irMZ)GS`-K{x9!2S^+JMEg^(FdO9%I9h?yrD%mVT`Py=?h{+pNX` zkWP;wI&cRFY!~Puyy=_9&e|<`{J zpr%>a7|2NvG*|`#N&aIk;=$?1P2_L?fCR`6g0C6ve9rU&${P1VAB1f zu$@V2wU=txPFl%n;qZu9xk_$m`)#*x7U|0*h6>%9UaJY(BnC#HtnAwfn$~8YUzZ#Y8V)ek3>dacQR-aoh=C zqJWD(3{-{V3tsC`&n&EcUy?c>j@*8P=!9xV`4`Oj z(j_d*5;)pel@jNSy&0K@dA|Nw^bm!Wx9CdT)&`RG_vFmkIqoAT^w}>Y0V(sM2{dz% zeC#}fa4KJ7b>FNZBaOu~G!ejr!w}YTayol&%cyd3Hp)^)9L~X+p_!wfXp*%Og{y^< zrrQbpXI2=zeTq*@nP>$1nAN&gUvaLPYs|18U}8a_VywDvOM?iBh!D9S?5j0P;5est zut7T)lUQ%*!1=tRTJr%8|NfPDNI%`dAGI}(V}#=+**u{b9U#g1`X2PFJz3&&P1ns+ zC0{&WcE!h(?K3u4S#2M`{SM9vvOfMlwAIIt3$&WDFOxcR3;o- zQXfcmKH0r;lrLIEX`(5nE7p8w2aXpeHOyB=dQ+e#PkVGfU|0ugrbj0=d6e%W4Gw|h zHe}~!R5K&6Y!@N?tq5O%6lCYrsbK)Mxb8KQIs$QMQsd-_;e5C2sh-3$9Ocr&Y-)Qo33J*UO3m z1+ey~31#3n%*^S0lAX;Y7*NUl@&NZo)0}wGu-H<(roe0h_W$-lCCwj2mw{5bv}we$ z?`rA5*>AbhIIQtr0aun?g`~m0sb8YMQfG1O)bNJrnrK z#lGRYJ0a3iJM_mU(V%Lx5G?}y~CL4uOf$*|2- z?XqTUnoyWP1>?{hv0`;q`+L)p1QLkMm!~3x4-g&5*`ET4f_bn8)nuqNRhs>*REoD= zurw%%O6bbzSBArh8k`d{dPTuRTW9m4u`(S%V1T#$ihDH5>ttQR-=io0IBd%`0*4BN zm^|Z`Ruajerr*NIb_WP8l%~UMys)LDbNv38(ZPzBVUmG05y~ENF49|B1q_y*F@xx}+jB5hqZK^0w{J7R*9)C3HSj;kGsgL>OV+hZL zB`j2taG_tKlf3!vDj}yWjkPmzHEt|FsLsIwFuX9RF>CS0v6sx$J)pUW z-Jp*XA+12Q$Ya=$HH)(nO0odz>?8#z3X+;HSAp3j&9V-Kuyo;GAMZM4xZ}bJmF@K5n05V%6W<7-q_@x z%!7e^#e~#Q*W|Qvd_T?B^k7Wzm7w< zo?NFKfE!%-(1A>tu>%@mbeAOg-VXiDzm3Wnc zILCCIA&^+FM3*ISrQ62%AArI;?K8QM-4BC|fEvzDk5bf`%Jv6{eJu(yfyxK^T70lG zuUf2gGU>q@W{7`H`;ePT>ZjH*#k=|B^^E1MQl=dAtVw{NapSix3p(0U0meV8ECB#3fE2Wo?YCWa**Y+7}$;Yc1GFL8*$gZ&n zndGffP08aJchFKG+=+TcS5Y-k`-4NDo*E?yJ__y0yO2n{=w!s@DoJJI>TGIoz;-~! z@IOe*+3fD}|3+e5GSS}_ZBlvWEXyFH%X+^OYYY2dVBJ4N=b_iw za2u+Pzd*+O@&C^U6GlFJH>Vhhx)|tv^WNmYz?v)UClm* z=3&&-nK<3|5LND)MehCNY4TJ2zwx7G-VlTlS7L)qlZskNX-;%h6q~qs4$g%V2^xQU z5{m4mD}{|yePw94<3e%IsAtaO7nx}G^6RtxG(ORb)K@}uBfkO>@NZ`;Q&Xl-9T~CF`TLDlV;LCfzucFRPAnA&;!PGIzpR3TJ0Uwe zsIFq7_x;5*Ie+j3Z`x!(XatpmauGHX5)!1k3RK@wGoQ`}I}gvaf`S5@R;783?t<)Q zdnylDBZ?IE6uk^rANRH59u(FBxhwqL?Iw9W16rM*y#27tOF^y1r*O&Aufp?ea#D3r z?uI$%@bHj}tFSe%eN2{}o_-n=3rosS{zwW|Mz5r#WSY>Z)X>>r;79~1^(%(x&+R(i zhlD(w=uyLks2$T15?-B6@-JEcIaQ$j4oEZ$}Ae#a$j<#z`uWuc` zlIu%RqbNDw=xQ#oaTc=cijP1&Xh)xVZ@LvCD*TWZY}@mW&w;zb{t+pdra`2Mm*uJ4 zaM@rxKcBwwshS;ezxH^q+R@~^_SD)zgA38YE~tqqk^df}(T0UG^Xv&7@xWsRFD-rH z>U3D-e##NPiaBX>5nX`9yizp}e0;d~I$WrkRMP^l=Y><(nl)`#JY^L+OY6#Uc860~ z9Uty)@}@eU&Wuak?CQ>Fy1D&)B{p~xwfWscMW8==fly934i%>5O@bUX287$wc`kSV zI~mX6Q>v}rcDm>rf5=kR<>loQEYUdmptYz~>;*qugzu{a-~Kw8{__WaY06HcMD*R$ zMgc&64Os8gG(;!G>Okz3jn$2Y4R%@!a?sJ4pohhYAY!53IPnJ`ys&y2>^*8>uNg42 zl(vQjL8FE+z&HE7>*&@yg_jCfTa~p>Va)p(PDp7;&DKENx80Ew7rN&4D&xm^cBA(9 z^})T81MS{0qjDhd@_ewGQ86_mThVT}^JYi3>fqkg-}4U%n=T&eQoS?O8CrH4l#epQ zd3Vx-3v6iM>%~uL==`daVi+m?lnKM!jE9B~|IFrubs(JfqP4ZOzICtop6^ToNsD=uD|<9xE&B5l_y| zCm$cGr$!fkr)5$hX}^y_$L={;bW;aaozza4e(O-A+o!#oqxL_nIr%{8&lV8YHHJqD zJ*@5sJ2xd{OH8u2oq9>}RM~{oLg?#=6NZT@=tUK;CUIo`F8)qZ!Auf?vGikG>_K<@E)26uI4ty_bG$7 zfX>TI3ErjVQza6U)t6sNmqzT2gSRNws;dHz>`D4a8hRS;c_u{6IYAfd?^%z|Cm!!6 zqyiI83Xm3_n%v%?Yh?;J!_8N%@SR77hwtCZ^}v`Zv9Yl^NVCvy4h;C-{@glZXqeK{ zx%7wrcxtg*9xmaDP%?JKa%{M{Y-eF-$8rqD=)?c>u#WrCmC9)xG!@0%z`6R`1%#p* zrWJmnPPN$LZp|ed?;V{QhybtQnC&}1!ky8chr)ucgdaZniq@xDU|b#6O)SA4j$vWl z7+*&Y3djAPdh*&>NVDvn8({5^l}AGU{kP_!slIuk%dnyXgu#c~hj4&{m0At3qLOSt z@k@fN(hOd5WV!4MEwW3O@3Qn8-TC2Tu~foeo)t`WKXLUDGe4SDy8^waF8Ev^c#G)D z`%q5&*45?%RN_}`0(lsD;Bu>{z0V}OUM<7+Iqu^LuIX3lHF>;dEo3zs;K*ARkDgzj znwZ_pe{HK~%7EIf3Da(o1+9&;qwcPDbArY0a>rw+b;+lupGTvFMAFhG*`@HTAT;L~ zipskyalQ{{$woX)MuJfSq*dHZGY%5e#VB8)RYcbl6S-P;7u#$T@`$n&JsmNApi6dd zV64wJn6UsR9B5-?t_6XgN-LzmlJrAQcG4CZpI0lJ(PVg2Ztm3XyzHnfjcrHM=@LvI z=Yakt!JxrnpVn2*Z2up-jW$B5w>fxb1h%KuLXJJV2d>=$t8pV0$RnWp`=GrCcpqob zJKgKMm9_hoK6vAtTF24R(E}7c%Nj#jNEt(TLJaX8c+y?v6EN6U0Yj~N7Fmg3T2^L- zT24!qv$VIwF&h~KEiFC_L8C@@JfpealarW9!DFz04Pl2Nv!_{xe>H}9Zx1H8u*t(d z`&94v-0l}2`L7|2@J8zmz=^ajbto1}7o{qJED=>@)-3L|UE0DWmB$rVa_*qjf^a{^ zytAhk!IqD=$+lm}F%)WRlSq)Byj}W`wl}1<76ns4Hm{#T$1&AEAkE)oZoetJ&1}{7 z-d{DX{MkD{plU1juFe@L?Pv3p;#qC<5&6;Gy&bBFEzF0>M_xHxmVlXFVAm_N zIXRUtceLL9+^KMen%c>4Z$E@iO@0SdkxfMPpZ@|VTPFXe_FUcS8@@?EB#ddz09DzM*2&a z^ea_*dAiooN5((pTfdt1%qgx38l2C*J>>*d!?mx5NsI&Dy(AxEkvKxt(;XbU8)C}A z{C~)MtAM(eYzs6H+$C6Wcemi~PH@-Y65L&ay9NvH1a}SY?(P!Yg1^PN-F;7YbKl?l zdSC3lS-WWn}RX7fz<2VKDYRXGzgj+ImdD1om{88 zDLSa4avWPWsOK8b`K1y-{Y0S)J&I|H(#+NcuBAX@5B&$z z4t*E5i@zVr4fcE%g_n^T(T@g7R63kpcRJUxdC+HrJJQK)=fHB1D{TFF568C<;V8=~ zE5+Xd-ibYOT~U4Ceb?z$<-T(S+rIA=u#bb;tE=nmcNPR^d(8<+Y(|UHU!6^fhvA`z z8s`QV)X9K9y}s+cmsv9Nq392SgT{B&-ses zZKq99>~X^}bRN?t^?A~c?j${x*cxUDV=%|BnL5&UkQN#gRfHcjM#miKAcHCi4{$lU zRY2s;0^~lpUbNzZT}i77X&Wn#c_e5;XCBfF^(fxTC0Oy?Dwod?s*17BK*(?D8tbSy zqUKaOy#*_hx?M;GrUSB@eWa{eX5Sa*ZkK4*W$-t;B%>DV-|_c>8Xq0%dZnMyVZ`} z%bVjopD!~Jj}OG~Jz1bsIfHbcFOmf2W11rmO%7d&1SHN4j23R)+i%@}jNmi1pNRph zw1CRb(9ih|q92#XZOkuAtcO_Ta6NZ&wxo9W*ywqM*4>~B%f&G#bD61LD%$SNDe8-{ zcXrSSX+kq_CEZl|?c}aycI?;Mo&@%lS`~4DdEiC#YSSwR?{|$@F6uhIj)OI`_%xIg z;+fZ3DasnwfveHYEJfK8!>(5o@B$+%07sKgyrj!tYPU#^_s$3@isZ^vJLT|@F#Gh? zuEBUDK&^mN+^kra5E-ih5us%JfiE?)5N>~Zx_3B%FU(v%0(-gOx4Vll-AAHuxS>?RBg^@pge==Ll?g)? zoa-p@(^%sVx=%B@;IIgeb&YGQhsyd7-$}C~3kNME*JDItK#$EYFhaQ7FS*)LISWyE z$1+vJyMK)DCiLepRos*8|6qA_(CBDx)vez>7o~rE%JK9zbtwzgPzU&Fg*VMp9xCXV%+DWlF z^<(5J%R!D#%TmVup>(Q@jLD-$fHM4dWAarBnuVo)Pk0HF=SCpLulKe?iMN8J@ej#( zNEg8>ct8=&Bhv`Xup_Z)MEESEsd)*)to1Q*Din*I!&11=$COK8J|T`fcXN~5oGMHJ9-3IY3`j~`6TBM; zlror@|CENJTazB}0eo78N5Q>uNqc+8{PUJR7R!2ZQ#L}y^19<%k`GB3xnnG;=)m>S zoYyh6K)g(PrXas~|D;W*CJBgymF)~;k8XT)$yWSM6gS9p#)J_bXK%bn5a+z^{bW+_ zPRUK9)*i`kNwBz2xw0+Y)FHxEAE#X@z0>2C{Ya=nu>7%$N`5_zAj$K{r%%31J&d_e zql%Jro4XXa7TnCwz;GKaw3dWR_*T-OMHO6RWxb0z4*}{N#=poK*zui~S z*$I=ff;E?Qtz*fbH~^Fq4mORM6d1%wa9`?P;FoWn`jxfY>`}V6gqLGf0^Y;XZe}52 zCV(@ms%rdO1r648N<5lBCkWNtAsB^h_~M5uw{ia1Mf8u9Dg~;iH6UbS3k~>Vf>zs$ zi>N0E)ui8usluq*tI8#uRN|}|QM9Hd68c|i`tBy4G!wI{W)-mT-N#h!62tO2>rljJ zR?9C&%MCsjU6u?OvW!#tN-mk5DP0%z_K-B@No*@HSdGw8bc#y2N-`*>Va$-u&{~zq z)@%j?k^!@x#m-faQ{Aj?syxb1aSbKO(&oRUFk?+wZ<1#+k^)PX{Txo*5Dr>MNDkOT zOcyKe!4_qS5+Y^#MhW_!)GkgV3}^NH4a_Oq(ii!uK2y0%9+DS74kjqJOMoR@rR=FLbyu2aPi{$&Q)_%Y{)q@vcGE3grlL zn9AL22kQrG0=)93`495M3Yf|rl`u$tn(`z#?-cDU2J;@VLyHaSzAr7B7eLAR03(=g zKw4H}5_Iu-Rg$xJx?1Qi_b^?U@>oh@D8Byii@EKs`L*nwx#x_6V@GX9B$sl5@|+{i zy^QN&-qT+WsM4+yoie#nhSI8{gt3gV!j7!5#xu<&P0f&%Z$CLPaIjkt9 z>B>p$EZ6wy`PRxUGx=?3Wtig81;W2oT`%K;9zqp#Q$Vw!#QYCkgW(Qpnc4ZaYndA( zq?|ZWsqY2Q$eHkqdM9?BB6Asv+5gKB* zK07-`8YG@+A<~54P8w;K5TUZ|_dTm4F*OFjAzezkAkXvW! z6ju>VNl~C49;+1BXzJ1a^bt#DP&5u7(&WD-qFxOV{g-4|Bg55K$xtEU5M*pTtjZXd zE>XI9EYB8%%(raz4vdW2cZeoj@x;B!U{{pQ)2X~->Jj1=BiC4dXTqoXKwxtA=o-90r~r=S5=_)60YZI4l?x4xql(y`+g zQ^ATErrAXsCK+Z&OMO|TTpo`&^hWOi8{2KAdZJA6&dxIwQ!{yj1C zPuq5o0{^80=~8{GOAIrwOVBk+$K4x5v3I^wPyi(hG@#Au+|C30Yf&q%%7Lww6Bbc9H)+YeTNHl8`#rnl%*f|I5_*_-60cfKJ+ z3_t!N;6NDsN)#v2Vz3*4ngP^Di2qA{;S6u-0A_rk!yR%o&)dZA>p2xwA8h=(X% ztcgBVzu;U*(aJu%Ya>2<$7iNtz8VPZh#y&&AcWNw+$L*Sm4gRrAgI{%t7! z^>U8L77X%kUh=^LA+Mfgr`K72m5oNI*-(jBNNeeR>qBmKY|spsv1wx!Gpb zerjUNfF5~!wz0+5{v~o}Z%4z%rd?CH2gr~9D$BC_b&iP8W7#oxYw2&SBr3X_0P^$0 zTU*sK(JMA9aTje$be<28Jj(2;{Pows=GBvHFFzBzWAbz)&;WvdX+5VK&XmW^wl^8ILzLpd4iUedFhrcwe z=O#;4eYEq>)!V2sc_HNTdd$6c#WS|{z1rSFY@ShwgjIR))HV6V`P5l9;%A$;#o>@U zyU6YJSwY_yRvj_mj|?z}tL^uWR=TJRl$rAvh!M-|byDWGqc`7Pi5ieWo#hxVa^m;n zY$wFC<*x*3en=teWXFJIi<6*iK9a0dmz(Q-U`u*PUhdLa`%^a{S=drK4JiNM34g!2 zk;MoO?HwRLssNqr2lX!34N zVWgS434dO zu{8dq)vg-HTRMxLnI5it4;cw2Rlx1cqgm-u$#d2LQ}R`c;;v|*xTw6mQ)6-Q*VjSX zva+&~9@^?bGvm&{ieF_vwpGY8+0%1e0-Zf)5%0bA7cc`n0{*o&|80AklUXlU$CRjv z(Noe;`GSn04X7DH3W%4RAv-rq=1(BW-)pVhA+?Joa>M{$g(hQc;ON!C)bF0XOgK8r zK?@Sbk6Jy7npESp&y-M(fHvr_6KgU?$`i)$52_N?MFWndEkKz&92y#$n&{8p=fjFA ze;&TU3JscU__=nD9JiKnc|6E!))}>Fisq@4&~7s4kvejK-^sePEk>0_KL+Qz?A(ca zOfpK49A5LU)6&I8+*c|qkJu*FgVwvHS_LEER|^G4s>Nwak2u9hE%jeWa>k6R2cw;L ztk|W;$&;4W+UVP^*Ap{LIc49O@5; zD9P-cm;ZSfgA^Ngtin?sEl$&@5i6A%5U2Nbi<)#zY=x6@Ws;sIX*`?q6s@DFxtSg6 zGbyPEoBb|a)aROMfTQZUTW1}G`r-PMP^bjSIcf5ZM~kNVWdmmJBPm3gPUG-sM%gXF ze6!_UEI8Y*mBkwtoGYw_Lreb7GPG~*=b$C294iRTM+*|pBGmRJMfdkX(e0oPV^=OR zFypN*6OTxb8h-Jcv^@srdNH{R%aP3uvj>TyRD*35i)fO! z?;PBnJgz+zL_Fa(>*ZcW>QGSsfzYsuvT z`DaomN(aGn;pzh>!%b(ZOSthAWRdhqkl@`thMlb8?bRRQ|(AtHscF*!+RjOJFhvi19QYaB5 zO4m(UIjT)zJm7S(6lyhE;|Bik@wo59$Ecio4dIm+V|&85ZxnQFA)9IBFic5$P4k(+ zYh^VcNaqfnRq54#8@Xg1`abgx-C~O3-SusKaJ*ZcS|%#!4|;Ur;^JBnp*`7D$k=Iw zBDrn+F|XGzS6wz>-iOH1kl3S@tALXuow=*SoDAQH#JXM?p53NX2djDCT2j(?8S!w# zp|Z(bbKvpd?(XlCaMnV~Btnek#qFAiDHCu_3TJ$G(_>AVOEAZSCskBX!Iu{GMGh4k zS`T2kwb7tx9S~*MOt;_OTm>194GxGhG?n`Nd;|UQl_Rp1gA&~!(DsQzi**kN&%uPI zELxvN@r2N3F~8IsM@gg_Tp6TbJ}N#@sd|o~AU?{EUI2$F+L7oaKlWSS{u<=r$_f)lrWpQuIOSh0O$mm<~6u88xavR4^8Dlhk`Akl(n z&G?fnuFbp-Y|ZfJZ?)S;BvC6Ee@tHRBSo}oT9Zw=a0?<;_i~P}QvO>62Jq9Z<2zO& z^jU69{pT4s1^ea$2gXp$tCo2zXG>EsM6xV;c4O3H4H+p2=Hr;yd5(BpodP{1`d%X4GQz3R$RE(Codb!(bf? zpkOk7hHu7j4C=2T=q&Znn=k|Ly8!4Hw>}T|md7Qn0*cBjm6{(C1y5@ENydJt;O=Pa zV2zwwY4mO3n=vplB?if;ejmya2*@Dmu9zC4?d*rf2HW3%+sOX;QW_i-l?u~Xbc!}M z$(SPrIgA{IjnmJ71q}vm?+q}j<4NWgT3 z0$@Zb?NB0#%;+$Y4Y&dWoZlLJ+c6aWu0|7jcu0u1{Eia@0P|`7mEQU$rskdqXk+ED z@M*RFUpQdY>jg!@zRYi;T1eu6!iHqb`kS+dp8$yRvkBftG{T92Ie`GF`__bc2VfEu z@BcZ_|Ni|g0Cb4>)rs-eP`m>HBOZLq`2ZwJJ^>KPmhBl(S^8E0-1&{^jc^-iiXjr1 zoS$$!-V8loZx8O@yZ6u5|NnJ+&QTrv`}-?P9PU9KJmNl_UlDaaARLsVHYm1^S5ecp zXZW`+9G8=yYO3$)@RVzEkk_SSf~rzcYdGcY%-Mq#S@pG9G=CpCb-Tfu#hQYXK7MGb zPtQWjL5)9Ut)3aUy}k}qb#-kNAwmx8F#v*Ai-Q9*6-7k@Gc&WfVSoJBtx{SPw27}b zD5$ixY^18Xx~#B}VwrgByaDj5HT3m=?Ck7l-xg8xofOPP9F>=S;^xLFKkex7Nk~Xg z2dZ8hted;H9h0JydQWDPEJ9dMH$PI zA1@v(ZES2zA4^tJGDa~E%g&6JxPCpijOxhTI?!EWN0q2YcwD~g1T&Q3KKFF5#~mPeDIo6DE6Rd>3}rSy}mdnJ-C#V}@cycn0AJ zNMi{Eq6zFGSNL<7Irq|t@5^f2+eSol1VD-SS$sVEdv872)7(#*_R`!(IW10cF)<6R zvRZSrADR~O$CBc^&? zErPpug)A7=F34(BEh>|zwY7_}9dS@WLxXH!Kmr97^)hg)qq+5Y1@DC)ir5J>Ffh>W z&l$2SP#s0e#U;hno+B0o>L9mJz2|y<)#843db4}%BGiGz0Je(_>LC%I7(e)M+D?zo`Pj}IBgcq&AvUOs{15azYsCdvA}F%j1)I%!hl{2 zeW2<$CEGRzWlJRC2b6etDt`VR5H! zv9%U3B-GTO$tP~_&}{}YPT5d2Ng@ml4a+=N10tVnk=C32atD3i;~V~FAw%6l<=kCq zvZ6k`On$t-_C{l`fpk8DeQxurLa`!cW7AmmxRj~+K2!B&g#^)VcbNllacc9k_?w!Vx92Oj zV%u5pjl*K%$YmuR9c#HOFQEbPW)($h^neL}X~ZA~!2(r}GBvOJsm%TNe>M=kDROcQ zT__5AriMN{9lHr~j!UqxvQb(j#m3V3>YZ_({k$JnN4P?yaPjhL+vkSt=!!7NN-L&5 zf7Di0C2!q-Y`E_RVNrLK3i2V;gW`sRvgQAC?kl&wverUvW_Ey*8C@8lpsD%2<>}_T zOAM)`wRHxHctk|R=IJSYO0uv*#Pm0yXt`BJmA@fXQB8^D^tY$#tc@D^n#-NBV5zL6_w;#Tq&xDSTC`zER6ZN z7fw&8m7rh?ulFppR8WV9pbx5HapUJQ8PJGj%+qr1^-r;$tKcwUD2HOoH zQZ+$01I{A_)mMF!jM0#XuoCd7O~KheEwy&UD*1j(i#WtAxwzyTDV z#BsdkhKEhkr=TzX3U|Z@o#X2Zl8$L_ml_vW7J%G`D=t(W*cA6BO-D;=t#}CKG?HVJ+uP=kpdwkc$73Z=iR!Y(I8r6neq*Kaa_JixN?bZ| z5hjaW!sgY%XEpV&s5h0U(dj_({Zf-+1J3(CT&}vKb-Omhi^8O+SQCWuOc#UTQXOpq z>@2$Mly?aYN~x}Tj^U>r>+47qbaeY2;L0GUqsH?4Uxtj~;$i49B%u!dlIoMvItDqiu--e&7Kub1Wc~NHLDI^*swu3bN zTSPT9o@AxfK1sHenu@vxclf6)FYO8x?wpK`|cYv)UC#W|`Au#7IK|n^G|E!J; z4knUkE|=LCl&Dq=K0iS+#NbSV2L-~S_uG&0RiIAHF@{)o3r|9ZNvx`UDgcK>m5|4; zA(o>`vWUyvPYx~4@bS^J!nOp%(XG~DZb4Ymq&I-d&WmJss*mx+3iAeX~~0*-1?dS$dK91c+eK3)_!REQHVH+B%iDkYa% z*_+;wumL~!ke7z$qT%OHdF4FshXhrlUqSF{NNvtv(h!IB+)?4HM>IbyGn~xqcHKhq?*wwWxSPDUrbC zbjd2sjQz5BufYTc2O^}`M%=+$l3ypPk^0>T7eY5a9s>>SFf`v;-B0*FwUib9#&Ix9^QCMwYP z)yTL6qt04**B7)slBYnS{`PVGYU0az{mbWaG~GDcmOrp66|ul+6v%P@`zMelbz zItU60>jXfM=_?F(!b?WOFz9>qcCbi8Kp)==FzHMws~1N#NJej4Eo35|@Q z{mw3d`TL3kq|yj#m>uks?cU(QmuUVp{^uUu$2HCghrT}y6rbeDLnrpfR4TOc0w!I> zAE*V;Wu(K0vPEExxu9~3i;v6!z36G0B>ET<+$12SA`7{TfBYh@qTiG9B@@TPo_i4F z6FF{UBS#g?@hEnjF%|PC-#Xy;Ai)Zm3WZxEdkr{7hQw28G-|}3&k$cCjEqgFK&C-1 ztE;LM(}z`5l!c5xvanM2;!4K|wP0XCGar?YpUmH+1?U#bXZdY%56|ph8e>gk4(XxD z`Gp!Hj~siH8mJRtYW2-=!D>#RTHYPe9LIH4~eu~1VTq6Uykk#73%gpabd26cb=QStz+Y?^${`=4LoUt+rgDROUsa{Agg#5Th}4=ihr}OGV;wtI z>tV!G{*3jLjiSXvJ*r^grd1kISic*4{XJap0H)2^{)FM6*3^mZL){3|yT&sP2Xy%8 z$)xy17%cn2=9Vm!LEjJIUbr`HPl+yuOg+k~oavnK`~w#g;bpMJxf0Ul6kNOScYGFO z0VfI*^b*&XuJqeDSPnLQrah+kSLLy>ImFOx6vx@VizvOovb$+#hT4Tyfsd-i*e z9I*6BN2axYhM_lkg9nQepi<_QS zY7FvqIT~$5%@Oe)n6nDyCcA99pS=)9Ky_XACrA2NyzBf5RS_w+_G}}gLU&BAM<{`JCKic zdIuA(K@&7HqcTLE>5-jp=a4TGhMf3If<-syvwofPeP&1}XmC;z`ALxo`4*4q(%9~f z0I5~}G{TptOY*W{H9m-Yw*m})b#DpNDs9^zKHgU;(gu{s=6J>Hrh=m2)GHgdojz$` z-fP{(vLHkE15b|*hldd%*aSJC4mdKh2BhfpF4F7`Fy7M^k(~#c;oD^u^-_vS^#L+Q<%7$Iv9lD#*q z3dM8XgWn_CVOw-*;hlJ?3tgu%xdcR%tN=$x7Gkcc1A_-c{5KI15d*~?_lmF8kHDJV zfz+@EHC}! z_aCW3w00Sz$&(U_ghXY(E$PL{eZQVE8Qq6LQ%2%hNmo=>_ce)>+K7rXlKkn((6HxT z`5}zfgMCsJ_6U4#3}w?m58|injM+}KqVBtc{v!_mI4-&xTvMoJF|bc(`3B!)rOh~n zNaYQQ#V@1+HFP-$vl=ClAZC^1e|pu|@JlE;pyl2X4C`L#&$`1ckvp8>e3Ni863#7W zgQSRAEsZlzJ)B$ve^9K;86Kt~{lW)+AiO53sn^@_xUdIoe|RjQ9u@Rj4f4Fte+cd^ z<&rgJA?S-j3p8LDL{SN-a=+X}| z&hlq{aVq%Et6o$ULJ$yNc?TuK&UWcF)nhBGGfH&d9{SW?R{?l%WAH&yG?5SJ9Q)Dp z5@~Z2G zJFH*b&L4WHwEA-vFrX>u=3{NIJ3y_~TqqWO+anv@E7!$zW3O&!rsuQUS{~O`f=_9w zasiHYbWT`&w!d5Gmp|Vhv@Ju9455(M#?@+`rzY4>!@_zz>KUVkW5}b|wJjmyPn033mac9v^aY3`lH_L#(SYnNZCO)l2Ger?_*82B%C8gh zxILY0d{A-0B5vG}>nqWRNyLMTRgcD1C{DNVXXjnrdop5S@#OXdot=C~$dIH0YCf;d ziWt~FO%ibA#72_ubz**$@}wvIxhb(dH}ncW^X6f7)oRmcO$j%vhOpmhwe{bGOQ^w6-O zX)t5kpZFktoM)rA_Q<>p%=tN*oV$76sN|Krdw#zOCAy(3l(uMniZC(K=B<+pfB$e@ zVoV;AXPpN7JjzQWSW2np?<|{^df}p1B}s}$-l$~tlc(|+U{1-FxyR5em+L3@p=ndb zADK4u5R|yIAS$7gG}j5T4skaWc81X5>Q0HR4GV9E!tlqcumm3Yy9Ep)6|-Uf=>)0R?*T70i8xIi=G1kXKHHl+(0Vmh26QO#)B~$_E#?S1d%PBMBbOu?$1F(%I=(MyD%Yn zkikA}u;-SsKkD*Y?=ipqQdSdL0k!v2vfLWPAg@vquystP{!DjWT0&<#J|@7vwiccy zS``v=)xg;k!f3UaM5A3=GLrVeo`_#D7C{Ua2IflpVf|#a+!AUz^j%*rCx5SS0#)Nl z1|D4amVI2Ol}`k{o>Y%{hl}M?5f69@aCI}SHC|QLVbd=1(k%H{JqA*voftkgAq5n zx3SF$eLeTyF*8i8^oYbLP54?KXHgVs5q`vB9$|kiFgHdhl*xu}-kve!ICxMMLMCeo zNml8gIquC)@3)vWTun8?}LNz2wShSf`)l&U5RzH7%G8BlkMXtB`lJk`=-gK zRQK*biew;qsnX=_FOG(V(wRO}j@)7-NFi?^%P*BTg@D;dR?7+bTz~iSJX;*ERAA{x zhY(O}cA`D3Pm0ZUZFJ>)b{scImlAf6Y18dzwJjYEtaFrKA7g>Gk1QzC0E1GG<=*}v zPFERuk&cRrdZc*IZ@jJ10zU_Yw9X53rcDFF%!(IS;NT^dJW3K8C{mXG!%2ty#Q?EQ zjs~44b^^VcAXOjFqrJy3d?z{jlqzG3DMYjIIFX91&Wf)5gCFEq)$QL(<96kJ5G=6SVSKCxa??D2y7yQv)h`!5jir?|ddOX}LoSj;YmG(7 zN&sgVx4_PV&tmNEkYwDt>MZkyTyj@NjID7D^1}Px1-^S=ZX#YM56No0=Qy#ig}nWK z$g>1_#Lc&Wm$ud-R0n_KKgzZ@W#<1lVsY;AiY^NIIA)xJr4Iazbo*JJJ=(O2Pbbz| z`imKLrfAE>*>?F%u=``;4Ie8`SJ#euI^(vhbxf*M>!AO1+|?pTesy~vnQkP{J18b#-1CQC1uk4w~hDq zv-E9-^IBR~(AUyQYrJCdu9s1+9M|J_BRMV^QxLp-L(1)UOUe+c?v8^!Oq|ABjFuRq zHW1EwM?0)8+(Z2qXY6tI_{*an2)LXiCdgpHx#(z~Npxrf-j7k<2yurIZjY_^d%nn` zw}%ik_6JPzn*R2sU>>Y8swxN+lVM?c2(Iy9Za3XOVXQ$`Syy_Bc&?t1! zD|aOYb;4`MYlf$*AQ6@9dl36!nbVn-kNOT3(KR0bZ0H~Dz5a2rM79Uq(ZQ+XjAJ_lyx6hD>^a3V?{*0IQ|L=#d!Q9{9Ez5z0 zGc;xHYpnkL(|^B)I{*q({|bqhg}UmmVDQZ=Z&7_84zJu$%A0ML8wlg#*iZI&)c#)@ z#RR=Y@_mp54(f=Iuvz;ChY*$Bf3;=xm#6Z#QT$&U{RP9=>OvF83gh9OY#tmiu6_M^ z0SwA3%>VBl{>M9M!q?03ZR9pGUkCs1P5u3yZ!jc?z1!0nP&8Wfe>H^(stXG$is?zq zuq5(^t^d)qiwhD%*Zzj9ii+a@{d;Zbz=+>#=+%Y2+3CMNJUb%*O!w=uv^4kszC91x zSF_Z1SYj~#Ya;*W$gOV(bQrAiagPm3n*aA8bqM)(bVpz_aWWABYwG6K7I8*K#^&zs zjePtH%$+F_1Ba^+a8|_*#3697Xj0N#j;q1Nto}c>0CH~6%7M8Ptf!&!Mkj%ZMMh4} z`an;ln`XF6)u*+`(Kl8rXQY@<=L)-VDYAEcbJag%F_&ALC!$iWMtFXHF8OgpnQZ9` zl!r2y8pd9Ed*&WD0|N;lvYZHPMe2YO`S$ji zHwz2NuU|qG@!$X4-ydc+KaA*zx-8GnC&R%bmNfOj_i=`R;sYt&r<~1T$*_qDg^{Ga zyN8F8i>?$Gdmw?y7l}1t0S*BnD>vx6y1$?7;^OixGqb`zgi z020QAhDxS$b3J%?v={@Y_*Pjhsf2`v#>U1fy1qOi=GN2*_xAMxFmK!M#YQP~T8&)P zv)EV^*R2uuyp~d}i_4@z07VzKmSy`^h<$Oh>TEk20EE<{OiYvMQqta$zVhZaR&hYG zi{Zyy?~e*u($4%5>!aYKN&OA4{L-&z4}YU<2j-i zflh{w{GZooUw~s!F1GMr)W|0vWl;9Fq7cO$Wg@zJ`Y6pD z9{+sh@P2M-Iok}o7_4stw`WAWJ8FOS-tG=TZ5Y)U5SNQ9Q4KZj2~Cg`Pv>!0L6f?6 zbga5fceZWSTWHX4B_Sah{=8kP7R3Y#$lF|ua=9l!8EXTXX|BURUUz-ok75g9bumdv z)CULkRBL#~(kFebSTpW?^0nM=JZ%k-P~lzO;UqHBmT4bK>7s#>CkbiE_-g`-$EWv7 z3KO7xld{=W!OsyyL_{QPY$`;=#4~aeXod6!nW^K@!}mx? zOVjY8>T&LtM;52ZIXHyZ{K7y^z`n}-fV5sgGF22uZv3msvC4c0X0PhT49cSnYWjyv zwD?M`MUv%mgTm&ffxyS(=#}QocmVo^fhN6YuezFfU6V^TOibR`DQ(w~vallP1$~^I z9i=qgn}N!PE@VgiZ)pgBkUm1jFjEji>3TN{XYWn!4A~*Z*Ub5<<9yFr+2<(|9+~M%5R8Bo$vL$0h5^BOO0o{E)on!L(V1!1kOInQG3N6UOR9hTL>+APGVm2t1 zLKzoyjD{me^y#R*jWW~ANgf79We87L5EcPpR!AHIkp5CblWxDCIkMa6B6YnlB2Oqa zFsl9e({>@G&^%mH1QbXHo;ecmduxXO>0{yM_AB&6y-&}it6j-GDcEwB(uMa8Zc>hl zT8qwZvZl1aiq@7gAe~+V@(p@5KE4}_=kJ&gj^3X>IXm98@+D6;CXNy|%Fj?*@d(9Y zVUSQ)Wp~dlDNj&;ciRy(E`SSPjov9DjE(z1#jAt&b0jT3G@qA4b(PM~T_XjHuBcLA zGs5$|kfGx2IB_8B3d-gYWr8v)k@kB2q#oew$JgJ*Clv zS_#L8tXvUDNiU7$0LX{pmWmu_wb4XJaf{n%qpWbLsb8f1Yns+sk24f~JxAJ1EKGE; zv4TclH9nPc;nyDO2EaCVj)l6vhgxf!XLj^Tw|oT>!*Kb44@zX?tXBe zK#e29&Hw;OieR=W4)PG_dw(O)T~pNxtr)!kL_|1;hz%1%Wd$8NfM|it{)gCLx^Uq~ z?-GzTZe8;tIBkFNEmdoiZo53BKBRGR;>8yn5&m3LGp$4#x9WCeb&h!E53L!2*W}^K z+fS@|#kQv>QhtLm+HnZjp;9yHb>xQ}o5qFz22w zd$J$a(e}%x4Pvy+)mRUOPhuO6FC-K7>G5$w;w&2$4(7Cc7zqcNwKN4*CqmCkI--qY zN>^4Ee?MMMey%b58WPtS1QHE~fScuL1WKb+mnkS%A8?KrN$RYRQ6nz1_oedb7=5hj z%2STrnWBH1U`miEd2V?lBE6r4dLkO3_Ple=PX*Z||L~LsLaVaYO?VFa)S zjPJQsKd^Hn#FaJMTWZ)us!;s46=jkhca_o|ZX(6A*m35sBL?aoKS{vdCMf=X*q2V9 zc0iQ!3H}~VY_yl32TgU%rMyf;UQsJaJW37P_T-;)(R~4ih1X1YnrRh1L{J;VUzfmk zBe~Sk@LM#a^*yoOnP6*L$;qtA!t4aO&Uz>ls!(35iJGjISE z#_0u~!TPJmc!|v@izXp@Vh{x*?eTh*w6$q7Hy1%b+Aa>Abz)*INDtpV^zl9a04f?l zZgl4;EPpV#Zh3@KMZG4`&ru6f;t+0&Z?C z;;Zz4M$)6ls=T|i8ApkukLj)U?KuqD?K$`NoQ21ulArCv>N2~!h7MVP%5_ME_d@Z) zsY&ejKCsvPP&ri>Fbvb=(+X(HtVS&oC<6OA!oT2=h~oZ?!M^~7X#Gu&;8hL>v6@-g zA87elr8j>)l0t>X-;WA3g5(W?ealrq!Uk#6LBZY)3*DsC_9UK!pBcuyxCu_BfH6<` z5{>EY{Zn#N@R7vV8`+CMm@F3yY!HgqQy@D4{7zilryfoaZ3=eM=tD8!I!c^_qoSZ5 z!Ul#HM7x+nR(3s+c!@jNW3YsT0l}>s7>{ZcB~01}DUJ`zduCHpN`xZzvA0Jatgp@t3Tla}@(o^g+8^QTXy+&t_D0hKFS=AS-eYZF9A9u`n~bH$wZ8;=N8ikF3`!?$3D(_`l{bzhXwfc;hV4;P|1`V&l=1-q2cKr@e zXS}v(?Z-+ryX15njx2$yG&fsx5R;HPBy~TXQLo!RhF3tK-!di3EC@F*XGnZCyX7Z6 zN>nBtNk#I@vqT0t9I7+kz%bdc%`AbflXE$<#q+gV$>ZUS!rhf~eX_tGMTKH9`ESgr^ zwF3n8Pf}_Xjn|V}N{4@of@te3XztrnB6<=FHjW_*$Ip*zZeCBWo!MUx6Rpzy2ZMPF zGYFMiI<`5zGtD|q`xVgz0ZyMCkCRt+R)wogj_W$e{OEz>7qdbj>K zzGDZ-IG~Hk>Boc9u%22pL%j)^z~YGiU4UzC6V`_^L(?*`A&ZAM2F8E%H>BR?FO1ex6Ntfx z8AGhvftx;)cB*6zMkO83BX|ucv{72^Tn1M1(C*ArXGn%TnjuYmmtUkC4wENTIs{70 zB1vq>T(*ti7^RnBj`56d(!Kd%o+SK`vE(4N4wZdH0WT6JcY^&CUixq@>eX-*vXb-9 zypLKq0TUH9RbH@?GB9jNW}<|c+gIq3)bHhCZLZu>>sp_MEd?t*-R@V7I>iU0E`7kY zY7Cx&s%Yzn?|l}NCx0;{!1M+>Iy#eMCj_);D5rYamjeWJ z^=9LIDCuGVz>e7RutVr=A3+Rr8!YW+ak`(FQ5{F;I8GQD8L?&$*|pJ{fF1V1US3R* zh5mZY{y81@Ck`xJ3VkjXODzmYzS7)Y)M&JsiFca?YV>zYYyOOPibMtdA1X>M8>YTh zI?SS^#;L_g7(d9%PNWEyk-jp4qL%ysMCMrFkTPwE*0G35RD}?*G-!$Om_@8 zAk9sdy?umSIi7b6R#>nOhM)$=l(sWhYS2CnEMYze3x^k@ zI2QxT>#Y`LjpUO61q+B6U@SUB?;zh`BZg#J%6YWkm#GTr33vT@8XC#np~0@EpOHuL zL%LHZ;l3d0keOu48p(AS5=7=ZcKF^Gu-Zf%tZ(cZ{_guMH4n(08^OG*XQ&6EiYEDX zbPixEe3RCX$Spp7EAvIBF#y&!jCpl0LqZ~3_ET>68LDvn!`IiCpL{_5tjNv5UErUk zADC-kAif?R-_iWHB&A!f!lXlRG?~?6N_>1iVl>esLg)FTOC8c=nP&di{Gw0qt<=mV zu0!!L?JU&ifzx`<&WU($vh$z{A$QY%)DS1UJe4bA{9&^^WK<>nK6>L00)bq>a|sP#y_rM2DM8B`bYjk z?)rV9SceOJfth7COv36S%qBufuT0-gj*TUry*&R}*D(iJq2~@Hmc4H?OITcScXuz8a!$hv4aY!!7)Dv1USy>(Fu)Tu7xOvl&(OM# zXNVnqfuEG(E|^%TVbn>aeK1EHki#BHm1cAW7L0wdBa3&wy(>6md;{1uqc#GH+ZT)H zBqQy8r!CsT0~A_ebcNW6XD5q$NxQVF;K<~rpBE1!jwsyXk13)inKC-v7+9xJ3Z{sD zSfS0jD4ZL{e*K<;)4FJ8kB5_%*5oxQz!J)tQfa@RqS*MBGlwjZFrKBv@t3k@V~e9S z)hqSwaF@3dX1G-JDwS4*Wou4;!h05*-Pta^-b&gEpzd-(V9=1Xrl3H)QCZzO zHXq7XD}IB)%s^$^h1t-=5(1g86Pv%~^bo%r+wLg0%4_xUUdM1=xMFL{@zd;sFqcP9 z%2Na5@zht&HsPDK!mSpNV-;xRe!A810z>C+#Vcv3j1s;4{FXI{VxbK} zU0f2L{q3xz6pbf=kuX08rK?qMKG@F|8lGiB~_&XHg)Y!-Y72az=h%AogKoXxfGqE*@`ga6y z2%8K%eHF+3DX*-;)zg<%i{~VgnqOG708xu`VnzO@SZd?yq~;YLm<&EarjGg5SfLst zM0fR-H0e>$R1qbP!J{Yuue8EPOGjb_p#baG52tUHTa2vAzu7PQdYop4fs|*|)!YqbbJw}OM@4y|Yw^ptgowl1R+M29&;=Xa zMaGLC|28yEIp9I5glvY4=!9%N`iJPqEPtAbQ`>1cV_qF?Up)GD(0>(G3Avy%q6C-> z+=Wn$0GTymh})YMMH7EQBujfXHaiW}4<9PtJG;~s@CSoQ0r{g z(zOXpi6PHH^yfL;Bd5=}B;ke(R5Uw2?I_y-V1gHoB+>WUa`MB&Fjh>glB^B%{gC?W zi?Mq%Y4j-V!Ev|r)PztP9_hmH5Ig$ax5$#A(yBTQd9%G&#~S7+`fU*2Kvsot5`BVX zDfOq1iAm)2iW}Kkv9%)SBB=Cs1*0@|q&8&A<<%k7AsYCSJJQze%jY&p=GI#pfB*%7 z8V;<|_XnH^wurqh7o-3-##$_i6@sV>9)-obMZ+%=LLB{5)5P)>v~(wRILs9t4b-iX z`ycZN8+!ucIkKJO!02O5AWY^j1IFp&*JEX2%7XrV#1rOlzToi3k>7@6A}sjTEG9ej9x@KRV2$Ms8<=gaTpnSidOcnT?;%)e%61#UW>GmrU zN->oqi_F9adQj0TRumQblMwgxGoe=9I=rsQrG^TftV_*8b{*erlKeVosu6@?b@rQ>xVfkKU5D*$9+3AKZx4LBU6aBnKC*l}yKYP~stT;wT z&kvT3XfJLnHH62B^_>}Vo7v^NJm~ty8s1X`15KgI627%jy{75T6B^ROzN1)~-xR~? zi!8NF#)wmm9`C|lO}m<4z2$n(3<0A~FRhiSEL%A=dha;HfXCBt=lYC}8e8bs3e>(k z@wXdg*#0iaQZiB9)hLlP*n%aL$ws*Yui!xH?&;X{YSbn`oHhzG8RW?HBTh{g_=QAC zm!@dPgJ8)$E%l;o4%-NY5x1C8a2huCaGu610&d(EL&j%!c1UV-?EKgR!-gU%LV8^j z%^kL?`6xUN&+xd&4ng0HM-hhhdF3p&W(|2fpNZ??1f?tUUH=<)F&2&0)@9}s$4!F| zYY;0t+KY<|-O*UgxcaMN4p#|*Z!YG z1so%hcPQh`>7yxb(Ia<-{HPaSC5l_r^^gl~v@M7MvN8OKq;`+E6}qDP0SP>mE;tV&o%)ZaNW(#%M~(*f*;)RBc+5;{)FDN~%| zx7F2{N|B**zrKSxgo}SbF5V`=N2r4e zocFPAmvSX|^(c zPG2EQ-C5C7%|;wDn1G`sZG86k*5#BKi)*}sCS~}?-R+Ds1MCib4g==oA2n)-Nh64H z9tdZqw?B@K`!)eZfw2Wq;gSL%#9fiq!}8=_rgBr@7ilqKUY;5=z_J4(Op+=r)_rZ^ zfuE3Y%jB~xd~#DB%*%?;yD(||u|i)r zpYy1IyO-^ejjf8WER4Db!5hYz7Pf0}BswVC zKR`PB&DHXW`qG575=|Bo4Fg-xwwd0plC>_%XcLo?TD{kxY%fc>hme}XVQMNG?hW6p zKT<%uheScxNhF9f_>l3fZO2ZXG9Wn=cuKs3}y1;X~PYP6zUvrN36AYOX;uj@OU3(E-%|XdQ=LYK_ ziaoM^k_OMar)9H-hb+__TzQ`1@<)k6Z%3TO?|-TU!0uMm@}gx%T3%hP3UmITMXG!^lF3)8&8D8J&yFG{!V0s+(SR{x zV`7x2As)73@Cw^IJMt2}%qI?D#A)8_vEuz)#_yJn#_}+ElOG&DwzJb6NUa(lqRR94 zCTY6~!3s+8@cImVbazc-Ywc~;BEN8M;SnXJq_%g6j1u`O(QyV3mAUPRVIJJ-C;(m{*Y-Wi<0-53G2mQmnz7Pxs}*_wCN}&CM{ZIE z^F#WV@i zr4|&g!kd5|7(hokwH?Q8sRCO7}u9`SIc%KX?DA@JXSQ4lUrz2I46@Bi_ z0}NP3qQH9i_{`%#sS@%fl?Kq70PDz)*(|hZ_fRAH3@ztxTC_XyzRXNa zQqozpq$O8HPkF#amBdf0$!voF*uEx*g2T3_&9ie?hhp>4%?)4WIO@bnh5n;W>B6Nn zIN>8n_|xS0_g-DZ1XGi~Q6w;fmuDb#gn<}DU3Pt^R%^MjxmnT0<#m&XNW@~uI>y&U%X&7}V~57XAx?6lqQez5plyHO7*hFN zDpmMpz#&`1tzXIdRk6bxtz@^6KSm0++iUFd_#BJ^PvZ3Y2f+^6H|L%4f=x^< zlS?C)Aib)xV%VlBAN{lx=e1B6*o|e9DQweC8uF#B4H@%ZJn?gaH!KzTgAZ3`sG6Tw z2;TXII__3}rZ2tqoMDC=XTF`qkn1T4Yn21V?nYJ3kD5-VfBm4Q^7VXmIN|^MJlE%q z^O4)9sDF;}`7Q7q#t5mp_*+T%2l%Upf;tckCC={i5LcJh)W^mVPg0AHUq(d+&%g*~ zCMxC0f{tA1&(w|@2sjHkp;Is_Cww{9rV*QOzPfb-N~!Ieta--c{S*(A=_af(TD)Eq z(nSzTsZA#}rRTTcbWXY|8wq|ot>)?+7-%f-b-i3{f1Di=2hSgqYT_Qq% z+ssbb;#?a5gL;O%Iy!`1 zbUZv#YjC_W_96GY%-oVNgjjOCUD$#p^{l^1WQFx8PC5rb&2c)Y?Y*8J>NvFnSW!6z zF#Dm@iItz1pHIP9oO(#ib|^EI>VkQ+Zk`Z{z$CE9;zJq6$90z7&(cx{29}E45y}zB5E-&Ppc4 zAZ0P${E4x*5Cf}%p_0-{FoOe&NFd*^6p|DeB@iS;OOWot7}=jZXqDV>kTb0%;LdHg z3oO1C5w~2t2W1M<)VuxxI8rB(zNTH%YnCZW)oyC+$s;4cL%%c!D+nvi+EcVRic7g< zBV*i%i8`vKwDU@l$>jis^K(NeVuVM_;gvM61I_S{055KSA&HPFtSL3@{xXyiW)*4} zGTXHehmf)Yq@kvkkEiXO4+CgVd_>gE>+I+-pRY2gGu=@*2vePaNx&ZTg$Bm1e=O|V zb2|8D1#|TR)c8=6QU>2SW@HQd=^#*m0w)Sa>7FJGx((TAZJZYh7^dGWK)97Jw-OVb znZn0-G2pQI?R6_dp?uqJch0zxrT&-Q0l%dCCV6(o?$33o5CTeC z0Wgfe9IoIf9NKlAFpkp-f_C8YY4YB#NPngE&|UqX1z2Yy3Mc=iZEIK+ZItT%kfN_} zcbYEBjqBU~*lQS#N7Zb6_j{eq+?X|dq>a|SZ3kc;W@@3WKz!Y&Jqe?XUI`5AfDHQ2 zpVRf?EYm{n1VPC>{?3bVadakw)IfV(*PPCPo3jP4spd6V;_uB2raS-0E{qA`v#+p& zdT0t}(4EWuaBxW^&^U!bIUg$5XgbpOaRP)lScYx2XrQyB3;k&%;9~A{GtM=;-wA3Y zG4gT?k(sSf=49xEh6K*r1e_94h(_>ZG19>FW{vTeGb$Xh%r7(!Y8adlsX+L6T{}ii zvRFtcwt!+c8N9#RpEn8Jk~+KF3THp431kh=kHW3Y&j-2R0llQ?pk01cqcDlqVuZuO z*<=E*>!r11L?yxsTN}5&iE;}q+QFfrNHL|+!jFX@f;$amUSYhV$-n~^PR4WzY^yQ+ z!mjwu&5vOwV}Al3A>^XI1T^1y%wWXK8T^peF|#F%pogGWZOrq5O9vws2BDckSgV$q zC0uoD(2v8eKe}LWrzaoK^1z}IG0yI=K>%V;c@a)dWyO(jz`P%JeTGnW ze@ID5ahgyjg@y{Ua^Ln_+F=K?xB|ss=nTLQxOcRy*bIx0D%z|R(=LhrB9hkkg*SsZ z=|Qg`FADKlmQx1F4*pv*vxA~^A_uGVm|bMp6q3o`Jyvn=onY>IEUNbM0!sJ z(tM)T+R;oHw!`4Zr=*PC>S&;lmTs9<)k4zPAtEIeHmJILG(T0}pV!~anBeXXc=s!3#Kke3AqsQ%wnITx7w5+)Aah6T+ zj1St8Z|Bpito2WD3+)}^3OeqJqM+zVT8cEcK8sGxnDFPk@qCNIW8XgWuv?o7gAE%$ z!_1Y%0CnZq2~ZtbL% zDo?KJo8x}m**H+L7!Iwl=sU&vpI!P7_&_>jQAjyCnpD?;V<1H!5rr~z(!+HexGh!4 zNVc>fRZ&AU4+%cB^6^bhrZ!yy3-r0 z6k-=~D3F_-t#)d{T;9thXni+s1>nc1Im-KfR(~k+if2U&v|fy*SQ>~Jzo>mR0C zdl#L(i)q9T{Uyu8TN)M_o0@TO!AFdt@tGc#-1xWtvpceikrw-sC16<*v4L%Z7<(mA zU%;P&PPi4`ktK>&0mEQ;0ht2?Hu{*p+D)1FU@9~n6 z-%b{_>ku@cT?+RY2)4HG_ZtO6oNtc3T0g%+x>DT(-JDH{UKS&BmPY{HFt$*cH4!)^ zx||SfOygxFIG0Ap#s)Tn<7SO(3mU%}1WO>Mn5?E`C9#dF={rszf$$XN;&R0i`%UMU zQ5AFuQ2f<9OFHV_8{Tyir6j+N7=0`m2bdxbetJc}2BUn(U+!^KjKO*aWM;EW3vK53 zvEQ3Kq7bV5R&n9`)s|xl*%{~<@}DD6Q+}l7r?bec$Ieyij6`u9L!0pM(d!i$H*yAU zW}r}1AR{@Pl<5^Qo&YA`D`$|qrj|bAJGJU3Ka*)}jmtrz+!-#sH7SstSSVEo?XZfx ziViYCWsa2`Mg?EcZ}pn52JOhhvSVZpr%1oIOU(}9qrarG8iIyBu?~fXHKU!gQp2r| zWr>C2c5d=OJR_z_G$5Amk%UjWofe3Eq6BsP(O5&;TJAQki(n=$lFoRXwCb>o)};J` zlMQMm`VpOozCHN*jT`ow^$=Y+?14k(Cqb)c9@Qa_#fuwYA~K1CLyf=6CbPCtfY_r5 zA`{vEr#%J~TB&`t(fs<$T`uzM`b}5k#KAYMpU)z&1VM;*!G75pp5&K%hv`(4A1RY- zxC-UOgg?4h(db_9^bA9;dgpw{mOMFvNa=qLKKy?FmXiy$^b4SBm`IX?c^l_^y%-4a zm;ID4hVS=a4|szJ$bUJP?G~4tXR_))cA0E+Q=Hmw2@Ux=8fsMV$<=k0SjijO%6HR_ zSI891>&ZonRr>LCGej&x9*8OtAhi~{WwW~lx%B)bh#bPy5=$jtCXPcSQM-{Cx^~>( z2bD`Ae@{h3!?LcFg^TY+mng4VHZ->YwFcg7kA4oj6%eUi z%Tw`;KveCVZ$aZ1`Au;Q%A`JzgPdWg@WXOnY&5vUyssf2i)e*YGb+i+e{sBzN6@%* zk^7mwY`@T{Hj#Hwi z=irc6;SE!Jxbkz_8Pn!dYgeOi>xug&>vafpmk<#lhOW5AE7`Kdw6@U7jYi8^O#1l=~kAr37 zjsgI+C#kh4Eu2{)Bi^_?Hk!G76?JAQQ-=sPVG(U*P`5B`Xsmr$= z9+8#Q>}OW#vg>t-L&$~oSU9RRBrSr5pQqs6!zXmLEPuWVfq>PP2pJ(<()2-UM+wUo0 zDr8ja>v^sRCKAvFmAI$wTUFdOV+McmIiGCn8qCg*xm1*9xQvWn~iz9tGS4iqh8P@?ZsiSHkD~ zI3GEyNwy$bSO`2PDmjVDVyS*70ZuL+L&?l?Yw%EDeB6MRLBpcb9CK3YSOX4Rn>q|X zePY$ZZ`IwW4E&;(7EgU~2FfF#f!}q#Eo7&?IPJTc3<+GDi4vl0SvxzLe7Wu!pLutu zXhvK`An!|0zuqB^2!Nv@h~t-ji6Mw{G$K;^G4jDt^t&&Z()_MOQCLa5RW~g=yHJ`1 zCWNx{8YkLSUQsbBRPr|g02c-I!v!{K3$hTFL-Zb#O~LJs2^c$Ch#CglT);frVVj;` z;>aNR;<*uVSYbf`GW{4I)u`hxzA(c8G94*ymJ&@(CaA{F8$g{CXx&dwx6<^az*A^D zH%9pd=cAXXzOf%_#d3tSD~y3%2FD75q-}3Yn-h4kv&_7jmAj7l?o6_Gyx5hHrClgX zSOd3&UY$G=Ye(kVeu)jP*xe=k0tZfs-RHt*bfLZ2`~5ZAY^I)DlMjeOJEx|u{bByq zMFm2RIhwGyw6OTE&9-}bhBzOD@j_hQ8+4xuS#9fteH&8(B-e?JE0O6RKyzc&FF!YX#{L!nCO8lUJ-6}| zWRcZ5F|sYNZ!8D|u=tIB!)ZdR!coH5>2r8}Ms^|{EgkZ_VqH#ie7UJEM0qYEUt>*0a`btasr|~&zbhA7lkZ(9E2Eqnu69kMqoc{HlJ%5{ z0I1t`tZZx&ZOY?1Y8Yi?G=IfVRIk{-v&nBT%qpq;@cbd^XrTxPG{We z{UqpEqDtcok6&Kh&{u%!f&+YUVo<(FO2jK6{9HIzab%_1 zfOgS$=AC|OS-BW#PCL~TrXCRujOgKCzt2_+LVm4ULLFO2^QoW_mo4%h+C^$|ks5gc z#Yjdcek_taG?B-S<^-}(z-^jBgFgud9sX2_+tt-NKd&Ym%Q@n6t9$iupcsUx(OY3& z)2*zPqRb^vkZC0Zxf_&votzvW__`QJ$nORiTd8guR>y@W$om8X2P+ejPk9R~_x0Nf zlGi3Ie+gV+yPOV{kSG2GtQWV?rsha>urRe885`qF;w94ri&2V7>8!SJeXZkPyr{dp zmXRqY5vNi*wGsd$;j=K2DDNt!Ccmyi86eh{*K65JVM$d`cFQ5ZJuV0F(=PK_m}<$? z?o$GSCSG%Awm?IxOG_zJ-1Jk~gAdW>3okVTZfQ5(noGsJ#*2=xBdTVsH4lYOlv%+L zMqa_<^5rch=40CffJMRgcdUI@7EB8$f(GfA2gi9&593WD4`)|1qic8BeyeOtt#BM# zf2_)RYQ00S9B!Cymj0KPc!~%&fkfP!hzL}I$ZLh7plH|Z zhr3{&Jq1@&Wg=?*f!$zNf=Io|=9c_3xIvsfzU-MF%E$&GAo`)rb^%r;QqJb_(7euT z=lcmEHvvfvkDE6~D(f{LDUA?yUr=Zo%D=Y63h^K6679~{bd83L(&8U6LewW`^qS?_ z6EI48LarMrPr|QLE?u!(?BrEc5+xX~ZNy2nX}PIUwb~$HW#t@t-qt|e&^rMLqXXk3 ziBhOt55-=RnJHO5JQM2WgLnf%MU?#Z#o~z?<=fu_{Mwu9Cvr%6xUxnX0i#WW!!jWd zGM(!mO0C3H@N+^Z#wGQ=cy%8^Swu)vn;^;0CJc%U>R`@cXS~tO9pmy*`cx@lF!ruB z=i85EGA^9qq@rH;*%dyp4`{9hnwKb;c&yLV_-JHoLursv<}#ca!XN)tiD!J|QvTWfr_$^_6LvuvXo&|Mo{VJrK&WUR0kY^s@WA2Nte7A)UN&IA887# z_n)qO{+=oShsnC`A!Yp32G7T_1xioI?s_^|OR^~k3bvLg1ebDT=UZ5s_Z3gP4ujyo zt01$Il)B_pY0C5S79cmAmn@jAvapV>1J_eB-wQ%5tenD`sALVb5TN?s!Msy?9iFw5 zVelJQY4mUO5iM66HrMrID`+b6V8+GyTA#xK)I{hnBlve*=kTLncy+DRMkNM^m5jV6 z-HvB)S}5SZ_Un~ztv#JKb6Qrto97rUH@f;gC>`udv51CB`I8InEqS92NDwLD_NDOB zcTG=0Owj;DI2XP3RSfhwnJbaxq#Ufc zm)~tkNk9d9j(#T^Z~=y(UKFC<7D$KmdH&Vzxs6i>v%3!KN4ed@&=C;(*my#vy?MMm zKNGF$kdMW*6>l?ZoJ#@KyF4avrZ5DA^}QVEUS$GrmP4^ zZ;6RIx$+t~Q|hgWT@TIL%?2gk4oj~YDP@CPPUF+kDlcEN*N8yIFe+FC<2Iad4L5Z2 z<-{@cry!5Tdqw1LCSPaFn5*}WHn~uaveB0*sXW7odCREq+2fid(!fZ!M7LiVA6UR> z}f|yQ1U(~X>}!tmoSE2Cl}-5D{~gn)6NaVd~~wU(-Q#OOrH_`;o>A(icJzz z7Sn6K6T#kQ+&h|BvVNy^?L;{VL+~1M+~Yi6dW{FDh2`*Z6k<}-eYmn~pmj*PzcGO( zO9$_{Fh``aBR`;&P5J`NW~@ICDon4g(v_(gh$mw>c-|USCD!<-e|t?xSfnvf&_ABY zp6+14&ipgp-SFIbGV&G3KvcCJZGhsJwB!)DgPw}tj^=<>1j&4Ka!d`cg4p~klEgr4 zmQ&eBYekGO0*YQPQ$40f03Tlyb;l|^=kF@4g&o76Znz3Zp0ya9r&@2JzA=-%P7>w^ zU>myiHt}EtJ5PbF$1Y!p+nC+reU!t3J+!zU58qWlrlOy3@mi zvtwfP3*Yx_W1i}ayVls-$F&SE->$hX5_pf;S4TheuOr=D-B+@_mSN=V2g|&@WZ9!m zO=zvtt`pDETL^tbsPkmb!Y9kzz2m&8Jb^!gMn2$!z?ezsdc4gTVi8iQeu;SswTvlE zJ%(nMIJavWTJ`9WLpMW$+BybyugT)Iw=|*RJfrCqM}zl{#+~B}jkIt(h7Ko|%KFf( z-1MeQt4*pl;vk-gwD-Q{K%91v&U-koZxan5X;sBU)N%;1 zP;9XpL$)774~iD!m<)NPE$P+!0U;w==nAR#oo&FeyTm`&*1ro0{N0Sx=K*ij`XZIc zDU2-5I9YSX6$P82X==W{(Tn85`_Kn5JEyI}{sELvjV!JeiZW6tHjfnHR>mx;96^}C zoNp#n7llIa_{rrp3#7s@{gBn&q}F7UYq`8hSr>S@6qZUckrd#C=64uq(+}K#fw;Mh z@I->B{WjMlz7$o;byhtD-WJq<(-+Lh4P4NF14_?1A3EJ2Vf^xC^w0$|VGdthteKYl zYGkV%MzWwVx7VkMl*wH=7Z||tH#xVK_5~Wpjh0)lth_yBfzU8|Q7y}A@|W8G!k8)3 zK=Ty|i-;(@{YTOea5Ccr^}%9$SlNl?)3-@v_U-??k)9E?&7wRM=c@MdB?x%lO@eJo|!;_o#N*d6a+x!fJ#fH$IRWw1H+$Q5VVO` zu#Q?I;}-@dCtPy2a;7pKvd>&j+Gp%0wo*TqjQ}mzl-dU~<~w%YSnj3y3g^5W_owF# zN83)Viaq=}xybO#e&YX6{fD5ts8=hl*>64I>=~HN4idv)lxc-VHDk#57|S;K4HwMT z(~7q)&1f;i$|7nO?yS+)90tgW!)>*$WPP8`kj73l3KNt9z2#GGvRf)vudF6a>(O(+ zR}O_@>Pk3rPmVTDN*P=Co`KS>ge2<9i(#6X>(*S7MAWhUMw4;=^R4l#k+61`FC2VB zhmhArLvnIzU*|ZcUZ;1-*Y}Oii`VE!<&~#xp~REEIoC;UY4%RP>|xcJZN2y$O3LT= z9$sKd+e<5=+si~w=hxq#`Tq0y{;st3?Pf}o9@QLSmbtk`QrCzCXtp#SBNA@WesyC* zgHn|~TQ0qAW>(hD2y_b&??Q4ak}9Fj1uBZXImVnPckS_^=+fjMA_SUw#xk>IznSZ{ z4G@zI?T6LWJ8_^XW2G=7x$8XAIL^(-97GS|qK`!tH|y7YKd^w3GP1ILbHjV;-*S9U zW^isR0Pzi9zkEq?+2a^JHCRdkeXFc|2eevg<5Rfd+y|r3F@Wi6Zzq zmL`5HcYSd&aKptXaTz!rjHsq7pI%&2Ebpk6pF}rH_)$Yon+XNWm%oHO^G8QL4-fAT zmFK#W^MuT=7H>OB$&%&6!rtMwFlvD5?;ZV2rd+&FT}xpt9T@-r>iSwy)gcZv0Apx* zXWqlHGqK6Vmz(OfH;IF(?(v=<0v^K>rGNj1YG6x3x)M9{gNtq>hhrpT-f6iau^UPI z-^X<)c4TY)cFs$VU&ryf&sYJZzP|j$5~DvEb=oUc&-%Yf?!Rrer)==NTrBKerJ_n{ zyBrCuh`$P2qu(zp8GJ4^;%&4J$}4PYa?g=Y5*H5GNaW?^AB8bG6VtLFkVfo6DWB2l zk|O7!yGk@Qy|30C)377v)5R@ zzJIvi*BV0oO|n31EI6-NoX>@fn0R*d;h*oKMmaj@Dmn};lIA!hIM~>fKfGJWmNa}=zR+{wq2pRjqTBFfI3-WLtJe1=k97EU_3+7NpZ-1cCsuv z4_5bNoDX*xbjuLo`1$|RUNBw-{(vsfQFU}v?HY-?eq~nXtly}38GFrQ|2a?}#fa5> zXD2Z=l|BI%*M`*n_!pD44bY?kxzuK7dU`S3??ue#jDlj`%lwXVTXIs!G7$7C(U_jj zA|a7Z507psk!^{seI@rGWB%y-l~T9Y7SYeIH&hO#^M_4KmF;%TOX|H6Lh8i>)LeUr zc+`+=7p$<`8__|a1Rzl!0s?IMYSf}N+ds~EILtMl2|Y-gsAZQX5Pjop!wSNgMaDng z{i&0Ymd5~NT9LjUkl?A5vNX3e_U=kfL+NpBS4COQ!HH5(ROGUv8hW#u*@mA#mxsTe z1rsz)BHrM_!2KNJamn3g+dltwnadl;%i9|ab7>^>A`Q}2DDprn6qISGmDfTpT)t4# zdqbEYiBO(ySYsRnqKD!2-%?rMTL@yTwpR7LiukIlL9IymdVfvnV7rZ>%x_Xbt=YIt znX?TE$L_Uk4}chs)))rr!R3Vi`$y1{M4+MM$B_&YN|Gd5t76iRHK##X}EzK}^H#<|%#-$-fR z8GD;g(^kOG;OHUak2@CkgXbB@zluD+cduZplx^|N%nuD2z%VUw*l02h6ipV0_Iz-q zI(2b*f?f*j2F&wadpkQ!3-W1NDDIErW1GG;RCNxqu`xDc?lM#{h9~`3Yn#06sOSXMKd#<~^ zDg@pfKgp-E>S1&jB3`q6mb}N*bR_1(4dSi;D~yb=rEYEOkTwztfW*Z9ydozx5W%Hr zFx}xsMFS+G2f@8J_)PzEm9yXCqgH%gb)Mk4ad85NMu4DN8Ey^s&$GBlU@1Z^Ol=~v zf2}|gA7#}aODx9!LXseokJhmgwPtN_P}Wu&3XYWhX7?>IXryg(Qzo-YNR+G8j~~Y` z>$0x9F3$U*#yKya3I)=?aoF7}(fbZ#1tB!oQ0dQA#K@sI)ozDNrx%8>96gLQt|Lns z|6|DMxAmu!1l;W-^Ac%(#S1ZfQZs`y)GN+gts9?KHL%7i<~ zSra}UtQAvJ7z^8U8*vHejgfG?`%sW0Ak|jt3JL(Sm>R=RSbbj1B)w+%92YllO%O#a zGhhcrrw34S!93*-4^D#C397$XU5S{c@X5Mj6bh4~?0hXI#KVjHY^`sv1qAkKOV=gy zJ`o@1eUJ}Kkhr2Mj3eZWZfVh#UTVD;eR%5^`#wGx>=c>uqwNR7LH|yVkear^H+Apm z;-lk3$xMsTdym%2doJg=FR91f1o6AhJiS)z0r&35|2e5ANa1G#^nvl?M3J)dr_*cM zlf5Udn;2_b`HT2L@Vm2JSqYyhCc>fyN{nZsEvB3U!wHdSH^|aiKiO;7XZGJw#`-Df1!16^*d4p(`fXKQAC#eCblk6xm45-?YXX0q6iu92Wu2EdE64C>ezdym!%h8a zo_&Uo+v0L;b=x~JZ4vf=U)TTpvps(k7J6boIM1f?|5^0^{?C7G2d6Tyh?S_k3W}uv z7SiRjyTe+w}R3`CVRdX>v&^B*hqU)zySLQkXj z=jM%l+2NrbOCol}T0TPrLtiTOZ`to6uzc>WH1~(c*VCJI2{* z|DTuq_l>nVrN{1d^laluztnj*-+vnx;vhZAo{Hk{iP&TAGym<;JU+wTn8)V^yW#&9 zQ6CD6sNW8$Tj7QOf8SD14$wFlngg_3;`(n9tTeC)*1P;q0x|y_ivM_Zj%9#!W7jhI zCHH@QJN_er6Vfv<5PI$;z<<{6RQ4(F{}E^Gj=z6&mUen-4}ruIQc>kC_;EJ^MBg8te!?JnwpwS{lA}WnG62pggl1Km9 zZh2*rTCX%RpcG$j-0SKU@BD;pkB+i`?=-UC_RIG}-heojnJ zXMFbDZSA=%ZK_fk8Xf}i@?xCP?fWdB-`)z|do<5(JoOexprWEeT|lh7SNMNy%{-+^ zGfCY#R}EM3#xLoG6{ZS$duhH@R}XuUL>_Q$o;)2Sj&t6;#0aeZ@PjeZJz!!i z+!_-b3o}(h*`EC}lm3RL3&-oPcHi<&SLqXLe&QlUpIKs`%P4D;QhvV0` zy|m^{=*O=few3K0b* zV7I`TY?;Hsp?WI&kIIze6Ljt1+tSVdV@9uQqH<<##sxeUJs!U6PQJKsmR63IdUG%S zJiPY&?Rc$O6{RZaUC&5?-vjoDXrwH;u5Aze07bJZ8p=FDi2qG}-e@K9vWD>{H%I4f z;^UR2m|UoIh%7_r@7)g?Awf-f{RK-aqj27;acIibUH26Y)SsDznQbmgX%u3{4|ptL z&KhfdzI5r`?_hdFYzv(}aScsP1_ISjCWxXOa5p=@Yn@IUe3hXkU0ph>-j@_!4tw?o zlFVj4J`s;Fg|*7ZTRAb=HQPD==Vz3&@woFpu#vxB_H=mgx!`!Ym?C{mKtN1QG?_NS z@qA5mL4VIW)jk>nJQTV*pnBO78_RO&2-`2kH7Q;}=jaS|xfGa=b%}v`ig=vH!<@17 z-*S))4$Sh%;{U$BIyr?fXLbY-n($_XcmC(Mu?Mg$gD5z{D)WBcP?~qbs7Ac&Vc7*Q z_KH&$?x|nw5g<8ft{h|Ho!M?(K{AlNT@1P#d)Ecj)62+g*a~ArE?pM<|Hyg^wm9Nv zO&iw$g9Ue&;O;WG4o+}QaM$2ExJz*N1PBCo3GVLh?hfz#_w4Sq=e%EFuAc7du3uF> zbw9*@favj&VuiH56C;0VQlCqTqRB_IfK^tSbieyk-J!9OIj-#0EL#R<#zeD$SUEE@ zY)TI6Jt-uG8$6uBk})FD&*JPH9Fg_h;k$biNeH9|pU%pvoH6Wuh1H*-S{%^sFh;1<>?%WW_1Xk}UtLLow7$z6=)T)Ygg?e=JpH`2K(9k3fDI zW278)0LYc1x!(1zk-ufEpW4q zh?p4XndIu{yOfAX2O|!os@l?pKm~WMJ^UX$4qw;-#T~2=a`(AG4(xY8iL$60URTS*)(fbOShXw~Vf^ABMvIISpA&amf&>r}0I)A9K{w-pd<+YQQ z+i^|A4v_!co`Xmcxhbu#w)ptwm zOXr7@O3lxf-IhC#*5;z=Tb1#@UO?nDKQ7u4r{+}PXVHjwW!>FlQIt*cDZtZ}@t=#T zLVIL8P-ri3bixzt_c>z7+P$G5mUD?QH?-K>i5Sn^D^rC7yD;N*$;ldWV3m02gS?Vx zj*Rok{N8KYX@S;+)TcqJxC)F#jljF(;frZJ$icCgEcz_<|95ZbLLRo3tdN&_IY zS%FoJ&EZ1}@pAmd3yB)+eweByCxn+w+4^3JBZ=WA2Fzwd`HL1M-wlpbw^jA1C@OM= zL$ zH@@d{WKYz$t2qB2eoS(ORA%wpmAC8j){9}$w;55ZB8UZFob=ojU35Xx$=0%sw?F%@ zF*_xtna4E4=k{kR;o#Zv#}GaZ+^R&U+o!^TSSsIN`paMSb_F+{VukKzd6W>_Ne27{ z7x*jTsr-C;d(Ak4qEw(}MZilBK%%hL7o<;ZK3j?BJHBUmlNTWuF)wmYl6o?R}zR1Hx}Plxh20C_9510#ih|T?4e}3R41(vl9J$w z=AJwRUkF~U)34uTp9@#Ty&Q%+YOq$@tZcu#@Mk3P*L=9vdGMZpOkS3Gnr?X7&i~K6 z=7_oJa34Fa{7E1;@#A{oLw9EQkl}X0|ILVt13WjfYGoB|oR`-p&glQZ2_G{POD4+l zAKGV3RyIQ*fy9~0s9E*sSS3Xz~xKZ=5VKGOTH zbXP@n2HmSu(f5H)jjL<&=W`6dOW3>JubqDFLLsxmsq>cnF^5Gnr7HOn%R;~fDe_-+ z+HcK^1EoAUaS;2v>ywSw&j%a2TizYFlflPIz!?uMDj_{*t${u-{-2Ab5?SHm>e_|= ztpoeS1v58;Zx8jH6J33}!W?8ol7_ZFa=F|;4Hi@#PS9|<-eDACi-&sTsgF6DF^oLN zibE>!l=pm0WOP?qWm7QR(@S2RlB|V7=j@KK16V>lA3BkQj9DC@9Y#Jm`}bbXP9gVE zEF>ZdC9&vG%t?&+n1DEeQ1RmM6c1w;WNG{}{SpcnEP$BT#B)Dryb-Us*G=Gn0r6s(mqFmsP;Ew$x;46OO}i6F0RW` zEg~Q>A5^wbv+{3SbD_JU!k?o_t)9r^pcdNx11$ACv|XC0QxoD7rYxY(%R*Spwz?t8 zA>Rr7x(d_dZa9`hPc}p2g3v^P2E6ZETn@mGCNuL#ku;M+tc!J)&r^4xPumPJJ*xjaJqT`)-MLZ*VR85i<=9L5+!~2Bo1m`?!bt8?%Zt>&e?%C_=U&Jn7z4^o_EoJ?;EGli- zoSRWFG&Hs+1JSQN+ z)O5#usz(Ztb!;5J=2Gm#C&P6phRQekC*$111h zT!A8llgeV)21e>Y!c`|CJl^YvxTK1{zCT<(dh3vSZbHw&(~E$rEJ83f^C8FIVaYO) zrnmMpK>d2qf==W(5kf9CkCuvAvYMM)u{6ds*(sz#^L`)C6(u_=?GV^d{BY4mlGfN> z_xcu|>Q;2}SQ2xh(fz{AcZ!+-keJ5g-q~WOu$arK#RI@__+V&!pbhpDX z8j2beS}^-(p>uZAqRyBn;!=(q{GP%+hKuTJRsLW}a?2mrJqNZs{P%v;xh4!TA0!lH z5&K%*FB1P#Gz)Y<)>r4D&sy$Ij0Lyo{JozniXusXG$ozMZEgB;Dk|aPcgjG-Gi({L z_)oWPU1{_>kgXS1NPFX&ry%nEip;-CLLILnX9{}=F%=7wt#!TLt4=5?aW6XHvDE+l zo6?!r>D55J!0g@#9_Xz~xv`(VL>3G}NA%yy)N!r8?{2+oBHT2%tu%U5gP(cKh5@~7O^%3ySKbf_PCi3O>sB&mY^-cF3R-qZ=RXQ!tb z82}y~4+s9}tTkf%PS-`Rr=_BEvm*m!{`xcQMxI+a2yqm@$vyuf0zWH zTEd9ki%V?`Hqk61T-+3hq30_crXmHvlK05#pKG2_!zoFDTZt|kY962x2BNNhI= zy8sl1EDhJ^$Wq~RN8i}=wr1eGxoJ}71DhC!s_)7bf~#MH|9mI6rL%)gIvsLbhI-eY z2%WHx0icnlXxr^ako7&tYxAnmeK)mf2tjxpVtvpWrr#_Ld#0GH(AN3_4)x>;nq_@_ z5Q8Qr$qpdrqNHPKkY@;qyM%J!2dz;JoV@H_70Wr-cIX)j>a+fw0tZ}Y#ABx|11vb{ zZKAM>ppT4OF=?oF3c>N1ULQWKJ{C%mz;M3ZF)Fv|4N>Z;z;(5V+iJohi?uk59&%SD zd*y@lWJ%yqBx+*HjVXkREEbL9ePIqeJ@%|A#xNco?}oaaLNGJEE~N9t!cBOX9d-ow zn@qVj$VD&L^$vZgTuq=p3Pn{)7t_&}Oa|pAt6G;d`QmNBT8&Q~pYAm|09OoY&F!~b ztfreh7hDM&lH&-#DH(n$W(pL3xn4eECyR@k>{`_NWjH#KxF{JUTX^Y$>=SEfn}+Mf z{>R%dD`e+U;71q*54QquNCP%EUxTdw(ZK5*AXkl&m@y<2ZX1sSyk(%9<-k>V-*bOY#TK*CaZN}7m+}?8iiv5g> zTkI!o1ZfShl|&}geVZ_g-V9+K5%R?Qm5R%x^Zqiv9R8b?9=4UhtHD6XMi8^f}Z zSjx+~n%a$|NWFu8Ndd76j}O0T=%|ug0gOq|!~3?{ew@}0a8-=|vT`&k$TI?xJI5WM zxBvT&FoDw;DkXJo@EAeD?+kb3Ad-P{u!CK6GCVk#ELFzid8F1{?@_Nn3s+?^k`~EI z`FftpV}>a`%3XA|{FC!rzI7udR}~z82qecagkE=kzrYP*lr&=p zf$SPrjR17tPJU3M!vIkVBL6v>d?|NGbyidW)=waU-Q^@07p%dI?cjQ+M{fnw`szMO z;s{i?G7Jp$QJ;8uT(r2{5XbN=JL}|%k+VO{Up{RQ01Cj*7Eaz}<^u@BnRJAEV>3z| ztio#dS$2uaMRs4tVv|iywFwH$(p%hWTd_eZB#Bsiar9*Xe!p@9!`GUxiP)QK!M9&Z z(qhEQ3ch1SB1+{Xr;CB*eqYv!iK+}CJ@n!QsRNoqPz7BG3>X}u{f+~nX5j*92(8R; zzT=noYBXt76}DCy9g~0W@0p-S_Y=d36}nXMb`9X$#MX!dSK1?~1zwVF_pf1WkMhB_ zG_0Etgz|z!LW%>J!dAAr(OthgG=CD0%8?|{@hA6*SnR3UU~o0)f^js*elMt(&BcaZzzFZ!%-ZaGLD6X#jO-0!l1|-6;((VW%Ew? z$=vGunA=VFKWMfAg!eM?z3_`urw=DD=M^53M}#iyurJ6tY#XopyxbfN_?QaB_%7ta zf1M2KpH+?U+Wu=e`)tX+9h)F1e#w%tOy98H=pBlKJDyfjVu>^AY>k7JR;U8d)6z=y zx%lCqZB&E<{$zWoE|$9Lij)C(&6 z;F2oN#_wx?+CenMDBs0nIMo!|q?+@5hQB-J+bd`0U>rUU@ARaMELmA$@3J zM#g>&MhPF4{y$Z%YJX2+lhi;gcn~-Uh*S_q4*<0pTU2`jC(FnZq7{((3Ly?WNc_rR z=A1u_O!}$&Ksi78CSnKDhAWyzGexbcPX?ZFVn3f&j zg8xPG<~xeKFPPR^5=Bo}iHYk%@c zNC5t#X?>^VUwmT8iEC#ld^4${JDTj(^RP!S%YeWBh>5Q4*0HHJPua+^koLC)Je-2t zPNs=-H`B8gQY}5A3!)Tbe79<`mTYXwrPxC5KV;?hTY!_qf?&Y8086_pRS^&;oW6#_ z(PEBQ%dHL)dT@dFS_y?O=543ZWfG?%36^i&JI4Vw;BTgpgZl$plLS#w_^gco)fLE9 z4(PyC8Ut&bAJ2Ew7czJ@&cDIF&7?JW#B{aG1;A>Fl-S_JKc=sGjyJ{l(5W1psOY8r zSU*ZV=t>9SoYPZ3w5jI?t7d-@WmUK)SONCs5JuY-4EAMo8b2}i5(?@aPFxO&?L(GW}wlyWyV9p{9fu0*oPmE{HMG zR~f-Qn_%qE>V?i=dce4BK?aO$=w|nFx62rnah*hJKo*uvxedFA_S$+=`1+iU+eV-B z*yBT(vnSAjEVhffa00Cfo&Z09+@u$vx58EiD8EML;P!qGT8rUo^sY)9@iY}SGK_ZR z1hRTj3Nw+4h!z6Mb>L$(mnlJ-Rk&8BXW;AnrrBWGvVZHKD;XRN?e!?xY)mky>igsr zCw)GkaGTscyDWqZ&~w;y1`46nD(g#j#(7>L#0>Yq0fibFwyoD(J@HKX^T3d8spGx|{ zfa$Z*W7Yi3Or>Q+Z*SRe0%H29CZ_$46(KiWzu&&TzR$u#nbgGb;af6sFDxswPiGEP zZ0d0MXioR~5k56GarM1zX?x%(6jbByEpStx7W|qfX5W|GAqC^3EljlE^FQ941cYyY29L78M}%6y6|_p+q^r8U>Qu1M`fOyFHgN5>&$DO=WTm+h*DLeVWx7DX=uT z?#dVcRu*Y$9Z1Phs2xFabLzuYo|gw|NOlH`hLFNTYEUvDWbJMk1Ys2#_qw(k--cz? zI~EO4prM1rEZD|N(k8d2KU+z{Hz20bjvy&kKltj6;OLJayQ-%!xU9ZZF@ot9$YsL;rD>M+M2#;)H08~)IR#}HI4d0>;XPlDf9Tg zQu)j*iMV^GEFtb9FW>9|lar$0di%hxH=(^luQB{Ea^c96IK2Hpdmp=>3^&&k;$WC) zpCau{L!8o|1Hwap&zW#3MNMALz342Irap1xgDc@gm%e*L;^Zsimx^u9>N=Am8z5bMo3tStxGwSB0QWAe-x4&rcKn5jg4IPwx+%E(>dc?MK1&@X=kwS+p?dIPI>E|Z)h3v{=AB6!+UK5xpOnJ< zGe#B-2qy0mlT46(JbjexGTD(D8bG|*aX_TBR?e|XU1PH#?T*`LE)x3n6_0i65_&lc zo2B}^G9|Z7i_yp+lky~Tdv`CG`+B)n;HnGbEc$qgI%=iTQtj+DXS^pIyetG^)QH`Q| zBD}0ZVP4PK$H+K}oD|M9=gBk;qNxHkT$%QR=J1E-(I+4~218H)r2B$C(@d(HL(O_t zoqF(oR0BteV(sJ%#<2i?PpKX6z`XN(CSAuqy?K6OzlMrshaZq~$j5s~9vK-R>c@kb z>s7$AxJjfQ-Dl8?H+*=BtJo!5Z=;Ve;gfDli{p5R7Fcc~m(JNxXAt#kRa7f@+e?tT zN`#K1)vBtrKTpbS^95yXs>TyDt5nGi2nAld5f7XoR_uy?Y^TSDZmo#4|EccMO6a@(*K|QvJi@ zlv(3l;DF3_%Rw>h^U1+OygM-Kw8|zSncQC&3m2i9qmSQ|oTs_jziVrnHW=_*)Hdj< zy;plb6!GMB)_d`{UM#1Pl`;;?_i&05*5BViI_E7c!s*0%fxU5&lyCl!6V$q?x zjmM1r4Rst-9Lxg?dM;mvjLZzSFB&6kh*TT7`z2>*B-^1EGk(%!TXl+J$8maMrdIno z>mqj@VDWK?*u}9Gd9uM6LIP6L)@Jg*)BYgx(Q___kdZ1XtQ|QkbSuYp4-VGO*J|z{ zO=U+^q$dAwt3jGejF1^bIy4L?BmPw^-3@xK=Qbz=Px4h(Ibk>w<@NE`43;}ivdAwl zNqzbdHmo>V+!7DrIvx_sA?QbOX7Hxd;Iw{f{Y^3w5=P~g4Gv6hfeEnN-1z-TCl+Bm zQ}xRiIQzYh$NVfL%)Rm#bsAEb0jRdn9#|i0f&wKJwN^HiAbuCH7GOu!issYrnRpId zXbL(M2JK9Wvc4YMOegf%=)LkhB@{nKUF_=)8Iuj+^ zzz|ymS+g|t=^C;J@l9m$5M`u$NCcYmRrlH;@3g}M68>CX1|n&IHL8(`T`2cU7pDJ= zI^sIwM`#4>?9!j%PzL&#Xta}(O6Y>Cw)0F#;qq8}1rIqG8{v)DQ^4}3kwkGOJ3Vkk z^qvLQKh-&mlgCi(0>Mx>;j;IOf2eW82?4dqs9V-F73J`o>G=GA2`II2q8kta49VdS zC>-qR{kN31Q4HRS?1hIstPDU7EJ?SYDK}>Q7`ajm6>CnLt@r~;5fA@05OT!K8=r}k zkE6+MpBCj{JOV^z0bt#E|Bk3Vc1nrkd+?%gYL@Xm?IbcTEle^_?3E1m466RrcL)^S z#4n%407V@5q~~J1lcpv8D*KL4NY8Hqaf~|hUHojBM6OTe>m*!^uQ(OCl9xd9aHO(_ zh7~o~SN)C7CPnhW&*$_fo{G&3ma(^vg+gJQ_P1`mufVIwx0|NBI2xI*Lk5dum0sAgeari#5&7a%d|eBkF+^H&r$Lh%45~g&vK@ zU}m4D6%-_HA4R(>0B=Whcq@EW(5^p4~m zyPIDmb2Q<$nRQ{!AGn@RWa@hO@^c&ED9(^y@o~T&ZQ)h&3SNl}otRFloGEF86~$>w zgEKj{5-Q<|R7EBKbjAMHi3~y@WCm6sMm?psB)>tFa8SsX%VG&7fACUpDVRs&kW%}g z!e`9_jDlnfk2}OQxI;ehfh3VDlZg6gtk0OxeHQ%L-e?;;g+w_PFM#sdXg5B`FMIqg z%(S0w;v{rrZs|e_)QWC$>@F~k+Q@=!%qW1RBWrJeFeo)m^E#;!1&S;t87^jdH4uMU+a=t@+;PD9QHWD;ux$egox-y!eP8WtYq`|~wA@k^=5$jAUs4O%?bRI0TvXPjfC4(Eq<_Ee5B zP%rMR1rx9^@$+P#y)?6SEoiuD2YSuOL>!b2tw-MIiirt^5I1$$mGd<9LI-RBAX`f8UmR46LMNe~y zD8(#EH$@OA!rwKOuFX7UJ>S03M~BUJwiJmawA#*lfFD&j1xHh!Jy)cg8% zO7tHHc@~%AACmqvvh!MpNXH)(i*MT1Ul}g^YxM3ff*Z-zrU(f$i}>=9B-Aoo3p!oh z?(&5GRFe193z}ocbbTRbgZU8z08e()+nw6ujK9IY{&je`ziXvise^R?$n)M^9`EIgfv7d^+DGg|?@yH@89r%OnqT+r|PCL3ADuzed$=UDeMXH;os9v%}r z$1j%oY$=V)=~clkvx7F-~b93iwmO%a|EUJQFuy4hz90eH0TK~cu%j49(F z!bKgh&dF01B+#3ihr$hc+^8p5p3rg2`o17_$XLmm=>Z5RNp%8GO82=2Op-(rpk~IL zw-c#(88p4)_Xk`h{fh|3qasph2!56od9{}k`QyVQz>(iAX%kW$tA4tEc#x6z2SVr&X6Z$y1PvdzYFm3h4@7uSBjIxId^2gn4R#zc)&vEz`nh~(&Nkq zmKi&&y2dTo@XaKxEU$oC)*}v87QX>ywpuP+?pE`|4P<0WZ+i-3c@cF21&|H^op`jD zEBSSG3K_+Fxg4as{5T@we~IwNN>$VMMZ__BMg8g^VfVFt4yTKZ9pOJ82LHAJC$#A*!#Kr zSq^y!EfVxCy)!Qg+AX6%j7HtsogG$;24_iz8r!DNt9WD@;Ti{0f-#izq6vV7R7oKo zvQjul{uZ;pgqgnI<(!PK!|kk?=H}3!BZ?82JSh9*PwK5N!sntUPjs?5gh!!=ir0Pf z1uc|BRnf}rBBouYz262uVS*9f;K!>hm7Vt*$qJ=QOOI>n1o z48ej-6qR~Wg?1cX2mY~ibxWI@uy~|9SDV)787`8!;2C?hRA%^YgQ`&f2KV-U1q< zXUFY}XgSn!to-T8{2CpGz3-+qHReR|*@{QkO)a#9wW!aJH}e(jxUQF4X_%`OM(h+z z29esw@E1$MhY{bx7~hQQwTmkuV^^{lzRb#vxFaqU)zjsyeZMmSMEs@Os}1*-pw`pe zrP?$P0ETu9cBhkJ1trPF>xF9j!zEbzqm@Sw$&oL{Um@HXcXXR))kOq=aB0@sOd?|y? zUVCsNLZRI(VUsXarFavJ~sbz?-r?PZPgulr*nCl`@ZO*|?iBhwRHWr#R`b>*ZMweXG}?!6>% zX*-6rN)Ih9%Nbc#(qO3dTR*l;kPKIqz;1S7rPOZ_M_MIYB>bibF(>v{kH|p%oBSj1 zwV?S{4`s~oNs!~PELD!mm=2x)0}z-8*6?mADlRs}b;sWumbJgPDRq(E#?}YTKeEU`Z}((5ihqwPTASujt#8RMd;XAjl;GBs-#E?{!xxmNa|IH ziiThUCw7tYisn)0Yg;`An&e_n3tJ32^11J((7b&X)LY~>IsVm^ZVaqVm=0?Yps&^T z6`Cxl^NA`PLSMoD@IHj#SBS=PMKL4*C=#29pVFkXyW?Cnu0u9)LL$Fc#sB+v7(@T* zQ@Y=0tk29QvQCG+Bz)3bQ{*cM$B{$t%`tHFVfKqP=)r-OPap3KAANDp{m-x+u$cA_ zYaY27MjQXeRw`n;4CDfWIDZfcJiisyFWSetECgws|I1in*0`}rq)561cBN10hPk&Ids?YvZH9^6iTgDg?8b1@O`91n_2FV^S82KwS*sf74#f-^P9Vd9( zX7=MiB<*<#c;{}A^F|XUOf;6YwY_En$0r60k;gH@s7wpRA>v>U%t|}8*{WZXxfo*$ zT#CQbI#VhtE4i|BZ!SHs)u+?#hrqcdCA2`>fy!??`BXA@C3=u8YiVpW@hXer@hHGo zPEO9wK0p4!=7T|M!3;EEiQHY>jRT&@lFhng_6)N9<8ydPSiJNil{ zQSY!Yx!`%_+uBH4nffdegNuu4tynHxx6HT@EcpC^=J@wZDw3rq$AsKM$)b}uX9fb8%w&wseiqt4jy(&Z1r>r3834Y+kPhY@{(@q~PtJ%;>Jt z`}Xr&vEsZ4?yu9EuINyYu(?}a=A%cu-GaTVJaI``5|Y7x8DqWF6iXbcA)x|<8b(bD z#UfuUf`6g%{X|hkBHR*;W4|vGA`6X^3(_y7)ziHmH-l;u$q5()=2AUlfd~rXci@Z3 znc#520I6vV3@S2xo432I(BW@@v_t<88)f=+m42RP`*EUZ)@f?6oYW=b^*@0oG%d>) ztcIyzvf!-!YsHqR$FV>I6FAIHy3&R&%8#w=|HA_4I`K86f2>i$qu}z&$jyb_$X+(aY<0O2%U6-`%s>i}HDt-N=8AsUPps*}jBRKVXCDOKNR@5(~QP z4+s+rl@=8t`JQ}b!!IpGRZru;+;19e|6N-PB2jh8N<_u1M6)_Sv%^amP72&W*qILP z=JZVrGclfU(!u!0*sAL0GBjrZ>V z#1g`MlQ2DRU5h*mF>f9-&365w!}(*s!I2ORY$*1dZ+L7WSaBy z^D~lW^ZQB{CU`;u8)JfKeBy@f%NHs4woZjVbsXgHyK+`bQVi8)ld`82o|m=wity8A zf~^8hX4L=zvHG^C3(iPoBHrIg-!)3Izu5hQE2Jn=nJr*G4xLuG)V)lA2Ozc$`ry}18!|RQD+|qRVm=>5Q%4#1{_Fn1t-E=(f8X-N8jK0n+0P{p>0Pe9 zwuD_DL)>lM8$2Dsp;*Ji+*CT+0Kd&T*jy$C^;$Y6CZ+5AQx!!|$)Rcu!(P65<4^aV z4*@SdfJUrS-q1$lRf4>3D<2=`>z_=J71f{4yG}FYtmx&4yLv%8gpvf`P^4b53ZMqw zYAqpW7e&l~)p++u(>OJd-N}!qLnRPw<6e!H261@+ zhVqE|ZU`ITIezrQUs?R-Y${#)PfaGhsg48(k1zzANfw{Nq*Vb?P;e4kakSakj6p`# ze!pTXwNa(=aG6rAG>+ci5Xs-O;w==?4x4+tmQ51J*n6gFz|{R0ekCKxCXOSsHSBF< zn54hUO^8+ci~*UEvu5ahnV41yNDgh*B`J{N9AcY1i=-7x^!WEYVuOaAel#Ae(RdoI zML0dKX1j~( zrp0j~_5L0eyJqBjrgXM+lo!W0B~)2pim3Gz6Ri;EYM6teK-H6bfXJ!1mWIK{=Ka#YbfEAcsU?cx(- z?;^Mgk^{ka`q4q5iqm1R**UNRgV*?DJFbOUx<$WV3_9N;E?iyENK`^ z&cFWhj(pwH#`=0WCSZ2V$pZOwnNp#jr}kfC@ti-Tef@`vLoQ9m#XW~#Btuio22>P~ zMB?jc@MuKou=CBzGX^|Q`v~&Iws}gnrIHIK--8E=khhZCYHFQ6tR2}6>a2firFp%q z8F=TL_d`W;*k(N}4%ImmuNbyD28MNkh#A{G<#0!1Y_v`M1&h!zg>eVdc132Y8j$j> znwJP#FxpU6wKu3qkU%5j@(Y(ONu>&0`kXBDxLPta^=$=T3u7XqP%%-oSq>b#4{n#2 z5pY*Ne;x~OIWirVEg4DArJQ`LOjD3Mk^-CHQJ{Mj+%!t~qIJKI4+spq8fcj9>?pEL zW6Zs?!*Ggq!NRcFe=Ezc9OnH*n6zZO4qVem0uYCZU+C-I8#$r+^X}{gc*Km@dLr6G+7< zjY=l&1fPcIynvZLy;?%WLNmp$Q5`@iPVH=G_l1(CMZ@00FWs z_`tKvA3^K7T)+4EyE9P~1Jqrhi2C1G!|4@<_hS6_cx|yjL zhG>u{lD@T(%ptn`;Y>Jp?^l=(7WG`3Fqk;qh%PhRMEp^Wy`+p|$}chz{JsCpm_`Dn z25k~%dun3Egko}bwgMEiI56na^%Sn_)~>c>^o4C=9POiId*zbSux_H96y8_cDuEFxHf8VX z`50Y73957qLF^evSQVcidlvf07$`9x#c{ESqp|7aV8;d=~c}9WB|ov?i0&YNnXJ| zceZu9q}>{KwL0y1lRWxC#K86ao9Vq@KG#wv_ij})jL&*~5ACkSA0TU^m=OPg!puAD zNc9rO+8MhiL<4~Jkw!6OW?DFm=C;uqaRN$mo05}!{#P5n)|3Mgu1I^NeP)*%q?VUc zPCdx|fQ9+;Y<~7u398z`ocnC}I{{>4dJIzt-3z8M_zmg$?h;}V!mz22tJJuL!Z=h&{b5STd@{piujT>08kue0!@@q^PW2y><|ol2Ih;C`M* z^JKNA3_&gQMiM^laq;_ZSBpdg{rhC|>tq6U;?Eq$qd^i^-ijy&h6qMD5@GkRRNng& zBU7kUy>sc$_uc2dvQ{T^UzD@p9@+UKRl53qZ@i|h_c zi*v#}!6k-*th9K3>A*A}BS9@ZWoU2;v~sR6YrAZm**c4G82((}Y>hq;bXB0^T}xb` zf-CTVGD?;Yl4#rH=wrd6R6}jLw1*yu*;-8V!=L6R*R(^LNE@jnuW+OI%R(ei|EY5` ztxr`&nqo>ecFqBxR>mo!s=P-4^RLui$_$HPMSNr9#q==(hH#BxkmKurq&Ml}5RXGj zBGS)sQcShjZK+MaB{`d98o$r*eb(<2a@1C*EVz0$aom*o#Ex3Z}+S;0d<-ZT&qeBZW48%L<-gJ0L1h#ogEoC?u z{q#Ra=v>HXXuVIhfSn^JgN39O(t&2&NT+tudlP8Iqq;mjxS?F%7hM8zSImQ*<^e7q zX~`+Vu$bj8+v6KZ=EeNnj~e7U#GJKljU%L-+YS{-15b9zO{Lf7D1cC^ zj81aiGodh`uZG8?)QNRukN&e0sYsa+q$ZTd=$Y^oH-}T9zW?a~XA1ZQWCtTSySjW^ zXYXf^6yQoP>`|`MHK3bUfKT#M#_@8F@0p)mEHKH<2bA&oQ&XnmYxdW3!5CL8@yVOE z-cbHr9%u#Vld0g7AJ{Jc#QQuNJfPOf)!4AD49q3XgsdJcL6&m_6`>Mhu}D}+Jt1P% z|1*e)?sA17ZFZZ83W-h43huTbs0qvakk+Zu=On^`FG;9$szT1Zv2=eD5;^~}w*=F6 zobOkRA5~29H-ll|sig^(?1@jB^wiV}UW$c@{-b2@8?+@6q2-NzIhdHp6_PW0c`-U! z!2v#{uhNTMUCG5zVzfuC#{642mo^z(+n;E4KW{Dtc{)RIduwkGYwtpZL6}>r#vrE< zMg+pbC>@5F1hJ7+7B!2^8UC}&ge3a@#e#BM6V+aR)^_jo-%{{35F^jRIDD+1VNuwH zq0g9GE^wAhPFL)*f+KS{RqAX5me#t$a3td+Q3O(u6=|-VeUVxx-F<|*76O-G0;#^U z=xsNq0{?V@0ra7NW_fJAGz=VQ=%3`EdKSt!I6M-X+nvCv$Dxn2Q%k?fJ<-b^MGV&$ zX)F5kuXXW4IJ9(7Cue!^h)U+1JjybhjquxXA|st~f_yMF_ktN^l|!cCxA>Y^dz)ap z4vT?VP!O`Zs#YbJcLj>(c3FK7g|_GG>PAqI5WbIQzfb1B@fM(vN2`oO zM&U{lpCsW-LePlDN(3m%%)gabMSf1gqqpbEQ#2%q&Qag&P^k@v=vkegUl0wBY-Gm@ zFuBI+2?+lkcr)W6{H<>LgMgr(JveYSe^fpc0bagJR`Y}c6_-v*gyxuJM87+gRyvVH zA4UYI_Q}$SYG9jsd22D4C1Z_M6L9x^LPd-XEYZ$#Aof$#Z$Qx8Je&enlN&K-f&tAC z_ItXcQI`wO{?P&wr53p{#Af2jD;SYzp?8ql!IK^|S|BL+5V{B5+)Y{~N`yO`ZvAhz zA?LRtu|jlM)7Z#Jf;s*DU3%`z(5y&FqXjueQi6Q3MQJyFiBT{tVb1VbYbfhl)7$^~ zqW!;A4aglEwSqAeee8U{_*lp`m2wJW=kSG926JI!VG@>^_McJrxiU!~vyDZEsa3iE zlO-%Mn%WusQZ#9iMLQ+l9Z0w(2~C4v&2V1RLl{a-ms)&@8E^;ED5yyU`}Eb%QWHpp zpi5y%KQSAqg~*cl^A$goMey`;9hm_=-Z#np)4$Oicd!+JgA@fT>aO0lrKFBgx!@38 zr7797qJuCW5)38t!QR^G$5gzB7Gzwjur4j_Q2sQOkN zH|NqPZh|I}IAr4Lxba>jdT-{b-iRYhoS|ta#U)(=#@H$Ch!QuUeMPW@4_gL!8?P`P zUpP4Pow{!Jv)7@{q!T$eFp8xl4vyX-1B9zXJsIo9$II=AqJ7Hh%B&;7hp#?mUE?@F#OoU>} z;iUO?{NzZrV!W{@IdH=}b>U#X_Ao3&8a$qWoFP!_1;v%!OQiRMONo(*hVat z)sx-Ds489LA4cSnK29)wMU$xOxJ+PJg0Sst<~D+h`O_%I&+4BA|D0pay}0BNw=pec zj+f(qr@>&uGx8|kNXz4w*80~F5;TfCP(3spVRIGDP3v@z8O^LV2^*FjNdl?(&x74H zs*>>JSw?(aDGg%F%}1+u1)fMtT?paX#s`jk{HKy8)2#YE!vFmg#Q-pxULj;acb^vg?c&fh^VJKN2#Ab@Il13WV!S7 zn~Jzj$zxmt;!^`FFFOMRdtO57aS?3 z;6zI}m$SMZ_@% zTXYjg3kF0>^Fb|pUmEHLq3yQOPD&$d8R>NBFadP0nGoq>k|q1S9wc(keJx7b2ahv= z=cEiamS9dAjjcK8KjdlGRPp|547h{1!(|06ELEB|6lte|5}&EaF9wy zWCWxhyLr`M+>+Gk)g%k!^OUqS5KZG_!eE43&N$=HG)hxI5PyIO zg-Oe(XlUdGs7OdqdMWpAHD|;gTJ3i_E5&@zbqZ735oDPOm+(~CE|#69p`nmgQA*EH z$CnE(ys(njMJz~v{q7mKbf}TUf4B)GNvkQQ7B``VHf%AHWdU3bJg3CX*G?Zj*@NUBdKsjn9~T~perdHk#}cQm(+u=Q`6>i@SJt^%N1--=48$StX*TRd9!`>qn} z%qFE~puds37TSwVmsM0~$tuP3GBbZI4An3W6|5>Y!QS61|Fr|I9hFBS{*hO~Ru~@u zR;wV6FJVBk9`t9VIt&RYCac_f-GxREvK2K-kmH3XSEkRXM;(z#a{kuO8<$3k(2#R4 z{Fr`rK2dA3w6&c!r}pUo+dh=wmnc!T1y2xOvA;osA@Ni18RFMg(x0-&P{|7$8$ufM z5&PG`lOjaN^ z9f~5i-wY1jeuk5fOE)GqHK2j3tdc%&U^e{SNl|1c*^7|5(SMp4{+KzbcS&J7M}S}1 z$4Ag{`7jbVgjd|5FVB)}7PPiU)4}JPU`m0V z9t_7|L5et@Rr$7A)}zEtMlbkk-uYZ(?YT2*={OF05lVbMdlW8@zbGT_7NqWLY7C`1 zT2X1mNmd9*0?3UDwP->`l>i!05NU9zYLoIWR-(S~lALwp&n{Fe`TxRQOE%O33nbwQ)*ab2-+*)7N zTZ29PLs(?^VAj@7ydG%s=P+gI9F!PyFvZOu!nYPBM$cpsvC}eMo8SScFU*BcJQq54 z|L`qD4Q{%Y1(9}32NsC(`P|fH>qRn71pXJCAuf4WJGGi5za^(_se*;^JsgA@K{nG?ccpgM(jtS)jJQ_1UPb!S%Os zP?X@h7#kB{nY6i1&FT6asY2d-F8{W- z|8Kw`C)S0j#W9Z0^&e?_lKQr2EZyd|KIblT|8pDt)4)H9|78P`;d%D{51aqr4uDf4 zz?XBnacV65cWBdpU8Rc}xXlsz^b-Dmx=UIngd9soW^OCt@Beu^|MO1-^=@->H?>c#FU3DMX?OhF z@3(~h4R-SX?sskq*7$|x`sOO(atZ`scr*dtNP5s&=70LiQGWlR2&Sf%LbyHQS^lSm z0yux-U2;ForbA6y|0DO1PoxW?kWXZ}!Qfw8zWviZ-8DFM-D zHr=uEzkQD`1`-y2egAUcF+u(W)!oaXZu&f4SdBhMlf`A^jRW%GqY3z9(!Ru_x&&BKYqjmrpV&( zuP#>s_2}#jC>3p{9{N7CC1ue!t7c};uhs(A@a<}O;(xJ*O7<2O7Rd_>>f+J}k-gh- zeSP8pcn_7C`DZLC4lZtYo6XG10#%{g*#$8PEbLX9kOseiK=7x@tu2y;WikL=({mIV z27qD1!{fWUgxiEj0T8x|sw#bZy8v1YO+MgaMq})F>cp&W-2*b+Pkf(@AI{gWrvW0K z%kzodP>1(R z-}Xh^K7EQ}cK>^hD6j=+g-;d#ZT-8}#r+H?`XjOTT_-y!JY6p0x3@uIk&se=erc;~ z0N7N9!oj;9xuXKm$Jzk7l}OE#5)|ocP>96nV(0r8_oIA9Ga~ZPpxxv?Ls*xu0 zIwIwDcnx|zckM*Cv$G2;{}x|UQ**-A1yBtTHS%g|faaqmlFG#@ETE^jys9F;Hx%jf@Y79Q zky|YXccb+CtGh~@TRee)hn!Y?h`O?}zsQpvB|Ew9!jE>}mGAYf7{zA`0^)fsEn0fs zcbwtT(eXB`4Z{(b^i$OA#o*;}cAalnLGxb#*5i48Z>LeHVZbz@m<|5Fzu;>Gpe4Ql zmWgzST6Sh;=CVa?!|MhShTo^oc3o?@i)5MDhv9s{oJdj~P@fS=0jxHbETTj|KjG*f zIDvV6e>>yhIX}?|GAX=80Q1N>oyRA)L*3uDq0u4yEjzLpd7d33)1N$phoV7k9Ker-QLikY~M z22Am&knpPa|6H1LU9ekn%RmRt&wh&w3#8*!Dhk=3Xm@wfua632D~@`I8x$imNh42i3Qi}L`DW)e8hc@Br74GkD8;CV^LWdin5Gy9i|V< z{QMVbAwK#@Z0wV3Kzy0-(`Uajt#n9be9iCdDF!VMg@c8qjOx$vae0^{{K8piP>?K| zSCktP0>W)2Z7YD;JuPJIK8n2hRs6q1gvnh;M`2k!4q&JPn%B4NlS8wLzVZOllb*Tr zwN4V9^*PMKa`yN0GnD&oG`Bv&>kpu86dGy zwOJIahZ=Lgw;11Dt*u3~$c@-S_@D$ga&``Pot-x&?X&px@Rpx;1c)zWE}~;j9M=e$ zcB2!62RUNgrJjh0_I5oc`@=72g*pz8NjqBBk{@ck&j)GlLr(y+Kj+@$voVgdBe)}Q zPW}))`b&O8$~*QY_BhKGC%=ZDiR_R==-Z;%!8^iwE@-E9lfnb5zPi=F8d7})v@JU$ zWN|qq4y}6gc>ahAb2%w^MEKMeH?M5GZvc&htL7^dd=C-m92@Ws? zS=pH@2=Y{bB}hq64_`2a98A>%q(GRc6#?veUg|#c`;I4GbN3Kc3L~Jx@yp`#l+1BI zz%N_4Z_5(&mIWrHnye-&7Sye9-3e#Bf*$+qeiicFJ+WG}H@Id1&{0<1G2V`gIPV`)jLj%pNX2OarkBMqz|31(bk{uUEU}Im@xW zUIHn{F8)&Zo4dYd-5y17I5q^3JT5)uTcx08{wwqre}ZaxSv$Ua!uy za4)SVTekKsjbyl1gzj;!;dXe!$XR7^h8do%XaBtbA{_DI>-IUr{Z%i!{0uitV*8r8 zW~BF(|CZYF9OKI*=Vxct+$aNZP$c5z0HeqOmxmmSq=X72hb^ZqSc0v~g!!A@A`$^n zFbA*y;XQWgPe>@HjIE9gZ0uK}$fG@{hUgWY~B7tOSIN0(uHr8OmOeXOV+mSro0QU-T^Y?;116BfR&+AX%z;Y@MR; z=Q&?4U<~F~Rzh%=*(|IsE^B?7c;vV96au$P;HW@GaP?}a@}y;C!%~3^;O=SXWz8eG zgppdBd>aXywZ@?-{5%VDu5H57rIP!1-5$a-Hnp?*?})>lM3srkD54JW`62usCr3$Z zzXX*tgh>dQZCN8oxx;c5C%DD#&}ppL1g>QqGP4*g&||^-&@Nx*r#+sC6awyW9LDQ3Njq?7gYpv9WMK zB@B_4p1c&>e3$iUqSg%=DA^|#{DDU8p`a3_%fxa2`K~MImD!WMsM1V&LulO`Ni2w6 zxmMf?vESl8gKCTN^GdWhV$#o8+t*x;QqaEQgsQanng5n9M{ zRBlgcXLku4Oc*ml)da4J~diS8lLbXHdXV zBYr-u0XpPH-=WVri)JF3-{{ADeJv1b8|^j?dIl|pZ+Qq@V8xgI;X6hzZn79yt~T09 z0XpXNDTUAY{Lye^3nlSGr=+ z3gf#}3{i66qpp$$4Iu3P3OjawP89S#Cp8w?%g`;%0HyGPL_E>->Mv1vF3Fg4u%p|c zjXX%%#DtScDV2hZ4U9n_8L3E!Ne3wo#-9Xfz_`qFNypX=gc%zf-_gIEfPP`N1b=)EC`B+lK0^sNL!$XY6d$|j&ueeqs;b12E!4`Mlukh0&|`?@C| z4;DfM4P}e^<+`94n__q{m9MDXN`s$7U;#L=6jahUc3n-_!xGsT1Zpz%g8;v9H_Ft)pa?6rK8!k>bOvy-t3&PL37})X8z_i5ka;*bdJpj~Uj=9uRh`3wv4B7wi_zgj!UH0go#rJKQvfM$T@Ydp# zAYn0P!SKzL#Pbjg?7E44;1 z^ZU1>cQ9-5sJy!GHVyjAznv-__G0hFhq-i)42_J&f-lyZBSVxlTTPR_9;XMx+Rs`# z_R~basL1I4B!Fs;M>|XMeJ+v=FxDba!vDgBEUi_gtHO^|re%G7KkUJ)vqA~l?O#W> z%t))8uL22Xo@XcLK_#`PB9?0{3!getBKWi=8d=|f9J%hR@|Yf+)#`q+XpwE}GQbQ@wxG zPOv*dU@I9g0f$dUh>mS7U(x(=-=gYNdnn-yd>;0sMwN$jCX-#Ip@wp7j%|k(5fY`x zv{Uh*q-t5qEl(3w_p==*wSsz!r3|!1NFsXnB0g z(zyP!Wuc>C`&fa?N4w|#P<-#Dm~7HZoD8E^%rWP1kreR;b8n#c^`h@O&G2JZ@8@+BNxqt86-Yzc*dd@X^aDTjL-yg{5ktO zlH`nd=bFzh)~j%6w<0n(Gkdy&*;wlELV&gIi(}Wb&dA8vTKd2;H2n$;!2KaE;vn9v zq3O;$fa#Nva}dm0XA=|o(R1MR%1Zv;6m}&VBFr@$?mGHQX<#m)&woZ6f|tHy+F0ULn{R7m*_A5YC+E)P-5p^oQbE-N!iV9P;i ze^XDApKKjE6;*wH-%ivT{v3nC{K+`Wsa+mTXrP8>)i;q2XPt#=BSXiW|AjKKf4%u$GER6|A_o=ak z)uEJ?w+Lg2Seu0L5y9Il>_G3B!i+FgYSTD;MwdfiRojJg&1?wMP zf-My2rV)U2Oy~L9&C-a3WZg`VYk`F&Xe75wNem6~iAEzV=3S2orsiU>zkk?iQh;7j z;I4`F$)qe}oygKl%MD4%=4vld5zh{r>4W&a_rst~=TUB(Ps&Yopc*F#2{8b-yw>B6 zZpjzW=NXP=8I5^h1-LIX@7#F+-G|rA9FVH9v z{g>2V9eIYzgpE8TKFIlC;vC{|#!kOP)zBo6Q(JjZVi-@Lz{HTmQ7@AeqUF!Y#5hPJ z2vXxi8$)Q0j(n2Z1C0~LWl5y+PmYLd^xuYkdK4!dtAs9s9#~ml4^)}wG>poB$*bp$ zK=~Q@WnF30FH2_KWJS@s#1s<>gM_tjEVd8v-AtVw>m87kbs1 zhLSoGq!ve=IBXy^_QQ?4R%9zt6E#R1KQ&O5j1P^QVh91Weqw!& zV4Gr<2uqTMVXo(u<4{Fo`Cdn^v6qDgHQePm<3F|_R8kQc#T5RUUOs2zF8&jdI1%ndK?bTVfMJ(t|O36yQ_&|_35(% zZlEIWH)5R#3Y|lv#$xZ+RudH!m8JwP_;o^_enN0#Q;6h@P?wE|$4|t*=BnOa#0D^U zSQ7fpq{2NRDTJ@u8g9DCB58OZRifxy%yj&AO>5C9`^`O0rncMOA>hvM>t!_pS65do z6YorOL=O>*C)tY)_|>JenEsg(enpfY9c49&0|Nsi$Q>W8lJVHEwQw(;DU(tF%$Wm{ za&qVhCoB{<+|M1~$bRsWgk_o!wkIsaLay_Ox;IW3sdqisdiyYicd}WK3}QpFEid7F zS8o9LNcv!dyZpkBfd(HpNN4;6BNKH5uqELszqhV~BD{f_kF#CN<(Qh9_LGD@NKSe9 z*Cc5_d-Qy+PZcjKroF)lBe+(x1RrS^WkbZ+3+3ssHOxMj%8s9*hRSbw8mmH8jy9$( zXoIL{Fxmp^P!>2r5suDw>mmKJk>j~gzNkSpXOqr=Ynsa}rk&R9_QY}_2+NBXp2OC# zWGl%9=L;ZEzm&DBnxb6a>qfy0=IK<3P}N!Vkx-M4MU8SfBgy7)&%_D$r!~S=a{XjJw#sxRG(?dSxj+lpFC*h+=9*D9-XEPfHRPA?~^Hz>z>gJqy zpMP4qq?l7}8#3%VFv@h!Gwpu+BE(BV)Z<-OSU4MmXD>VsdJ_%RtCPd}I;PGZgUt!_ zxw{z=TJbZuZO#|KFi=8B+b;CvJphr*0DGD|FgFAgpyp;S_HAz~KLID-{;%G_DA}D* zp~sw9lztVt>erq~=27~e9cIrhqsL|luDMU=>^&$DjDVYac}LdeiTZ``br!fVB*YT+ zp$9%=Fc;$;*BWZi5b^P88d`$*l%1Z3vWjZEB-%m$chB<5f~a_*!hauL|5-6wuK5r``?jg|O5 zSya~}D-I9TgYv?%pWI4U6cW_Yvcu(k_P!p;w;VbJ+b0a_wYhGggf><~eGN1J^Y$LD zg`!XPGutk>QKi7T@6$!Djp)H|Dw+6Zd>9gtKR+A;*1{FOAU z8U@AcA8wvMZcE3_Gul|=VG{_WB#r|c)SYhOE*lRkDU&fzI7IhnG{42-=6<{vQeyR)T{AEllyfFWzDSlu}n|kAGZ%Ln5C0e1)hO z7^6<;gDzg?r%SG7bWGTN$<9kee0fD6p!y8!zp)`$bSFr`+AVhelaWwl4qX@VgdsSKcI+cXV^m>5aIQVva7gsgT*UJGtAJ&e;y(DeYZBX6$J)a!c}N|jEUju~ZO zQ_pqrQU@Z$oGUkVdX=pKDJ;${=?QKaX2>vWK5Qy06xMq9;O!4GO7EZa)I!rDlj`Bm)u)1;3YUr4q zNZ09=Gpq`1;Gen{CU)~NRvUQeaws->AuJn$_?Z=3SjgdDq`c~AsBqHXis3omND@#y zp!?GXiD>w~4&WD_HAzEzWrv82-3?LPQ+(L!RC`Y)s37c8Gw7Gg6B+92iIOukd@LW`vgON578Uy31faAkbK?<@I%rh4&4R9At-~Se87R-AAfzVV3$rYv z2>ulGVyWxh4tr*>1XdcmBj~j+o6dsBCgyu&6`!4L!cSZFTwPJoqu&M{XobwSU6dII z7D+K@R0`vz3!@Z0ArvxPM7|8=t@T59-)oT^oh&vraClf|Xa~-j?We`B;00)6;1FMM z8X|t}zUZcB*OnH2oBY;E1C5mJ*CU{HzuCE{r6Yv--)S^`RETpJ1Mxa@f}*jh%ed3E zT5X+erEFocZ+d#LDy8tq7kkML2$1J`fW(uSjTzav(hQb8izS?XU z^rWUJ;gWXN=By{uQqB`f zzjDH=(2f{`Id%1=2UcOkNe$@WO_FEoFJy(HRKXPee(17aIfF~_K#}xvlPOq4jcUL( zdp%Y7DPywD@ZykF!VhiQFfk6`Nb()eI1OZXc7ENtKJKX(T~)Fjrf0^MUy z0A5eMi|XQcKcj8oTmlUdw;m@-&?}HkU{RNeTCWQ^oq&H4*FyEk>OVCs7a^>X&OG3R zKUBw2wFst|KkhElMKPA{mRrx+ z(xMfzr*-JxVCB*xpiAO2^c*>W&$xuj9B4)(S!XF@?!8d*iWTLdRV3B}*LZe_7Km!R z{!mh(pERKy{-lT#b?U&FX|mOClN$rKt-_d1fS5?1t66XWt}A~Siyo7Sm%qcA4ReS-+d z`b{HW{(yU-@DB~z@{l>!2wG@&^57Y}q4D|}R3y43Nkw{H-qd!%+CVg1qu9KvV2YVB zTx#Q=!%svZ5e~#G%pl~w&7^P?+G*iY!K*bZa%9w?xPyiwOb#n+&(=y1O3~s!3xjXM z#MI%`WP!#O=7sl~cO~P>?Zit@^(LrO$T}|t8{U-YTPbei@g#!$qgj6q z4%=a|GgV3ex%3~TT~1aIb}K(`5u|zM5-p_3@u0w(pi7>Ty}?!1g($e<__v$R<6r$z zhI`ClNdL(K&=ET&u`3YSyL2+h&p09z;W7z4|Fg+7$=j5$G=W{< zAwHcvxMmF}lgfza^S-`nC`Gey9y!Gic!=KG2Bt#U6);Ryiubf;wDBoNbeO0e!KJBb zrou~ixV|rJ7<-d6N(3P8PQ}fjqyx)0FytX0%D5OXXj5lk7P0%9Sqg3DAQs}tT`~7A zMH$%~$0_dO8}5hRn$h(`3_eO%F~a$M^>w{&?!8sTa-D4kyHLE*alZ?t6f>;(FWMjC zt8_H|IL7Js0JJt$A2sx!LK1`nz`giJ4JPtykJY;t(=gH4{`| zq|^D1|G55A{OYUw(&MrghS56R;H9BgDb`5~7SVMF6D8u`V_z@Ns)Rzem%Qe|p(c?C z1J1Xwf(Qm3#5R}7k$j+eBBHVU!wnfjOjn6WmoN4yItXoECXghWtv4&g{<(DKli0Jp z56cftGZBhx>x*~>?xd*8Y|s1(87gI0{2t|4eNW#b*wmgf77JXwc%Gn$q5?u(l5DrT zEFtS&2*z(=Aecr5Fxd{m&Amolo(073qE~z)+W`?y?`IjIa|j8wrx@qO>gj!~gu#{! zP~QHd;!>Uz?CgZN1yCX&{b?^n<(c^D0xE5b2{jKM?WW5iAy9xQN(4uXn?GS?@7hG@ z`1mY1q7br!8L4frxk13H^|}17@zn8@Y`el*Ds5g{Lqq!goT$i8%lvx4_>`IZ2Bw$Z zTGU(%Y1u-4H0kxOw)vyk?f7BezYF3OUM6p*BXBvpsupPylpdVw0udg5PzT-3zw6L7 zrn>5`iD1zvTisj7<(x}{+t-QE_G=_rO%jU!2jQT5cc!1B$k|DudguO=em437M~>72 zukpCH>`VRJ3fl+lE!S_R$3{7C*UXHpd1$21csVXP@Zv@_{1@@mY_Om&g<~4!_-=T@LIV;FO$1P+2mcd^0xR5p zOJTU;fG==cLxi-PC1_CI%@XFP6^N{)Gw7OILASfxu@sg7mHS8dv5V0NGYBs|ch z{Jh;JHw4g7FyMAiB2_e%DdUI8+&u?QXWa?4j6^~0(VB6Iu^-9lmIwH zQZD_tfM4WvZX|`!1w5clyICNRpmBhF79!_%%hdqnytN-&qHVwg}H<_;(z}9iGtSidVOsPq zfNQO4TXUlr92me6o%@8%^o^;T7lS%D`01d3#m4r&Zgq{2G%AHqc18amNyc*)Fp8*W zVVvpSs6ubSz4)R0TvUNzs)HaS{W@Bm(26|XUo`C;Cm7^y)$pV?$1t3QBR`Q0Y&hm~ za*EM#h)%`Bw24I5kL)m@9chHtC0+nOFS$R+z$x0QolXKtJKf3VsjiLH8 z4ML*&2m5iq3Fp$X@WJLo#hLrs2`yDb6SAy%en?c=(y| zWj&Nn?z~@nH^)SuW65g7QMa~QYHMW@(2OV;=HYVAutn{~+kW)#D=bu6WGtth9Z+d$Lv&YL;&Hwd)vvfP0P!r#)a`>Fo-=9_7h| z#ihqnoefnD8^c;H{$K?+d0uOOTi|ot*>iYu6?%fjs8lt@&Ecbn(1Gz6ij@o8Ceb!B zGWuz^bjrok`ydMTN8^{piA>)j6w;|(k%A$9^*vJyXm%OQ8i@bG0vGS&v6Gi$^@zVw)f6X5{Q z;BOEq?$=0W%6|e%y9=Q_8_i9H*$&PY5&FrLqlk_M$Ccncr_0fa`42|16Cu8>`L72m zRbsoaLJ~+1bGK;Pd=l~p6sh(}dreWB|X&LPGekb~MU%%)_&Yi5`DuI6Z zQDxs${SAzfc6gL^$11g{Wiu^A8Jkvi3h6Se%uoX_71ygv=!OQQ$o>=_juJ8%zM8Uf z`0ef8_PAr#n(KvLkT?0Zh;73a&kl)ZA0l%B=E0exfk6%|qmf3y>VCji{V418I?bKS zhGVl%%Q8da=>nKFNeH*`9q`wA_+{tS``|G- z`2@5(OtjoXptXhR@w-iszo(C04y*mg(JnG2_NJ2)TeZZUDyqgc49j;nh``mpAPAYy zpX0%Ey{JNwi4z4{U2y7x!_m`t6SoK9;lneE`ot+1G-xR)zZOBkqOh^eh=2u)RI5>^ zMn*+^-C&|aV?O*;f8Tb%{q~@uf>vBrg(h19Vf4k&{YrCnN>O6# z289H68R_Q$fN)-}vq&6n66D|rGE))^eojyQ)(%rjjEf6}%3*`yMiJ#^cS*wj!eUJ% zD#F1@E+dT&qe68@!itZJ8-BM<%F9BdEZz2-hO-ArW_9}0NiRRXN*@fWH&ZA=~G`}!clyLg)jM%HTk39T*= zka%!;>qhy*j2jt4CJsHF81Lg)Lw(#d_WSK>MPN5et_x&(_nYM!%CT>}d_)&J%l9X4 zx@M&3uva~ecpkTU*isR5)5KdZiHl#IR`<1UpZBpBCZI`uzf)Dp6;_Wy^|f_dY`cRxSPITLm_{wx>@t6Iy))_wmXA21l1*0V91ZL?*sG*(G`3m_e%STM=;6r z@dk#_%j_{X*+hm15rL7hh{hA9K{1rwj~NE01hUiEp$67gg+0Zn=}63C7RJ!!w{hGG z3EBBD6vF$U(y6oVth=RW09E`yjP zQErsKU@D4Z&u6Ui3B^%9d@_5g3Ln;feFc;kMp&iT@y^Hq9B_S}jsOX|F2R<)Gm&LW zLnAF^jgD7ZXhI0fv_e+#M$h}il%?ESyRu zEiOtw#-)(O6YVr>I$$=*|7H`^mfY*tfnD?^L#M?{1{mi`RF+*(T>-p#kJTtRpxeDH zW2nX_l&pKgGqF5nTL}qhQDo-;HV7=8myEU63zv(0eSN*8^QQkRHyTOM_7fE?Eo_i- zWZTU-^nnE48(zA(e?*I|mn-QnQz)2Rls1;#W;Nt5#J^k;Sm2Q02HK19M_SEqhLxsp z9wlS8gExm0%^cnz6F99kI@ML$^>|;GS&b;W$9^Fo-igPjsq`E^lCa&*ST#M@pV`X-5!P}7CCh8fHq4=JJZc8~#nI$b(7 z#EC&e9L`)Xci)1~w^i=9lE1k|Oi(>0QIXfZ5IzTiJ!c0=s+BYWD>&0x(mJY7V8(IH zMPuZaO*!buNs7hPI5!@d{(l&as&Ypj!Lh(Uv$10B{|iG!v)if~kaCP;uhASM0ebNAceKJOBlm&b#6 zJWUD%71mesb05%xfzQPzgxS<-bSZXUs67Dk9_P!{25y%^9=A<^&T`_hA?P@J!Nk`{ZPJk5SD<17BEauO#r}^^6&45ok^Y-XDNiM zjYE|`+ev@6-{Xk}-)D^F+!6pKi8TZ;46C@B@}G7|jG2pKsE6<}_yGmxi!o;`Wip0}HE4?K%p6Mx)%FvbeK*N~PUp)bt9aq4+w@Lym0IK_D1UQrK;u9CIpL9Df! zwYI%K<12|ujFiZqh;a0;jh$~yn_Q&zgh5BM4H;2S_~$tcFN~kaG1y3Xrs~jjfGN>H zf=>s2FUw?MMm?~Vipd^OOJL|#iA$xlQpe1Qq(-H9`u_fEQeIKcJ_c+SAVFGocHb1}?@;Cta2_=?lCgbc5&Qr(=!n%_*rJ z%@$r_b4No9-^{xP?z?gi*}+~`%Yg~O%*K7|XRuQ55$aBpWE*bGhQ!|yU8BAkB>t}e z{_zY|KW%gbGnkF{1*FqnzG4DbPq>&cTs3lSk23s3#Ud5HpCGrrYzRK^PZ;xVJq_3> zB4|h?AY)%ckp0EVG&C}nMk(kpIUtbY+lKthUWtGB2)b?VSS$>8GIEf}UHaP55$NAw zZ;Q-SGD2$kEGx@;UY5jTTw{uLLesW)etZ@mG9X!&hQ=DxLNYEt4m|9av98oRC)KtS zzI;9BPuY*(GqBH@ypRW*Vwn3fGcv|-B7F=G+Jbfha&5B$1Hs>vh`$UaDhk-b&@Pk% zrs`Bdm~WDg z-5m;$@#qckM!PWcp^t&SYA9DZ2A^K6DftI!I`o(DDqY0Nwu6)c3y?SLpit0ccj`eq zVwIJy6EC&|=y--q2kuhy%T^n_p?UmSHhB#=ZNq&xSbNM7xX($Ak7`L7>q(VSs6XFl zy~8V%g_li`hNDBMP@`S>w;d_-CT3>BrV!*KBSx#hYf>(|V1-!xCih_>bZAd9PvECz ztON^8Gd9kIbYG^rzn8TLP9o8BfyA+kWZCK7^PdDEABw!%LK@;OvZBO*$#-bDl9$)O+FI((B_MQ4D8e}?A>^P4vW2;!R3CCPR+7_!x@i5VdHYP;eVCF>_OTk zq$KK)Q^Q0@+2keb$TlE_8s>4tMJfayrlbEB^4jeL{Y4g`bsOjo7{9kb6rE&^SC9G< zf+{#TX1Ok~J~KN{wp-XsWo1ydPU?Ao8m#q)V}KJ<@S<(s%dh^dkr4FRP{NNK2jptj zFK+kv7%Ckq7bVv`7(bCCcpmW-j|VAsATqd&CKjW2kRHW&N)v{oOz+Oki_|g^=ftVa zE?ew$(g{7(9-4QO`)tK^VcdkZA4Sqz>1G{FT!I+SgbT03pjcV8zte zFDcwDR*XoDbTESbH7l+{1w9Z#5uA~+DnF#nF_ho697(@jK$=WA zP@q$SRM$X)!s6AGcJd^4L7t$AOHwq%Q`eq_6?`8=&hZ1WL_5i*?viZ6zM-hkP3DFw zUBjTtuMq^4N+;R_1lo`cS6xyx^2`JVA3nU+;*n=soF4M32Ynaa5ekmhHu1!*omEMp z7(W;-ya*I$yo9P31bGij?Agoao?VW1H+WS9kCUT*>(^{qH4Qyb?gxAhWYA7Gw;}6g zdiJ5XelWqKkl>=|*e1;=sFrO@SJMy+n)fSVj}wuQWZuOMzFCs>ivQC5`H|JMp==4K z>|(@7m?y2y&Kl|Is3KxmKEw;ixGh@`3MU5}!D@ZCZ%ar_1h~AoZf;+kc*t5sFqGp( z@Zmk$8oF*%DU?JE{Be(FN`nQN)mR-eZ=E%P-fWDZ9gW~!rgxXtHOXKRl`!X3Yf{sy z-5NgmM?7z%N46a18sfDNzu|gG%mGUZ>#%75kL}`7HaH;)TeD__97crOn+dWmR^~VC zM%!hI_ASJvP&l}_DUwNSi(bKz4q~AB1cc%9CP|1Q7N%~`QWGe@c$Vfy_?0ut!17o< zSMVf9P~}w{*;ip!SWI!j1dJ?D9ta;~NV~4XTN`ce9&Xx!wmJPUO`aeIg4SP~lYV7} zrkV=50YemMP%DDFPi&8r!FYilIcB5zYpgwC;xW*9iPfgkY0V>JWRh6z6)hV&dxl+5 z2{Z=zYE^g#R$o{cr`R8W^T>wi^4BC9qDjW=-I z#971_%cayIkzsIfcUd!z<9q!D*PeEiEe@5m8VwW6QlcB>`g%Gfvn#?8^H!D zUHf|6n~RBJF3>X@HT$o`RayX-;-lfEA2504X zUiL13LniZ5GtwYC5S=jxf_xDJB&P#79a#T|wYQ9ltIgK6kpc>LDcqf4!QEYh26qV( zAh-p0cXxLW!QCN1a0u@14yWEedw2IfZ}0Ed_lr@C8f&at>yi1)dEeKZO7R~z36li& z{ z)>z`{v!6s}g#;oo2UlqBfc%Sy9ez-HTjEWKVp;_|4)lxXCG3zUp7_HHZA--C@>QgE zqdKV+NJ@_n!~(FB3ca2KgT55xP8Ay0_xv{cUmEKU{M`?<9B0-llEBp)*8zg`Ch?p4G zPKnHgK<-5oX_W;y>55PQ`s`60hea{h2Prdj6Z||Vjvz{P3i(>gY=wX?Vt7U<_ftb2E7M69qS|E>knE3d;*yAm-%J~jTP9Us~h9^jBbq3-1ee-bpUDGMF6Sz9V7dY~NB zy;32|ltV@hJ0$i13%zJa*&!d`4S!9N3HDpjpgA%h@*up+oyaH z!PuDx4+M4YkER8pAsEc*3arQ!-oce0og>e;9jk1!RN**c5CtU@Q&kXT)KRk@J<)mx z@fL%F&9`sGjA4Jn8{>*amWN&+Zn8(?Nzex$5cIpPe5UozC-0M&9iFTvHffw#+ieH@ z9*S**Yzzq}Hn%h}awC`%wjrT1>$4Pkjg!npg3_Ttk2M(-vBHYvRK673#gHKkPIPd` zsg9AM^^soZivArh7CM^2N>6vD>FHV07*J`vm`3y*3%s^TH$lgpBoM(PY#5^w*|GvT zfCjLZW!b-`FFtOk&K#r{;vVObxj<1CQ@M3 z4g3v1orrECsz|%jYA*-d4J-4obOL5MX3{QZk$BKMscx1G%38T-{q`vGsdR}Qh2-x?{Ho(Tsmkg zG^%2kmwD-aYEfEQ=_fp8h+~bANYalp$^Yz2StQJ4zY0Ldq%6UcF$x$u{>aFEz%Yh; z{pnM}PSm&;hPLjVMyGtv%7@o#Aj|c7Pe9Jd&P|~_MSie}g}Gvk7$>_d18usYkXgAW z!Uyh{*F>3$1Eq1Zhb)=0Vg;cbHt!S+0en*()04I68$AiUwNp5qdxL*1=>N5fB$Gg? zAtWUyjqS>58tP3$62yqGlQ!Q4(w(HuSq(+c1tal(J76CfmJX>e1<1JKo4rHdlYhF- zZ6u9DW9OXJ2rxyfVki~PXS1SE!x@nY(?}XDXhIxu1sCb$d%i#nGhr@xlqnAw*;d1|Gwp-)+tx)-;Il0Z5YHL?Nyk|sivRg!mNaPaFEqjh zV|F~;{W|L85J~nRg{rO>jJG!ye1kO3qx58+_82I^6e0X)-6iXx*i3ms3H>H~B&8;4 zI(aVzB^Q^c{#}pGuM;!vAPmW|t6Hmqf61l(YbI>i34e!P1Eb1#JkR*q=x9=H#wblK znN>&gv*bc7|7|PLi%z^QzSj7C-s$b=pCYqh3goK?P%8_*9(;zJ60N738mK_}( zC5zGft8_fKzL!2>SW-`2o$9>(Id753MU1qmu~F8@C%dt!g}`@ieEeJB&9{J1YmQq3 z+Mh`8bKHlP=TO>-2nLI8@IgvdI1(Egfy#S3}SxrdxB3c-u6i znZ`zc%riyWH!`|A7$27}tFS2Evs!Afpus@6?UpOkdt#xb$s6$F3d=(#m>&)I_iA;! zjE4^}S+V6@$?vSxSOMp_e`o`!scD4W6w^D$f3e>AmhT3KcyGoDGNgmhl369;Q$kHu z#w9!RSx81(+#Yvp^kbXnQA)ST<=2r>P!iRLyE{#Wa7qvSV+ku1(?$HLsi|p=zBRx} zrD*=A-Sme5@LTuJQ_*_6-}r>0jC5#%Io|7XZhWqvGp%$Xgj-8&cOD612~RF8uj36K zmT(6iTHC-bN)kUUYkG#x&c)`ovi^;%3nwu5r-x~p-A8@txj7C;^rPI{FAKxLx5vu% zKrrqHO#q!`F*+)YgUr@w(=H4uPkc_o!lHyMHZ?0PD0o3dMP<;2kG>o}tLn z7rZWq2?IkFbZQmS(?27Fr<5n<KZ-p#Z~hOkXtRES6qk5&|yMgDRVQ$4WVD$+62)tBk)-h-%^QlE2$r?WJ%^ z3`^;$Bg<*<%ClIJEKx}W>9x~9gX^J^^X@<%0uT{Lp5@0!1t~2punIDh$MX-G1flZm zaj1{jcp?tY9-H>`k@az2sb!ozZNd*^bPP%0iQguNOb(sTmOaLsxSFH9qI^1JOOa!G z;8q{oa4{Ux!Zu026gbA$iT;kbFOD~yJ6KH3~zz1=#jLizQCIjTuTDoX?Y`_&~r@*ixgkY$Q1W>ENZCxp?|9sYTiS_u85*kT&>0*?k&PD4*3dot$Uar42b!4XCXzL+HiMj@>fxXfw397|7BX z0!CZIJi(EwO|0959IJ$hb6|=Efitfy_~7n+eHW)-${@$mv$X1!uHj~TSQuTZ4l17L zM;21$;Az*Tm^9X?edLZNY5qDCj2yMSB@vJKS3{wDvC(~rA)&BWq|JY#oN;-$D*mTny=)2rk}_d&qb=jKxa&a(xmuOH=TW*H{{3a z+ULZx4xO0xvzEW#03W!QvN5iY0V51|iZ-{mQRzhQIu0%3@w@F(PV2F@GdMZ^wE|tM z(q3of0zGMAQMQXG?vvAViG<~3j*G28MQ7XXtc8_t%UQ>NxcWc6$>H73K=2|*M9C}i zx844~U$tKw0VGxA+1YlDXAL-=^tbKcA9LmZ$Ln}iY0spN+QGg*Ixd&ZJ~$s71O7Jj z{+Vt_CWSI!F#5>DLl;1?&BiGRKO+raK;`z*B=eu|^DoK2Zbv_plG#akoJbY}Sfyig*`XU-5=g7W|U4V{Vz!xyXs zG}!%Hw&uUz@qbCf{mcTsgTtRaWh=4&{WpR)KJbw7{5oItzYPX(IB$dYEA#$;yO5S3 zaD04xcxR^&00YC6Bl$%R+mAU6;`w=aIJB{;DQvDoDzPYF_9Ya!Xo7fIc4?L7vktGE6nnqS(`fElpw0=7e8ri__Q%z%|3 z$zz4tKW%*mv4@3LluaLIh9wV(c1UCgk^99d~8RUgiv5lXiAY$6|b6 zOu&4ujx_q@)p}VxrdF|hWYxb15QgCTsfh`=WjOO32M1f2pOvVnzo~^qSl=eVirrWH zSo71T1~m<}(e91!V7{`non3TbP!K5I0&Uj%%W+{-(*)9wR~EPI>}dc)+4$aGD4Qvx(0p(~>G1FnT}dqw+=5Ogqy1^brSoA+&hfI>{gLZ^@7{E1 zl4z^{=U=-@5JVUWM*Q5|+|0@f#pdQ_e0Cg}LtS0)hVBm{47u0WSJh}Ie|pk30kxTS zeX*lhq}OsY4-ZLLI5-FWx$mUTqX!3znpIcPHScpOt=nz6$p4(8|9Wp58DS9E=!83+ zmwP%_VA;Va7VJn|T-?ms8WWgy5idpJt%ZS!xqr$JH~1HPL({-p0-u1O|L~iPlvGHi zUYCBh_mdS;`D{@|1LCbWWr)x-($1%R5PwW`bT}@wWyvfZ85t*!<4r2KZ2dVHHiVL% zegFD>K+O6tpXqYm^?B#V3rP zX9w0RYDyRayl;Dh5U-fK-Z-Sw$s7WJL?T^Ch^Ptso%aHCw6v+X2qRA509W+w68Al{ zb3JO8{8tTJWbeVs`dhTkpLQ8hF|jV|hVdu0ZSU;SLvT5kQ{B;|YTnlRyPf2JT5Q3Y znZY5N!pcfreYZClT3qX*uM&Bcx~(&`wE8}~X06{2>s5f-UlI(D0HB*uhMM8D1`DbW zg8CXY`c!0jWLNaXM1mez;RPaKEi8v@=*S2>ZA`t{=`zQIPK0tgA(|?>B%Q;>h6rY7 zLQ)bHG<1OD%YzJ>@Y>a3kC>{C9)n%W3YyG(^P|ih+=@0N_R#Qf?KtU8NmYk}EP6TE zEew7tRl>PNMH2eH+X`TM4x@vELp`ynWg?AiII}^rSco7y}GpE=gQYl^(CH0MTYi6_yoXfx2b(o z0b3`@Mux{921`Heoz}knpa8Nk&f*Y~Px+klxIgr~7RTfWcq%?U!y@&_V(Vh{QdNN& zgS6^Ez3XdKVP9WyVxI@HGRV56l?4V8p9?=S_NDu&EHNU|6gNSRkG~6i`AjF$=Vlfb zEMCIEkSqn@9$4r}$;5tq4}gc??0zk&-DDkfiE<=v zsVyg0amhx`Dz=Uj+^rR)FQs{U+7oRWS-zXWkRL>yRe#l0-rcypg3@m)~o{fy?F;kT%tB(`{bL*YaIiE4n9hCg}-%%o!Q~(y~_Vx5t#OLKHGc1>qTq*k7gK-srqV!D7&j17X z)UWn*&WCmEJCK`{QdV8py-6)JrsUQpYSTZI`VlI&1WJkPstd;sU%KV*uDJ^NIp)I{ zStynC%7BsMZW z{xQHZ9ftYl%jQRd=6zI*@Y8)SJKs%5*Vi6(h|Z5tA|fIzmZ+jQT{1T#3%k212AqK^ z8XD0rmgjai3!(1L30iBdCVYvmQc>^o5zHNoVtr!9aAePLUGLBF5G1v-ZiLftbY!eO zHxBfVZ#nNz?+9Y-z83-KV+Jqh?-_(Vj`BWl*9Lf7&TBuLWbr1%w80|izs;~*;3_&m z8q5Xtluv(}VW3b&urHXO#{p+@a!N{b*TcJ5|8x}d8wb3iN3-+t+P!g76rOaw(% zFK;?llrjbZK?ARd__aCp(%#EvH8vwJ4@E{kJU)tGo*;?%wfAS6=hsOyX&?Pg9#<4^ zkHy#`6RrIW{p6-z-~uU#FfBH2S|$tu(GLr=!>kqeWVUAu>|!u7sslCS!wG)4C6XXhIi06SxHqeU*?FN1UGw|~{&{{3xzy(cpSon0kl zGq$;$Cbqxu^LXw>zPt*(Kx3gwiQt)~{$kG;Qyo5Z90B8e-(YK?ID=UGN$W+as0O9w zpW&AzKjOb5|TV*W^MfT*Fv?h!-v6NXs;VxL)aeg;NjTc|FOu_Y4MMR^N>j4^lrq zY(pQs%Ul5xosQ9{WiY|*LEV+22?ZHfn(a6?ZAC8XHla^;;$9$64WL=8ANp zI_}U)>zAncS+xFgs*^!!7fZ(Vsn}t<%JK+~6_b{3Iyyu9_KS9M|72J^ik0PQLeHfP zJPLerM^Ih-h65hdp|DJw8rQvyT5K1<@z0T47$Ry?b*BoC<`Pv=RL52`jP$oaG0r{7 z2sp~mwkzK=nQT)!$Q==I>_tMn6=rmKvMSPfZ}aj#fmHvygY$R-;vE5*5iWiS8-)`K)M za}ur9-mH@BTAJTmb@hWYx4sBz6E&3oP8@PrJfT_2d^H(e`C0Pvok$%Ftn}y1PxGek zNDenm5LHS4^t%1m#2y1c7XK8Ax!L64XsXYT1(cf zUP%NO$DAq6mq5q-uCDb5RMrk}hf6A2Dpg8w`_Az2@Eykb($nQ8#I)&pzhIJKiuT{g zdy9znein!wv44D?Z3~tcU8e-tf-0?%qCBw%dpM+`yJrtly^eL(*>>VFByp^t9-S$K zF|MIg)p0j64F}oHWg|i(KW-+0p_?@`QE!5fCN|}#;Ml#Wp-m@zb0{e#gF&aohJ*Tq zGBf>abo=w!iZTgD_ZY2Fvf)+Pwi|J5X_k&xdFyeBgU;F_?3BbjU+{HvNy&;EW$W4p zF`J1hi&ig#%&^CFo%O}vWMg5nLD^y0t zeY|$RTeQe}W)^uUNwRHO*tp=ZxTB!GXW-^0TAGVx736Zf+&Y&|bjsPK%MCks9bm#5 zNEM?~T!!H+GWuc3=~nlcEynorC=n9p4pkgG+rh!>gKz=3HbBPEq{y|D1QuU;ziys_>Y{zApnpGIom9 z{Es^(7=YV8cT*=YW=R~j0dVb~wUkwEwAJQ(Y>p23LK5eB-k~%zJ5$)%sW`eZmK2{! z{vow7B{@k(#-VN`ch8?ZT6?10sMqIWR;g$#mPf!5R#t#(k5zsGH9QyGj5zXfsQN6N z%-4`o$<9A$bpUTNLgr;}ah?8SAJ`VtNGMur&K23nP*IMy{8$J7Wu?)oVC1JcQ(LAW z7&P^5Z(O_eYo0Wx?JDU!I2lCxVh{WlQKRc+5C40eG8ki z8Uiy!5m2tMw} zwu$?fYNc)Az+rI;1Z=CSt}sErQedDFQkKDQ#-s1Y&u5dBI>VY_;GVDscE?H6Ly&Fv z+)0V#C+1bp-$9B=OGxsVsedjctFT@PDTFkgLhEhBlT6OQhj$DjGr8Wiq98R47d{jB zKUn%9sG?!!v9q1e`M4y7U5`h8@@D=*E84*`RM5`TmFzBEm7!ssKK$ge&x5y%5MfGdzm=rR@NC9 zm>D5&tqJQ896dRn_QioAuRzoW>!dJ zCe^;l@*MpH=3Ch2%Qa(*J_6K#KkujSWHm6wXJL`q=e}NcALZS`!xmJnaSxILb%Z&w z=k9yHO?~javdnIDi5Xt+R41QX)R%0RBkvQf;XC_V!t93*nxXV~GE>IxtP<+zW?v3@ z+b8%?{C1=>%MdnN)UwlakdwP1Roa@9VW-_k7O}a*^ z(y`HFyfGCxUfs||3S9VutcwSFr>l{R&XXyMp56J-4e_X-cdn=2BVK&pPwj(V9q|Qq zk?O#B?wmOA;ViJYBf@C|hRo<%%J)Xm4QmA3hqOC9 zIN0)=wpZ&jgo0C8Dg@Rkfvz%fQWL1m6xQGUe6=?`iRl z3q3xWQMkqIe*OzN;EP{uO8MaXx*#+Z#2^Qz4=Dw}PsKZOC*<(C_Jop>xVv?^b^IZy zclbm~IEu#W3?-Wuh*$FRWEl_{6FE|SB3-I4xvMHx@bWn8x8?V=+tsP};qJSYcEU-# z6VUhSzMx$`5*6*!@ep#3pq{J4rk)$Wbqf4BX6d1_$+xsM7zqM%l)%K|>68Vv_ zdW)BZeQ`f&Vx%k;jt6rbi?ujyI@dfMkBrfl|0vBICjCfh1N3N?IhuA^YBmyiuyvtV zpr0P#@>4WRBhd3ZrQ{DvLP`zV;X3EExL_9g>LYO}l=wLyRRmxO%l}s!V`*4-gADxF zFF{)eVTs_?F8rcN8FU|TRbr;>DDt$^3Ps7m_Peyy5v_L~@^+ePBRP8`{vl1( z9)ac57LHD$X!@qI3+u*O#nzF^nGY}$q4f1DOpF#wiRaR{n=U^X*zA)(b# zM%>f` zWd60?ahG1Z!My2`=QCckWbg3Hgo;rr@-f)I!z4_Kv1tM3xKSqBw_YriC!pUL#0$`s z(W!pF_Wz@!vnhw=C+`O?czK%FXSLExmd1K5N}qj+uQx z?>j z@kQ7HwrHa{*dyrmu6p&qn^8vlzcqYx1vh9M&NZj?ith`EN)HA>s|vTvlgcweS{I0; zQCKNs#6c{@;xbq%Gx7)<|Gtfule;hdm=_I-{REoMt0$v@4NqgS5>lms`|@nc9Ga>0 zp(O(M_(UI_W_F8)2^i=95_-Tmr#p}tCSHM;} z4hu~m8Ytux3`qU@;mn?PnFv|+9!CxWf|FK8Ttv;$nsC!$qXo@zk3FoIn+~vP8<4<0 z1J@M8uxLPzo-N7G&5W?4tT&s;qQ*?j&3DS_R7ZU_ZPepG%yCF8ytvl?v3JKG$!`ZP z(?Z#Tc{me2@N6IuHWXPL2T^Rw{}&Dh_cW=Wv^-3Jwi&#{K^mqwDz=_p>QpVChiIC+ z){tLpqrUvP)UeJN#8!So*=YSp-I#4d@tV(8|J5ci$Ry925h~9wY2uX)h@tR5PEcSM zI$WXGuU3`K(px9iL)?>XkA1Bx*6?&C|SL=s6TkBx!5grf2<;?iWi)3i=d$EL=_4wmqW;c}-|6yEo)_;FJOV$J7HS~zd)vo${{qXq>& zNRz~i6BwoveRt+rr>_*E5YY3v=_5(y>>nEPWAs3?jcmlxPR?-+WXTUvbaJXtOVr$e zN`}o1*uB~{X4%6YBn-zDC(Z?2vYv3~;3hp)T( zR}Bp?iyF~<+)A0ai0TIw{R~+jvNwxIcCd%J8UlKDG8`3(oX=GxnbKrp<1pTErAsQW zfh6={RAS13cxYyqy#E0k46e$Ff9o);5igBWuA&Gfj?feO*&f`M8Ak53Zx~F4u-QkZ zo;P+<3#h^`hO)4d7AEv{t1R><;Y?V{gsxuxy_@(mZXS%Pg;vOPvT2o4FlZ2{u}qVTQ35l;UkAIs~|tWDI2eZ zxUOf0oB=p3hF|tw2|)7lDL&z{mb&7rHH?O< z*AjU*0C5r+Oqnf{p3@Uxj?fVW4!#oP11_+F(qR6?HZ;BFS1&T3R@50F*Z| zhSAfUu}5HIC>)YTbv}>J?&)J;1_Y{(wU0}kyPQTE(R#toeT+(%9L7O~g@he4+F6e42hM|}V6rZtlzizU0y)4F zI>55@+aPtV_X%qAgc289FwA$3Fh>|UBrMKmL%x>~Q3W?p7+!IzQmBh8GFwWK=rk5e zS5CE`iq&BVE@o$&$Q#neJ!w=^ou0>wTkg$e@A%KkBK6N6gLO=C4rrVfBK?a!)icax zO|Ie}7H*|Q(&0`64xLxf6w}d0Bo1`=_*3vdKT{E(9>CRM1FoxYLeW_AIjs(IV)X+P zsElI1)XLMSiE7JiTBa!c5nLdLS;CBubiZZk>-6U((E`ON|3tSsK1jJcV@X)5!aZWB zZ?_9kSl#3tHYCEpg)!l$Ez4I?f?Jm4n1&%t$U79tlbZvE7E-7S05_fRed*h2 zZQtMTI-hx}879u4g?A(;d1(BBl#qLj;o*cd-F0mz)^`nbhqi~)T_NjJc#gJwQMT!O7EyH5f z61T-1$WITft%;6~&i9{%;qmuMdUz0be=O=#=5qs5V2C?AYhJ8!r5E*PhK{8i@4P%( zKZ5;-mE}O#*!sq+fryk?Tl9#9iTw0gx}Bfxg`+?|u-rsyVlI8MA(LduXcLA~kZxWo6D}Wp##r-OC9I z5YN>fc)ZD!8R&no;)1z@3*9*@B?#q0&0qD-#!7V>Z_IB~vT$FkA{f$Jf z1H4C(BbLeal^E1$fHCwt*qd`~5c!3qeFk32s*d;=8OO0N7h75K$=8DXtJiM)FcK&g zMYdzWkn|CzbM?kCD1AOi$09tV=|h=KHhy?Mkbl0#B?t#FN)Rh4q6{O!Iu2SAQ8YnyCQtNV?NnOr7K+4zqjQ ztHIqlsC;ON8A05oQ$-?Jtvk}^L1xHgHmA^Xuyui7EJ%EX-9bY}Q5tqolQ|~LNP^Uw z)?KX0f~mtmj1(2V^3tA#W3yJZMz1E?*{8}ta}+@KuktOI>l7t*<#Nndgl;)rq#mLC zyx1uzd?$rXgb_A1AG~qOq>YY&yNAkP(1-+azfJ@;;&{!2`HXZBVNz}SFqPh#U%h_3 zQ&v}ZcQ!kDx1&oc?$>rH5ke)}$B+irbhbz>OTmg*K1WU8oq*Z$K%cx`r;!9pc2 z0D2!}`r!P{#SqFwV|0|WEZskWkn5tYdwXKZM88o}uXO&`jId2t!R#l|WKmWbCmsUG4QY^d4VA>EE;N~vhFo%;uPI)?Rp?-lp1KYx7O&rwPGWQ9IF z-=EFLt}6*X>Iyz=U@pRQe(|k=Rrz*vu&~@>;I&!%?VI!P`P;dDUUMh_()k{tee&+K zhRhJS$_Lf>ysFUp?Odms2@fi`J3w?}B{h}9+ZQDm=c~%{I@kBK+=z>D#gXPJvviwD z&`jK>if(QAlT%7E&VWvmfa@8C0Vb?51v+-K<%Db$eDc@D@gJFmvH%;4%2=Fmvk9?R z$3`DzTh%36)c4Q&nZc^>r7WNS@Gn!71XMn>Oj(R5xs;5yVe4H}og77DbG$%; zfV{EXSn|u8nPyY1bGu;!-__ir!yJaNxlwDnIg*A7h{8TLV8FL zwAobgi(6~psHFjkRUDP!OT;UvzJgZ7&&N!v`~^9=%e(v&Cw0hh1>Yy50mM(oi^n<% z!n)4Goj_#0?zD$@oA*GQunciOZcmB}@>4^Ilw={%uFUJj+XxU)SmVhP zcR@*<(eyG-3BO*={h^D;Q}uHQ9OWNudS-0<d6V}Xd2vy zspbuDH)>mDvPl-K900=h)yX2%9UTxR;#CUcM}7TGJAPL$bdlQN0rbATd1`5FJdkSh zdHoq5s#Xvb6l6W8np|b3MZdd1Nu=GAc&x(?n8$$pJT0wZUT9&6F;?W_8o#aRRPcU} z8a<+b!Tvtt9T`Wqi zVxQN-^KJo+1%L!8)(!r1Cf`3%0I(~_W&8Htf%s{-I%y8^4A_iTZ5N`|nXN#T~N}qr~vqj#JWwOv| zwfv3F5k!cmp?(Wh@=JzwkX$)S8phxU^umS-q&H!r&LPU+cbelhGn*6Ft-c~*NkE_R z&^p_Zh79S<3Fnb|a0_%nI4h7=8tKNY7}Gk5YC!~R<|kLF>_8i({1(JPBoA4VwbL4w z%>BA0__Qs6Cp}?p=-QWb%(icdrNOd?2D8~fDO}cPLt*EJCo=aEnaPSGhRtU8h3Ldi zO)zTf8hP!75dDJzRmB5ggZ~5JoJ4zfOaO=cI?4SbVMU_CCi^wda=)~rgHUOuvD-ak zC@p;qxls|KUktT8e~X%d>z=QovxR?_hC)V-1;IvI+Q+8#g+!gMm zjS*LTI?e7BlTGMXA@@S6{)VQOT1>K)ZmP%wGeR$Y>jk5u*Xbg$Nm(#_r)vURO3MyE z*K=HnaT=W_7IwPc-!xU%)`GqY5|S{E#YCmN-}W*%mVRTOTw|~`*V9|O%2iySn3A-8%ys2xg$RTi;GYc66<9wvl|}H-n;NMS5b$fj{@~%y@cw^ITviRfS4f<6lH`ZUx97>YiviYoBD zu?(m~Vi$kQM%4JwXSmn>_PWjsEgm0${nO3F1Se)zYi`VS?bJ_!f0*=-MhhwJXE!JO z1+vE*=BBS``0YGQIQ@zzr-YIgb#}+kHZcrnA^+Hl<$to{=%zzOg< z0LE4lXW~hz_c$!th>ZFdnmaB%thRr=xhLOv``KR&cwEh?V-_kU!!`ah*OB{{H;xg_dPhdDZ27nQ~Pi zsNnD5?f$PF-j(7)x%w?ZdHDlA)dj8hzVP6zH13+uH>W(=NNtIU^nZL!2`qv`2>%)s zDn!r4xcP<@8VHlvi`?^ibAU(tdPdm^s#IE8guUeP z1Dh}gu1nG29m{G-m1bsUKOUFn<)H`Emr{$&8^@8>{^|3+%c|^!w0X7z?B_#S#I^qlW1L5JO$650c`mCI|&k71mhArWx zrXdaFyL0_%)P7=;##+ZY^-I==MagO^u3j)>TkYm6S+*&fQBD_T7w{AVDa? zTKtV+B*VU?OjhShj0UBKa>#R{^C#xDwW3W5T!sBRh|H%HuEeCGf&WvQ?g2{IFAMcJI2l%T#4GW!$*?yVc=K=i~k9a0Ll5b{a zxBJOBtX&SI6n_NnB3+Aen+x>|G%`9mBjRgjmUI%p8w#>POf5q7JEG;GQ-lxZp-nb6 zDG))EkpA)|!|Q2D^Xh5JK)p8%(2oIY#k&k;O<1d~qXT&P%9@Z6OIu^JOfF^pg+FiM zZTjll9}m-?yWRO-G%5#)sOXR=(a+CtJ5^lk ziNS-g;8s5&Co64oHLOcY9qli_TQFrA2^{6ij6T=pn@$N6w7x(0R?0U=zx}o1gMa(TA)GFusf&5s#!`)o}H=KBI z0qFX?U0JNS%At=68(7-+Dci7M-0lmGF?nWFE5DhifO>`kiMc>0<);5#mdPD}C^GZhWN z0!LRvL$o0t31$~^a%Fyqq$xGO;4bt{qpg@utmv-B-B={!A3X1aqS||E_3-_|6x7t8 z;n0Kd#DB1K8&c%;3-+aPe+lmHll;De+E*p?eDaCM^A1VY^*lkydmC9G#$nxZEJ{hb zx7$eLGzkPclud4KYLOEcZwxlNb_PH6A$Z7mp+?w+9-qgXPjHkxJcl?&-*#mSGW(tE zT6EO&UVI4o@knh?iPH6?c3Jn45B4u4s3v|c^YZv?B_`%8ONxu9e*5-KG>^A>od^yS zb%eL18m*jzyOtU>@cj`+{^NyfFgb*sCm}YX#lHC*^~4sCvASo^-`ay%)=Cg%@H~te zYZ`nX&wj!NzFl6AbF3X7Kq6)vpquH73+0YCff#bqcKySXlld>DNNA!)%4-cu4e#}f zh+RrVM5QxPT|UhG73*1Ov@hBZ6ui6$17f0IZN;~S*?WY|Fv95W%*vni9j8NYw2L zEf;~Ef0zm`T-Nmd3Hc$--wcS5*cJyX9x`*eQ)uc=EaXyERW)1yO2}Mgbl)7X5W#Ts z$$a3|7}y$EOM3EX!mqPdhGn!GS3n5%C?qizla%~PuZ~AKM#8Q!U9XLk-*Ok_(jOQq z?e0G2qD{&Q{o=mb`eGM_OaAEY{<)*Fs!E|aPN~sqRk)3nd@oxLR+W$;Do=P zaHkkN36=nFaltIr3G5D?JACZMe2M%(L5O0pgFK^aBbk}3_{a!u$` zX;l^r2_Z1r+4$mnjtr^cZ)V_o8Dx>zxYHynwyhq^HY_vPuSr}TxA+cP=`MwV*HiUR zTHsNeo+$A34X|#|to|*>``g30NwW~S|B!T8V^0jM&=f1v%oV4(Pb@s-pnXWc(A(xv zGZfBM9B&m#h7F)xgTTh5F*sKKT38Z;j&^**8&#-6amPTzMIe5hkCgkFmFC>>!rP5- zS&Sxta}gJ+yj}oy*9Ud zP2Bo=wL9tYGWNP56IZj_D+=sESz*w3MoNPr0$;obvF@q;sC&cc{;J&ruNxY^u{z#A7W#1h zS_C!M4-fVxy=lfnEr&~Qr&Ff);COVyh@$(vnFLF)-8*N{35jYi4t=x5F%n7`|Drt+ zY5<;~>mA)K8=L+yK%xmAo7Sc%wzT1f*B2rsCxyGOcW9m%35qi8MFli#(7EnFW0e># ze8jERw|$NsLu28&^dmEBD5l0Fi2Y5_;V$wu!q$rJv#*?9HGli0R0``5J;EL5+oYY>hq}BI_gsH^En4WVkxN=6_jZ#vrU*!0hBJFx`etqF-XAUiqWY2c9#i~T4 z6|Rqa*-pBW&nOidG?diR+fC+W{F+SfPq;Nkq=JZiu@+w^Px!g8u+=&{um4Cb+NEl= z6|29ECc%2g=#f@Jv2-_^16P>={v!ISO&aRzOadLRvXRuJU*ZZCr7URPIJcjM3|!7u zi!qJV5H7Dm79`ql^U^Pz)mF!QT>}B=Is2}KXiG7KU7Bi{vw{=*;N9?LcMRMEEj`1G z0pWZ5?c{T6CWA70;yPw|xU6ir`W!w8lM4AZO8G2iq|@8;2LJgXY?kdKOW@0|-#Q83 z?hzxJRwu=XV8;C~k54bve2wNBNu@i}yT2~z+9~G;LX-Lu?!2_yRF%)q|DlW0%(yZB z(fC8Tfq?Lmb3U$??~1bsB&H1JHasgCRG`wy z9>*H&AKaiG_(a@GMq9l|6l_95TBfSg3)~jt`9B5-SB~B7G}S+VTg^kH@TX!!h~|WX>wP>-7IfXb~-Fa0uD^}x8oLQ0}k)sDU}tCIgy-Bm`#v8-DlxZB_^2X}WEbOHwpOb9+W z0R{*X26u<{u3dW@ zpsTsiJScIc#zf!yfpNN;6BZX1AS`R_G0NpH(!$o*AZqr8j*iqHu*(cR_p6Ds7&FO+ zwbrQ!sP=XOnx=-SdG`(0rw2AYTN(`dR0!y}sHBx&OZZbx18f>g@Zi(=GIjA!b)V+~ z7iCOu?<~naEr(z)34^;6`yy$K)j8zeh_cP*#)|y%uZpNjp;uW4a^Z52D^1-OofOG< z>53^?1>FEzJR5s~V2$Y7VHfUwIbUVZjEsz`NU|XYj;b8SEMi?2a+Jz7E&BUqovjfSnWjPM`9PNg0ugs_k+|DfMzDp{-k9|bP{dyYw zhAoy6QF2N5+17UnsmVKKp?~g<9?LGto7T}0aH*J`8JSy{7q(ai8u4vZZE5x{?((D@ zdF#|d=n=4Ctpw6BsFm3&Oq0D&f?ZwTUZwKfGu!sw!$ae$dlj#3t;VGQAaMtO+Bv_5 zN+$Al$OOOI@qvqz6YxMg!<1AtD5cdC=Dry^C7dpt5T7^$!uVP2eRs`+?R;3Bky7}< z@dziZ6&2Ul#G5EQr}`X)=l{9dWRFA>>X{cN8?L6(Bpcl*%e=bSqV}Q6q5kRmecVOB zvh8v;{_agj@r^ZIE`Z~yO#KZZzc=7vnADG-)cPlg{R78$VvoRuWEK8JS+lWmZ?=Nu z$m2ZhDt3+Co1!0T(ZWtYH_kWbkfL=Jm6hPt)XkQPK(QXZ!eUolmNp>gAb+-9ioPvN zI5yX72@)YiMa%bmm@%8|t4P0uu;*+%GM1wzfm=qot8fNd(`D5ZV>SARmP)G2o3fpL zdb@d|L>CPo!=gv_(D6K04<*uKg+$|^M}3Sat#;H%|R6+=;ISUR?Pee9)BO-`V| zt1kh4!E!PZJhSz+sS8`T%Q^Iq6~m2@P`z^5AHJX=?$hzUKEcVKrQ}NFwoq~qhimRz zwF3j$;5My=Z@}(JC-ivhd%5P=gAoe;qJ?>>;K*Mvr${nP2pYUqgqa9#1C();22oww zsljOCn5KwR??2(ijB7u}_q3tcHzrZ7Vd#(L5)jJgZxS`+6yU^rT;{I;+1s_N%Hx)h zLD#V?&#&v?7Dy>_6)|^2f^cRHO8WbS;|-TL*r21+2w5^XJ(ohlg{-jgX*11l+VisH>ra zh_i&F(+_3RadCAZ`#tN_q|6pd`w|{uo{%<4pI|(@urP-R24UyUMUzugC*_7c9^wK# zNk%e&xY#}dc+zJ<>PF3 z>2m0LWqJkeoV0%Vv6>bG&WF(zyx9dS)6LU+$0f0ojOg&x!FUP|<{k2|^e|r_L=Gsa z4k<5^)ZNJ3EBKyPb^Yqor1_2w>7qa^(U?MWL z*54L&Wy;i-kKLtC*JdPWCUs$U`m{>Pnksu+fwb@allSP%SKh$J^ zbK9(rVyZs_(0$lSLYnG|6oaV3PDU2P)5Q727z2S_M#ff{p0XH2v)q3$kY||GMD5^0 zL}c+U@eq%^3N|`@5A878C$JJzpDB3IaBzWGvCYpnnog)ZBU9gljoF2i0rQlDY=r&? zFC#YbR>g;lYv0!P@aH}|np<3{>s#q2O*B{eB_#MU6ycVxFL8qk-t8ohy3Bv*{&m01L z-O}xJSe}9l=Mnm|vzG`%o7_upZegblR#;Qe19;hge?dS5BNMZ2RD^)O<}<|4-8~U@ zh;n(`A~f~XQfn8cWl8{jaZ2>;V!^1=tPb}CaK8h43n z!KOjO(|kLvz}DNPvD&r0vuz#a+V{>+&G-Cc7#q_AS&yOswV*{f=V=~db&Q1)a+|G6 zBa&=yH&_!%^k{2EdOvxfRl4vzEGfxT@Oz;!$(%vkTv675q2hi@CQVT62L@NoI-n%joO7hy~ zcwP@Z9WH6)NpstK<$>nzWob9S!zK5q6YwSE9Tcq55geVj>i_k48RT6|yV4f$)^)SP zAXfvL9f?-~Ic0F1wwjSIYMiV<_}T!HzZgrr*j?t4Pfk53S|Q0a=s@JkpRirifh7@< zQ%@}n)fav$tckN%5!v&@fcBQN3^abc!8ulgrzQEPg!U(V4QF9}5EyYq?T;Tpnawsa zdq2}>p5cU7l~?KOEn6`u2&!7ki_N9^yy7UcgdNFDa+dNQca!vl22N=fDm6cS9FL5U zx3x5kF~>-yWMX2o$8ECZv2Rt}m6wS$fIZ_0=8zx10imX|f9@>(wZX(BgDDLz>j-;9 zv&u)iKZWO*CTC>kVUv3&GqQ&%?Ug9KzkMGbudr$>UA$K=GEg7XAn5q|t1L8|wQmY7 z*OpIk$EtSP9E{+(51#T06cTil6rg9Mnb6w%;+o&PFP$*nt`yjfqRE0;dKJ|Hqz~NZ zO;(2WeLb3c^befkj0n=w?PM9VT}MZJO`NO>t%h4USnI+~lP?HQ9#IWkty2pBUwy_{E zFmlmuj;tytU6gaJCSJm>{Jg+}`5Lf`GNU0@9>&umi9Yyrq4tugwISG~|An%sNL@@d zV;lfm`~BsYr@KHOfpQ0=azD$vBrbuj(1PL+Yvo5xD=I3G9DUr)a&_u?C&{>I2dV8NX8mT>?}w6duThv%q_+k&x}%g9%& zhg$EOASNW;hk>pTdFP|Wc#z`pYos(Q-02uSb#OYrAh*)_B4g(gvjDyI*YwXxy$m~c zPzLV4I8i*C>23#UV7J?v!wpz=?fQE+{Wm@<2>h?F`LE{Fta9k0csFw64~v|HV{yII z@HJvW!S`#Tf(N~~-~p3}I1n@Q4lo4EB#bN0<0 z4Vxb)8@syTqFzq09a#=Z*CAImITol9` zMR&KC7(K>zR^J0F08hA`%gVhytWB=!t;}Npi&fXG5H;SI!QkPYw ze}@SF!l1v0bmc#9gjI@xF|9lf_*mg7kg|%z7h`E@H%y{9g^*sk=E%Zv@{GxbJ1#JtpfC!DaQ_@Fj560 z4Z|tgSkXHQef9=Xx*Asw_vm`7YPJvZNc z#=~9%iS9ohFqVHGiFwOCT1iAS4QH(=DDmcilPg2*SuW!1wjQuHC$vg21sRxZ#x$Ot z4Iq(b<|E8(VT&s(k8bBtawr`<95V69z)C3CrBfX1^SD{O^?3p|lM!8e%2i?A^Xj$g zKRj=TzCj=*9dM3z6g>J*ee{XtLSHOVtEygyBjOEk0N5N^K)=LanL9kF7OsPDXiV50 z-W;CFU78k+Nz@&Krw>Tgr$vVV$4zk3et`HJ8m?#`tu>0y6=UShleT)Ms8s)v6@7)c zW=zv(o!!OSe(qsCva>OyDAFs7$GVW33emb_9`4w9&bae1RQ7@{Q-gxy$uX?l7>c_! z|D}pfxri;|-A<~HT4Vg;x|T!gIw-P5kP3jjf94N?*v?2)xHPX175lFpYn-zitGiZH zYRYhrJCQ#^q}q_Z%M2fUIksP=bNu;eF)fo2VN1hk?`yH4KsT0&VUr{+;J&UnP>)`z z7Fus>EamdI4!JmF>%FAl%43vU-nh+x@dg%3()Sb^(3nRrdh2Z2QO>sa>QE0y5BQPn zvk9~nY`8s)XM4I1;CX(g5ReVjLvfN3YN20;8J^1h`1a5v^>E6M$>Zh0lqzL%^x=qAlUUzrcX4~%#e;qimN%83oopRxx7Znm(ZjftiJi`^-i`4yIurX_>GYCdp!2et@W1Z(me%!k3MaOGB*TVs;F<1}KBM=|u>{IK z!NvG-{kk+j$(R~Zfr_c%&}T3w*g{~&hwhY?Zg-*LU<@VQc>9!BNG_=q@`6kgk0*#B zgLf6Oae&t}1AXYk&N=800rC83znSMT%$J4eD@k4QZoo z3xcJHlR=pF4wb4h3l((-F4#CR27pyfU+AVFYl$Fdl9Qb6P}RF-CxP4frKMy-q{d3O z3m5jNWm>CGIUW>aAtYnEg00CN=N6hAMOs>=C7=W__tfJP|OWlQ7CITnN-PT%$u zLv#M9C@j7V{WeMHOTw@Kc3{22F~&9whTW0S&4dB(S513dB2zKf%H zF~kQasGCagTP-SAryaLrg#`#7cxR>xorR_ zhw^5AZldDQhm(UM7|PKoqw&*glLejKPiD@0e=Khf!{{|=6s9z%Z#Vvi)q-bmQ-n)@ zB$ku$@puV$bzFW`mOqChrUP%Wf7-6KxO9FWVFECgVBjTV~GB0!w z2T&s-?FcDFxr6bT6xC%GGx9P1GDR&SxiF-ZBL%}~@o{nW*J$3e2g<|w+1(CbXlp0b z7h+Xyb7KvX12o?7@YH)zjfz)4=WkYj;2`)D1``08nI&5V{oExCwn-S4MFolzZ zJBk#Lt@gh)0spr4`K=J3W39)%ib6-~e%ZwnI94T>m!k4ySMf?OgH+h@3j6j!TRm+X z2#H8kjJKkJ+-g*$-U^bEm8{DH1MDx(Oeq=@J5nD+y}Z6?%cc;=Y==jFs=$S&J#|u2&qGkvt)V>n#E8K0@Me8oK0_6H8D*R< zsjU~XYvxx%2g?96+})9c+KcIwUgj)LNc&`C%f`o9b{>8l>8U&jXXL zCG?J!vLM&xOt6Rb|M7OAtQRJ%y`P-noRb8;b&1>N|778b@v5bJ*oqd}JTikVOOmp1wqpsh*$L$3EP{QY~pF2uyt zBA@lwFeB3b2=6!4AjlD$sZdXfG!)JKqpA_l{WWa;phtveWsWQ>4r86=5=m*+RmCn_W z!pI2QqRTKg<<1@P({zf%&eONwb?cP^R@3;4;d7QpozQ|?m0SDUAl~ccO^~bqj+|&f z5Ew(buu-XrmyX_Q{O1IIsGjVWb7bmk&6W3mE7pJGCZx#fXIxJ3|F2v4NQL{Iuo!Ot mnzjD-2ABQh(f^l++=ukk^nL2|EP9THxYPCS?@c#nx8$}5K literal 0 HcmV?d00001 diff --git a/docs/user/monitoring/index.asciidoc b/docs/user/monitoring/index.asciidoc index ab773657073ba..514988792d214 100644 --- a/docs/user/monitoring/index.asciidoc +++ b/docs/user/monitoring/index.asciidoc @@ -2,6 +2,7 @@ include::xpack-monitoring.asciidoc[] include::beats-details.asciidoc[leveloffset=+1] include::cluster-alerts.asciidoc[leveloffset=+1] include::elasticsearch-details.asciidoc[leveloffset=+1] +include::kibana-alerts.asciidoc[leveloffset=+1] include::kibana-details.asciidoc[leveloffset=+1] include::logstash-details.asciidoc[leveloffset=+1] include::monitoring-troubleshooting.asciidoc[leveloffset=+1] diff --git a/docs/user/monitoring/kibana-alerts.asciidoc b/docs/user/monitoring/kibana-alerts.asciidoc new file mode 100644 index 0000000000000..1ac5c385f8ed5 --- /dev/null +++ b/docs/user/monitoring/kibana-alerts.asciidoc @@ -0,0 +1,36 @@ +[role="xpack"] +[[kibana-alerts]] += {kib} Alerts + +The {stack} {monitor-features} provide +<> out-of-the box to notify you of +potential issues in the {stack}. These alerts are preconfigured based on the +best practices recommended by Elastic. However, you can tailor them to meet your +specific needs. + +When you open *{stack-monitor-app}*, the preconfigured {kib} alerts are +created automatically. If you collect monitoring data from multiple clusters, +these alerts can search, detect, and notify on various conditions across the +clusters. The alerts are visible alongside your existing {watcher} cluster +alerts. You can view details about the alerts that are active and view health +and performance data for {es}, {ls}, and Beats in real time, as well as +analyze past performance. You can also modify active alerts. + +[role="screenshot"] +image::user/monitoring/images/monitoring-kibana-alerts.png["Kibana alerts in the Stack Monitoring app"] + +To review and modify all the available alerts, use +<> in *{stack-manage-app}*. + +[discrete] +[[kibana-alerts-cpu-threshold]] +== CPU threshold + +This alert is triggered when a node runs a consistently high CPU load. By +default, the trigger condition is set at 85% or more averaged over the last 5 +minutes. The alert is grouped across all the nodes of the cluster by running +checks on a schedule time of 1 minute with a re-notify internal of 1 day. + +NOTE: Some action types are subscription features, while others are free. +For a comparison of the Elastic subscription levels, see the alerting section of +the {subscriptions}[Subscriptions page]. From 9ef04e7fb21306456e182c4feb422bf09a7113a0 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Wed, 5 Aug 2020 15:28:03 -0700 Subject: [PATCH 026/106] Rename package configs SO to package policies (#74422) --- .../plugins/ingest_manager/common/constants/package_config.ts | 2 +- .../services/artifacts/manifest_manager/manifest_manager.ts | 2 +- x-pack/test/functional/es_archives/fleet/agents/mappings.json | 4 ++-- x-pack/test/functional/es_archives/lists/mappings.json | 4 ++-- .../es_archives/reporting/canvas_disallowed_url/mappings.json | 4 ++-- .../es_archives/export_rule/mappings.json | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/constants/package_config.ts b/x-pack/plugins/ingest_manager/common/constants/package_config.ts index e7d5ef67f7253..48fee967a3d3d 100644 --- a/x-pack/plugins/ingest_manager/common/constants/package_config.ts +++ b/x-pack/plugins/ingest_manager/common/constants/package_config.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export const PACKAGE_CONFIG_SAVED_OBJECT_TYPE = 'ingest-package-configs'; +export const PACKAGE_CONFIG_SAVED_OBJECT_TYPE = 'ingest-package-policies'; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts index c20aaed10f3f8..9d15b4464c191 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts @@ -237,7 +237,7 @@ export class ManifestManager { const { items, total } = await this.packageConfigService.list(this.savedObjectsClient, { page, perPage: 20, - kuery: 'ingest-package-configs.package.name:endpoint', + kuery: 'ingest-package-policies.package.name:endpoint', }); for (const packageConfig of items) { diff --git a/x-pack/test/functional/es_archives/fleet/agents/mappings.json b/x-pack/test/functional/es_archives/fleet/agents/mappings.json index acc32c3e2cbb5..23b404a53703f 100644 --- a/x-pack/test/functional/es_archives/fleet/agents/mappings.json +++ b/x-pack/test/functional/es_archives/fleet/agents/mappings.json @@ -28,7 +28,7 @@ "application_usage_transactional": "965839e75f809fefe04f92dc4d99722a", "action_task_params": "a9d49f184ee89641044be0ca2950fa3a", "fleet-agent-events": "3231653fafe4ef3196fe3b32ab774bf2", - "ingest-package-configs": "2346514df03316001d56ed4c8d46fa94", + "ingest-package-policies": "2346514df03316001d56ed4c8d46fa94", "apm-indices": "9bb9b2bf1fa636ed8619cbab5ce6a1dd", "inventory-view": "5299b67717e96502c77babf1c16fd4d3", "upgrade-assistant-reindex-operation": "296a89039fc4260292be36b1b005d8f2", @@ -1834,7 +1834,7 @@ } } }, - "ingest-package-configs": { + "ingest-package-policies": { "properties": { "config_id": { "type": "keyword" diff --git a/x-pack/test/functional/es_archives/lists/mappings.json b/x-pack/test/functional/es_archives/lists/mappings.json index 2fc1f1a3111a7..3b4d915cc1ca5 100644 --- a/x-pack/test/functional/es_archives/lists/mappings.json +++ b/x-pack/test/functional/es_archives/lists/mappings.json @@ -70,7 +70,7 @@ "maps-telemetry": "5ef305b18111b77789afefbd36b66171", "namespace": "2f4316de49999235636386fe51dc06c1", "cases-user-actions": "32277330ec6b721abe3b846cfd939a71", - "ingest-package-configs": "48e8bd97e488008e21c0b5a2367b83ad", + "ingest-package-policies": "48e8bd97e488008e21c0b5a2367b83ad", "timelion-sheet": "9a2a2748877c7a7b582fef201ab1d4cf", "siem-ui-timeline-pinned-event": "20638091112f0e14f0e443d512301c29", "config": "c63748b75f39d0c54de12d12c1ccbc20", @@ -1274,7 +1274,7 @@ } } }, - "ingest-package-configs": { + "ingest-package-policies": { "properties": { "config_id": { "type": "keyword" diff --git a/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json b/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json index 1fd338fbb0ffb..3519103d06814 100644 --- a/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json +++ b/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json @@ -39,7 +39,7 @@ "index-pattern": "66eccb05066c5a89924f48a9e9736499", "ingest-agent-policies": "9326f99c977fd2ef5ab24b6336a0675c", "ingest-outputs": "8aa988c376e65443fefc26f1075e93a3", - "ingest-package-configs": "48e8bd97e488008e21c0b5a2367b83ad", + "ingest-package-policies": "48e8bd97e488008e21c0b5a2367b83ad", "ingest_manager_settings": "012cf278ec84579495110bb827d1ed09", "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", "lens": "d33c68a69ff1e78c9888dedd2164ac22", @@ -1212,7 +1212,7 @@ } } }, - "ingest-package-configs": { + "ingest-package-policies": { "properties": { "config_id": { "type": "keyword" diff --git a/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json b/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json index dc92d23a618d3..bb63d29503663 100644 --- a/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json +++ b/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json @@ -41,7 +41,7 @@ "infrastructure-ui-source": "2b2809653635caf490c93f090502d04c", "ingest-agent-policies": "9326f99c977fd2ef5ab24b6336a0675c", "ingest-outputs": "8aa988c376e65443fefc26f1075e93a3", - "ingest-package-configs": "48e8bd97e488008e21c0b5a2367b83ad", + "ingest-package-policies": "48e8bd97e488008e21c0b5a2367b83ad", "ingest_manager_settings": "012cf278ec84579495110bb827d1ed09", "inventory-view": "88fc7e12fd1b45b6f0787323ce4f18d2", "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", @@ -1286,7 +1286,7 @@ } } }, - "ingest-package-configs": { + "ingest-package-policies": { "properties": { "config_id": { "type": "keyword" From 4ae6746c0bd5ffd34d70720b641506088d768840 Mon Sep 17 00:00:00 2001 From: Kevin Logan <56395104+kevinlog@users.noreply.github.com> Date: Wed, 5 Aug 2020 18:32:22 -0400 Subject: [PATCH 027/106] [SECURITY_SOLUTION] add z-index to get over nav bar (#74427) --- .../management/pages/endpoint_hosts/view/details/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx index b22ff406a1605..69dabeeb616a0 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx @@ -70,7 +70,12 @@ export const HostDetailsFlyout = memo(() => { }, [error, toasts]); return ( - +

    From dfad75ff1a9e9849c413dfe665229c7f7405d5c6 Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Wed, 5 Aug 2020 18:46:56 -0400 Subject: [PATCH 028/106] [Security Solution][Test] Enzyme test for related events button (#74411) Co-authored-by: Elastic Machine --- .../mocks/one_ancestor_two_children.ts | 46 +++++++++----- .../resolver/store/mocks/related_event.ts | 36 +++++++++++ .../resolver/store/mocks/resolver_tree.ts | 53 ++++++++++++++++ .../test_utilities/simulator/index.tsx | 22 +++++++ .../resolver/view/clickthrough.test.tsx | 62 +++++++++++++++++-- .../public/resolver/view/submenu.tsx | 1 + 6 files changed, 198 insertions(+), 22 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/resolver/store/mocks/related_event.ts diff --git a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/one_ancestor_two_children.ts b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/one_ancestor_two_children.ts index be0bc1b812a0b..94c176d343d17 100644 --- a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/one_ancestor_two_children.ts +++ b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/one_ancestor_two_children.ts @@ -10,7 +10,10 @@ import { ResolverEntityIndex, } from '../../../../common/endpoint/types'; import { mockEndpointEvent } from '../../store/mocks/endpoint_event'; -import { mockTreeWithNoAncestorsAnd2Children } from '../../store/mocks/resolver_tree'; +import { + mockTreeWithNoAncestorsAnd2Children, + withRelatedEventsOnOrigin, +} from '../../store/mocks/resolver_tree'; import { DataAccessLayer } from '../../types'; interface Metadata { @@ -40,11 +43,24 @@ interface Metadata { /** * A simple mock dataAccessLayer possible that returns a tree with 0 ancestors and 2 direct children. 1 related event is returned. The parameter to `entities` is ignored. */ -export function oneAncestorTwoChildren(): { dataAccessLayer: DataAccessLayer; metadata: Metadata } { +export function oneAncestorTwoChildren( + { withRelatedEvents }: { withRelatedEvents: Iterable<[string, string]> | null } = { + withRelatedEvents: null, + } +): { dataAccessLayer: DataAccessLayer; metadata: Metadata } { const metadata: Metadata = { databaseDocumentID: '_id', entityIDs: { origin: 'origin', firstChild: 'firstChild', secondChild: 'secondChild' }, }; + const baseTree = mockTreeWithNoAncestorsAnd2Children({ + originID: metadata.entityIDs.origin, + firstChildID: metadata.entityIDs.firstChild, + secondChildID: metadata.entityIDs.secondChild, + }); + const composedTree = withRelatedEvents + ? withRelatedEventsOnOrigin(baseTree, withRelatedEvents) + : baseTree; + return { metadata, dataAccessLayer: { @@ -54,13 +70,17 @@ export function oneAncestorTwoChildren(): { dataAccessLayer: DataAccessLayer; me relatedEvents(entityID: string): Promise { return Promise.resolve({ entityID, - events: [ - mockEndpointEvent({ - entityID, - name: 'event', - timestamp: 0, - }), - ], + events: + /* Respond with the mocked related events when the origin's related events are fetched*/ withRelatedEvents && + entityID === metadata.entityIDs.origin + ? composedTree.relatedEvents.events + : [ + mockEndpointEvent({ + entityID, + name: 'event', + timestamp: 0, + }), + ], nextEvent: null, }); }, @@ -69,13 +89,7 @@ export function oneAncestorTwoChildren(): { dataAccessLayer: DataAccessLayer; me * Fetch a ResolverTree for a entityID */ resolverTree(): Promise { - return Promise.resolve( - mockTreeWithNoAncestorsAnd2Children({ - originID: metadata.entityIDs.origin, - firstChildID: metadata.entityIDs.firstChild, - secondChildID: metadata.entityIDs.secondChild, - }) - ); + return Promise.resolve(composedTree); }, /** diff --git a/x-pack/plugins/security_solution/public/resolver/store/mocks/related_event.ts b/x-pack/plugins/security_solution/public/resolver/store/mocks/related_event.ts new file mode 100644 index 0000000000000..1e0c460a3a711 --- /dev/null +++ b/x-pack/plugins/security_solution/public/resolver/store/mocks/related_event.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { EndpointEvent } from '../../../../common/endpoint/types'; + +/** + * Simple mock related event. + */ +export function mockRelatedEvent({ + entityID, + timestamp, + category, + type, + id, +}: { + entityID: string; + timestamp: number; + category: string; + type: string; + id?: string; +}): EndpointEvent { + return { + '@timestamp': timestamp, + event: { + kind: 'event', + type, + category, + id: id ?? 'xyz', + }, + process: { + entity_id: entityID, + }, + } as EndpointEvent; +} diff --git a/x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts b/x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts index 6a8ab61ccf9b6..21d0309501aa8 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts @@ -5,6 +5,7 @@ */ import { mockEndpointEvent } from './endpoint_event'; +import { mockRelatedEvent } from './related_event'; import { ResolverTree, ResolverEvent } from '../../../../common/endpoint/types'; export function mockTreeWith2AncestorsAndNoChildren({ @@ -109,6 +110,58 @@ export function mockTreeWithAllProcessesTerminated({ } as unknown) as ResolverTree; } +/** + * A valid category for a related event. E.g. "registry", "network", "file" + */ +type RelatedEventCategory = string; +/** + * A valid type for a related event. E.g. "start", "end", "access" + */ +type RelatedEventType = string; + +/** + * Add/replace related event info (on origin node) for any mock ResolverTree + * + * @param treeToAddRelatedEventsTo the ResolverTree to modify + * @param relatedEventsToAddByCategoryAndType Iterable of `[category, type]` pairs describing related events. e.g. [['dns','info'],['registry','access']] + */ +export function withRelatedEventsOnOrigin( + treeToAddRelatedEventsTo: ResolverTree, + relatedEventsToAddByCategoryAndType: Iterable<[RelatedEventCategory, RelatedEventType]> +): ResolverTree { + const events = []; + const byCategory: Record = {}; + const stats = { + totalAlerts: 0, + events: { + total: 0, + byCategory, + }, + }; + for (const [category, type] of relatedEventsToAddByCategoryAndType) { + events.push( + mockRelatedEvent({ + entityID: treeToAddRelatedEventsTo.entityID, + timestamp: 1, + category, + type, + }) + ); + stats.events.total++; + stats.events.byCategory[category] = stats.events.byCategory[category] + ? stats.events.byCategory[category] + 1 + : 1; + } + return { + ...treeToAddRelatedEventsTo, + stats, + relatedEvents: { + events, + nextEvent: null, + }, + }; +} + export function mockTreeWithNoAncestorsAnd2Children({ originID, firstChildID, diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index 2a2354921a3d4..ed30643ed871e 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -220,6 +220,28 @@ export class Simulator { ); } + /** + * Dump all contents of the outer ReactWrapper (to be `console.log`ged as appropriate) + * This will include both DOM (div, span, etc.) and React/JSX (MyComponent, MyGrid, etc.) + */ + public debugWrapper() { + return this.wrapper.debug(); + } + + /** + * Return an Enzyme ReactWrapper that includes the Related Events host button for a given process node + * + * @param entityID The entity ID of the proocess node to select in + */ + public processNodeRelatedEventButton(entityID: string): ReactWrapper { + return this.processNodeElements({ entityID }).findWhere( + (wrapper) => + // Filter out React components + typeof wrapper.type() === 'string' && + wrapper.prop('data-test-subj') === 'resolver:submenu:button' + ); + } + /** * Return the selected node query string values. */ diff --git a/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx index f339d128944cc..c819491dd28f0 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx @@ -9,14 +9,14 @@ import { Simulator } from '../test_utilities/simulator'; // Extend jest with a custom matcher import '../test_utilities/extend_jest'; -describe('Resolver, when analyzing a tree that has 1 ancestor and 2 children', () => { - let simulator: Simulator; - let databaseDocumentID: string; - let entityIDs: { origin: string; firstChild: string; secondChild: string }; +let simulator: Simulator; +let databaseDocumentID: string; +let entityIDs: { origin: string; firstChild: string; secondChild: string }; - // the resolver component instance ID, used by the react code to distinguish piece of global state from those used by other resolver instances - const resolverComponentInstanceID = 'resolverComponentInstanceID'; +// the resolver component instance ID, used by the react code to distinguish piece of global state from those used by other resolver instances +const resolverComponentInstanceID = 'resolverComponentInstanceID'; +describe('Resolver, when analyzing a tree that has 1 ancestor and 2 children', () => { beforeEach(async () => { // create a mock data access layer const { metadata: dataAccessLayerMetadata, dataAccessLayer } = oneAncestorTwoChildren(); @@ -79,6 +79,7 @@ describe('Resolver, when analyzing a tree that has 1 ancestor and 2 children', ( simulator .processNodeElements({ entityID: entityIDs.secondChild }) .find('button') + .first() .simulate('click'); }); it('should render the second child node as selected, and the first child not as not selected, and the query string should indicate that the second child is selected', async () => { @@ -107,3 +108,52 @@ describe('Resolver, when analyzing a tree that has 1 ancestor and 2 children', ( }); }); }); + +describe('Resolver, when analyzing a tree that has some related events', () => { + beforeEach(async () => { + // create a mock data access layer with related events + const { metadata: dataAccessLayerMetadata, dataAccessLayer } = oneAncestorTwoChildren({ + withRelatedEvents: [ + ['registry', 'access'], + ['registry', 'access'], + ], + }); + + // save a reference to the entity IDs exposed by the mock data layer + entityIDs = dataAccessLayerMetadata.entityIDs; + + // save a reference to the `_id` supported by the mock data layer + databaseDocumentID = dataAccessLayerMetadata.databaseDocumentID; + + // create a resolver simulator, using the data access layer and an arbitrary component instance ID + simulator = new Simulator({ databaseDocumentID, dataAccessLayer, resolverComponentInstanceID }); + }); + + describe('when it has loaded', () => { + beforeEach(async () => { + await expect( + simulator.mapStateTransitions(() => ({ + graphElements: simulator.graphElement().length, + graphLoadingElements: simulator.graphLoadingElement().length, + graphErrorElements: simulator.graphErrorElement().length, + originNode: simulator.processNodeElements({ entityID: entityIDs.origin }).length, + })) + ).toYieldEqualTo({ + graphElements: 1, + graphLoadingElements: 0, + graphErrorElements: 0, + originNode: 1, + }); + }); + + it('should render a related events button', async () => { + await expect( + simulator.mapStateTransitions(() => ({ + relatedEventButtons: simulator.processNodeRelatedEventButton(entityIDs.origin).length, + })) + ).toYieldEqualTo({ + relatedEventButtons: 1, + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx index 6a9ab184e9bab..7f0ba244146fd 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx @@ -233,6 +233,7 @@ const NodeSubMenuComponents = React.memo( iconType={menuIsOpen ? 'arrowUp' : 'arrowDown'} iconSide="right" tabIndex={-1} + data-test-subj="resolver:submenu:button" > {count ? : ''} {menuTitle} From f5c9aa8860f813b88d910370e735a22ab988e688 Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Wed, 5 Aug 2020 18:55:23 -0500 Subject: [PATCH 029/106] Filter out non-security jobs when collecting Detections telemetry (#74456) Our jobs summary call returns all installed jobs regardless of group; passing groups as jobIds does not perform group filtering. This adds a helper predicate function on which to filter these results, and updates tests accordingly. --- .../security_solution/common/constants.ts | 7 +++++ .../machine_learning/is_security_job.test.ts | 30 +++++++++++++++++++ .../machine_learning/is_security_job.ts | 11 +++++++ .../usage/detections/detections.mocks.ts | 15 +++++++++- .../usage/detections/detections_helpers.ts | 7 ++--- 5 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/security_solution/common/machine_learning/is_security_job.test.ts create mode 100644 x-pack/plugins/security_solution/common/machine_learning/is_security_job.ts diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index c74cf888a2db6..0fc42895050a5 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -140,6 +140,13 @@ export const UNAUTHENTICATED_USER = 'Unauthenticated'; */ export const MINIMUM_ML_LICENSE = 'platinum'; +/* + Machine Learning constants + */ +export const ML_GROUP_ID = 'security'; +export const LEGACY_ML_GROUP_ID = 'siem'; +export const ML_GROUP_IDS = [ML_GROUP_ID, LEGACY_ML_GROUP_ID]; + /* Rule notifications options */ diff --git a/x-pack/plugins/security_solution/common/machine_learning/is_security_job.test.ts b/x-pack/plugins/security_solution/common/machine_learning/is_security_job.test.ts new file mode 100644 index 0000000000000..abb0c790584af --- /dev/null +++ b/x-pack/plugins/security_solution/common/machine_learning/is_security_job.test.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { MlSummaryJob } from '../../../ml/common/types/anomaly_detection_jobs'; +import { isSecurityJob } from './is_security_job'; + +describe('isSecurityJob', () => { + it('counts a job with a group of "siem"', () => { + const job = { groups: ['siem', 'other'] } as MlSummaryJob; + expect(isSecurityJob(job)).toEqual(true); + }); + + it('counts a job with a group of "security"', () => { + const job = { groups: ['security', 'other'] } as MlSummaryJob; + expect(isSecurityJob(job)).toEqual(true); + }); + + it('counts a job in both "security" and "siem"', () => { + const job = { groups: ['siem', 'security'] } as MlSummaryJob; + expect(isSecurityJob(job)).toEqual(true); + }); + + it('does not count a job in a related group', () => { + const job = { groups: ['auditbeat', 'process'] } as MlSummaryJob; + expect(isSecurityJob(job)).toEqual(false); + }); +}); diff --git a/x-pack/plugins/security_solution/common/machine_learning/is_security_job.ts b/x-pack/plugins/security_solution/common/machine_learning/is_security_job.ts new file mode 100644 index 0000000000000..43cfa4ad59964 --- /dev/null +++ b/x-pack/plugins/security_solution/common/machine_learning/is_security_job.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { MlSummaryJob } from '../../../ml/common/types/anomaly_detection_jobs'; +import { ML_GROUP_IDS } from '../constants'; + +export const isSecurityJob = (job: MlSummaryJob): boolean => + job.groups.some((group) => ML_GROUP_IDS.includes(group)); diff --git a/x-pack/plugins/security_solution/server/usage/detections/detections.mocks.ts b/x-pack/plugins/security_solution/server/usage/detections/detections.mocks.ts index e59b1092978da..7afc185ae07fd 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/detections.mocks.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/detections.mocks.ts @@ -41,7 +41,7 @@ export const getMockJobSummaryResponse = () => [ { id: 'other_job', description: 'a job that is custom', - groups: ['auditbeat', 'process'], + groups: ['auditbeat', 'process', 'security'], processed_record_count: 0, memory_status: 'ok', jobState: 'closed', @@ -54,6 +54,19 @@ export const getMockJobSummaryResponse = () => [ { id: 'another_job', description: 'another job that is custom', + groups: ['auditbeat', 'process', 'security'], + processed_record_count: 0, + memory_status: 'ok', + jobState: 'opened', + hasDatafeed: true, + datafeedId: 'datafeed-another', + datafeedIndices: ['auditbeat-*'], + datafeedState: 'started', + isSingleMetricViewerJob: true, + }, + { + id: 'irrelevant_job', + description: 'a non-security job', groups: ['auditbeat', 'process'], processed_record_count: 0, memory_status: 'ok', diff --git a/x-pack/plugins/security_solution/server/usage/detections/detections_helpers.ts b/x-pack/plugins/security_solution/server/usage/detections/detections_helpers.ts index 80a9dba26df8e..a6d4dc7a38e14 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/detections_helpers.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/detections_helpers.ts @@ -15,6 +15,7 @@ import { MlPluginSetup } from '../../../../ml/server'; import { SIGNALS_ID, INTERNAL_IMMUTABLE_KEY } from '../../../common/constants'; import { DetectionRulesUsage, MlJobsUsage } from './index'; import { isJobStarted } from '../../../common/machine_learning/helpers'; +import { isSecurityJob } from '../../../common/machine_learning/is_security_job'; interface DetectionsMetric { isElastic: boolean; @@ -182,11 +183,9 @@ export const getMlJobsUsage = async (ml: MlPluginSetup | undefined): Promise module.jobs); - const jobs = await ml - .jobServiceProvider(internalMlClient, fakeRequest) - .jobsSummary(['siem', 'security']); + const jobs = await ml.jobServiceProvider(internalMlClient, fakeRequest).jobsSummary(); - jobsUsage = jobs.reduce((usage, job) => { + jobsUsage = jobs.filter(isSecurityJob).reduce((usage, job) => { const isElastic = moduleJobs.some((moduleJob) => moduleJob.id === job.id); const isEnabled = isJobStarted(job.jobState, job.datafeedState); From aa75f80afd853960ace1cf2b2e526395635828dd Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Thu, 6 Aug 2020 08:07:19 +0200 Subject: [PATCH 030/106] Skip "space with index pattern management disabled" functional test for cloud env (#74073) * Skipped due to occasional flakiness in cloud env, cause by ingest management tests --- .../apps/discover/feature_controls/discover_spaces.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_spaces.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_spaces.ts index 767dad74c23d7..f8dc2f3b0aeb8 100644 --- a/x-pack/test/functional/apps/discover/feature_controls/discover_spaces.ts +++ b/x-pack/test/functional/apps/discover/feature_controls/discover_spaces.ts @@ -137,7 +137,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); }); - describe('space with index pattern management disabled', () => { + describe('space with index pattern management disabled', function () { + // unskipped because of flakiness in cloud, caused be ingest management tests + // should be unskipped when https://github.com/elastic/kibana/issues/74353 was resolved + this.tags(['skipCloud']); before(async () => { await spacesService.create({ id: 'custom_space_no_index_patterns', From 626fbc294857a565afdd19dbd7262b7452e3ca7f Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 6 Aug 2020 10:10:09 +0200 Subject: [PATCH 031/106] [Lens] Clean and inline disabling of react-hooks/exhaustive-deps eslint rule (#70010) --- .eslintrc.js | 6 - x-pack/plugins/lens/public/app_plugin/app.tsx | 114 +++++----- .../datatable_visualization/expression.tsx | 5 +- .../debounced_component.tsx | 8 +- .../config_panel/config_panel.tsx | 12 +- .../editor_frame/data_panel_wrapper.tsx | 7 +- .../editor_frame/editor_frame.tsx | 210 ++++++++++-------- .../editor_frame/suggestion_panel.tsx | 4 +- .../workspace_panel/chart_switch.tsx | 1 + .../workspace_panel/workspace_panel.tsx | 96 ++++---- .../indexpattern_datasource/datapanel.tsx | 11 +- .../dimension_panel/field_select.tsx | 4 +- x-pack/plugins/lens/public/loader.tsx | 44 ++-- .../xy_visualization/xy_config_panel.tsx | 2 +- .../public/xy_visualization/xy_expression.tsx | 2 +- 15 files changed, 285 insertions(+), 241 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index b3d29c9866411..5a03552ba3a51 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -132,12 +132,6 @@ module.exports = { 'react-hooks/rules-of-hooks': 'off', }, }, - { - files: ['x-pack/plugins/lens/**/*.{js,mjs,ts,tsx}'], - rules: { - 'react-hooks/exhaustive-deps': 'off', - }, - }, { files: ['x-pack/plugins/ml/**/*.{js,mjs,ts,tsx}'], rules: { diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index ab4c4820315ac..4a8694862642b 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -163,7 +163,13 @@ export function App({ filterSubscription.unsubscribe(); timeSubscription.unsubscribe(); }; - }, [data.query.filterManager, data.query.timefilter.timefilter]); + }, [ + data.query.filterManager, + data.query.timefilter.timefilter, + core.uiSettings, + data.query, + history, + ]); useEffect(() => { onAppLeave((actions) => { @@ -210,57 +216,61 @@ export function App({ ]); }, [core.application, core.chrome, core.http.basePath, state.persistedDoc]); - useEffect(() => { - if (docId && (!state.persistedDoc || state.persistedDoc.id !== docId)) { - setState((s) => ({ ...s, isLoading: true })); - docStorage - .load(docId) - .then((doc) => { - getAllIndexPatterns( - doc.state.datasourceMetaData.filterableIndexPatterns, - data.indexPatterns, - core.notifications - ) - .then((indexPatterns) => { - // Don't overwrite any pinned filters - data.query.filterManager.setAppFilters(doc.state.filters); - setState((s) => ({ - ...s, - isLoading: false, - persistedDoc: doc, - lastKnownDoc: doc, - query: doc.state.query, - indexPatternsForTopNav: indexPatterns, - })); - }) - .catch(() => { - setState((s) => ({ ...s, isLoading: false })); - - redirectTo(); - }); - }) - .catch(() => { - setState((s) => ({ ...s, isLoading: false })); - - core.notifications.toasts.addDanger( - i18n.translate('xpack.lens.app.docLoadingError', { - defaultMessage: 'Error loading saved document', - }) - ); - - redirectTo(); - }); - } - }, [ - core.notifications, - data.indexPatterns, - data.query.filterManager, - docId, - // TODO: These dependencies are changing too often - // docStorage, - // redirectTo, - // state.persistedDoc, - ]); + useEffect( + () => { + if (docId && (!state.persistedDoc || state.persistedDoc.id !== docId)) { + setState((s) => ({ ...s, isLoading: true })); + docStorage + .load(docId) + .then((doc) => { + getAllIndexPatterns( + doc.state.datasourceMetaData.filterableIndexPatterns, + data.indexPatterns, + core.notifications + ) + .then((indexPatterns) => { + // Don't overwrite any pinned filters + data.query.filterManager.setAppFilters(doc.state.filters); + setState((s) => ({ + ...s, + isLoading: false, + persistedDoc: doc, + lastKnownDoc: doc, + query: doc.state.query, + indexPatternsForTopNav: indexPatterns, + })); + }) + .catch(() => { + setState((s) => ({ ...s, isLoading: false })); + + redirectTo(); + }); + }) + .catch(() => { + setState((s) => ({ ...s, isLoading: false })); + + core.notifications.toasts.addDanger( + i18n.translate('xpack.lens.app.docLoadingError', { + defaultMessage: 'Error loading saved document', + }) + ); + + redirectTo(); + }); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + core.notifications, + data.indexPatterns, + data.query.filterManager, + docId, + // TODO: These dependencies are changing too often + // docStorage, + // redirectTo, + // state.persistedDoc, + ] + ); const runSave = async ( saveProps: Omit & { diff --git a/x-pack/plugins/lens/public/datatable_visualization/expression.tsx b/x-pack/plugins/lens/public/datatable_visualization/expression.tsx index 143bec227ebee..02186ecf09b4b 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/expression.tsx @@ -160,6 +160,7 @@ export function DatatableComponent(props: DatatableRenderProps) { formatters[column.id] = props.formatFactory(column.formatHint); }); + const { onClickValue } = props; const handleFilterClick = useMemo( () => (field: string, value: unknown, colIndex: number, negate: boolean = false) => { const col = firstTable.columns[colIndex]; @@ -180,9 +181,9 @@ export function DatatableComponent(props: DatatableRenderProps) { ], timeFieldName, }; - props.onClickValue(desanitizeFilterContext(data)); + onClickValue(desanitizeFilterContext(data)); }, - [firstTable] + [firstTable, onClickValue] ); const bucketColumns = firstTable.columns diff --git a/x-pack/plugins/lens/public/debounced_component/debounced_component.tsx b/x-pack/plugins/lens/public/debounced_component/debounced_component.tsx index 08f55850b119e..0e148798cdf75 100644 --- a/x-pack/plugins/lens/public/debounced_component/debounced_component.tsx +++ b/x-pack/plugins/lens/public/debounced_component/debounced_component.tsx @@ -17,13 +17,11 @@ export function debouncedComponent(component: FunctionComponent, return (props: TProps) => { const [cachedProps, setCachedProps] = useState(props); - const debouncePropsChange = debounce(setCachedProps, delay); - const delayRender = useMemo(() => debouncePropsChange, []); + const debouncePropsChange = useMemo(() => debounce(setCachedProps, delay), [setCachedProps]); // cancel debounced prop change if component has been unmounted in the meantime - useEffect(() => () => debouncePropsChange.cancel(), []); - - delayRender(props); + useEffect(() => () => debouncePropsChange.cancel(), [debouncePropsChange]); + debouncePropsChange(props); return React.createElement(MemoizedComponent, cachedProps); }; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index 73126b814f256..5f041a8d8562f 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -39,29 +39,29 @@ function LayerPanels( } = props; const setVisualizationState = useMemo( () => (newState: unknown) => { - props.dispatch({ + dispatch({ type: 'UPDATE_VISUALIZATION_STATE', visualizationId: activeVisualization.id, newState, clearStagedPreview: false, }); }, - [props.dispatch, activeVisualization] + [dispatch, activeVisualization] ); const updateDatasource = useMemo( () => (datasourceId: string, newState: unknown) => { - props.dispatch({ + dispatch({ type: 'UPDATE_DATASOURCE_STATE', updater: () => newState, datasourceId, clearStagedPreview: false, }); }, - [props.dispatch] + [dispatch] ); const updateAll = useMemo( () => (datasourceId: string, newDatasourceState: unknown, newVisualizationState: unknown) => { - props.dispatch({ + dispatch({ type: 'UPDATE_STATE', subType: 'UPDATE_ALL_STATES', updater: (prevState) => { @@ -83,7 +83,7 @@ function LayerPanels( }, }); }, - [props.dispatch] + [dispatch] ); const layerIds = activeVisualization.getLayerIds(visualizationState); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx index 0f74abe97c418..5a92f7b5ed524 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx @@ -27,16 +27,17 @@ interface DataPanelWrapperProps { } export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => { + const { dispatch, activeDatasource } = props; const setDatasourceState: StateSetter = useMemo( () => (updater) => { - props.dispatch({ + dispatch({ type: 'UPDATE_DATASOURCE_STATE', updater, - datasourceId: props.activeDatasource!, + datasourceId: activeDatasource!, clearStagedPreview: true, }); }, - [props.dispatch, props.activeDatasource] + [dispatch, activeDatasource] ); const datasourceProps: DatasourceDataPanelProps = { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx index bcceb1222ce03..48a3511a8f359 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx @@ -62,34 +62,38 @@ export function EditorFrame(props: EditorFrameProps) { ); // Initialize current datasource and all active datasources - useEffect(() => { - // prevents executing dispatch on unmounted component - let isUnmounted = false; - if (!allLoaded) { - Object.entries(props.datasourceMap).forEach(([datasourceId, datasource]) => { - if ( - state.datasourceStates[datasourceId] && - state.datasourceStates[datasourceId].isLoading - ) { - datasource - .initialize(state.datasourceStates[datasourceId].state || undefined) - .then((datasourceState) => { - if (!isUnmounted) { - dispatch({ - type: 'UPDATE_DATASOURCE_STATE', - updater: datasourceState, - datasourceId, - }); - } - }) - .catch(onError); - } - }); - } - return () => { - isUnmounted = true; - }; - }, [allLoaded]); + useEffect( + () => { + // prevents executing dispatch on unmounted component + let isUnmounted = false; + if (!allLoaded) { + Object.entries(props.datasourceMap).forEach(([datasourceId, datasource]) => { + if ( + state.datasourceStates[datasourceId] && + state.datasourceStates[datasourceId].isLoading + ) { + datasource + .initialize(state.datasourceStates[datasourceId].state || undefined) + .then((datasourceState) => { + if (!isUnmounted) { + dispatch({ + type: 'UPDATE_DATASOURCE_STATE', + updater: datasourceState, + datasourceId, + }); + } + }) + .catch(onError); + } + }); + } + return () => { + isUnmounted = true; + }; + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [allLoaded, onError] + ); const datasourceLayers: Record = {}; Object.keys(props.datasourceMap) @@ -156,83 +160,95 @@ export function EditorFrame(props: EditorFrameProps) { }, }; - useEffect(() => { - if (props.doc) { - dispatch({ - type: 'VISUALIZATION_LOADED', - doc: props.doc, - }); - } else { - dispatch({ - type: 'RESET', - state: getInitialState(props), - }); - } - }, [props.doc]); + useEffect( + () => { + if (props.doc) { + dispatch({ + type: 'VISUALIZATION_LOADED', + doc: props.doc, + }); + } else { + dispatch({ + type: 'RESET', + state: getInitialState(props), + }); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [props.doc] + ); // Initialize visualization as soon as all datasources are ready - useEffect(() => { - if (allLoaded && state.visualization.state === null && activeVisualization) { - const initialVisualizationState = activeVisualization.initialize(framePublicAPI); - dispatch({ - type: 'UPDATE_VISUALIZATION_STATE', - visualizationId: activeVisualization.id, - newState: initialVisualizationState, - }); - } - }, [allLoaded, activeVisualization, state.visualization.state]); + useEffect( + () => { + if (allLoaded && state.visualization.state === null && activeVisualization) { + const initialVisualizationState = activeVisualization.initialize(framePublicAPI); + dispatch({ + type: 'UPDATE_VISUALIZATION_STATE', + visualizationId: activeVisualization.id, + newState: initialVisualizationState, + }); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [allLoaded, activeVisualization, state.visualization.state] + ); // The frame needs to call onChange every time its internal state changes - useEffect(() => { - const activeDatasource = - state.activeDatasourceId && !state.datasourceStates[state.activeDatasourceId].isLoading - ? props.datasourceMap[state.activeDatasourceId] - : undefined; + useEffect( + () => { + const activeDatasource = + state.activeDatasourceId && !state.datasourceStates[state.activeDatasourceId].isLoading + ? props.datasourceMap[state.activeDatasourceId] + : undefined; - if (!activeDatasource || !activeVisualization) { - return; - } + if (!activeDatasource || !activeVisualization) { + return; + } - const indexPatterns: DatasourceMetaData['filterableIndexPatterns'] = []; - Object.entries(props.datasourceMap) - .filter(([id, datasource]) => { - const stateWrapper = state.datasourceStates[id]; - return ( - stateWrapper && - !stateWrapper.isLoading && - datasource.getLayers(stateWrapper.state).length > 0 - ); - }) - .forEach(([id, datasource]) => { - indexPatterns.push( - ...datasource.getMetaData(state.datasourceStates[id].state).filterableIndexPatterns - ); - }); + const indexPatterns: DatasourceMetaData['filterableIndexPatterns'] = []; + Object.entries(props.datasourceMap) + .filter(([id, datasource]) => { + const stateWrapper = state.datasourceStates[id]; + return ( + stateWrapper && + !stateWrapper.isLoading && + datasource.getLayers(stateWrapper.state).length > 0 + ); + }) + .forEach(([id, datasource]) => { + indexPatterns.push( + ...datasource.getMetaData(state.datasourceStates[id].state).filterableIndexPatterns + ); + }); - const doc = getSavedObjectFormat({ - activeDatasources: Object.keys(state.datasourceStates).reduce( - (datasourceMap, datasourceId) => ({ - ...datasourceMap, - [datasourceId]: props.datasourceMap[datasourceId], - }), - {} - ), - visualization: activeVisualization, - state, - framePublicAPI, - }); + const doc = getSavedObjectFormat({ + activeDatasources: Object.keys(state.datasourceStates).reduce( + (datasourceMap, datasourceId) => ({ + ...datasourceMap, + [datasourceId]: props.datasourceMap[datasourceId], + }), + {} + ), + visualization: activeVisualization, + state, + framePublicAPI, + }); - props.onChange({ filterableIndexPatterns: indexPatterns, doc }); - }, [ - activeVisualization, - state.datasourceStates, - state.visualization, - props.query, - props.dateRange, - props.filters, - props.savedQuery, - state.title, - ]); + props.onChange({ filterableIndexPatterns: indexPatterns, doc }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + activeVisualization, + state.datasourceStates, + state.visualization, + props.query, + props.dateRange, + props.filters, + props.savedQuery, + state.title, + ] + ); return ( diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx index 7efaecb125c8e..aba8b70945129 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx @@ -205,6 +205,7 @@ export function SuggestionPanel({ return { suggestions: newSuggestions, currentStateExpression: newStateExpression }; }, [ + frame, currentDatasourceStates, currentVisualizationState, currentVisualizationId, @@ -217,7 +218,7 @@ export function SuggestionPanel({ return (props: ReactExpressionRendererProps) => ( ); - }, [plugins.data.query.timefilter.timefilter.getAutoRefreshFetch$, ExpressionRendererComponent]); + }, [plugins.data.query.timefilter.timefilter]); const [lastSelectedSuggestion, setLastSelectedSuggestion] = useState(-1); @@ -228,6 +229,7 @@ export function SuggestionPanel({ if (!stagedPreview && lastSelectedSuggestion !== -1) { setLastSelectedSuggestion(-1); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [stagedPreview]); if (!activeDatasourceId) { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx index a0d803d05d98b..88b791a7875ef 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx @@ -188,6 +188,7 @@ export function ChartSwitch(props: Props) { ...visualizationType, selection: getSelection(visualizationType.visualizationId, visualizationType.id), })), + // eslint-disable-next-line react-hooks/exhaustive-deps [ flyoutOpen, props.visualizationMap, diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index 9f5b6665b31d3..b3a12271f377b 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -85,29 +85,33 @@ export function InnerWorkspacePanel({ const dragDropContext = useContext(DragContext); - const suggestionForDraggedField = useMemo(() => { - if (!dragDropContext.dragging || !activeDatasourceId) { - return; - } + const suggestionForDraggedField = useMemo( + () => { + if (!dragDropContext.dragging || !activeDatasourceId) { + return; + } - const hasData = Object.values(framePublicAPI.datasourceLayers).some( - (datasource) => datasource.getTableSpec().length > 0 - ); + const hasData = Object.values(framePublicAPI.datasourceLayers).some( + (datasource) => datasource.getTableSpec().length > 0 + ); - const suggestions = getSuggestions({ - datasourceMap: { [activeDatasourceId]: datasourceMap[activeDatasourceId] }, - datasourceStates, - visualizationMap: - hasData && activeVisualizationId - ? { [activeVisualizationId]: visualizationMap[activeVisualizationId] } - : visualizationMap, - activeVisualizationId, - visualizationState, - field: dragDropContext.dragging, - }); + const suggestions = getSuggestions({ + datasourceMap: { [activeDatasourceId]: datasourceMap[activeDatasourceId] }, + datasourceStates, + visualizationMap: + hasData && activeVisualizationId + ? { [activeVisualizationId]: visualizationMap[activeVisualizationId] } + : visualizationMap, + activeVisualizationId, + visualizationState, + field: dragDropContext.dragging, + }); - return suggestions.find((s) => s.visualizationId === activeVisualizationId) || suggestions[0]; - }, [dragDropContext.dragging]); + return suggestions.find((s) => s.visualizationId === activeVisualizationId) || suggestions[0]; + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [dragDropContext.dragging] + ); const [localState, setLocalState] = useState({ expressionBuildError: undefined as string | undefined, @@ -117,28 +121,32 @@ export function InnerWorkspacePanel({ const activeVisualization = activeVisualizationId ? visualizationMap[activeVisualizationId] : null; - const expression = useMemo(() => { - try { - return buildExpression({ - visualization: activeVisualization, - visualizationState, - datasourceMap, - datasourceStates, - framePublicAPI, - }); - } catch (e) { - // Most likely an error in the expression provided by a datasource or visualization - setLocalState((s) => ({ ...s, expressionBuildError: e.toString() })); - } - }, [ - activeVisualization, - visualizationState, - datasourceMap, - datasourceStates, - framePublicAPI.dateRange, - framePublicAPI.query, - framePublicAPI.filters, - ]); + const expression = useMemo( + () => { + try { + return buildExpression({ + visualization: activeVisualization, + visualizationState, + datasourceMap, + datasourceStates, + framePublicAPI, + }); + } catch (e) { + // Most likely an error in the expression provided by a datasource or visualization + setLocalState((s) => ({ ...s, expressionBuildError: e.toString() })); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + activeVisualization, + visualizationState, + datasourceMap, + datasourceStates, + framePublicAPI.dateRange, + framePublicAPI.query, + framePublicAPI.filters, + ] + ); const onEvent = useCallback( (event: ExpressionRendererEvent) => { @@ -162,7 +170,7 @@ export function InnerWorkspacePanel({ const autoRefreshFetch$ = useMemo( () => plugins.data.query.timefilter.timefilter.getAutoRefreshFetch$(), - [plugins.data.query.timefilter.timefilter.getAutoRefreshFetch$] + [plugins.data.query.timefilter.timefilter] ); useEffect(() => { @@ -173,7 +181,7 @@ export function InnerWorkspacePanel({ expressionBuildError: undefined, })); } - }, [expression]); + }, [expression, localState.expressionBuildError]); function onDrop() { if (suggestionForDraggedField) { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx index bb564214e4fab..bdcce52314634 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx @@ -409,7 +409,16 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ filters, chartsThemeService: charts.theme, }), - [core, data, currentIndexPattern, dateRange, query, filters, localState.nameFilter] + [ + core, + data, + currentIndexPattern, + dateRange, + query, + filters, + localState.nameFilter, + charts.theme, + ] ); return ( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx index b8f868a8694dd..4c85a55ad6011 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx @@ -139,10 +139,10 @@ export function FieldSelect({ }, [ incompatibleSelectedOperationType, selectedColumnOperationType, - selectedColumnSourceField, - operationFieldSupportMatrix, currentIndexPattern, fieldMap, + operationByField, + existingFields, ]); return ( diff --git a/x-pack/plugins/lens/public/loader.tsx b/x-pack/plugins/lens/public/loader.tsx index ebbb006d837b0..f6e179e9a6aa6 100644 --- a/x-pack/plugins/lens/public/loader.tsx +++ b/x-pack/plugins/lens/public/loader.tsx @@ -16,28 +16,32 @@ export function Loader(props: { load: () => Promise; loadDeps: unknown[ const prevRequest = useRef | undefined>(undefined); const nextRequest = useRef<(() => void) | undefined>(undefined); - useEffect(function performLoad() { - if (prevRequest.current) { - nextRequest.current = performLoad; - return; - } + useEffect( + function performLoad() { + if (prevRequest.current) { + nextRequest.current = performLoad; + return; + } - setIsProcessing(true); - prevRequest.current = props - .load() - .catch(() => {}) - .then(() => { - const reload = nextRequest.current; - prevRequest.current = undefined; - nextRequest.current = undefined; + setIsProcessing(true); + prevRequest.current = props + .load() + .catch(() => {}) + .then(() => { + const reload = nextRequest.current; + prevRequest.current = undefined; + nextRequest.current = undefined; - if (reload) { - reload(); - } else { - setIsProcessing(false); - } - }); - }, props.loadDeps); + if (reload) { + reload(); + } else { + setIsProcessing(false); + } + }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + props.loadDeps + ); if (!isProcessing) { return null; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 59c4b393df467..6d5bc7808a678 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -379,7 +379,7 @@ const ColorPicker = ({ } setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); }, 256), - [state, layer, accessor, index] + [state, setState, layer, accessor, index] ); const colorPicker = ( diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index 871b626d62560..a3468e109e75b 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -180,7 +180,7 @@ export function XYChartReportable(props: XYChartRenderProps) { // reporting from printing a blank chart placeholder. useEffect(() => { setState({ isReady: true }); - }, []); + }, [setState]); return ( From 13fd9e39ea92a53169f2664c0bbfc2e98ebbcc6c Mon Sep 17 00:00:00 2001 From: Oliver Gupte Date: Thu, 6 Aug 2020 01:12:48 -0700 Subject: [PATCH 032/106] Observability Overview fix extra basepath prepend for alerting fetch (#74465) --- .../public/services/get_observability_alerts.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/observability/public/services/get_observability_alerts.ts b/x-pack/plugins/observability/public/services/get_observability_alerts.ts index 602e4cf2bdd13..cff6726e47df9 100644 --- a/x-pack/plugins/observability/public/services/get_observability_alerts.ts +++ b/x-pack/plugins/observability/public/services/get_observability_alerts.ts @@ -11,15 +11,12 @@ const allowedConsumers = ['apm', 'uptime', 'logs', 'metrics', 'alerts']; export async function getObservabilityAlerts({ core }: { core: AppMountContext['core'] }) { try { - const { data = [] }: { data: Alert[] } = await core.http.get( - core.http.basePath.prepend('/api/alerts/_find'), - { - query: { - page: 1, - per_page: 20, - }, - } - ); + const { data = [] }: { data: Alert[] } = await core.http.get('/api/alerts/_find', { + query: { + page: 1, + per_page: 20, + }, + }); return data.filter(({ consumer }) => allowedConsumers.includes(consumer)); } catch (e) { From 9186171ad160ead3fb9ec977f3465904fd293aa0 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Thu, 6 Aug 2020 14:02:37 +0200 Subject: [PATCH 033/106] [Lens] Document UI terminology (#72423) --- x-pack/plugins/lens/layout.png | Bin 0 -> 487029 bytes x-pack/plugins/lens/readme.md | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 x-pack/plugins/lens/layout.png diff --git a/x-pack/plugins/lens/layout.png b/x-pack/plugins/lens/layout.png new file mode 100644 index 0000000000000000000000000000000000000000..170324a2ba393980e24762c0a2d0c5a5653d6420 GIT binary patch literal 487029 zcmbrmWmH^Uvo1=42M7t8;0{59yCj6*5ZvkDZcXDBJZR%C!5xCTh2ZY)(rDw2!|i-~ zpL6yd=iVQAU&f$&vDUOTYtE{to~lX67X?YI7ep@*5D>7Wr9LUczsL{}P}R{;;CE)w z)EE&EFr_WT#lJ|4i&K07+L>Bdn;;-ag~V&1YO3@TWaubMoBMvr4Osc~I#(7wOX5`& z;~bhaMb_`6SDy}<2N@d(R6lhDm4`Ak5s1x%wlasdiZU0LmWCk{GukPO%|5JntO~C3 zUOnu|Vd5ssqY zoEQpjfM)S;Elb_(-)}8-^Qxr7A!03v2pkc;u_n)cEI+?2eeO-LHQt6^nfi$$0pW*u z5MLDA20BG#fUB$i3KwmVa|in-aYkvogDIxNnX8t#re2s#UzTAbS0eBElXdS?LW^$q zS4A6~E{We^h*3m(J~m%9xk@a!iNmRXs#w&x+mNSwnQ(dy?6 zIeZNZpO4Y8zh_QX@z5Ln@9jcAg}mEOW4H9><3};H`JQ~17Qj%8WvWB7@f&lY5ASr~ z-i8u}D?{~h>V7UxPRq5WM?Zm{yp&Lf0mspZt3dz|_oirlz7tY(#v9Zi!C*j-b%wT$ zn~iGq8cn=ws@5nmAcjW1RkMIgltzE^P9}x8pt85<*AiOZ3XvhF+XufMLhPYn4CP^P zuhjV_&a~Uc+xeDChkehJkFT)!DDZxMdmf4T9?KZf!9&pz`#vuN9aV?|QA-R>mpkPH z7;icpNgr42^))UPWfb;JV4-Q?4}^VDY>R0Pji{m&mM?Bw-{@aKd>NuJe3(@AW3tTq z*Vw1NKfO-Jb{q~A=f6@UCAQ4wChDeOlQkQQdGi^Q_A^dbh(g0VvhR1B<0nLz!Gci# zyO*YS(-|iLV;@|l8b0sRETu5ACU|LJV}v87zyH{fzY}g})pJByLQm$0D(2l6!Rer~ z777lEo^yQ_euQ32BEK`R-wt`y!CD3B8A&?i{J^7@dEb5Np=e`fGfGKdqS$^EB`_PF z)dmbQZ3BdgV=zKrwRxs-QSv~im^zF}|)S4L1&jfRSi+mN}Y4ys;SURp-@ z;w?E?i!=EeTR@$2)s6-RH9%qz&#(9gbrdD}LTcAEeMo4Jhco(;5ahP(Z(9 z<9rXG9G4P`3C*R}`i`VTQ5{Vl1o#m3=%IBQ?i$#}o$ZiwllJ%*j#SvxJ9e8I&hs z_jDRoaxvq^8aP&Rl;V_h5ml;Rivl_YD#;EJ6@I_v!*B^?;=@t=b#o2!WNmv>(Nn)J ze~o_s;t}DvyZzNJ5~m+VC%A)Fj>7o0=_?uZ_yCrGhk)1i>n39qt^?%Hoh>SBcda^qrn9>5QBiTfOYyi0SSS40S_nE z{fk{?(2)~=lhATw6L%9T$Zi+5$A0m7uX}%ck7Z`D+(rF3SwwnOUsMk81CZS={nYSC zjnebe!2XSA4|e!)cx*T;Vz#gUvssG8A4^{gJ~V%*$ZA_R?=tTC*hSPO9+WN@ZZW#W z;g~F&?2$B^Odc^5G57gnj>PAP&xsK$Z?QRF@(>UuzCGq>Grb=VFu^g6F{)b1o!`oM zXS;7LumTF&6PS$67w*Cgy20MWW+JXLo3r7Z8k%Qbu}+w$tHv<(+9B9^y`y~2z0*7F z!JI_UNia{q#PU)Hq{G3C$kLs_!~)iQ?Bp=6)M_kcoIzKwh)-6_jsIntqt>j}UhD4^ z<5YRcdf>sMN=%+Amm1Gw!_!)qP`7Dqw#YNLQkOG#GZ%8GzL;L;VRrmA)9@+QtNMWx z)d;m*JX+kpOHZ=NC~6bbE6`h_@QI$hfTW;SAu&zKOwlabG2&c;aH@My;;?Ea&xp^U z;n=?aq-mX3*P`5d_W3NzEGl&pb+#lP*qrRtF!!jhCVEgZgY2ezc#>t-rg|}5={Bb) zl96m$U_ZXOT5z?s=b;#NnR>}6Lo%#)aGW(KFlRQRZLj}?1acE=mI^Urvtvuv$kC{; zFLP;fDZ9cVN6h5Q>=rTeL~o;PJNLxC^*%X28@yWFyh>~@@ritLeljy6=|StYCOc>7 z5co#;ll=#06n+v}1LaT7KF05as)QHs=jb$Fwa{L_TMS7bUg`9Hy+J^QF;9LLx!IfC z#ZMF(_&FdUur7Enm^M%?cp1C?<>(7LwBv}A@FaW(u9#PE@f(HCP-fExAv2C1z3$+2 zPS__r7DmcqfqjD-#~S7)ClUeM!v_3KXwO`?lwpd|2WDPpiNjXD;D$Yi_6Yh&FfoAh zQTo2{dj7Nk_YJxVZXJD#Jf^g6iYt9TyL9waLTRkfyGD^4JsEQu2^mO0H13WZU#4XW zqk@ezbslYjjr2k48y<)0-{sO7u`={}nTPKi?a$`l<*NV-NK%S9<9VIz1So}Ry*zH| z^_eRoXA?Vz3x{{N9j{AnMv*)H;{9w5zWw}o&BaMkO?9rN4o5Aewn|Zj%2U)k-%GmL zs;R4I&DsY;hUZf_qf%pxH`<>u8a&6fm*_}k8TlS6K zAmt-vt-XlMdmrugR{#e6xwbx|@e~Qb0Fnu0V0nOPP?TkdP2}plFtfy)Of#l2*Q;oD z!fEjPAkAPo8@6^^*~g0P!j17z2c{JDD)odi&uYv4;_CPurrC=8a`jSZX=u5nmQl0m ze2U_9_P!N2C3mysuqEMin+}tvhnwC>Q_tnj!QiaV62*$WqtWl4e1W^B0r}tZ$f+6D z3M-zsgqeW-`Xt+Tt7mQ{##WHJYa9Cg)`NrkR2#s;Hy#F}CKtH{2Me>^k%Z5)JrT`G z%>yp}%c09Y_bHDDm%>UO3$WWmnQ6Hd z?Ge{D2OmoOxq~sWS%l?;b%CyHQsdEWITJa;y;YIImZ=NQkn4a=4aIQLac_?Otz?z; zg2+tMOc5a6+E8b;w;6WYIsdHZ%7N!3@+iig&(*z`PqT){q{ML;OQI)Rt#kMupC|wB zStV1JhJxO5?g6izT+_Iliv9U~*^&;M9pMtRo%4xx-F9Ah*(3gH7&`kf zxCdw!XcfQ~M)R^?H~7^h2)+hqh$e_WPN|&*Jm#JiZBO2sK}TOY2fF}njW)>jM)OAR zJY=4x?y6ydn_*r)$WKmLE+6e?W#;lnzPtOI>P24?|X|saSGC+3Q5@{dto2WBmp=oslf5hP-q&4`(ZV|$J*3O5nPnZ0P zwBK*7i$AW38eD39q18v=`jrZ79^rq{Vas<25r=+7h|{_J{q>u>D<)P%AE)rrv@VzH z24xHR8&{i`2u1kcMyq^%A8Qd2GkLp=?Vj0#nr=Od@Ti1{tds7>}*&KjO`3fSY2)G;iVA} zgj@ySmo_FK0}59gYg|*7sB* zFDNJ|gn-7T0?MC0|95rxU&2)8AdtNP8=H%Z3#$t!s~ymcjh&yLpY1&d8wUpqyabD* zn=Qz|mBrSP`o9|aU+sJ{aWn#2*n=$WY$^V{`s$Qnz&m0pPpd$#|tY9I^K|DS4qp8Qv}|Gd|Kbtm+vF@Y}@t|r!6pDb)lY#rf4 z6Jh7$Cak3FqMKoCQa{`5iB_1WPvs%QN4L+|M- zDY{m;7!I0;&a>Cg=DXCax?f&dPBSj3m#HmU-c>BjsMV@lm1*ObsFiFKYdc_ndG$pM zw!#$t3aKjAawf=SX1P7d-z~P86-)!+ebyvPH&>(@YKmNOI@L0zR10{-^)H6BVP_$@dDxe>WERejt7kNb?4h4CIIS zuhcQc7!X;A&K1wHv3@k2`d{dEif>|E<%hRMy}8D<#OH+i`sA8jvl?a$oXo(azp? z`VKZwpu^igA>3^2;+=uy7op=i1i6%QSFXa`kD{b^KB9bB%;#x9$EEs*!yijS_PgO% zu5qlzGqa1^Xw_0qNoDcMfDiR6{0vCcU_Y)QEcRMN>^)FRe!{u zMQxM)j0SFjrrJ9;2MGowQ)gzMJ~<_=$C0&e7a#^t86dGr{6nL=)<=j&ur1Ts#2-`d z(1vGfS2&GDpL-dzmC;30Im&QaCsQ>2=F;hPXU=Vm4do_^vk!xB+C0uu`=^h2Zcsgs zSdTFJqWWu2h1YheozT;SHizC8tt!{qk@x$bVYGdJ}a{YeVs?Gvg^jIE{`6&-OHB}44?T)` z*eXy?@#@gi9B9bNeE|1-=Pin#;s$MDT6RgA7UZdkXg8T9(w-#I7&%%r&3vJt7+FXi zY|^6try8abuTSSO`Y`#bm~_H!;)8?sej!=v=ulP#j>>J}RNRM!ha1j`EDDVn)HG#q z^=I-06tIx?a=?rsa#iNFD$uN4VD~ZI$U-BXAy4Zm{_D!E|LxSyw;-_J+k)@)!)pt= zE6f%1>6wK3E{?bQOgbgaFw=LV+5gmd6}E~Q?=p-8_}*WV2!!eup`>x0su=!~R5&Th z>XLl?R%E_$enU0e?Tm=VtW&)_!toOTK}jmxf7j;br9U+m?I_`S_0pL$jy!cNn$xyF zfiQQvqX(OedkXUE{p!|m?KEV8c%Z#;q1yHzSR*Rrl)>|Q)R$WWeielM;cq!jdLz@T zgsp;&lN0NPh7=~|TLhf;8F1+%W3zfmnaXquKCPI>F59v`$`kyI#IVAAf-je)4sg)7 zngu0sUSbf(q~#?w7P%X)3Qgr~A&O4W>cJ(?oUzMpI1? zNQVIhFyC5AtAW!zAf*2Y7V_aBbLn1e#rX`@xU5v1!D_&`AAz^>0uO?~?JZdwhN1xs zeqS*}jJO@^gyqbq#Su#;QtpqteT^o>t{j(NYR;m|iyRk6HtbfH`SmJ}y}`ZISzn|s z(r2oWLU~PO-?#5Z@uu5@%+TX^qzlbwDetCtj4ft}aaQwBOUR~8k96TcLNcekNm|h1qmS?dVh^BoL-HMjZe?6FqCLi)aGCcLp77F ziwUua1!(pQlate}O{j%^wzmcko!I2PrUSqtKiBg{MKWo@kDJeaNh)3P&3$>^7*-%{ z07E%VLEn^HD=6a9lO00>gKV05;yPpZy(}KxGuPkahLdJDVK}?7)OR}c~S=k22SLiN0Y0+V`h%AS#*&))?WrU z?7O;|sIAs)`~yGbhv{=7o{6#OAh5D>%y!U0MKmW}x_Zus8lnlC`bTxTZ3=XRiA-B_QUYpsF&CdgkX6Z^dRi^c#cAbXF+;>dPP$t&aj>nAxK|yC| zg5dE(vv5Xq23`FFG|~A^>V~@FN8gG}sh?yDSq865_g%^*Ua+BRu#0Cg*XCs}jm;UNL-_WV_m)RzKEuKn@tu0ewOO^VrQpiMDsP8#{9( zWD}aNnyg&vjF0=HYhGTaes`j`{uUv0Uag=5G+bsPE7NV%wrxCmIp5-T@PP@??A*G0 zknSQHWrT_yBf9z^DJ?4qnr`$*vG7ApVAWao_8~EOl<-wA+lS5}*~QXQ{vGNTqkTsI zW-A~vZPI1QEpr)EOlI-bWTEEjkNMzf$)>OMQz%d%l@H80ZupQ;U(iZFQahqKLh@gm z+JphV)rZ$B>8@5Bo2_;;zK;i~S5HL6qWr3nPd>AI3)_u)6R`pcMkm-FXv60`eEuL} z7pqrT&hmw*#>z(c8uJfouCK)rD&}3t7e0y6%j0nI2)VF@#AfVFH%q4cPSr@AL|F{9 zdext~vS4eamVIlv!n1y}Z*@;?v1G$(Mh;x?OjD%0FRri;V%_d_VIVDc= zDu;0oovOKee!>I>uIwsBS}P|U2U2^bZwnL ztQ`_J_CBW0;<$wku4aul0xEId7CPMS&k6L(ssQ4d=m9$zI!_FQN%-gE1wp!T%JnNmH%lJ(RJKIDU)q|3k(QtnPe$@27ac_t2vX=**k zvu`R(j+HAXR@309jg2bpg_6%LA@C3 zUpzHGI~v%jx8i44>jbMIBNgf=yBL$B7VfQ+L8LC>B-8C+bBWwKn_tg_AxqJ)l`Jno zx3vr%lVjdHTH&Ld*Ou9l}_-HJZ$0k8T z|E8i;x3&j*ynGjdb#xDDd^b@6AomCt{acF2cZcE!zWpEFuD6dh3ou$`(qIDmeY#D{ zMbQXKVU+x1(7iM&w3smDuBH4rZ%OhedCyk3<#ObE)6b@=c{Fnhsw%qVf!>SKi?VkaSqgV-s{GH-s%s2 zYwok|b(*JPbGz8M))`Fpn&nAa{O>^4Go+NTZzw7?Si;b`7xB)F!Qiy9&?A!5-uJj4 zCuWf$nbZOaxQ4){PwFS*Ut)q{YgXZgduH!f^XoCOFHetN+nw#gh9#0mbCoL4R*193 zvOu1?i1zYsWHU7OEvM;%j5-lxm=kTDHcRO}DR!RvmMN<8*0S;a6oBnyVbcXC~rH!GpVry=#NBac*8I3vb^t_nOl##oSqoRgoby zmQ9eMp&#b8x~NtgFd{B4VSoddkw~b}Fo{9g&=;MaU!IA?;=0FTHECbePT{Tt8cD`4 zcYAfTod#UJN^N&dWY&2{%xe=ZpIRTX8jv2LkL=xlU(KfK6)ROjbhxn8}G z=ekyQR^b4Phhn7XW4A_?BgA$-J)OF2V{>Tf$mI74CCAC`BmQ&t_=>WY3jEXjHkjx* zg*uyxh1IWyXxqd_fENpshDN*bMj*r+t~@uF57Hx?h4J);qc;NyoWfD5Or(POvK1M^Tg^KV$!#CfuiFFDXDfH)^LO7#4k~-|r9OXd5(e#H zw?kG`j5A3Eo%@@Qy(oxzZRsy&Pr7; zsQ66VXH4ivDYm$VH(J{O6W=&9vdD@iv#d*S35MDgN)5*Z+_(efK3f-)xq0^Eh@R-5 z(p@E}X}O)1K-BwTcE9i?$(~%pjE`92L^D*X$?d0G6B8yXoa$MDhl*^8H`pSEc5a(@ z(meW14=ItQ z0Lw8(Tc=c6_bJ*Rrl%*0)h>VW5DBGNe3V-_ll#E}?=_Eo%%jX!@TycAhrcB9VHbCF zAXLqY2{Y?iZeUnqzX!QoVzrNJlPauYtT92*4S79NSUTi%BMfJy82a-#)jo5QYmM_J z^bGJLeKUS_R2U-1>zWI>NED)X<$9=2=CE0~gT=(f;oTgbvu$0@t^$L{zKu6HPn9$hjCA*;1;-L=ok={u;Y(9ekngD|nE`Q^o> z1rpVTCmO9d$~k+YAIm9oc=dh8gTPaJ`&M>wIzB!swPhDt>RuVDa1&XUm9wBOZwa00 zo+mzHah30(Be1#MU;*B&t|Tt~it!I>-u6=hE?9wjYyJK9QN#%AaV_5NO}a|1 zT5}z2|B!Yt*L?L+I})^|$79~1gag5*7f)mbn3P<9Y92&vbgMGhB=C@7f?n)RQ)|~3 z_NrHCv0*=*zvTtxcK-18avvC%ymS)(C;&qx_aV5vZ6fhp-{yV!g4F3K=AEzy$O*EN z-YQAvzE#vDx2d0+7H2Lz&9yLiq*<4xmPwUb&dUMHH7JDY2{vajl*wIAl-Ttzxvc}f zP*;>4IO}`!xyGf<70-y{C&u;lzBWibPCwO?mg2j2)f+N9yJ#nirO$MoYwJm+P^y6q zlsuKa5&+(si%F)U)I;wE#g#rvDvX}o;VO#Q$eODQF;>mpdp7JB%&NVG7kh#PCT{PU zWwsg+NAU-!$8 zt0h~_k*fjcElKg%-YY>3g|;F65~E$s=;7qSWWh6%MT2KpFD$;APwW*eAVjOPxm)a8 z1#i3kfesSyut@i6S@=P@n%y4NrCQ8D$uOS7gmb7{^T%BVTFQ|JIjE;a!?vSMD2B|rCpf*UR6d^~ySv~Vu1+mX`>kAL3um>EsO6~?>yGjeqN zqhgq=_Bw-iN9)EZ{h-dd%OF6$VOLD)VqcccJDQddJRCPt6zt>LzJOtFK-x-&6thqd zK1{0bSaI`3PpQfF`(8WtYV7;ExbaNd3ATAzG3VK}ze+Y>nC;2LF1Yt@Q6$-b@uB6WeA#<%o7ZG*{DHPRpu=$b>_zC& zmwxHmC#~3OGrPd;a5A+@4)ws;cxRNC*XnuHsK)|o-xc_8koa$ML+GaBC~lCEW8#v` z1)mP~AX^cvc)8M7Q&{ItajfyPd;yNa`)8d+ste(sSVK zvX4W>bc9t!qs-?>64rE1&h0@qNWY5deXZ5(qR5jsOrr53CQSa@u+bCvS4}-2UN4_x zT9K8lB7keV-$%;Slz!aPC8elzyQZQ|o5JUMb9tmZoP=F>MDSRS-*ilD-pnt$;^~TI z9H3oWrd#_tU+A(_*YPsm*5_~I`#<*3j7^Se!p6-|s28WIqQY=-LWMNaZLmgmYqcxQ z;J!1Xs)~%Xbfq|-qlQ^a!ki?QUGrr<%uT_I>>Lg{so?Y(cdu>afWsZ>RbP#Z$WI6z zz#+u^x+JfDV#!+e%WSBm7QY*Cy>(J|q+M6!gZKNUiW*s4+CiS9=*)*rajjaL3Uo3r zT1hAQ_+#+lCai4lvuhcp!;JpqLCNH50u369zb$w8zAoON2(@G;-r%~W(9F_&=G1k{ zj&tX2tFJc8&F_p;;KO&CekPV^w`P}tlZ(ihv`3rMWR0&^!OAI@`AFx#u=6yyed~wW zaeSt1YwUVRn)^`NSX!NA90py-YGAIg|>l+@6E0-0_ z^XmB#AhynU@5Q1X6RrFk!k2D*vsN8D1B0w_SE4DD{wUtE3pMCZI9q8IgB}$b%Ud;e znG}w4eVgHv3JKA4U-9P`YOScvo=!k+J2x7K24zjEvujFQ*YWk4-cS=>5ErPAA_Ttu2*FPHsW@Y6M}Vsq~$VJqCb-iMNV zT_~M_+gI6UQ(k;jxZbUuT><(_-rOK_jHqhMa8c&Nf#m{#VKfPp;_=W=*MVpD(W?D% z`1q*u{@!!G%B19CcYIhi*OGQ`N6nH^S)xuA*H{*eMzY6WHgG|IE?YGDIoW>Z;c9s= zXlx;Q^a0K{vTyV0gsGcO!1cCWU%ZAs-KoQNh%LnZZ-Z7p9FVJ=KVg$ubd%VK2djGq z)zX#J&Zcz8ZGTgGdR#XfOotm_Q`y6k(Rj=Ea{iK&D{cTdQ9%EP;5lzGy`DFDC@pV; zeI}NXVISo^s7{L>jjsE|3CV!Flodt=p;3-4`N!mJ3(WI(7>6cTx;*-JO9(7!7 zd3KPIeh zB$+f%{BDXU>sr3M2nV-stoXA|y@~WJYchWM@nS*2F4K&>zo41tmGND%<)QQI_zE7I z6~?Ye!TjQKCxOS)3#}^94Wr;^OG}-babz>KH;PR1{6{r*ib4#atu(>QE%Y-e>ZC+h zz3FP(i`jbi^<>RD)*UN|-}z{Wz*fPes0-N4I9CIWl%Kw4 zVrE*jU759g!_s5-JQ>h{AA3RA3(!4R@o34-Ro&P)tUw&egFQ4*;g!rWxHnZjz_7jXs$bn|DaVQ6X!>>t5`z!(Tjq8Li`b_Uxf| zvi9;=qjKywJh&twY>Taaj%_A~HSmcC(!lAm#b1|$VIC#5?Cm{_#q$-kGf&u$)!x$M z?0u3Y`Ke1XIbC4D>uQBk;V09r6w876&l)~D-uufYJt!X}^7z_C#}oL9X!2|!}6>+_Vp#r4j1*e z18@(*=E~#owvfbQ2qBrzI}VQe^gKlXPQfA4qF8E23-K%-K-j>{k>ID}X$y(&${X47 zx1(-=dV|>etFo)Zauh)MLs5|~E}#-Pd>fIP4xN|@$bxgjJ5Y@kbCY5y9v*?r%*a{0 zC(~8Yp11yo>y_BpeF7mF8JXhuwd%l$yAU;EF7t0?19&zR?uq%wy|A z{fih6zlbC>&q~8)L4{1F3}Ai9LLU=z^j1LVsIJCzJ$vLGIw?1bN7pDn!!nz!3%S5p zEFL7fzn6AlELxqf$>&sPUhj=JTFY6enX%1lFD$7e3dqGi8={Kf!v1GUT%H#@WrTpc z@&Be)rXyPh63Lwbh_Yq4mIO%xhd)>fyV|~gmHcQq%m}MN${(i=ZtBco+Zm~NC6rInt!5SnWZBc#-uv&dxq(GaOBWAf!bTDz-&#Q1swn?xGV4jW|A?jgQ~{|GVJs+c}LE&=tC$8MSR z*8Qq$54b$)L!~F+5}NE%lnkk)&x}>0v&So=rK6F8Yj=-!_Z6eZFq6r4Su*yloa}6S z?kxB!>OaZy&r!(254W6z?@sLE4An`87hy6(W;juN?TR?s(=7N)ZC-aTCfRgrK1GV$ z7QX1+x1z5o<@h4s3oiY3G15%lNB(pHVGQ1#pjD|$J`QQ(D)3X1?=6&f%1asf;PaPG zcVVL#90C&y4KRA>&%gapa$rtj(die6|6F?HX20d2b|L6xnWoU!%l#^`nB-J-!Dm=R zdiIa}FvEvZ^KoQP^mjNzEF8$VL+3NKo=e&lg5`=qo~^ctxk-$l?Uru+cVi_;Y*w3K z5-gyy1<=vubfK#%pi16)$%x|~XgKP612W>nd)3&|H#W|JOLJRN1d7wp#+l##xk#k$ z4!Zg1X7XU!=(6QHxk|kVn_<;`-{P{^H6j_j``kC1O6$Va?Oh#NK?YtcwWP^?(rY@` z3jh;)FH(TQ(?|%%-5_%L&^3E+^CI{1nB`}}v~w^1<5EuR28-Gv#%j-PBCUGwSW-qd zHo&9j6EzS*?oCbPS1dg^9H#%_u*`y79gP%=6c~<4G6rx59Wav$)bM^FZZ9&gRmnkdQr`BUm5gSBnf zlOJ-}_4M&I|7UG&)NxCRg`P-K+C)8fhpj!vdeoFl%f$wZ^AA}$A-FvQ*QZ8#cA5GU zWjY!<0_TFO!qp1#Q45l)y0YBsZFkVtoPk=2jNS28oh{bIzt!5GkT^Kyxw9)I7*WA= zNsw1&o;H1t zV`G+takwnV05-9brd!dHCJSrP>KyxVDa>z=VzNgF!~C1nZT@HiB=Ej$9eSk4f1C{T z{=~%rafw#Bz?>&ytG1}vRt{mSFrhk6rF8YS=J$Y=`IZkON6P?KqSSYao>jFyn|n?* zDHw-ZmGHybUhO(ZQcR?m50AMi*i#?N-v}5-wVa%#X2-j?B?&6FdF-Q~ZELK@)dYc1 zQbHx2Y_#ReHAZb=m+2~WGO!F1w+#SWgIX{Fn-(Q*Peje+wWo-SK*4^D#}8|2<45JW zCT@4+6ceVIhGn}JsLbASb#wEv_2F{;=zRFz9o*y__Y5^U%e6uP_lF!IEtvzc7EbR9 zke@%>n_};pFT1*Gxwqfz+WI{gha>dRT+q}>jYZ*ge+uHi*}{G4MxN=(A=4RAUgjp4WJGm6@(-&@jCS8?dNv zqkCw|U5J`E5+zbu_mp=|3;mDs*Y}FjBX23F#e9ZEuJ``^hnj)tph&0yJFRIJwdBb% z3$b-~Zdk90jOk*E8vfgv>IlqZJ$Nq{>IWAIA3urQ zbXP3HVIJ9~PkTZ`+}0V!d@;olS8h`Lf2fxbiqfRHoLhZrO>;!<^RddDl+(xU#IJvN> z?(%?l!R5hds&5@NF!JJhB5&}rY@w`A)xLNs2wSlHSC$KWoBV34j?K)po4xrJR*{6T z<~d&c^=}WEn7cn$;HJWQGYok3DEXAGW;so5qXO{OGaX9WBM~`lhD}@5@Eh?F?vV&2 z@|f8|NRH8dYg34n6_8F8QK>GTDv~a!L>}O>j+{)GF>Uu=wKHY1EHldTm<~E-GAD*T zokf~+=T^)f#WX#pK8|Ro*UmZ*2RDrzuy1Eto_~ADLfO`x#Fygn&B2gA+09bXSsaUo zidMU8r8ALAtT^afgp|2Y33RfxKkAS6sRS=USKn!oHEb1%!`6*8zsBE$sR2p=9x7Ek z-n7Wg)p{vgLkhrsTx{6|cEn{P>raGlM0Z@Tep}hK9N2=x_@HE^Jw5P%K|dn4=sP%B z@F~OdRw5Q8%(ql+bNA9Eccpcp1ShYK3H!i$sYVS{+E)ih8TSvB1=QGTb0dd%k6{*1 zkGk&|&`=Ah1kEY-yA(yhLaLCX>}J=3&^aw(A+6-%l zG6Y5UwKF_Uo!qPzg3s1O^ZUAj8?FioCHV`pa=yN&K`+~&83E`UFv`qYl3T8dsChq> z02&^+#T@6iMH795AJX^?-U~POsy0s;i9XCw0Z?)41owWULn*QJEPgUn?U@1L)YXF1<58C6wl;3| zQkyVS6~;d>M%wiX(b5H(mKx_%Dx*y$?j8#swysjxD;JB4TYti{8A?M=cd9F6jti1^ z0`iDb0tu5B^B-*l3P$9`e~2J!J002uW0Ty!agE5Am;N40=n*slroVSKNRC-DJ{K=2_=gO>@nnWQ+o~5` zPhqTUiZXa*&Z>=jr^YJEKW#?ICLXpzCdO6YoZdQ=9^%=w`?RmbBt@;M3rvV;vlm(= z4w)}wdmJ_xq4xXaw;A~JX`}BRgCAvsu!Yr|oQC5fQtSICOqfh=2DqVo;=!1}dTylR zI}8HW+TO>9OpWb9Hw;?gR)1qNNZ-Kp!C}K~wSe|zrV*T2Lfq4vziC?wJuD4YjRxqXk%T%-MRZL>&~W?!91KO2DE=Su!Lncr>L#Cy-j}Jvzu%H%mv~GwU91PH4$Lii|;^ zc1?Sg34W5j*j5z}#U$o8GT+@@EKp@m-Axl*^7#0X$!&|=C%#|f@fS+6dbu{WS>`#l zj&G6GENhkNkw7xHl|rC_H*9iHg2~H*m_RASJn=?b7y^%+-e0p%_x&ty3d2%^quA3FLnd;(F+ zj`E5s`u`-~2AmoVSBHt`0#;8%)5=HrM>5;T!cW_bP2!(&9!C(OjrgY{K?+3AFIm>) zE!qBLiof^pM;a0>KQ0mH&wgoxvmL+cr3g(Ckkn6Ad&F#9@kfa*zlDBnbf0)-5vzJ< zmg*F-02=-;e+xlKTP^Z7<>y%goa$A*`Qi^9O@EN~ADNw^D*=y1ujHr;%bfK}J6M$C zp#n`@j}>;Nds@A)$SvMjT*8EIR(^)RfGjCktG?npFH2-PtX6S(_Ha{RkfLbaUPID((V=#L>EcBAzEa=Z;Cetd?zg zh6mKguB@y~B`f!>2uLjI958fa>FWtM*LUuB%V3EM{Be$nNn;HyCuXoK)yR}BC&#Be zYB^qmc=1|RJ%RbPXxMn|{aMQ3_G56y&qUR>***t_I~Y2!2EAyi)}ou*reC^jUtsFP z?5g{q{2!b=ej;yN!q@`Oe?E?8&yoD>Tz2ZbD$=@rjJ<63OLDep*8AcV%EUj*1 zgQR=pdoWA};IlQI=(??UYaFs;J+@rV2twVK-*6cJJX~pAR2MC_r!s`JIF5k)CEYc9 z$7j#BnIsTDEhx)5m9z`HR_Hoxb3-*9+tcW8i?YdN~gA&Uv>d!e!g&%!|zhE4Bi{ovQ2XojGauwP*W&VTV>b3mztJGgdLN z_3DuWatUF*rUP)=Uv{@}MFbh8JhEeMyo(7mNujK_@N+XV8V-)D7)$6Zx-$WKF7fb8 z)cqe83rS~SpO)><`~#|t#Y;W#pnX8fNV(_SvfW~S?Go_Z38?yHkFzAKROc}9yAlWw zN0oUtC|!BLcIkL^1-0Bk$2d-;$>|(h#e-}yoNXS!sdH}rH}9vD&M@GJvl5$ZZ#74> z@z5~&c7qfDxk$9t)V`$XedpV=fhn^Re1Xs~K~HzL6L!RHfC^dk>1NL-g>74_D9EVG zlalS@@Fl7mPs?MX#-RL;tEFW_K#oWBJRjW1opn68$S&5|EO(tcI6&*F9e$y2Zio1Y z(0JXc-={49G{~9kZmYM;WPI|xumi%hL<{Yg=Eu2r-Tx3?7DjCe7JsWvYLHp^o=C>W zzSN9GKl(#?SM1ALPFD$sMWwuBA9{x_$>nGB*YUB4{?IUP7tyF&H)feNUbTSjeE2aA z0YVn$AI=M8T)u4dukb`vM13qfEC$*$YW=T{HLgBBzpNgZi%gl5%shulb>QJLGBKz^ z&|~2FoR50S+jIJRbm3D1bXnATspU$uMEZ{DiCWtTWGY8esa)#Ug?Z{i+I6PQ4_{DV z2fEwADy#HduAn~JAfK^Mk@&}o(F!&}ebSQ4WNr*;`^X;Ou zs<+bBY!$OQWgqgV?!DVWZHTP0VK!(tijgQkRBbU+he4+bNW)(le{r}#sotf|uP}BmpAj2NE$DJo zr-m#DGH2VfAl<)om}v`Q~5Tmx(albyc%+jk4}E9uiRq7)@9}z2$jUGGG~Hpe@}T%Dg|B5@nuSBz8kr zJ+Mr6qx>Z}WFiU_^Ed1YdT9~Ym@Z8`;Ipd1*58Id*==Td|NE}w>b}0ZC&-DKl zX)#AJs;(FCrDF2-avhc;G^SrsVsL_jKNkAwa@sw=rcxZTRS_m20XG}gBgyXsVQe+e zatqV>zKd}Zj-5p+g!HDYgg)v*ji0}*wGhc1Reim038-ysV=o^EU>;Q88^Y5wTg$d` zgV3McTFIn2KTvydt6D8L)!w+5=xH)_scuYY=xM`K+Aa>~H-C!L(A30`?Rnyq z`fnoicXQO(1EUpok{adCK#hR=A99}4@Y|MkBBY=lo#afMP0{Ddjdll+iG&aLfL zESu;G7NW~*+fv&r#U&lhe3V!JAJ*PFpsIZ99~LA81VlgtDd`63PT|nq2#9nYx*G)q zl@94{4j|niA>G{}of3x>csFxro;x%5_q=zI=RZ*P-rrcg)@QAgj#HHfM-~KVh$=QU zvH^%0{zMi1omyJiHdRjn5X^f&K^;$xA05iPX}2uP2GmHaSc=zmLj?_hK^QC0psbvC zDFQ4GkLsl$sXPMZ*v8kXywH)-w7r``8L`!|H3Olx%^t0CJul6#tMQClj*0$eVZ*0YS+2jbOmNN^2or1EZXt^x3{=ME zJ?`jcL?I-v$jd`%zdeHO4ROlX)M@Y~WCkb;ENN2ai`$=+?(CW})!`vCZ1sv#Zm>S^T$wY-hfkzcr)j>SHY21_+0pCjW2DJKdq&95xo^4d89t=72zK!` z6xv!MY+l5V9wqmW%OAdw!^9LnZtu*zMC{V<#%Z%Kyg%hotWQAW%v!i7GsJOO_PKX* z1o0r2hyf;^&SI06&)K8K5f8RkqY0Ie9D~=aFPYRFbh|oWpH`)3>d}G~S|U&*dw=p+O5g(-l$UACd&guIIG;uzNW^656{5b$w>bziQ?SOKIR3 zVd!?!VXUFGRaZkuZMl53Tffao>Z(J#e}y%fz#?V)!BMh~QG>gj;0-KjK5TcVebl9J zl~oWxJa2dOvI!Wlu1rY#^46#h+wZW##pMf1mJ}KKI6Q^F$Nf zUMQhD$1O9%zcnRbE%Zk4tP7+rxj6KiCYB#~=K~<|`n3c!61;JBX$kz2H&4XRPo9n@y5Cd7lT67KZnQ+9;kXzru?w@qPIsR;7LDg@Xl9LiP#> zC(Nq%&Z}dxSPf$h{1|K+L1QL0&!?NOT`T?|eQ>cdbaj8_T@N^5XF8nc$SR&D`)Hk> z$WoIrHC%DOHP)&=OVhCDU9kOcP8o2jw-u4UyA1T&H@s$$;90uNkVL_SG9T^ja>f7J zS2*i54C1LgjV!LY*wG;UgKCC%$g=}CoY^_tE@f~IiI5G?V>nS=)9$Fe_KH=+TiI!oWSWoR-+vODe)k^>b-%;qxt5Ij3{VqtVM-DsL*?lexQ*fwB zp~--xn}z_WVxp=s`sGbLh(s|VrUD>sTmU|6vhs}>r?){KRxIi>;e$9~a?Si!7sf`# zR^A$`JhIrelkPca$-(L$$a8Ef#fyWMPgSBnaxnJe&qp-R#C2t-ftrvbi`j3JEA>xc zE76E(Lm0J8Xo*alD3zZa^$;xv)5i$81&_Afpx&{%{bw~#+Xcr zeLn+$IX0F`Yco2U`joaZGZYbS2(Vvm#g(O!ImaWl+nWNvF&goJFB~gXB<}*&#SI)` zuy0f`pmV`jM^lUoXEMYV3w&2Ohy{!c%`4r@AnEe}?x4%}PYN8UGh) z|M$lR>fnCUioIJR`sH_e)kvi`$J2+BR9Ja?E>DSmQGWdXSX`L5T0Vioeh#k38#?T} zyvqmSQSsMwgwFxgw@lstO(mw_A~`!izP>KTrH{@0)ixXdx^Y1dl!=9~_V2m>C+Eb0 zg^cty-RLOri}Gy^tG{d!Pp}DyG{8j0!rtk)jVKmS5#IJ%bkgD679s@RRqQt)cZq3zw=J7xuI<=WC^CH1^*{^HvfJ9eZy_*fBr5myh#PyNI||%ce?dQ z*6?-8Jht=`ckEKc3{%vA$-lG(bGJ(;fw%ZUb#U*td5!-#8bA;!0zJ3x*kdS%c!3Sl z40GF}pTDrxjns+fM)ngH|5c&?$L0#}tpxucv_>obN*dDsef!Q`?A{wg{Ry4}1-fVO zqSklan`)DJocRAqLp)^U4rXx5VcET~Tq`!gUFQ;sg)ku6cDZlE*3e8`Xa5B)6+_9>kM{XN9{9S!tA$QaUI< z;a5b97v{EoRfTycp`e)|XwXIq&vc=AB7P`J2ytCz`%22UaAG>qkr6IUM!h`Tq|mXu z#kN?WklCt`sl5ZbHIVc#d-S1TkblBSqnnxap}E%}So&Q2q}PkWeR=$T#ZZ{U^FR(V zp&jGvflmkT6wXxrTBZX1f4AR%QKt6_HA&#cmWx?L@0qrC%mttlMp;fJWjzc}D)utj z?!YeyQ&R?2xs%boYd~3q%;@lZ?1B9-;d0I!=QIFR+<*!EOI&! zK6X`X!+XZ_Gmi#K-WPIuckn2jFlc+%QSXim4}J~f)dUx8vD_ijwEo~Kp_=VZlxs$| zaALO5@sklNZ_vSB>^~&&ZC>s}st!n{)1D7^q_zi~uvf3Cs8YSDoid_A?yU7O9>j2y z*tO!^|5c~=U-bF%fwM?z=&5_ddl8GfQHY=v&X2gUA=Ikd7Eu1p9dt#N4mf>>>aH3zsSbFEcI_E z_8-6cd`5DXlDh9u=$H`|{D7csn?;Wp4vjix-u#^JE;4#ksc8%9(zXR1a}92LcG8uv zYf%7&z5-&_Y&ZjZT$gj{zv^HE$`wiucnl(0OA0At-y5MTtD3sqeh-M{-C!C{%&gj@ z{vu9qBloSHVT$^dc^~iNHyB3}0)43(G$ROB9tHpbn{GRHuJEQu+a;Uv7rX8!=` zd9BNuKzuCynL0zFV@3UOxu*T_MHRymo<`6F**Xgp>r&I zLV1KM_rqjvAL;&`V2PDrD#zgh4nlcK5LjaofshAQ>bs^ zzgzy+!YEZT>9&JNmyhji@ARr=ohAZ3Uyx1_<%w1a{I5&i8~Z(>7#18dP78KwMRM~^ zxLbSH2g^FdiX0MBhpV1a6;w<Ta0in>X4C8aN`v~iE+DQJW@ z4Oj9Fv4&soFrbrPNf=+*v#5coUY0#=!KQJJhzNS8C$W9QS7;De)4?PmXAVMHn% zg6F!y8?-SemUuNmF2Bkzza0betEN2Xm*wfOPQ8vzJOLG9C~oYw=b5f`2faO?4%$9K zOB^qr2L{_pwSOBm7~z6s=tpd-3MhS+yzUy0c{JoXon~%dS*$y=%yFxz{=@$EQzx( zC)eMnco>d1GL5Uz;i!CWVYw~B@Xu^32!s4GNPB01cz>0*s{PDS zpGwS&WZuUhZ+uM@0R*-vSn8Ju(P zyACJ3$WwhEJx|0n9P72~)xFFzOqqXtx{|nDAPX&Ea6>1GV)-W9HK2W8^+b0>wx&Gi zxnVj5o>9MK>Guq*T3p&C+Oo7_BMkgYz zIZf1JlE&2e<4V{~G}e1cWG+^^aE#tDpv4jKRh55yIw3rxrz54EC6waEXhMqv4T?w& zkpp@enoc`$iiRul06>n(BNQ68tL8&#(99&H7F=uuCI!w?6$89AzX zWIs;R#?EF3s&U0bWP-_2zsC_uZ;!__97WH59M1_|T-Y2N88;|=LRO@v=!!*8Tpz8; z!sH%uu#(fn9$6{WvjjLgnD7ve0A%n^YZre?3?WlZ78&my?j5+=hXmU?o&sZ4h^GOT z<+~FXPk}mvB*jNQ5kkB8c^Kck|#*&qxuGWR;cRx+BVazRg|Yx2BUjQQ=CreJy#MLV+;hswx#63$i~Xgk@m zFUGUuf;1VgtAx+5*3>ra+e3!HN7u`pR?+XzGg_K0gtBOxZdS9Ed#f~V09n)xjnJW{ z?%b}9_u^7}prr=WBo;t_{)bC&3zb7f z2-~0tqBs%;Zj3rtXTvz}UaxusOG~hMTpmcIhAs32bP^5Eh!*Aq-XXVPqcvDJW>l~8 zEK0a)dWn0wKvuoi;&SkfasN0kWv!(%x5VWH!&qZ>^F?2otUI?yB8zUeS#|Mf41z-* zr2@tkvPMyCXvA!n7)ZR7J8E0QWnmb;#JPpvnBV#h1c~dC*QvBLN94O%AM4%jig7`f zMa7hage2%nTyhb^lh#uCUM!G?jIR)wO|1nP!t;P$o9I(n`8 z9#?jgXD7arVr?2O*C;TNrz(b8Xe%{bI0@h$OknNDHK`jx-c(a@wY`g~Vb5pi-BJzL zROyni$ShGzwXhzbvUe*&BIwnq*Q$xPEJxjZrJMBAC~&xU$5CQhOeOJb&&bj~%OTB0 zu$(leYPmPw4Gw~yIJm!^<&y_co9)r(cAZw1I~Zkx7|1VOd3BH;dSfkqi9FXf|7`BC(o?hKqjGBC0rk1r2H|stFMTvrBeQ+-Ik25^j|?4s zFBGT-5s`62C%_KLHH%ak4gv*4C?zs*BuqBPHXMz7>pRM`MD#u12x1Py=sT~IR%VKd zyHkj$O@x@4nS^ATNphcaWXKIGzmgyl)TmC@uQNR=OofS!p&SSx`%t&$m>!ty1dA}c zje=uw8>ONxW+;&WT?XCzv`d~{mV+_EVQ;kL3$gXd1!wFW9Xl-h$l<)-Emf)Sk{w5< zD6#=4|J~aLkM%nLm~V9g?K)9Ar3h(PIQH28BY3x#d5M!YF?JsHBfUcttGSb`%*=*LE?*=Kcny4 zQf+)L-5h;Z!!x`{!C!Z&9D6!|%Y1V7^sftv(jTA!-W2eD>_qZGP znXl~6wyl~@Of`GvsBGp2G(g*S5dlUQw@NqHG~HaW8XDzAifcrJ!YRtjpw4K6kG1&M_o-#vej2Ozx?9p9Ymd2A28ic_!);7JWQ>UFhW#dv3IfP+jGeP%cf2 zXNsMAAEao|dn}TcnnY1fBdKwi5bt>O85C_XLAmox4Q0xrd4^u-FqH)`L^b=i=EU*F z^Ik*Dl+%5=l6*=W_An;vcm|Q>+1}GLVmyDIe<6@W#Eo@$CnBS|F_2^q-meetd!iDa zyQlViJW-<=x~%QpN>TCE9513P2kPMm1{4&7K!xsl{uZ-#Wb4-Du!GsdSRpv>)w-taiS^wEczp-+v1(EFvJ56)(1%^Ij(eqo^;kJNa6KeVaRB1;b=vJ)0{& zbB#~H7;nI3X{+rZ1&JjyBaT?(bA_E(Ny5o8mPX?+(E~~L??$5(jB^Y=9!H!fg#2-% z6l2`8MnCi;3};%S08UZQx{Lv&ZVWGr%(woz1OPSv@6X@X;r~(>USDk=h{0Nn4G|hI00qNlbN~Vk0Qb?CN zLrnZVy(_9oykF)AVYpZAihL9z2H`Im)H?EdjFAWp!7X@j!P)n|rhm`vZMbcm0aNdhzPhsYg!@A zIGnp^;#N>?C^9Urx+>zn|W*4WuPf z`M}MQ>rV;?b{JPrP5;MCYJYx zJx>}wNy6r4-V@cmmwV5tN&cTK{IC4``x8K#!96qhK%Ggn1r2=oz3(d|LkSaAXaG3- zV)&!_tUWG|Jq%773(Ie}#0~rpDWn`BR}BvhkpW)$IBc8>^A|*$>RBVVN?sccEv{0) z(hq4t08Y;i#v^3IO=jNie6DovE!TWP(l77HTQC^@RW6}bTz90*zH=SdoH&o!YY8GF zH?HV7nodxN#Lys?Mx9=fv`#p2cLjda4Rv(bo3#h+uZ996Jo zXuo2kR-@4DiVh6V=@1VbxfiZ-MipY%{j>HB^8f7d*0=rOu{D8=gp6Ih_1n%zD>W{? zVmd|RIQ-m3%^>P_vNqn}xDDlyc4U@G7;*w$^x6*Si!U&+N zpvd)gDr$2=1tU!n5EvMCV(EJqot2UTPr_EZU|TKogUSgz93lS^Q<~rB8e1JCGYAMF>A6r50b#6q7^%JNa%CO6L!chmuCxqPef0fyu?RTeOXcv7Fjd(D6<)~* zAmeusmlDQkZjfZh!*q#3)dt%jp6vg@U8U{S26iy(gs}?ukQr#>YolUMYwj;gF2U!> zRf;mzq^O81m3U!FlT>^bK)ny8{madqN4moP{0i{y)g-#79Y4#2#m`#`-`S@najg0M zvhf4N5{9-$y+g;Baiu%c+*u(FX+95npPIfV>5Y@pef>%5yyMLRA}rVA0jCJluX3yP zQ4LL%(aCpU(p03XvIPaRyzBv3)CM5J;`sC7$0j6t!M^o(o-SNmzZ#AXDi_R%rlRS= zqk*Fgf^PMHy_3cCNVRE4<}hwqK~F5Cc{c_qR=AC>`1>Ere}tdWvBIlPfAbU8=1!rX z2Uvc94@e32C{wk8iac=Ajn_6m@R;xRjho|r}SrVFYUNA~`qXln4gLg=T zE_H;YVU>9x9!#{f8(8SyDdzu0ZI6iM^Tjf~t7qhF`NVd6C;n!C6Q97IUH-(YX>WUW z+<7_~Z`ijvTVg1e)=48zPCoM91rAw?xOpf1e6(9?eDw=+hSq&k9JO*m#}!GgRf*v| zAPLVQcmF_CEooxnpCz$nU;F&jscM5hrToE&nEltn1T0dYpPrtmyix59nsoC$Gmom? zo5DS!681rH`__4_J;N{$dX!6=k-0)|k5zRt#dheFoz(Q@Gs7#NR#H%=yL4>xEK>SE zAtQNYc*kvS^%Ub?=u`MEjhweOd}65w%$$EdQmkS@AurGRvtA8m7Ed)8BJ!5!-h!TR ztPiRz_b^;8zwMskip|uNcdvAf6I;Bpg*%ceY$fd^U-RZt{AbcA4ugupcP6$iJ9U#{8pQKVw>JkC;d9!p?` zC6^->*i)(OUU_T_BHt5Td;hDR1QiVoy*INlbT@5^??UvR&#MRPz;Z=D%oM)beqZ>H znBf1#7~X<$&nHUO9y|g{%3$G+>hty{>sWvHRv4#CQ2$H||Af*0=NpmCF!{DYxxldK zRkkkqt|m@xxFGc=*P^%+3!OYdQ6RUmzll_p?*`+; z#{{;uy{Zfxsp*f8H0^SJ^-!>4y^VsUcOprq1$e~n`OE;+$IiH?`I`%KhX4mLC9E=U zSKwohM^yZlj|ck<4O%mG;GRTw9CoSV7GR3ohc2snZE5y;Jt+=5&BU zHyXmgs?a;ySaA3-l^Ga3wydA;_#&x)8MqkOcenc*1vAFuDZrIdL((gEyuL{!Wgt;C z{?LSCHm+Ur?ZiR&rbNUiq=1z$#wVTr+5x502~hHvK>Cwexb&vBplF`{)25oceP;J^Ei!sAGJAD{rDBKT)q%r#vkOO6_!*c{#{OZOMPtOqj9 zJ_eJKp;Wq8)jCU+_#Gu)LPZt|Md9wQYo?EtD40#wr&PKnq7DXyx+Rx-q)27Mj2vh* z1Fn)o*1DUaZcEGK+$br?C@k?&Dh>|8x zt%}1gnH3$L!p?N-#AaokTdgY0>eAkKyBvqRhIOl$y;N38r|NAw-fm z?g-=}dw}u=qxklbwrN9i7$dv`j{%K`kF;_N+_|!fW)2r$#WFcbJ>ffS%(I%F0$Kq> zR%`wDj4i{pFCvydx5r--FbRKoTueh){R%80#i9}tq~P{_JgUS)_bbp5bOeo@DB?>p zV`#OxQ#Wah1D%+$RtdV{?77V2Mzc>A6U7?9_yUUD++4*(Xm`M71|!HWL!6fGn5BqKZMzbk}y59nSss_`c_^l7@PG-lb_ruQ($$+6)i z)iHTiZ*zxQK#NqW6J{)7X;OR53-wNoSHQ7MRv!vxZN%BPdFc$(NDFu_*^87E{2i>Q zDA{rz*Jup5gM(>JS}@(kL_k0;YPQBdjY(F;iYY&&+T1bzL*n@({w~skQzFWagvrAK z$X@Lp!&cl|UNn^@j_GQ#&MjVlG(J#`{RY-?0{`g(rbex!$Am*Fid8jKELWve zY<-C&-s|d2Z8_e`tN8eO2}Mq#609Axtv>PMcS6BRYC7n>FuaK%P&XlPo{uo^ z=F;Absf$>6ACfP~XE*#Yz7I^^BE3%aYWSYwwWC8py9Z8L6w%crnU(Z=#-V#drSptz z*q?&A1GXG%GxRE_vmjz zq{LoWf2cA8N5Z!%8XOda6_V`?AF@3#*o+hKj;(a>bHt>pTY8fx5E^?60?G|4R5AHW zq7IG=^vd_HPx7U&?Nt3?*uhgI=bzcXTba%ke0k*swWijpu)h*99t_7W(Qju63_7}e z(eK>``#)6vZ+idhPbqLH1yio_6!a5DiC_V(O>9by? z?RD1Y|4jSLi2zMA#+g;+n2_6yVPu*VkXb@C(Cd3bNlw}AaZN}|t5#USzV0Zw>XV@Bb=f<^ z#9{1o)NnjS+vD5@3}aiwxrTQg&c4>z_5~p!)%KP%@<7H@Tn>#gkMU9xF2{yYemel4 zkFe(&>xmNiD{PpW4=j~pwjX(z@Z>A;x%?P9eyq<=3twSKkz?SsS_7RKGg8^8Bjgw$ zv*#us-Fj-8l93WW_eg|x;pOL)0RL7Ka;*h>Oe)tN_vF`V9OubM*fK9vJ^`ZK+E?`4 z4Hz4Kl!_h3nvyXMty)_n;W^V?vtskp4sYI_w;U3a)0vd$+u209FDh1bQ%$+tfbPLj z_MldQA4j!l{aUNc^&-_h_}glmHu2ETm>H<;k_lz?)IVX#jTD2wt8r~Go%&#^3LRn{ z#;0jv!IrC??_VVY4@s&P3{@_!mY+izMN|I3-;w+waEfQpPFx%5?yMmTJnUpD@+t*AY05-X@IM2${bEl zK30qPqw;X{XFn!tR3vm=55)Hitea!a)|Hn2$Z8_b*nKG`Dr#7Ld(@jAzCc_XtH)}41jJXOH zM73m2*=f`)b&6HF*lb$JrQ7{m=QaY0D##Px2?jEgpR5K&z+*|~zo^0bA(c?9u%J^BC)uDSLkyJS)PsfJa>Q?n*A!H-qjJuf3yaNaj)cZ-aF`5k z>T+2crjbZzk@cPfg;CRR$J2HLYLnd78nRjWDpdMGZdC?rSKF22jj@KkHiR!YvO494 z?Vz9gLp3w08zDgLAU>}xU1Lk+`yH9jy_O5StFL8bAc_MIh_HJ;@ET6(0u7St&YD-x z%>$$&sumROrYrU$ZT8$rF3|BKMFKEawyeCupA|ONy+-p^_(R+MmHYps1_3|uV^h1* zc-KY5IA{CCstjMoO$BA0ti@E~Q!MVyk+PZ@_9_Q?0aToyU)-~K4`&r8-_UHCJlKe~ zx$ZbQIVokhhk_RxTMVlSv?D}#*IW)5L`apKEhPo#lloS)-*5~KIiEkldgg=9|5Lf) z>YQh?(#k71#B{#FLw5e_Tf|PwbSuYIspi%WjPVZmHFUP9cU_Wa2aEIZk?t^M1-hyP@)q3wI8?^cl{aOb7gxZUi+s6uzp(Y__nieiMc- zQC;s<#fN}Wn092Cdb2CEOI{9r(aA08>v+WSl5;W8S;b&%62!c#ZVgeZ8`>VAH2!|h zTWnfgsngPgL$`0CeqOCRKxwQ4W!x!Zm%e-ovYzN0jPDTI)xR8M0jO$7t8?L~k*_3m(Y?Cu%aU20!cFi`kQD;Potb?%jL# z58C^s96ea~qv^jY?%`TAF4`dB(;T&4br8NUitbr4py3D}KR+1D`M5|{UkjQ0a#C6= zSGxPS@Y(iEGFefEZqL%go7{S&x(_g+1;HY&#ae>)5Thay&#}(a5qXI^|EZ zhZMlVpjZMSASgMO*RsKJ(orzKuhZaOdX0dFSM{ZZ+owHM#Xn2HCi>@m+fIh#sIBa} z_=QPv7NE*+kSaYgI_FXZrToQhs&wY?U{-tm0Dt>>*)8S^48RO5)#&Y7NmzkAQx0SN zb`+HaF+;E{`kH-%_F(6pS~W4)}bH*KvaDAg2T~#=e8I?iU^g^4YFJ-`BsWQWMd~9D(V)_}SLq zLDY@gCWeM2b)S+I9}Ke0Gh(~(ch6&~YQk!Y?JRs18MBY-ipo%xnJ4PA=EbIojJcU< zxyiN#8SU%@kyB8dqK6g^2oCv*N*Mw@fWwR3LPpizO3C1HL@L!d+BZv$1u+TO&j=Xz zMfYk|Xiaau*!)s%KCQ{^U_xuy_0o94Y-Q7d*{u)O{HzVugnxE^ z8OLf$hLh-2Fz3(~qGe2n)_?*)yb286S&B=1} zO66Qd3B0(+^Ov$)Vd*;}{`&ttYDrZA>(x%#aY=Nshx{|8x_bwgVAF_m?riHA7)aG{ z4N>2NfOxyeV>+0gnY3$Lq6Lo z(kLQ%yC@NjHm>(zZkgWVbU60=b=jdI)amtvw4^)(I| zYDK$4<>tmVu^;lc*^T?$&o1`73OpvdJ(HLe*ewrcA67|3aB`i@2p#9qC2N(l?ycmh zWP$9R4!TM<+3)54%q=(tx{$uj!BIb&A%?R(jYlpqmOI}3>+#j#XNMi4+qcIOtirB zT_1FlY1F$yu+3_AYw~@^CRto(duxpZ2tzz3Wx4$s5)p=H2hNif9s%o65!Zx79;b)X0`_ju0ZX;G`Ficua)@cO zfehZ(-hf81%sP9|ze4x&`0!=xZ9w%iL}Zu-1ZBzP&Lf~{d)fKmFxJTD%p!w+!z53c z3dc|;0I1vF?-0IxSPl+RAyo@jJQlw__lzn`l_|DCNSb=ur8QzDDG-CsL!%*&yv)z|$Y1HOzG<-r&BDa%(yYHsx$&vs(aYX+aV4@4DjB`qVbYgo;%J}v97?6- zNEBvkNRrWT=FXHNLNJ(D>m!7W>Q#R*j4T1o=*)vOjK3JHW9awXYy9#}h2k{jtN%b& zdv@E4F|YtxO@Ga*gQ<}YDWobrHMn5vg_56P^cfwbD8gSnymt$dtTz>(_w_CJI12J> z12(iRUwANoZIm+WUM{s%#ah+S;6=LI2LdK!!d?LmmqEvC=@*}e=CNxx=2Id^782fH zL1GPjInSL)i%p{lFB8#!GGzIk)&7{A^~jj_@^q-7z?ZJ@q;&An-UnqnTtw<$d60iT z5v_EGUo0d8>Bv~5s@*sd`7UjJc!WqHxy}!TCLR4~ zdbo!>JFZ|?fcK;%B(v1zT0oBm7v3|#aIeL4%uLP)d_MP)S>-cHkBsehR{LRi?yCKy zT|d374H3epFILwu)u%u0610sR z6Q1?r(0Tnl3sGj(4gXlPzxnXO27w9FRl2|KhtYs%1$g>-cXUxW_3%}A*!Weq``}}o zDx~4R1!n*ASHVCm^%|SxnbU9ceP8BZER%6Hf=;hzPfq-%6Fl|(%aLl{w`yQ8E96UZ zRa;t{yHM9p4US~;Ec;4-L!XSCd`w(?Q>6>`1&!A;42z+u3UPev2%h10cUfmWpPb?B>eP16q_KQfJP;D=scom8h-UY{8UmpA&{my5Zc z5fDq07NjedVfvcxa`;3X2>6hdE(~5>UO-;h*CJ!na()HIHhIOgeTYFoqg2Y0c3RyU zFN%LIo}pJc4X$l}C1>Bdk&SuomYte8d~w3IWp(3#3T-)1kduq*xNbNMHYrsdpFgwe zuHw**uCSbbr`5~+FWWRI(OYLgr$IWyL|s&b3~#BEPC5h83jm$;kZuhRECl->#aJGw zu?^A#&Nc7deG6xJ@uiP z-@IeN@0uR7-c+YNj@tclx>|E|ztEHK}s zt4dd`E4kZAWAXW=#~88&9`{gIl-~__Fo|Q2$a3$pVaj#=s69(E6ydn+2D<@vp1mdr zEobUMpH>!$y*}x5-?ECmN*o;T0FR@Y5Mpsp*#W+g!5oi3|MVNbBv$96ABF@4#hKvr zugNwXC!vSQ31;YeeDiKX(q)rFGxsyf#xP zDy9H?LjYisuy`P(7l{ajD-P~8>^f4OL`LbfFxcQXD!E1AScVsd@V3kYx+7;hnb{%@%XRwUL&E25d>)FMfjIK(If|J< zimC1&w!`rjYWOxvso>)FM?~+7hN2Rzt>RxUVRjk)kIW&|oRJt^Y$LEV9X;)NQ z@l%_NzOLP4&oyYkM;f1VztE?Am;sXp0AI@Zs-s?lE@;R%Y#L6dYK7W!FQ~18?P`%Q zH~3jOp+|>S9hT{ZJ%-7dtI5bx>hJj%(h>C~%z zRd6B9n0;05iyuUo8R(kGxvG;$^Jg~*e68G!9ev(~z>0wAw^W#gvUD_dYFdkUj0$b4 zt_9FLC6zKez%O3B7^-(u{4b^irRJ@ptHkEX!eK zmF**c?ziizro05W5RL1acYaTy1p&G;qU6>I_?ZwIff}3dRbqW`fgj*#h%*} z)x)@&`Q)Zi*`wxTlFfy1xkiO-rc-2n%4VBk&m+HEM1Bao*mY|{CdmDudNB!%6|k5F zBEGAG?MdOz->;zK^BSZT=1wJ0{HJp+i+*aE@wrb&a}>s~vxU)3hpdzgVz`Jb>9yEn z;<8GHftgVW9_D_jtG)4EjSRJ9_QSmWl~(hrG-`!(&w9DQQ`@zI8oJ#F*zV)=CeVVW ztkF-xBA_XOQDwyvR0_FRqe8AJn!UQqxR)6G{a}kM8FZf;>X+SF%F`73 zAxgoSvPfa6FH@Z3@jdUcF-@m`1x}COg-+1ub=D`m+Ac&ExW8?W)~+NlGUZGdRzw&ZZuRsB=mUQEa1BB zBNL+i_7$Gafc*IEUO(!qM7{HsC*=811xhl`eyTh zjBWm!W}PfQ{1L|DUI5Dl;5CXOuFy=_)TY(*MF?aiqiXw6(3G~!Ik)$z`^|!^=2l}Q$U<9eH=)cy`<~sh z6AhQG&nw~~1iy^^(ke7qU~0zT8~6fKX?Z)qE27E6JY};1eN6-V>n>j-WK_jUH4VGM z3#ICd4B}zs02oEuuL`kuzOv~C1oCsMdV_gTS#-$E_?&+B*#4Om+DoP%WDHsT#&k4B%&t_D9qM4EPrYL zCi!8tw{_=uR>7k!D9Uyg%As}N<6`!j87_oECT?ka`RkYKXqfxwTrgp85z#w4!Yb9D zM;a%4NXTxCi2^YVTH}Plc~`h#k3rG3?qa<)Zhh?4)(T6WgheX?k4nsMHc#S^Ag6~% zN+FW*?3C~feb6!l>%zJvX51G`X5DT2!fbm_577nAd+?-0Ks7};NnVngWk28y1rbg5+W%B{(DiKWNZaXC^tVsn3pSdF0?>(~dG@NtbM5UfEYl5s zgqCK$(wLuZ8C_TeC6(ndno{j{Gd4zbGt^GtzUfcm17a!nwL%1rQ9L^Tm99eQD0d zwllW>XQ9 z{N@AHO!oHkewHfo& zct`pNl$i}R1v@}~e4f4DJB3>--3Q=>>dEQl%|R8)A>*!}C_e`=Mo1Sg9i3^d0F5uU zWnB8i1a%QD@ye(>WoR!<1iyj7Eb~>W@cG=Ks(7XS!#da7CsI2STW2*aaXg0?XxRq9 zaB^CJNLR&(y?D7g&M!wj9KlbvettsQj+r*S)NX)UUSE*eUkI(9a7!wAWtlppehrZY znufq1Uz>DkR_E!m&?aPe%W=SzHZ3TW<>HxF=3zH`iA^;yN+86(j_?mXnkX@wYQN&a zo3ipjVgO5uNBXn5d#S~b=02UuZ0(PqzaIlli!5W=7%Bk#frWd6JU8!#c^|b z*|O!fs?=cmPKd7hO1YosWTtKk_V`$d3nni6sr1^9$1*OU&bh=-rkl{CKfY?%Z$JW&f5D1J_m9JSUK}pyY!W+;iH>xiziBo;X?X^yv zt5#WIzcVD%_slgKXj_3+bGg#ef8xL{Fm5%mEgc}sY9TLI*yvh?NihUH#sPP$7L@p^ z)X=e4#LYNNccge~VoRLpdnu#|QC_Cezv3xZ8&9z`NBB|>FJFaQ%D? z()&pxKsO^oRd8(}b-^6pGnsc(Gh5|jAFrJ^uzSBK8kI;yqB`9^?yZM|@`}K(1r4H? z`ckfJgnVeV=kn_>cBU(J!L^q<8u~QPSF)iyZgDft-yMQKsO|u=2aguZAcV*Ds2AYw zn6_`KF>bKF%#KjvS})n;(K<`5>%@Jia0}qC$(^%HpIn8c-?kwvLg`UW&WN3-a z665G@H%5zvh@i5bW~S0v;?&n>nqVh=27LjGs|+7^7f6;-gm0!XO(9k z4FiJ9+*UrXr+Cm!*9n+lK^`8>TSaqrCso%-$*+s6nPf)t$gok=)<2ck%c;$+(XYhq zcAAP9JItC5>|1Lz+ZgrAiX#q3$k>Sv-^7N<=R;&#XjF6Bbz)`@IlL_GYhJy9Rcn#6 z+y=-`l+TVd2wlc7xLt?8BvIO2?3dGezWhF3M8fTL12c8sz*;9{U2`p0dmpz~eEK7XuPfF|j2ztcB;4w+ zJWApbD6D{x5#O_;0+?^x!l0V32ceC?h^No7pOCKhGB;HZJ=CzLvdQ{Eo5?KK$;aXD zG@^FfnP+G`m*+>3(OHsV2*G0ovkP_iYMu6?a)*sILxQlov|uv(5~tw(EXxiPTs|aN zGE`d^ANqYPW%5|6dv4r?QdFnkYst2l{-hUAYZwSOe?S1nXK8#0-1nlcx3OCl%DM7z zGvefT>zTB}nTk*y=tLvqLg{@+*iDcQ>IhCmQVnOdZuGfi&NmntQ`Rb(E_@fBm{s2Y z*7(0A!Kpl8(LHys=hdLw(BM9EC;aeLhqsJZ4E$|J)XP| zk(35vx+Nxqif7Bij6H{s^YQvWam+Fhc^p-YK$Ljo0tlWS{C}ifPjL4 zQk5!QrFR68CPgHn6P4bP-VqTH5JC}<-aDa(4xvczy%Tz9p@$X%UuNF)@69~tH~-z6 z+}zxI&OT@Fv(MUVmEIb(R2Y>lAT{5b?eh6pI>*Yw@`|rFtH}2Sn}?V4K&^F07_!xQ zYpyQmb;@N9)Mn3Xj!s8tmM^PIjFy}JI+6$_jo|^3Y!d; z`9MT1P?FvAoo(4MMZh}X2o4>j%!=={P6CG06!_h&rR!hoERf*y z@TFbzs>dcW&DHDD0gJB+2#uYV1F-vQ#QCltWHcamxx|&3A43E(-{UltfMmL-FZC9S z1sq3GV^o+KJ#^7$*lm#&%C~P!{qg75g>>%8c8vK%%@|su9zk?;1sX^PB(rfN=XU7E zU+rAEHUglgtCfC0ati&N6hfpxs+YdU^BGf!^Fg^V9oAVA+$1e9 z6dl3t>~)iSCFqctzVG~UT&i2oCjBuV|HEpwd35HP<%w28qBZ+-b16NFls+d}#(+N5;o` zT~Q270sUu`uJhT(=bPGIkfywsTkSc|&)f(OW4V7eo}2ve{08@6H^|v?BsEw(t{Bm< zwyOwKCTy96)VhI8T)t6BROlv!Cro`qJ7pc+zO54Wyg7rq-|A1iY=UD6&fTgGf*}E6 z_R~OXLhpe9o2s4*+LD9-Jk<&cwlx@A#9FJZinx>0JXfV$+YAmJJc(4LC>4eXFL4!^BvR{iDO`+;gevos ziM@yZD}_elj8C1<@04RDMW<|V*+i9}nxHoM4@OjBLSA8XM2*Smrr@`K1{sZCZGk4b z-CA$zzDSPAwpTaGyuxhWQM<$PoKPB&tMpQ>{tCV_@MAZoIOo|3=0C zTvcwqO!ly3MppJrCLHj*Mk2Gm#%hBS6#vuVqKnEn86EIL9&;M(@y z0V~4YmgiQUUG}~;;Ppv(w&vZODlXkhk>-pjl>@k!=Wu3Mna!Mg&B_vCrpHN9_W7Gr zLKoym*WdVwQ<-j?L5U!Ij#vI{z+9vDvZUuuUBrmNi8yM3*~@;bhm)m67ZVyhUEAf# z8C2wn*3zuFJWZ-tKt?{p1`LcGhq|pz)L5wH$rVrm_vF#Vb05`e`3_OLrujF_A1EXM z-wb(AUn-LDn-9La&hI=T6$yMWY+{=;l9T-X3{_hzQ9}D#F`{9E+#aeEPU}ptZK%3c z9fw6TN%#)j0@IKYrJ13kQKBSqP0_Gw-0sRrnIqq;xk;MnJW2M?v$@{ZzE%%F}i@~1U|&{^xfgC(y~<~ zXG)bd3HMNL5`W3j1l+->YuHsmEV61aj3Wf@gBIdQaOhPHc@AnchNjp>e?KUftd#vH zD8}!hHG-v6b=saEoXzEQy@hi_ca{oWX1v!!{11)*`YrP{b+sF|RpJ|z(Nl+0;vT*F z^(dR!X-AkZ<&aSo*OpR@luB`r(3_&x&fS72E1P~1!*uuwYRZopSB>Txl zWS6PGsUTS8g$?pBq??6xIS&$OJ12;nChK{(p^mL$2HYK%lQ#sli}mYb@B`-5;sg<4EjcS)nIp(GR4(^Yt(2+53z*kp7HltD}#jU;IqkSv#?{ zN00#(_a8d<6eJnvTzp{+#tVzF98qUJCyXN;GV#0dEVE?Oc3eJK4L8_bp>~iMRi&S^dubiT(O)pe|^)L zzi(2TA99U<=F44{9|Vf-R?ewx1=jZEHYbmLvZ7qPb-B(v6=v#1-%Rrz0V0K4HTHKJ|Dw7C1+PpajHrE z(yv~eJD!VZn_u3gQIs&rva}T|$a0ftbgApyh}9F=4mvm1babq6+?btr@6|1NDe;UP zT%T<*^x0p@_*7OV>-9qr>Asf5&aOrlxi9X_Pk46Em!P+}l)@uaM|rwcm2Z97iks=s zLOs!ku^|r5Ex%9`_lZ$$UW3QoLql~-IyW%TCEPgSxThbZFy7{n6dzyLo4g6@DQt+i zv_(26SaRR!Q6?;O)_}Qp;lEf}qXBDz>RR5cU)tA+VFgYT2X<<|k)cGs%~I`5mCL;X z(=l!dTHUG3yD1nM#w1K`AuS5X)6CF6WyCAtaP-$FPGBwR#lum zl#2h(T>WH!M>~*`sKm^ePCUo3L!FsD-xX-bUimeSMoV3NuMHgM*i&*U-$@jJRU;NN z9~M%P;Dvek48$XkCMLE=1{y2qCO|$=J+HCVbQi0f-%3T*hVi;z%KiwMv&1GuUN>P8 zeuyBT?-&7X6^R5}4}oNj@X1f3D^zXtNWqp-rPn)XL}tcix1^48oK|UaScW@I(C6=$rmEH7NP9&z%Pocx!?uP#aR{T2@ z%Y2#t{X{~W$2S%vz|3?Lc~s&iX<_iQXl#FTV1G?C!Rv)rS^SyL@y_+9VF%MQ zr&H+`+A%BKC-WZ#E1M@BpK?h(N%N2SvJ%OIwC_^BePj4GGt-wFkx~Sd@_yH{sh-k) z^VlUnVdw#P^|-9Y3sxVJ1RAjW<|G=d&O z(OyD1IHV}UugOG6>xIah}IOSez42US34q z2h73_XuOUzlD5Jl5q;93s4T+TD)>i>6|7Dk0q&Kl0OBF8!x7s{K)|BJ$>HRj=JP6LRD|b0OqW8p2R|I6A~^ zy)&Ow-vtT4D!Qw&GL1HRg%M{Sb=U2BKXSpWH?q&v@>8)3B^1SC*AN?%;OH{D z#Sf;Ux*eY%foj)S+)&X7X4ae~k7;Cvu*C7^90yf3`xDN)gxW(d!)Szu9|bsTKkFdO zPT>Gu9zda+JiNTe<@0mzwkL-^fNl}f3{K3kYgbzN_r{~JJ6ID@s+RyoCB@as8JmxS zi}!xR_W~ckBlqKun|zx*B7J8ZXeIv05Y4ZG6F?kSO1*2_$MISV)hat%NNzc20x({l ziPH(~XnA_J%gZlOGG)!=*naCZ8qZ^X4oWuDm*)dTR)&)0H@kXGfEb7f1?I9olf zN@Lb~Z}AujO|-HYtGqTUB%Z$jk9fO4H(zvl7jKJeahjU*$DLQ6UTY;O7E)lbkjUrlDjI4^ z`9hZW16v;B-&$U>>{}|a@VN`z=$x)t)L-2~kbJMqQ#fb};aI_}imnC;PMDpV*&{_Q zGx^Cd5nFk-D$bFSl_4>7B07~Hpq#pN3M48I1QpLuw)8XfY$jBw#DWX$SL9zf&h_@* zVRbcH%m|~k&nz-d(S(FWKNh>19a*g}&yhttvlb4kud*xblub)i_H=(w*Kbpi3`CvI zm|!;wYAe0U=>Bj+a*zt|`G}!Q2=tJ8oLA`*QMP!{cc1i<;dG zYlWK`JuY+NER*WQ>UunN#+Hm|?;rbJ>8|%q*Q38)z+JM1{EEEKq*qveR4$B)5Pxt$ zBc3rl-JIcNSF4T=+Z2IGvnn4k4OQQ9(PVXB&#kV0Nx`YLVz;v994#q{sx~rtb@NTl ztK(`ONs8%^6p-6=yZs%SN%&dq_Hc;t3DRSQ66Pwu)~~xzD56R~AbwKVoj^N+09qsF zPWTpbuOn{W`ATEybgRVkEO^G{S%rn`>6VyiPIeq?@h;(wcaXxx-rTaAhnWDNiQb_d69tO6VExnPK|1qLadqAAFf-Q1>xO zTl<3JLUPYck@IF|@ACt)IiDIrR1tSJ3g6Qec%tKq%H^($j~9yUta}UhJ6gkxtAg-S z#;w4#n(4@i-ESHI#ft56{?hK+t9rxyJ3DlQ%5_`2qIydz<6F<>yYqplQ36FGYoLEu zBljQy7re$OS1j#V6;{=}ag1yey-hcUGnp?x=Qed4tB({NT!^bK6OVfTg2ghF+{mJH zzrNJ2uJKhs5P+pzK+k9V+t5O~|J70g9^o8yLt=qXU}>SOGNi8Y@_5~&hVO2^IrNpj zi6n2}cbFWq!6JHbsUQU~udVVb_zTJhU2ql`S0w4Njfe!S6wPvup7^K0SPAKC zr0b2&dmGdhHj%A+K!>pI2dtG*|MsZ=(HiwwlU5 zwfaBW2E5O552K5H3e$dpui~qogAOPsJwkg@KiB89R~mC=i@KTj(K?t|!(lfY6GNQp zuDrWO1Gh>YBhNWzk?1*OxD5Dx`QYWAzX|4xluUK+oJh; zcDkw4QBV<;ltTibSaDP$NnCJf`^zB#|2m+C*}U3(_-E&2lCZ;C7b3+ruU_%!i~y2s zOkPDyQz%r_!%pLMy2yGkZ3*aL(7v`)SgsNq!6+w$*`6xbJl+W z82x1kaHh04gJ`cxri#79rhK3-bc}^)^8s?xmP)TQzbq&o@XY=}`fHL3T#88;AT-V3mZB zoGN?~wCP86EL!Z(5!_R7J}od_Y3831i?E6owlwS@)h5Na@iIJrcVh0p9NKS`u7g8e zb#;)~X^GC62+ebDnC7-amq{WyjO&utiIt zIsf6*g&PUz$<=v^xyoIRH*z=-Tyh_xw~<~!K*MALSIBFiK1bgpO;MZ^u-^V+2G*IB z@zRShk#3in6JB|q?$hMV#*2e(k2`V^AW!AW-LIZ^%hczv8Ry`l=O3lFZ&mp_&!W;f z)?b>N=ZT%8C3|{`8<}CQd(Yg^bKvw4kCRQhr1=`&gJvcX8CGI?2?kY3wC6>kyRzy7 zN%q<~xs=|BG0OsPp;EV9A0gf2?YSH@SNL`{>F`i!+#eUksz~9~?W4RVzB%u>TjyMr z5{r2}w|NxQS6&B#JD}tf9OD6kWzBB;E@KTcw(^_vsPUVvZ6w|3f|GC<0WUSC#S%}%h50%10*RE#rT`f&@|PSebd$|xWWSF$v@tF*1ktrQx=(+GGWX zcwN%9I9({mbehWj`}e#1lOmqUPwBkR^Fkl*hs6CQhow#MZ6uh{rX22P5LY!8%m*~5 zFe+7)PALle<`0E~15n-hWd>fRcaRa}5c@JM4$q6Tq{$}lDpk>d(}mA-r)llX);4QT+Wz?_~>-*I`+aIGTYVA0L+XlcX{as%HCvznQn+O_0 z1$|F@rl0R|isV50aZgkEEW1={mU#|WEnz8KrnCIKwJP&zA8OWF%U5;~6kRSA>LpVE z8(sb%E0u4k@>9o@n{3|MXI5hon(L1yQs#?os5>AS|0oX;FD=lxse?I1a`{Brj6IY+ zYVIdh(T(qQp{xAqlW;D z9EDZ6>e0E~TPd9b7>b+bUDkS6#45~bw?KN2tIV@9u;HJMq7B4B(U0_di|9CFGXT6z zpBam=8I!a-OB%KSN&2XTU<@@yF@Ak)QSCvxS?m6>2C-8P6rDfbv}P&As;Fq0ZB-^= z`;QhWc^8c%fT`zY;^N|W#}{$zjG!*AlfFFfg(X?MB)Qo97-!$z_1s9!$F#x8JvRD` zFygY#%&tTg1B>Pb6Bd{sG&vQ*;OQ-CBN@AqL zN;Y*-BuosWnp4nmb?UexbnC<=%%iIeQ1)(dc-Q*qx6i|M-5xk1wNiX~;KaikdMF83T8N9D`> zgGn||L}c2~rf}#-MS)DzP;nyX#Kooz>)^qpWr6WP^M{&uRxSz?FVJ--lwB#Pb`lE3 zG81xhSawHJt}^YoENA_K0AW*w5}0VG>dX+Wd52-DUcryyJySxFQk|J6N$I8{MQ+K{ z{%8`Jr5=Gsrf}?v8SSy%|71Cf^pu_oPWR$>LY-)GnQ`$qNWj%?JAZrL&hE!uEM|IsVz(=UU{MS3i>waf}Xg zHm-$Pp8(LawE2}4!E=M^!?JrSw@b1WwS#IKY;+{gE>|Pi6UQ|@vl3r!(QmoATsk%O zR&VvL+w9ib8~Fzh1LqJks(sOtmz1VNJf$PeDpqQa613W{allS(t2!f!N!XRwL1*l7AKR`gJp6)fn5w7tUsPcdu*(E zBE*e&xxN?)s!e&N$|H7T?_j1(cXjkYHHY%h<1D+s7~4&eUYEfk)HaD>js=rv4l zx6uG7g>{z;zTw$MZ=HU_;NrlLA36WNW2bOLXPP`#|4H4+O4m72LeksmQirNZO(&$1 zrUAn~dDtxKm8I6kLR#wwa&V!x>|?azXruih|M07;>eWh#2KUav=Ich-LMU~L+ns3o zKIg{S)nl_QN^(k3oV0*1+pm)NG`PjCUb~?}wN*~WXb}pnft@v`%At}seucYLS#GV#^)su%`Jri1 zcTID2ejd?QoRjn|@GCEmS9o+)wQuwhn(JR!LmBqA9U`c+#z*7uBsg7-knPmP4$?9d zbY+SHLHSePXoRIXzo^$}+if&@_&mAt>L5vyrI;)&euLlt>%`Iu1GYfk1{H&nA*rQ{o56-Pwmpnr`V1IbqL@yV(wg!Vz(-Sr^*pMLzFg6Xl`Xsiuz&K>QPv+%*5?SYSggMo=?_#Fx#@3J< z?bPG-SMKZswG>jmJrq~R;zu^S%iY3$s~s#SFOkMeaFV*x4RIFg5c23VC@tQcmJtk% zDwpH;&dsz`i5K&pd0DgB+-b^0NYZxe>+EtVdpU`xn-$;P<$f3X4gdkU@>sa~YD^J% z0?URn%j{v|(-ObQz9*X_oIehmLYG&@J0zTNuTxN!5Y$E&tj|Np9e2?kkzeXcK1Jg- za@MbSii1!Ndk-Kg&=N7N2s6EgIlc@BV7$W};Lv(AB_mGY5LJB{oEf4$mH~o`7}%Vm zI{HI-IA5ELg_1%YULm@PqVspOqT$9VyDqrEN^8#tT#Y1k?>o$8wkTJEcM&fWle1nx z>niNWRg0;YZ+vAjLuG(0#?p~z{`~fiBbzTOLjg)AeB!K*FuT<~(+@yH3n zh?T}4%Wm6m3tCogS%Ny|umJ%?tu9%(jOv5vH5@+tH?A4kPC^`Y)SPLBBZ9H&Z zby7J(P-u))X!bzdjqoewY~mgP&pPvIwaYhHZ6#&t3s_84j|k_r5VquAjc2HYl{Fp^ z*OWGr)HxyBMd0Be4158zolSh|xMIVHtWdB=ky9#pYMZ#kiR)Ca_wRbOx_wKreUV-~ zZx2a)hP+QS0PrFrp&Ha|yn@3A_uh=r6Ypb2ozJ&!;3`@=MBssQeUG7>S{HZ=|vRfHeTF0m&}EfmCh+XZ-F8_!# z&iUgg1Q9DT;)x|9`Pwv?=C^9=gYmmVEl@$A;Orc8v4lA3<_FcLcRzOt@c(kT_cPe!Nkn3y#7R1Mi*+`#RdgcReFtAB;$>EpGVa(U&c?KQvlJ(3=#z_ zPSav~R@-EeiSXj*Op*56eVYY=4P=Etk*>7@?6j;^axjXi94 zbhtSsD7)UtU#iG5;O!C&Bvho)DTOzC7cVloq{8a-FAOcpid*{VSTP3}{S*B-4T4;d?51{(%jC&4_oMlEdl-jjnktpIP! zE!eP2%sle`xp7bf=AD0Ep;j9`?3qH*u%diWyuKx&0_Gr~bjX5x$6dVQ`LF|AoNLi- zTI9L|?`o`jqH`-TEa0gbip62d6X)aG-vb4f#sWWs^*=$=_$RW z1uWll$vgUZxC4lYURYn4jWE^`&x7)-%7e56=!$j#4&Qm_ z8&1N@U&X4#$!V9{gv^PqRl5x4&5T1qXf0&UvD|2dH9T$;6xJB5NSV|Di@%4o%0<(;t*Y3vTdT|)0k z&Gdv;;6zd=BioZF;l#AltaqX`s`O0W09wg^|NTqQ{aK)ph6)33~O!lr9v;#0#?p$O2_3p2)YN`CuB;>6s1gImAT z)<{m(C_-z?-KOw2m`hXX-4g1j+r2!)#nK8B?2OlIO~&h})MUb3V3%P~8E|uZxb9$X z!p#rEd>W&(Gxs20K9C1)yR`Ic=c$mV*V2^ZJrLNDVDKQJ5S=;R9Bt3bRF9SDt^ixR z`A5bqMfD?xE3U~eK_CP@VHkgVDF~9c8gK&b=1>_6|C#U-L9tPJOf{9!VV=fXa1g1- zrbez`gF{Aih5<-YY?`)&ldb=->)0X^3SKVH^Z(iCb9Nh}E6rH}9Es4MjK*Ab zu%k?l5xpYRT>?VT=Eyc|*l@D3}s(a>(&UGI@CTQ^T%PhK2Vg z^EA5+ozHr3s~JvIABseu>r=#Vg{yl=uo46JW*1oJ(7)A*+3GhRes!yt zc6U77S9iao-}Reo=$d4o>$f$ZP$B7mobGd<42Hu&y6$_O(IwrlfPL%VBJ_<*0@OJt zKlJ5OL*|{;Ot|LQc)TjJ#_+;s4-xx6$#QM?I(Ns^Eh7ZIG2K#0uA_;6WheSOv)1n& z(b(b?cpr^7n9}dInw6sAX)gE!V|DR@vgM5ssIsy}@XiKS!S|ogAil5eO%_FGRa)|A z#2)=gUwn+vRYr$_=RN@tc2nt}F8!BZ{^O~Re^d1(ZQ@}ydN-tv=r;dakao&=74*g2 z48O_5(eKed+tJ*(kbt<}zs(1;kkc<8F-BZUKSUuPD))at|0-QDM1KLB95%i@7eiQ{ ztInGbk2E0bUnoyYCjA~ID__GWO+JSe^K;Co8;N9%a|KO^R5-HrSoRm$M|J9&HW+I= zv3s@**htyhLOmm;2xaaicRbWMgwB!q=VtwLO^iH-?GSUcYA%zy6t&I9|Os zOtqfQR$S1O_jlgrAN%_c?7}P*_fqW%(|d^f%c+cUS2tnS|LK04tP5k=X&L9%y}ZMf~vpCqu&0TjJ9-|2IwgdoA{p5L@(ZCqyF&#&SjfaVG!YUn10uSC3`4=%h_r zD8^O!MOpUW|3hCzTm#jthhl$>`}_Bg^QSx4r*|>J215Ra4pXzlq0dsYux<;!O{3}? zP_Nn0{7xR%cVS=5`+wka<$C={kQL%j`z$b|DTr+_{3L&3YyWHD_r;*I?#04iU?BV5 z*UrspnrswC%|`a!m0Hju;9F_f9AlBd{Hp)?y~#+9auD|kUBqGg3Y`~V9E+}5=6<&e z@E8adf^RyC&8rD9`AU_jP?y^Gkefv%Pur6uGyWnYb9~yher^sIEmi^7ozUfvoELukkMqXg#%P7JZ$B+BwPWzN4zs)T z)c@kxN7YjsVX%PK_xS!T>J)br70l!AlgD;478gduDIJg64-{e}8f7lKolcd5q>!5m zIu^m1Osoo#CV}+^gpbA`?h)`UlmM!9Sn}7J;%|@j_j#d$0jGysi<}%bz@gv`^K>}B z7AI2C(5q9a3A7UB^dN~=RBKhhQdtWL;7SmYJN3Sfc|SMP9mgort9N3F4+ zo5^>#@@M2t;;k{Ox_3{Qnx&+0eN%a9hc^{s3>+^t2fVkOo?3nRwI-vvjzg`NbrR^b zL%KEAOfAu{UjW}FOChc(+Yp%-s_eeUOP4`_&-;&7gdO>tj|abFn=&z9?lHcZcWNQ$ zqc)whTn(6_qeyCW_-7F~JL6O=e>xtj`jge?rZ+ccr)7a{osFL7F6=O%fTF^IQW;QK z5vnLBg8TwLvISB|LnKd}k*S{gl2jb=@<%j8fSRl7EV*gi3G3ADn2OoV@FMXg;zKacQtU_SzS4qjK=g z6Agp?+{9Ukr{f2GoPG-5Y;rqz;IToKIig)iWsH&Vv8*&U&AB=WFWo$;;!rg=Z^~29 zfD`L|mdCF+$c;FbPh->!_~R7RpW+rX2yVYC5oYZ|wF660b|Gub+HR;pu_*k{uPNpA zr)Qn$+%0;KZ~pbs{a~>Gen+DL#u{9L_)$cBDG@G|{42==ov~-CZvKpfxFQ4A$%itj zmEu6Xfehx}#D&yD$WobzqyyS6pGH=RR+e>hmY(`wI`7||_PtHLATFg4V3%wPxU-PE zLGuv&CW^S{U(DHpLP!7xo8B#opn1V$Wi*hU#>jxj4`PU67`%-ep%;PoZQB+QA?NWy z5{K$s5Zh?lYVhU9$j&_5@!Np~05F5(GpZ~ekr%%f%*7W=ok@im+I{-gA#}5I`=0|s zGbnDy+Q|fg;K0)!v-Kw;Ll*wR&u)aJNO8V1>rlHaZ1!b5@f5@AE!@2=pc81*A@+aP z1!@Z7xLXs{9^`SED2&^o{zx5_yMMA?bt5go#NuLS<2NYdKUv-HM-%_wB`Pm{vk9aV zzs4l;;&v!CQ4<96xxGAEch$dk{67gAN;%x$3y^+qFW0x{+(t1n`iyRv2fzvKzira9OD1dwQA*3 zPoJd8obea8{$1z8ca1sqA%m@nN>VVTFgaL^uJ}u<4(gX##{a>ONh#x|g@3o!X7zW` zdpn}T`S;bZnF(%kp;edbDQL-hqH$bqjpU|Gci{_fAY)qpwKWMv;NfB!4E$Nk zt|5NgL&5s93LzX;;mpSewS2__5NC~8hSMx^B;fo zFO$b#PklvhyZY%cbZw!=-jf0Ux7gZuoO=OEb|+8td~S+w{K~2fujB!F;?6?5gNC z9dy&Ox9b-JgTMbJmuiz?U?DtFE~$bV=}?S`aiJCd@R#N`8^ZNQbGDn7PLZh~ZPx++$TD>*uqA!g< z(WSiciL!^?Y{{J|-b1bpFrXolkZ3oCCOIoG} zcj0lA@&^jbd}gC61Xrkv8pQ2XZ zGYyWJy}%W=HLO1){=7V((ey0|_yLI)7AV*h4Y)ppCi?`v@I|_`mG-{uP zj1@jsxz;tVTk;}(OJ6K4&=WcP;zJtKFTi*H#f+s6@9(V>9key(n*)b(RvM}@x05tw zj}bv%mTa3!`hb&lo@KAjjW$}L?AhGT z@guII86FoLEY_=Jv8w*$s&>x$Qsq@DFO-KoJU#gJ-^chb z9&yP$a$HZn-{)%Zxtz~YLx-k|QaHo32MkZ)jGSjt$H;SBYMs6kTlF*G|8zeQ75{w& zd2aw(6)aih5khGDz46e!Z7?EqYwTKdl~R#wWVfG&4tW>8VO&U(B&3b-3v~Dm-#g9h z=!U;2)bSbOz%ZBsneDFk($=W9*uywdZVqxn%P-DWQ48B7O!Xdh$*FkZEu=akAVqtRuP5m}*x@jO zt0Lz7HElrfdrF{0rm6g}zvkDfx0?GT4>*%Y`AlWO$!{m~h0UXJz<80}hz|Gne-rjJ z6T$J3m#pyjJ8$k8mg`8>9!uAyM{9)LkL_xjb+(7|XCxBHIZZj)sMOjBPUAnuRv)>k zd@?`x!m0^WsTMhaoThlTk{{sSB2+ZqsTI?%L4CS^|5j!}<2*ObguY0nlGC;ET`|t7 zhh4*s*4;rkE!zKGWIA{Q*EeZ~S&hwcWn)%9lDk$t@>Ljx?Tqu1!g#RUM=m|BC&rAg z6sFL&N_)#LeBUwz=SlpTPItD{1?;{ufs@sY6RP_X;70FX9Q_b$I9KYfaNrY*rcE*> zV*^#|NJr(E|77R9q-$tP7^-ZsPyU;EDzh!Ph)4>=F_tRI*{qvc!H5sAMNQNiS)J^U zF^6G!9~Lw4s1FhwK`?aTP1Mx)Nv?+7hYnTU9R<#!IUkQZ^@Ke%Y%-FD54g~)8z-Dl z9{c5o7-KVVp~#8#<1~+}n#n1f%@S^V-vIwjY{k6jlPlCu(@39}J(2Cus9Vn1T;&O@ zprIc(&=j4y?rxlWz{Ey zX4+OZ^fT9`8o$JF4H7}GLjp98 zr{q+!9)VPDxuAZ6Mb>%rNFTDU-$9qO!+S;uZ3Ru;N2hsO-)-<8YM($*Cmr=N!!3ok^mPXM z_H7CC+0&O)TkdW2v7)phB_I%?TUcpB^7gdb@G#>ibN;rCZldyMTG`C53e_I3TPL z4izO923>bRU4O@6&QVG8H6X10$eKs8)*|z0Bk{36)l2)<{fXB|4j*?*h(kLfbO*S_ zn^I#|Cw4JRV2Yt^^r=1Cl8zhESuSP38pxo|jU(_&W8HCuMcRpq7~UnZe+ZEN{dyyn z9N)F9jCpy{$6P)W^GvuPQV>MJRyG*C(;vKahn`D8CSZcyafL1wCTF`(Ov9c=9^xd5 z?6he~c@$12Vy~r0IS^Y`1&ZFYA)+x4m))JD#}_v*ky9UO8-c_!C3zPyneTPQLVQzh zkjDmteBMYaQ7Tqfyo}5Sv2-o7C{9fSNKa4o@poslAKxeHFx%_M)A=63mK>(fd^Q`x z6v`#?j)h|gNdMXSpm%dZ(^5A8zwhMbZ z)+K6DpQ-QZKZ(kp<-GP*#J2K=1X``7Zrhdk)p=EuN)GoDwWxL^YYIyKrpnVxnMIv?FO-MK)-EKDZDqCu8l4 zpCf<3Ho})V`c@3TD5?(DG(M2!cxg(Scv70&;T#e9p#kV_jf8$!PL4u(inx%$JNF~` zydzINj)$7G%Ie&XN=u70D`XM|9f)#4U82QGW^?TL^n-TM{>9Sg?q$u{53So~JU*SW zszhWip6is|O>AiYOOR3V4hIGhIk4Dh&bAV*818YPw{dj-i1o1XnN$$~iL$++F%qvw zK0j(+VGFrrHs7MM*=Tj_;l=%Moz*?KR*ABokxW6aZ5}VsW{hNV6Jo5PH{U*>lgJ`X$*0C9Di!U%{S)) zC#L)AlNv0ZGAcw4G^*8OqfHfMKRPx|IFm2RGSRTgLiVy>pTqIqY+VO_&<&FY3jFhG z1y+xW#d6@sTs4l(LVfP6836^mB@Kl*@4QoJyvl0RS2Dh-jArIJmRvOFc*&c+auP=m zqU4`~kmpQ590iyn-zT#1(pt7<6=(LPNsAW{i~I9sk4XuJEnW;|zsM}{FRk$B^E8Z( zF2v&xzppL%B<-9+a*S)Q-G`~d z&5sG>4rM~oCqCu8KdPu9>*F~hD7N6<_~8@%QVqov9~O7Qk#J+ZxB2LN^D$(RtNF;WKqTKe{Hlg{RoyW>)! zZ$mrgxXY7HIoHYPpMQ*{U453fdrd*yvNki>!8h~u$Tej>r??UzJ^STAxynLYi>%7s z_V!*2^2e%0z&UfcHV4y`a%WO=g$iDF>P;8Lc~|X1ceUtjUrJWJbV6y%7^OYGst;+5 z1q&H~u$KjdvgaXU@|Ol|9+&3$+tUy6`?PX^n9gE=U1GjuOg5V>(73A@v+fB7k^}?y z+1P_`WLiO=6Y&G6Y9Ed-vyVT0y#R@21Z2*tMJE;b*Ayy-^AjPzP$H!> z&<`y)xJs)EYiO{8VWqDQz~4J(p>EI3?K;*E;#q(;;*V^(XSq{$*#*9`C8fVzuWL=@U{YD#=ut7L>J%TcF}f@otgJv1eD8 zc&4Rue6K-+ri4z7?l@A22~%4conj!GebMRqH}m`@Ke=#v`^zzM?3!|3g7!UCV3@pp z-|~LGxH?gq>r%_B{jF$or}za^dW)~JC&pY{G8YICOXIv(+YGl-OO}o>VgU!gP@ApU z1q9Z3H2g?;FG^coV4F#SE&~v(uFfz6ylez@H0d<`OyQh=M%Grma3_dnQY|siQdin(hRT)x3(lwqmhgve9F3vEtQGF;QP$uV<#79F$ zdOZ&ZEr+lkM^#eO6X>Rx5_r67?w`Y7yX$fkZ)w*GEBs0>y4irv+?7z zeMt(-aFYaUQtJ@@pN7qeA*@H?Y%-`K969r=lgpcKr&;8HarZwh08%`PAL<)xTbo=Q zW+Kk1kv_J*vHM%flc~}*cWa=5RTW1<50Qmf} zhwqxx%&w`XaJEbAjw8EU60eBn&S{I?#$?eF&wVV!FTKO$eIEUlS83s-{iE6~EDVuU zEZE|y@4qB{{^O}#{S90ynxJCm<dlJJd1+n?4vxY z^B^E8J6wObBtktC;QpBx6s%D;WT&!`z!L&fy^?3nei>+-mQf)P={N+46kB!N*FMek z4gQv8BibRrcfPXK;?-I`m)zG;t^bi9H*+UF>XG50y+7l!iV=ZOC0Aup*h)_mW+F}*2 zwgu99wbd{tJRevkF9V-LPf!;y7N=NYA#uom674%7FC0AxdL^O&&l$?73OTTn$sD3K zqS^+_%A0GIl}Hw)!sL-E&8ME1C^>b{Siu_}wT;-v zU&H$^7(=4=L5LkHob8{)z$MyJJIO~Gw8CZHFG^>9PVP7gUMH}?`@HyMiUu`m&^G_X zHvR&-|A(tlPQ;D_9VVy!ol&honJ>LmKu`s?vb-ki*W>(}#vtrZzp`Bx?F(dg%}s&N z$h4Ax_w)y=Z{<500WUtZ_0P~Y+ed!B+|tBMobDgne75g;o;H-BIZyCsUI*RLX9guH8e3`UpwkT z*TWH~q8dQ};!8=UCp3E3Jz?3@dt*@yOgd_B>ow3PEv_v}B2l2lGM+B-^tN@fSL7ZD zUc;?j+GGqb7SY2CMnvT%4b(W>*CEeuOcJu*ZyDhWcy;T-NB zJ{*=uJQ|7kJYMaqJmM4QkqsQ)1?}X+JW7Gi3yRscX4#|w`J{&ylA4Z;s^@?WsmbBBG9!DP z_O~mg&3e48Aulg03gG>J8=qU|jZdNp-a7;;SgYNg!h3i=-T7h1?MF8+ZbBBAmb@)K za2~&GD-mdMABjcJ&NU|>K3ABEX3o5#G zE+RsguRa*tyl=w@`PFy?k2Qwf>!C@9^-lG=+(k*bG%~^}I#2gQMwsIp_D)G*ri)AT z`ocN-of1Dq)L!RsvN?}HbE*-6>q%&yWfT9%`~FFM^ByA7Y(U-nak{@|uU+(mQMe{6 zPzZ(`i-&kS@JdYLy=JwPC<_}OS`I2{b_RFUEIOz$%FGPtosRuJ2a26+Ujno(8s8{q z0BM}oOHIWnBr=blMSM<`1WVKG@o8X_HNdLRWLvf!7_PTj zN|^CpE$y*dZs*W7NkB(cbqh9Qoo;V_`;D`jT~UEL1-EV4l4HDAbjc8CWV4=wvzDxv zwsn81mi@kcJ>-3-b_XLIi;idcM)C}P&Fs{% zlxY}2?RIA;ZDs*eiWa)Q2AQl}thR?3k7qN9+f+&<&lOBE-!W>Ed)YTsS^dU6phiCk zTIxB$D16Q1(>QX~&l?oe1j};-ohICFZeLb04MzK(-W6oZWPWhBux;>=&)jxQ-JTTI zd$=u8-#Bktgs`>c3ArD3MUEZ+`mJwsO6fpn1rH9`CcwMA#8~h8m=Ie7fa+vLr?rCrj`GQ3KoPWN1g<@^jCliDc{O0h3B<4tj})p_ zi72az+=95{^cm607HRgb2XRv7N>~O?_R8h_hHwea@M$v?ePqi&t?-;Rk(96Q%%i1Jn?lx)r*WVY69Z*zBMYndxBMl3HxAFD$-RjWAUDAI!_EttUZ1lt7d^v zG&`n;&h#%em0feC8L{Mwm9$4$6F?pe8U!PGq;BgyEnlu=2TCxl%93uSoDGZ3)vs_ zLb-i<{V8H3H(shjX~iyh0v_ zE`ztQ<6-)s&B57xXoiPt@ioRbmiqN|a(r=_!^?kJWMJ2fA~QudHom%92Gr223AUIA?874?fbSfJl z8VMX769|}^H&*k?%bgARWN}zMt|oM~?Y`***YC&+NVUnndDN{yN6s`PSjpYdlN36g zlt3Mq_M)VAUDp+3t-D4=H5-|`^d)#54}L~+R&t6_@e}WVLF2R2wXKeS7CU;k@;H#8xeWYj2kxf;g{SIAvMagDC=HM4 zRf&omME<2pF1tOwZrqI=OkWO0eYfA{?a2wBDOe`)3=X46J-P$e+kLi_?)nJzsN^K1 zWkKNa`k}8yM)clLxDre`l9#+z%o0Qf=;95XYk+z)c<-UqPt@~rf`{zH`8M?2X3a!* z%?#=FrWjxLyk^ImYip{ZQwNKXSudHG0Al5T0d%HMp!S0sLyXVx+wN147u^-hwpwLJ ze}16*u}@m=Q)Lbtw@`DCEpxZlK`Ko;yNw{M+6C0uxZJrMUz(vQ{Z0^UJiC_2E`Ja> zvIi4z-@bAhQc6mPVY~!(o1dpAxNf65qHa#=c2*W$F2&#bR6EoOo@}OAxSpJQk`yyH z-3L%PW0Rv?IG-Fv^T@zXVa@PCCEJ+k<+}nlp7xhp4rj?oj9#>}uDq8DqD!pS3xJox zvwLq;2Si9=cHCLuMY*itNj|2M;JhJE)jM}>{GzuHr!CrK$D2Yj-NkYM8*B`@yPtMs;40ZQClU7=|)xgqeq`AepcVBjMqLTgX#pYOwBr?;C diff --git a/src/plugins/index_pattern_management/public/components/test_utils.tsx b/src/plugins/index_pattern_management/public/components/test_utils.tsx index 938547cca04ab..6aa71785d779c 100644 --- a/src/plugins/index_pattern_management/public/components/test_utils.tsx +++ b/src/plugins/index_pattern_management/public/components/test_utils.tsx @@ -23,9 +23,9 @@ import { shallow } from 'enzyme'; // since the 'shallow' from 'enzyme' doesn't support context API for React 16 and above (https://github.com/facebook/react/pull/14329) // we use this workaround where define legacy contextTypes for react class component -export function createComponentWithContext( +export function createComponentWithContext>( MyComponent: React.ComponentClass, - props: Record, + props: Props, mockedContext: Record ) { MyComponent.contextTypes = { diff --git a/src/test_utils/public/stub_index_pattern.js b/src/test_utils/public/stub_index_pattern.js index 5a81139157cef..f7b65930b683d 100644 --- a/src/test_utils/public/stub_index_pattern.js +++ b/src/test_utils/public/stub_index_pattern.js @@ -22,12 +22,7 @@ import sinon from 'sinon'; // because it is one of the few places that we need to access the IndexPattern class itself, rather // than just the type. Doing this as a temporary measure; it will be left behind when migrating to NP. -import { - IndexPattern, - indexPatterns, - KBN_FIELD_TYPES, - getIndexPatternFieldListCreator, -} from '../../plugins/data/public'; +import { IndexPattern, indexPatterns, KBN_FIELD_TYPES, FieldList } from '../../plugins/data/public'; import { setFieldFormats } from '../../plugins/data/public/services'; @@ -42,16 +37,6 @@ import { getFieldFormatsRegistry } from './stub_field_formats'; export default function StubIndexPattern(pattern, getConfig, timeField, fields, core) { const registeredFieldFormats = getFieldFormatsRegistry(core); - const createFieldList = getIndexPatternFieldListCreator({ - fieldFormats: { - getDefaultInstance: () => ({ - convert: (val) => String(val), - }), - }, - toastNotifications: { - addDanger: () => {}, - }, - }); this.id = pattern; this.title = pattern; @@ -74,9 +59,12 @@ export default function StubIndexPattern(pattern, getConfig, timeField, fields, ); this.fieldsFetcher = { apiClient: { baseUrl: '' } }; this.formatField = this.formatHit.formatField; + this.getFormatterForField = () => ({ + convert: () => '', + }); this._reindexFields = function () { - this.fields = createFieldList(this, this.fields || fields, false); + this.fields = new FieldList(this, this.fields || fields, false); }; this.stubSetFieldFormat = function (fieldName, id, params) { diff --git a/test/functional/apps/management/_index_pattern_popularity.js b/test/functional/apps/management/_index_pattern_popularity.js index 530b8e1111a0c..e2fcf50ef2c12 100644 --- a/test/functional/apps/management/_index_pattern_popularity.js +++ b/test/functional/apps/management/_index_pattern_popularity.js @@ -60,7 +60,7 @@ export default function ({ getService, getPageObjects }) { // check that it is 0 (previous increase was cancelled const popularity = await PageObjects.settings.getPopularity(); log.debug('popularity = ' + popularity); - expect(popularity).to.be('0'); + expect(popularity).to.be(''); }); it('can be saved', async function () { diff --git a/test/functional/apps/management/_scripted_fields.js b/test/functional/apps/management/_scripted_fields.js index 2727313ab2336..116d1eac90cea 100644 --- a/test/functional/apps/management/_scripted_fields.js +++ b/test/functional/apps/management/_scripted_fields.js @@ -36,6 +36,7 @@ import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { + const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const log = getService('log'); const browser = getService('browser'); @@ -57,9 +58,9 @@ export default function ({ getService, getPageObjects }) { before(async function () { await browser.setWindowSize(1200, 800); + await esArchiver.load('discover'); // delete .kibana index and then wait for Kibana to re-create it await kibanaServer.uiSettings.replace({}); - await PageObjects.settings.createIndexPattern(); await kibanaServer.uiSettings.update({}); }); diff --git a/test/functional/apps/management/_scripted_fields_filter.js b/test/functional/apps/management/_scripted_fields_filter.js index 2eb53508c2846..2d59d2ba57d5b 100644 --- a/test/functional/apps/management/_scripted_fields_filter.js +++ b/test/functional/apps/management/_scripted_fields_filter.js @@ -27,7 +27,9 @@ export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); const PageObjects = getPageObjects(['settings']); - describe('filter scripted fields', function describeIndexTests() { + // this functionality is no longer functional as of 7.0 but still needs cleanup + // https://github.com/elastic/kibana/issues/74118 + describe.skip('filter scripted fields', function describeIndexTests() { before(async function () { // delete .kibana index and then wait for Kibana to re-create it await browser.setWindowSize(1200, 800); From 244ed04b249a3c0559cf0274ac07481596dc9bb5 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Mon, 10 Aug 2020 15:02:35 +0200 Subject: [PATCH 065/106] [Uptime] Fix full reloads while navigating to alert/ml (#73796) Co-authored-by: Elastic Machine --- .../plugins/uptime/public/apps/uptime_app.tsx | 15 ++- .../__tests__/link_events.test.ts | 102 ++++++++++++++++++ .../__tests__/link_for_eui.test.tsx | 77 +++++++++++++ .../common/react_router_helpers/index.ts | 12 +++ .../react_router_helpers/link_events.ts | 31 ++++++ .../react_router_helpers/link_for_eui.tsx | 74 +++++++++++++ .../ml_integerations.test.tsx.snap | 5 +- .../__snapshots__/ml_manage_job.test.tsx.snap | 5 +- .../components/monitor/ml/manage_ml_job.tsx | 8 +- .../components/monitor/ml/translations.tsx | 8 ++ .../uptime/public/lib/__mocks__/index.ts | 7 ++ .../__mocks__/react_router_history.mock.ts | 25 +++++ .../uptime/public/pages/certificates.tsx | 8 +- .../uptime/public/pages/page_header.tsx | 9 +- .../plugins/uptime/public/pages/settings.tsx | 10 +- .../__test__/get_histogram_interval.test.ts | 4 +- 16 files changed, 371 insertions(+), 29 deletions(-) create mode 100644 x-pack/plugins/uptime/public/components/common/react_router_helpers/__tests__/link_events.test.ts create mode 100644 x-pack/plugins/uptime/public/components/common/react_router_helpers/__tests__/link_for_eui.test.tsx create mode 100644 x-pack/plugins/uptime/public/components/common/react_router_helpers/index.ts create mode 100644 x-pack/plugins/uptime/public/components/common/react_router_helpers/link_events.ts create mode 100644 x-pack/plugins/uptime/public/components/common/react_router_helpers/link_for_eui.tsx create mode 100644 x-pack/plugins/uptime/public/lib/__mocks__/index.ts create mode 100644 x-pack/plugins/uptime/public/lib/__mocks__/react_router_history.mock.ts diff --git a/x-pack/plugins/uptime/public/apps/uptime_app.tsx b/x-pack/plugins/uptime/public/apps/uptime_app.tsx index 41370f9fff492..1dc34b44b7c64 100644 --- a/x-pack/plugins/uptime/public/apps/uptime_app.tsx +++ b/x-pack/plugins/uptime/public/apps/uptime_app.tsx @@ -10,7 +10,10 @@ import React, { useEffect } from 'react'; import { Provider as ReduxProvider } from 'react-redux'; import { BrowserRouter as Router } from 'react-router-dom'; import { I18nStart, ChromeBreadcrumb, CoreStart } from 'kibana/public'; -import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; +import { + KibanaContextProvider, + RedirectAppLinks, +} from '../../../../../src/plugins/kibana_react/public'; import { ClientPluginsSetup, ClientPluginsStart } from './plugin'; import { UMUpdateBadge } from '../lib/lib'; import { @@ -103,10 +106,12 @@ const Application = (props: UptimeAppProps) => { -
    - - -
    + +
    + + +
    +
    diff --git a/x-pack/plugins/uptime/public/components/common/react_router_helpers/__tests__/link_events.test.ts b/x-pack/plugins/uptime/public/components/common/react_router_helpers/__tests__/link_events.test.ts new file mode 100644 index 0000000000000..3e857c7c20904 --- /dev/null +++ b/x-pack/plugins/uptime/public/components/common/react_router_helpers/__tests__/link_events.test.ts @@ -0,0 +1,102 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { letBrowserHandleEvent } from '../index'; + +describe('letBrowserHandleEvent', () => { + const event = { + defaultPrevented: false, + metaKey: false, + altKey: false, + ctrlKey: false, + shiftKey: false, + button: 0, + target: { + getAttribute: () => '_self', + }, + } as any; + + describe('the browser should handle the link when', () => { + it('default is prevented', () => { + expect(letBrowserHandleEvent({ ...event, defaultPrevented: true })).toBe(true); + }); + + it('is modified with metaKey', () => { + expect(letBrowserHandleEvent({ ...event, metaKey: true })).toBe(true); + }); + + it('is modified with altKey', () => { + expect(letBrowserHandleEvent({ ...event, altKey: true })).toBe(true); + }); + + it('is modified with ctrlKey', () => { + expect(letBrowserHandleEvent({ ...event, ctrlKey: true })).toBe(true); + }); + + it('is modified with shiftKey', () => { + expect(letBrowserHandleEvent({ ...event, shiftKey: true })).toBe(true); + }); + + it('it is not a left click event', () => { + expect(letBrowserHandleEvent({ ...event, button: 2 })).toBe(true); + }); + + it('the target is anything value other than _self', () => { + expect( + letBrowserHandleEvent({ + ...event, + target: targetValue('_blank'), + }) + ).toBe(true); + }); + }); + + describe('the browser should NOT handle the link when', () => { + it('default is not prevented', () => { + expect(letBrowserHandleEvent({ ...event, defaultPrevented: false })).toBe(false); + }); + + it('is not modified', () => { + expect( + letBrowserHandleEvent({ + ...event, + metaKey: false, + altKey: false, + ctrlKey: false, + shiftKey: false, + }) + ).toBe(false); + }); + + it('it is a left click event', () => { + expect(letBrowserHandleEvent({ ...event, button: 0 })).toBe(false); + }); + + it('the target is a value of _self', () => { + expect( + letBrowserHandleEvent({ + ...event, + target: targetValue('_self'), + }) + ).toBe(false); + }); + + it('the target has no value', () => { + expect( + letBrowserHandleEvent({ + ...event, + target: targetValue(null), + }) + ).toBe(false); + }); + }); +}); + +const targetValue = (value: string | null) => { + return { + getAttribute: () => value, + }; +}; diff --git a/x-pack/plugins/uptime/public/components/common/react_router_helpers/__tests__/link_for_eui.test.tsx b/x-pack/plugins/uptime/public/components/common/react_router_helpers/__tests__/link_for_eui.test.tsx new file mode 100644 index 0000000000000..4a681f6fa60bf --- /dev/null +++ b/x-pack/plugins/uptime/public/components/common/react_router_helpers/__tests__/link_for_eui.test.tsx @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { shallow, mount } from 'enzyme'; +import { EuiLink, EuiButton } from '@elastic/eui'; + +import '../../../../lib/__mocks__/react_router_history.mock'; + +import { ReactRouterEuiLink, ReactRouterEuiButton } from '../link_for_eui'; +import { mockHistory } from '../../../../lib/__mocks__'; + +describe('EUI & React Router Component Helpers', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders', () => { + const wrapper = shallow(); + + expect(wrapper.find(EuiLink)).toHaveLength(1); + }); + + it('renders an EuiButton', () => { + const wrapper = shallow(); + + expect(wrapper.find(EuiButton)).toHaveLength(1); + }); + + it('passes down all ...rest props', () => { + const wrapper = shallow(); + const link = wrapper.find(EuiLink); + + expect(link.prop('external')).toEqual(true); + expect(link.prop('data-test-subj')).toEqual('foo'); + }); + + it('renders with the correct href and onClick props', () => { + const wrapper = mount(); + const link = wrapper.find(EuiLink); + + expect(link.prop('onClick')).toBeInstanceOf(Function); + expect(link.prop('href')).toEqual('/enterprise_search/foo/bar'); + expect(mockHistory.createHref).toHaveBeenCalled(); + }); + + describe('onClick', () => { + it('prevents default navigation and uses React Router history', () => { + const wrapper = mount(); + + const simulatedEvent = { + button: 0, + target: { getAttribute: () => '_self' }, + preventDefault: jest.fn(), + }; + wrapper.find(EuiLink).simulate('click', simulatedEvent); + + expect(simulatedEvent.preventDefault).toHaveBeenCalled(); + expect(mockHistory.push).toHaveBeenCalled(); + }); + + it('does not prevent default browser behavior on new tab/window clicks', () => { + const wrapper = mount(); + + const simulatedEvent = { + shiftKey: true, + target: { getAttribute: () => '_blank' }, + }; + wrapper.find(EuiLink).simulate('click', simulatedEvent); + + expect(mockHistory.push).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/x-pack/plugins/uptime/public/components/common/react_router_helpers/index.ts b/x-pack/plugins/uptime/public/components/common/react_router_helpers/index.ts new file mode 100644 index 0000000000000..a1885eaee4cbe --- /dev/null +++ b/x-pack/plugins/uptime/public/components/common/react_router_helpers/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { letBrowserHandleEvent } from './link_events'; +export { + ReactRouterEuiLink, + ReactRouterEuiButton, + ReactRouterEuiButtonEmpty, +} from './link_for_eui'; diff --git a/x-pack/plugins/uptime/public/components/common/react_router_helpers/link_events.ts b/x-pack/plugins/uptime/public/components/common/react_router_helpers/link_events.ts new file mode 100644 index 0000000000000..93da2ab71d952 --- /dev/null +++ b/x-pack/plugins/uptime/public/components/common/react_router_helpers/link_events.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { MouseEvent } from 'react'; + +/** + * Helper functions for determining which events we should + * let browsers handle natively, e.g. new tabs/windows + */ + +type THandleEvent = (event: MouseEvent) => boolean; + +export const letBrowserHandleEvent: THandleEvent = (event) => + event.defaultPrevented || + isModifiedEvent(event) || + !isLeftClickEvent(event) || + isTargetBlank(event); + +const isModifiedEvent: THandleEvent = (event) => + !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); + +const isLeftClickEvent: THandleEvent = (event) => event.button === 0; + +const isTargetBlank: THandleEvent = (event) => { + const element = event.target as HTMLElement; + const target = element.getAttribute('target'); + return !!target && target !== '_self'; +}; diff --git a/x-pack/plugins/uptime/public/components/common/react_router_helpers/link_for_eui.tsx b/x-pack/plugins/uptime/public/components/common/react_router_helpers/link_for_eui.tsx new file mode 100644 index 0000000000000..7adc8be4533bc --- /dev/null +++ b/x-pack/plugins/uptime/public/components/common/react_router_helpers/link_for_eui.tsx @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { useHistory } from 'react-router-dom'; +import { + EuiLink, + EuiButton, + EuiButtonProps, + EuiButtonEmptyProps, + EuiLinkAnchorProps, + EuiButtonEmpty, +} from '@elastic/eui'; + +import { letBrowserHandleEvent } from './link_events'; + +/** + * Generates either an EuiLink or EuiButton with a React-Router-ified link + * + * Based off of EUI's recommendations for handling React Router: + * https://github.com/elastic/eui/blob/master/wiki/react-router.md#react-router-51 + */ + +interface IEuiReactRouterProps { + to: string; +} + +export const ReactRouterHelperForEui: React.FC = ({ to, children }) => { + const history = useHistory(); + + const onClick = (event: React.MouseEvent) => { + if (letBrowserHandleEvent(event)) return; + + // Prevent regular link behavior, which causes a browser refresh. + event.preventDefault(); + + // Push the route to the history. + history.push(to); + }; + + // Generate the correct link href (with basename etc. accounted for) + const href = history.createHref({ pathname: to }); + + const reactRouterProps = { href, onClick }; + return React.cloneElement(children as React.ReactElement, reactRouterProps); +}; + +type TEuiReactRouterLinkProps = EuiLinkAnchorProps & IEuiReactRouterProps; +type TEuiReactRouterButtonProps = EuiButtonProps & IEuiReactRouterProps; +type TEuiReactRouterButtonEmptyProps = EuiButtonEmptyProps & IEuiReactRouterProps; + +export const ReactRouterEuiLink: React.FC = ({ to, ...rest }) => ( + + + +); + +export const ReactRouterEuiButton: React.FC = ({ to, ...rest }) => ( + + + +); + +export const ReactRouterEuiButtonEmpty: React.FC = ({ + to, + ...rest +}) => ( + + + +); diff --git a/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap index 15f5c03512bf1..e7ad86f72dab6 100644 --- a/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap @@ -8,6 +8,7 @@ exports[`ML Integrations renders without errors 1`] = ` class="euiPopover__anchor" >

    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 Date: Thu, 6 Aug 2020 15:07:14 +0200 Subject: [PATCH 034/106] Disable in-chart "Explore underlying data" by default (#74332) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 🐛 disable in-chart "Explore underlying data" by default * test: 💍 disable in-chart action functional test suite Co-authored-by: Elastic Machine --- docs/drilldowns/explore-underlying-data.asciidoc | 4 ++-- x-pack/plugins/discover_enhanced/server/config.ts | 2 +- x-pack/test/functional/apps/dashboard/drilldowns/index.ts | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/drilldowns/explore-underlying-data.asciidoc b/docs/drilldowns/explore-underlying-data.asciidoc index e0f940f73e96e..c2bba599730d8 100644 --- a/docs/drilldowns/explore-underlying-data.asciidoc +++ b/docs/drilldowns/explore-underlying-data.asciidoc @@ -33,9 +33,9 @@ applies the filters and time range created by the events that triggered the acti [role="screenshot"] image::images/explore_data_in_chart.png[Explore underlying data from chart] -You can disable this action by adding the following line to your `kibana.yml` config. +To enable this action add the following line to your `kibana.yml` config. ["source","yml"] ----------- -xpack.discoverEnhanced.actions.exploreDataInChart.enabled: false +xpack.discoverEnhanced.actions.exploreDataInChart.enabled: true ----------- diff --git a/x-pack/plugins/discover_enhanced/server/config.ts b/x-pack/plugins/discover_enhanced/server/config.ts index becbdee1bfe40..3e5e29e8c7de7 100644 --- a/x-pack/plugins/discover_enhanced/server/config.ts +++ b/x-pack/plugins/discover_enhanced/server/config.ts @@ -10,7 +10,7 @@ import { PluginConfigDescriptor } from '../../../../src/core/server'; export const configSchema = schema.object({ actions: schema.object({ exploreDataInChart: schema.object({ - enabled: schema.boolean({ defaultValue: true }), + enabled: schema.boolean({ defaultValue: false }), }), }), }); diff --git a/x-pack/test/functional/apps/dashboard/drilldowns/index.ts b/x-pack/test/functional/apps/dashboard/drilldowns/index.ts index 4cdb33c06947f..ff604b18e1d51 100644 --- a/x-pack/test/functional/apps/dashboard/drilldowns/index.ts +++ b/x-pack/test/functional/apps/dashboard/drilldowns/index.ts @@ -24,6 +24,9 @@ export default function ({ loadTestFile, getService }: FtrProviderContext) { loadTestFile(require.resolve('./dashboard_drilldowns')); loadTestFile(require.resolve('./explore_data_panel_action')); - loadTestFile(require.resolve('./explore_data_chart_action')); + + // Disabled for now as it requires xpack.discoverEnhanced.actions.exploreDataInChart.enabled + // setting set in kibana.yml to work. Once that is enabled by default, we can re-enable this test suite. + // loadTestFile(require.resolve('./explore_data_chart_action')); }); } From 152f41c3b04a34c712468c039928bb2a37c36aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20St=C3=BCrmer?= Date: Thu, 6 Aug 2020 15:18:49 +0200 Subject: [PATCH 035/106] [Logs UI] Replace deprecated getInjectedVar with NP spaces API (#74280) * Replace getInjectedVar() with NP spaces API * Fix typo in comment * Fix typo in comment Co-authored-by: Elastic Machine --- .../infra/public/apps/common_providers.tsx | 25 +++++++----- .../infra/public/components/loading_page.tsx | 4 +- .../plugins/infra/public/hooks/use_kibana.ts | 25 ++++++++++++ .../infra/public/hooks/use_kibana_space.ts | 40 +++++++++++++++++++ .../log_entry_categories/page_providers.tsx | 19 ++++++--- .../logs/log_entry_rate/page_providers.tsx | 15 +++++-- x-pack/plugins/infra/public/types.ts | 19 +++++---- .../infra/public/utils/use_kibana_space_id.ts | 31 -------------- 8 files changed, 117 insertions(+), 61 deletions(-) create mode 100644 x-pack/plugins/infra/public/hooks/use_kibana.ts create mode 100644 x-pack/plugins/infra/public/hooks/use_kibana_space.ts delete mode 100644 x-pack/plugins/infra/public/utils/use_kibana_space_id.ts diff --git a/x-pack/plugins/infra/public/apps/common_providers.tsx b/x-pack/plugins/infra/public/apps/common_providers.tsx index 9e4917856d8b2..fc82f4bf6cb00 100644 --- a/x-pack/plugins/infra/public/apps/common_providers.tsx +++ b/x-pack/plugins/infra/public/apps/common_providers.tsx @@ -4,19 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; -import { CoreStart } from 'kibana/public'; import { ApolloClient } from 'apollo-client'; -import { - useUiSetting$, - KibanaContextProvider, -} from '../../../../../src/plugins/kibana_react/public'; -import { TriggersActionsProvider } from '../utils/triggers_actions_context'; -import { InfraClientStartDeps } from '../types'; +import { CoreStart } from 'kibana/public'; +import React, { useMemo } from 'react'; +import { useUiSetting$ } from '../../../../../src/plugins/kibana_react/public'; +import { EuiThemeProvider } from '../../../observability/public'; import { TriggersAndActionsUIPublicPluginStart } from '../../../triggers_actions_ui/public'; +import { createKibanaContextForPlugin } from '../hooks/use_kibana'; +import { InfraClientStartDeps } from '../types'; import { ApolloClientContext } from '../utils/apollo_context'; -import { EuiThemeProvider } from '../../../observability/public'; import { NavigationWarningPromptProvider } from '../utils/navigation_warning_prompt'; +import { TriggersActionsProvider } from '../utils/triggers_actions_context'; export const CommonInfraProviders: React.FC<{ apolloClient: ApolloClient<{}>; @@ -39,9 +37,14 @@ export const CoreProviders: React.FC<{ core: CoreStart; plugins: InfraClientStartDeps; }> = ({ children, core, plugins }) => { + const { Provider: KibanaContextProviderForPlugin } = useMemo( + () => createKibanaContextForPlugin(core, plugins), + [core, plugins] + ); + return ( - + {children} - + ); }; diff --git a/x-pack/plugins/infra/public/components/loading_page.tsx b/x-pack/plugins/infra/public/components/loading_page.tsx index 9d37fed45b583..c410f37e7bf6b 100644 --- a/x-pack/plugins/infra/public/components/loading_page.tsx +++ b/x-pack/plugins/infra/public/components/loading_page.tsx @@ -11,12 +11,12 @@ import { EuiPageBody, EuiPageContent, } from '@elastic/eui'; -import React from 'react'; +import React, { ReactNode } from 'react'; import { FlexPage } from './page'; interface LoadingPageProps { - message?: string | JSX.Element; + message?: ReactNode; } export const LoadingPage = ({ message }: LoadingPageProps) => ( diff --git a/x-pack/plugins/infra/public/hooks/use_kibana.ts b/x-pack/plugins/infra/public/hooks/use_kibana.ts new file mode 100644 index 0000000000000..24511014d1a06 --- /dev/null +++ b/x-pack/plugins/infra/public/hooks/use_kibana.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CoreStart } from '../../../../../src/core/public'; +import { + createKibanaReactContext, + KibanaReactContextValue, + useKibana, +} from '../../../../../src/plugins/kibana_react/public'; +import { InfraClientStartDeps } from '../types'; + +export type PluginKibanaContextValue = CoreStart & InfraClientStartDeps; + +export const createKibanaContextForPlugin = (core: CoreStart, pluginsStart: InfraClientStartDeps) => + createKibanaReactContext({ + ...core, + ...pluginsStart, + }); + +export const useKibanaContextForPlugin = useKibana as () => KibanaReactContextValue< + PluginKibanaContextValue +>; diff --git a/x-pack/plugins/infra/public/hooks/use_kibana_space.ts b/x-pack/plugins/infra/public/hooks/use_kibana_space.ts new file mode 100644 index 0000000000000..1c06263008961 --- /dev/null +++ b/x-pack/plugins/infra/public/hooks/use_kibana_space.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useAsync } from 'react-use'; +import { useKibanaContextForPlugin } from '../hooks/use_kibana'; +import type { Space } from '../../../spaces/public'; + +export type ActiveSpace = + | { isLoading: true; error: undefined; space: undefined } + | { isLoading: false; error: Error; space: undefined } + | { isLoading: false; error: undefined; space: Space }; + +export const useActiveKibanaSpace = (): ActiveSpace => { + const kibana = useKibanaContextForPlugin(); + + const asyncActiveSpace = useAsync(kibana.services.spaces.getActiveSpace); + + if (asyncActiveSpace.loading) { + return { + isLoading: true, + error: undefined, + space: undefined, + }; + } else if (asyncActiveSpace.error) { + return { + isLoading: false, + error: asyncActiveSpace.error, + space: undefined, + }; + } else { + return { + isLoading: false, + error: undefined, + space: asyncActiveSpace.value!, + }; + } +}; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx index 48ad156714ccf..723d833799e29 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx @@ -7,18 +7,25 @@ import React from 'react'; import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { useLogSourceContext } from '../../../containers/logs/log_source'; -import { useKibanaSpaceId } from '../../../utils/use_kibana_space_id'; +import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; export const LogEntryCategoriesPageProviders: React.FunctionComponent = ({ children }) => { - const { sourceId, sourceConfiguration } = useLogSourceContext(); - const spaceId = useKibanaSpaceId(); + const { sourceConfiguration, sourceId } = useLogSourceContext(); + const { space } = useActiveKibanaSpace(); + + // This is a rather crude way of guarding the dependent providers against + // arguments that are only made available asynchronously. Ideally, we'd use + // React concurrent mode and Suspense in order to handle that more gracefully. + if (sourceConfiguration?.configuration.logAlias == null || space == null) { + return null; + } return ( {children} diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx index ac11260d2075d..e986fa37c2b2c 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx @@ -9,23 +9,30 @@ import { LogAnalysisSetupFlyoutStateProvider } from '../../../components/logging import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { LogEntryRateModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_rate'; import { useLogSourceContext } from '../../../containers/logs/log_source'; -import { useKibanaSpaceId } from '../../../utils/use_kibana_space_id'; +import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) => { const { sourceId, sourceConfiguration } = useLogSourceContext(); - const spaceId = useKibanaSpaceId(); + const { space } = useActiveKibanaSpace(); + + // This is a rather crude way of guarding the dependent providers against + // arguments that are only made available asynchronously. Ideally, we'd use + // React concurrent mode and Suspense in order to handle that more gracefully. + if (sourceConfiguration?.configuration.logAlias == null || space == null) { + return null; + } return ( {children} diff --git a/x-pack/plugins/infra/public/types.ts b/x-pack/plugins/infra/public/types.ts index 357f07265ac6e..a1494a023201f 100644 --- a/x-pack/plugins/infra/public/types.ts +++ b/x-pack/plugins/infra/public/types.ts @@ -4,16 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CoreSetup, CoreStart, Plugin as PluginClass } from 'kibana/public'; -import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; -import { HomePublicPluginSetup } from '../../../../src/plugins/home/public'; -import { +import type { CoreSetup, CoreStart, Plugin as PluginClass } from 'kibana/public'; +import type { DataPublicPluginStart } from '../../../../src/plugins/data/public'; +import type { HomePublicPluginSetup } from '../../../../src/plugins/home/public'; +import type { UsageCollectionSetup, UsageCollectionStart, } from '../../../../src/plugins/usage_collection/public'; -import { TriggersAndActionsUIPublicPluginSetup } from '../../../plugins/triggers_actions_ui/public'; -import { DataEnhancedSetup, DataEnhancedStart } from '../../data_enhanced/public'; -import { ObservabilityPluginSetup, ObservabilityPluginStart } from '../../observability/public'; +import type { TriggersAndActionsUIPublicPluginSetup } from '../../../plugins/triggers_actions_ui/public'; +import type { DataEnhancedSetup, DataEnhancedStart } from '../../data_enhanced/public'; +import type { + ObservabilityPluginSetup, + ObservabilityPluginStart, +} from '../../observability/public'; +import type { SpacesPluginStart } from '../../spaces/public'; // Our own setup and start contract values export type InfraClientSetupExports = void; @@ -31,6 +35,7 @@ export interface InfraClientStartDeps { data: DataPublicPluginStart; dataEnhanced: DataEnhancedStart; observability: ObservabilityPluginStart; + spaces: SpacesPluginStart; triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup; usageCollection: UsageCollectionStart; } diff --git a/x-pack/plugins/infra/public/utils/use_kibana_space_id.ts b/x-pack/plugins/infra/public/utils/use_kibana_space_id.ts deleted file mode 100644 index 86597f52928d5..0000000000000 --- a/x-pack/plugins/infra/public/utils/use_kibana_space_id.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import * as rt from 'io-ts'; -import { useKibana } from '../../../../../src/plugins/kibana_react/public'; - -export const useKibanaSpaceId = (): string => { - const kibana = useKibana(); - // NOTE: The injectedMetadata service will be deprecated at some point. We should migrate - // this to the client side Spaces plugin when it becomes available. - const activeSpace = kibana.services.injectedMetadata?.getInjectedVar('activeSpace'); - - return pipe( - activeSpaceRT.decode(activeSpace), - fold( - () => 'default', - (decodedActiveSpace) => decodedActiveSpace.space.id - ) - ); -}; - -const activeSpaceRT = rt.type({ - space: rt.type({ - id: rt.string, - }), -}); From 8f98b72df85156179b7dc17bc77a99388562165b Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Date: Thu, 6 Aug 2020 09:19:59 -0400 Subject: [PATCH 036/106] [SECURITY] Bug investigate timeline (#74429) * simple solution to avoid duplicate request * fix investigate template timeline from template timeline --- .../containers/matrix_histogram/index.ts | 76 +++++---- .../public/common/mock/timeline_results.ts | 35 +++- .../components/alerts_table/actions.test.tsx | 12 +- .../components/alerts_table/actions.tsx | 47 ++++-- .../components/alerts_table/helpers.test.ts | 149 ++++++++++++------ .../components/alerts_table/helpers.ts | 35 ++-- .../components/alerts_table/index.tsx | 5 +- .../components/alerts_table/types.ts | 3 +- .../components/open_timeline/helpers.ts | 3 +- .../components/open_timeline/types.ts | 1 + 10 files changed, 255 insertions(+), 111 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts index 8c7acfc18ece6..2122eab23957a 100644 --- a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts +++ b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts @@ -7,6 +7,7 @@ import { isEmpty } from 'lodash/fp'; import { useEffect, useMemo, useState, useRef } from 'react'; +import { deepEqual } from 'hoek'; import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; import { MatrixHistogramQueryProps } from '../../components/matrix_histogram/types'; import { errorToToaster, useStateToaster } from '../../components/toasters'; @@ -34,7 +35,6 @@ export const useQuery = ({ } return configIndex; }, [configIndex, indexToAdd]); - const [, dispatchToaster] = useStateToaster(); const refetch = useRef(); const [loading, setLoading] = useState(false); @@ -43,20 +43,54 @@ export const useQuery = ({ const [totalCount, setTotalCount] = useState(-1); const apolloClient = useApolloClient(); + const [matrixHistogramVariables, setMatrixHistogramVariables] = useState< + GetMatrixHistogramQuery.Variables + >({ + filterQuery: createFilter(filterQuery), + sourceId: 'default', + timerange: { + interval: '12h', + from: startDate!, + to: endDate!, + }, + defaultIndex, + inspect: isInspected, + stackByField, + histogramType, + }); + + useEffect(() => { + setMatrixHistogramVariables((prevVariables) => { + const localVariables = { + filterQuery: createFilter(filterQuery), + sourceId: 'default', + timerange: { + interval: '12h', + from: startDate!, + to: endDate!, + }, + defaultIndex, + inspect: isInspected, + stackByField, + histogramType, + }; + if (!deepEqual(prevVariables, localVariables)) { + return localVariables; + } + return prevVariables; + }); + }, [ + defaultIndex, + filterQuery, + histogramType, + indexToAdd, + isInspected, + stackByField, + startDate, + endDate, + ]); + useEffect(() => { - const matrixHistogramVariables: GetMatrixHistogramQuery.Variables = { - filterQuery: createFilter(filterQuery), - sourceId: 'default', - timerange: { - interval: '12h', - from: startDate!, - to: endDate!, - }, - defaultIndex, - inspect: isInspected, - stackByField, - histogramType, - }; let isSubscribed = true; const abortCtrl = new AbortController(); const abortSignal = abortCtrl.signal; @@ -102,19 +136,7 @@ export const useQuery = ({ isSubscribed = false; abortCtrl.abort(); }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ - defaultIndex, - errorMessage, - filterQuery, - histogramType, - indexToAdd, - isInspected, - stackByField, - startDate, - endDate, - data, - ]); + }, [apolloClient, dispatchToaster, errorMessage, matrixHistogramVariables]); return { data, loading, inspect, totalCount, refetch: refetch.current }; }; diff --git a/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts b/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts index a415ab75f13ea..ab9f12a67fe89 100644 --- a/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts +++ b/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts @@ -8,7 +8,13 @@ import { FilterStateStore } from '../../../../../../src/plugins/data/common/es_q import { TimelineType, TimelineStatus } from '../../../common/types/timeline'; import { OpenTimelineResult } from '../../timelines/components/open_timeline/types'; -import { GetAllTimeline, SortFieldTimeline, TimelineResult, Direction } from '../../graphql/types'; +import { + GetAllTimeline, + SortFieldTimeline, + TimelineResult, + Direction, + DetailItem, +} from '../../graphql/types'; import { allTimelinesQuery } from '../../timelines/containers/all/index.gql_query'; import { CreateTimelineProps } from '../../detections/components/alerts_table/types'; import { TimelineModel } from '../../timelines/store/timeline/model'; @@ -2252,5 +2258,32 @@ export const defaultTimelineProps: CreateTimelineProps = { width: 1100, }, to: '2018-11-05T19:03:25.937Z', + notes: null, ruleNote: '# this is some markdown documentation', }; + +export const mockTimelineDetails: DetailItem[] = [ + { + field: 'host.name', + values: ['apache'], + originalValue: 'apache', + }, + { + field: 'user.id', + values: ['1'], + originalValue: 1, + }, +]; + +export const mockTimelineDetailsApollo = { + data: { + source: { + TimelineDetails: { + data: mockTimelineDetails, + }, + }, + }, + loading: false, + networkStatus: 7, + stale: false, +}; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx index c2b51e29c230d..e8015f601cb18 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx @@ -3,6 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +import { get } from 'lodash/fp'; import sinon from 'sinon'; import moment from 'moment'; @@ -12,6 +14,7 @@ import { defaultTimelineProps, apolloClient, mockTimelineApolloResult, + mockTimelineDetailsApollo, } from '../../../common/mock/'; import { CreateTimeline, UpdateTimelineLoading } from './types'; import { Ecs } from '../../../graphql/types'; @@ -37,7 +40,13 @@ describe('alert actions', () => { createTimeline = jest.fn() as jest.Mocked; updateTimelineIsLoading = jest.fn() as jest.Mocked; - jest.spyOn(apolloClient, 'query').mockResolvedValue(mockTimelineApolloResult); + jest.spyOn(apolloClient, 'query').mockImplementation((obj) => { + const id = get('variables.id', obj); + if (id != null) { + return Promise.resolve(mockTimelineApolloResult); + } + return Promise.resolve(mockTimelineDetailsApollo); + }); clock = sinon.useFakeTimers(unix); }); @@ -71,6 +80,7 @@ describe('alert actions', () => { }); const expected = { from: '2018-11-05T18:58:25.937Z', + notes: null, timeline: { columns: [ { diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx index 7bebc9efbee15..34c0537a6d7d2 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx @@ -19,6 +19,8 @@ import { Ecs, TimelineStatus, TimelineType, + GetTimelineDetailsQuery, + DetailItem, } from '../../../graphql/types'; import { oneTimelineQuery } from '../../../timelines/containers/one/index.gql_query'; import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; @@ -34,6 +36,7 @@ import { } from './helpers'; import { KueryFilterQueryKind } from '../../../common/store'; import { DataProvider } from '../../../timelines/components/timeline/data_providers/data_provider'; +import { timelineDetailsQuery } from '../../../timelines/containers/details/index.gql_query'; export const getUpdateAlertsQuery = (eventIds: Readonly) => { return { @@ -153,35 +156,45 @@ export const sendAlertToTimelineAction = async ({ if (timelineId !== '' && apolloClient != null) { try { updateTimelineIsLoading({ id: 'timeline-1', isLoading: true }); - const responseTimeline = await apolloClient.query< - GetOneTimeline.Query, - GetOneTimeline.Variables - >({ - query: oneTimelineQuery, - fetchPolicy: 'no-cache', - variables: { - id: timelineId, - }, - }); + const [responseTimeline, eventDataResp] = await Promise.all([ + apolloClient.query({ + query: oneTimelineQuery, + fetchPolicy: 'no-cache', + variables: { + id: timelineId, + }, + }), + apolloClient.query({ + query: timelineDetailsQuery, + fetchPolicy: 'no-cache', + variables: { + defaultIndex: [], + docValueFields: [], + eventId: ecsData._id, + indexName: ecsData._index ?? '', + sourceId: 'default', + }, + }), + ]); const resultingTimeline: TimelineResult = getOr({}, 'data.getOneTimeline', responseTimeline); - + const eventData: DetailItem[] = getOr([], 'data.source.TimelineDetails.data', eventDataResp); if (!isEmpty(resultingTimeline)) { const timelineTemplate: TimelineResult = omitTypenameInTimeline(resultingTimeline); openAlertInBasicTimeline = false; - const { timeline } = formatTimelineResultToModel( + const { timeline, notes } = formatTimelineResultToModel( timelineTemplate, true, timelineTemplate.timelineType ?? TimelineType.default ); const query = replaceTemplateFieldFromQuery( timeline.kqlQuery?.filterQuery?.kuery?.expression ?? '', - ecsData, + eventData, timeline.timelineType ); - const filters = replaceTemplateFieldFromMatchFilters(timeline.filters ?? [], ecsData); + const filters = replaceTemplateFieldFromMatchFilters(timeline.filters ?? [], eventData); const dataProviders = replaceTemplateFieldFromDataProviders( timeline.dataProviders ?? [], - ecsData, + eventData, timeline.timelineType ); @@ -213,10 +226,12 @@ export const sendAlertToTimelineAction = async ({ expression: query, }, }, + noteIds: notes?.map((n) => n.noteId) ?? [], show: true, }, to, ruleNote: noteContent, + notes: notes ?? null, }); } } catch { @@ -232,6 +247,7 @@ export const sendAlertToTimelineAction = async ({ ) { return createTimeline({ from, + notes: null, timeline: { ...timelineDefaults, dataProviders: [ @@ -282,6 +298,7 @@ export const sendAlertToTimelineAction = async ({ } else { return createTimeline({ from, + notes: null, timeline: { ...timelineDefaults, dataProviders: [ diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/helpers.test.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/helpers.test.ts index 4decddd6b8886..7ac254f2e84f7 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/helpers.test.ts @@ -3,10 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { cloneDeep } from 'lodash/fp'; import { TimelineType } from '../../../../common/types/timeline'; -import { mockEcsData } from '../../../common/mock/mock_ecs'; import { Filter } from '../../../../../../../src/plugins/data/public'; import { DataProvider, @@ -20,31 +18,40 @@ import { replaceTemplateFieldFromMatchFilters, reformatDataProviderWithNewValue, } from './helpers'; +import { mockTimelineDetails } from '../../../common/mock'; describe('helpers', () => { - let mockEcsDataClone = cloneDeep(mockEcsData); - beforeEach(() => { - mockEcsDataClone = cloneDeep(mockEcsData); - }); describe('getStringOrStringArray', () => { test('it should correctly return a string array', () => { - const value = getStringArray('x', { - x: 'The nickname of the developer we all :heart:', - }); + const value = getStringArray('x', [ + { + field: 'x', + values: ['The nickname of the developer we all :heart:'], + originalValue: 'The nickname of the developer we all :heart:', + }, + ]); expect(value).toEqual(['The nickname of the developer we all :heart:']); }); test('it should correctly return a string array with a single element', () => { - const value = getStringArray('x', { - x: ['The nickname of the developer we all :heart:'], - }); + const value = getStringArray('x', [ + { + field: 'x', + values: ['The nickname of the developer we all :heart:'], + originalValue: 'The nickname of the developer we all :heart:', + }, + ]); expect(value).toEqual(['The nickname of the developer we all :heart:']); }); test('it should correctly return a string array with two elements of strings', () => { - const value = getStringArray('x', { - x: ['The nickname of the developer we all :heart:', 'We are all made of stars'], - }); + const value = getStringArray('x', [ + { + field: 'x', + values: ['The nickname of the developer we all :heart:', 'We are all made of stars'], + originalValue: 'The nickname of the developer we all :heart:', + }, + ]); expect(value).toEqual([ 'The nickname of the developer we all :heart:', 'We are all made of stars', @@ -52,22 +59,40 @@ describe('helpers', () => { }); test('it should correctly return a string array with deep elements', () => { - const value = getStringArray('x.y.z', { - x: { y: { z: 'zed' } }, - }); + const value = getStringArray('x.y.z', [ + { + field: 'x.y.z', + values: ['zed'], + originalValue: 'zed', + }, + ]); expect(value).toEqual(['zed']); }); test('it should correctly return a string array with a non-existent value', () => { - const value = getStringArray('non.existent', { - x: { y: { z: 'zed' } }, - }); + const value = getStringArray('non.existent', [ + { + field: 'x.y.z', + values: ['zed'], + originalValue: 'zed', + }, + ]); expect(value).toEqual([]); }); test('it should trace an error if the value is not a string', () => { const mockConsole: Console = ({ trace: jest.fn() } as unknown) as Console; - const value = getStringArray('a', { a: 5 }, mockConsole); + const value = getStringArray( + 'a', + [ + { + field: 'a', + values: (5 as unknown) as string[], + originalValue: 'zed', + }, + ], + mockConsole + ); expect(value).toEqual([]); expect( mockConsole.trace @@ -77,13 +102,23 @@ describe('helpers', () => { 'when trying to access field:', 'a', 'from data object of:', - { a: 5 } + [{ field: 'a', originalValue: 'zed', values: 5 }] ); }); test('it should trace an error if the value is an array of mixed values', () => { const mockConsole: Console = ({ trace: jest.fn() } as unknown) as Console; - const value = getStringArray('a', { a: ['hi', 5] }, mockConsole); + const value = getStringArray( + 'a', + [ + { + field: 'a', + values: (['hi', 5] as unknown) as string[], + originalValue: 'zed', + }, + ], + mockConsole + ); expect(value).toEqual([]); expect( mockConsole.trace @@ -93,7 +128,7 @@ describe('helpers', () => { 'when trying to access field:', 'a', 'from data object of:', - { a: ['hi', 5] } + [{ field: 'a', originalValue: 'zed', values: ['hi', 5] }] ); }); }); @@ -103,7 +138,7 @@ describe('helpers', () => { test('given an empty query string this returns an empty query string', () => { const replacement = replaceTemplateFieldFromQuery( '', - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.default ); expect(replacement).toEqual(''); @@ -112,7 +147,7 @@ describe('helpers', () => { test('given a query string with spaces this returns an empty query string', () => { const replacement = replaceTemplateFieldFromQuery( ' ', - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.default ); expect(replacement).toEqual(''); @@ -121,17 +156,21 @@ describe('helpers', () => { test('it should replace a query with a template value such as apache from a mock template', () => { const replacement = replaceTemplateFieldFromQuery( 'host.name: placeholdertext', - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.default ); expect(replacement).toEqual('host.name: apache'); }); test('it should replace a template field with an ECS value that is not an array', () => { - mockEcsDataClone[0].host!.name = ('apache' as unknown) as string[]; // very unsafe cast for this test case + const dupTimelineDetails = [...mockTimelineDetails]; + dupTimelineDetails[0] = { + ...dupTimelineDetails[0], + values: ('apache' as unknown) as string[], + }; // very unsafe cast for this test case const replacement = replaceTemplateFieldFromQuery( 'host.name: *', - mockEcsDataClone[0], + dupTimelineDetails, TimelineType.default ); expect(replacement).toEqual('host.name: *'); @@ -140,7 +179,7 @@ describe('helpers', () => { test('it should NOT replace a query with a template value that is not part of the template fields array', () => { const replacement = replaceTemplateFieldFromQuery( 'user.id: placeholdertext', - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.default ); expect(replacement).toEqual('user.id: placeholdertext'); @@ -151,7 +190,7 @@ describe('helpers', () => { test('given an empty query string this returns an empty query string', () => { const replacement = replaceTemplateFieldFromQuery( '', - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.template ); expect(replacement).toEqual(''); @@ -160,7 +199,7 @@ describe('helpers', () => { test('given a query string with spaces this returns an empty query string', () => { const replacement = replaceTemplateFieldFromQuery( ' ', - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.template ); expect(replacement).toEqual(''); @@ -169,17 +208,21 @@ describe('helpers', () => { test('it should NOT replace a query with a template value such as apache from a mock template', () => { const replacement = replaceTemplateFieldFromQuery( 'host.name: placeholdertext', - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.template ); expect(replacement).toEqual('host.name: placeholdertext'); }); test('it should NOT replace a template field with an ECS value that is not an array', () => { - mockEcsDataClone[0].host!.name = ('apache' as unknown) as string[]; // very unsafe cast for this test case + const dupTimelineDetails = [...mockTimelineDetails]; + dupTimelineDetails[0] = { + ...dupTimelineDetails[0], + values: ('apache' as unknown) as string[], + }; // very unsafe cast for this test case const replacement = replaceTemplateFieldFromQuery( 'host.name: *', - mockEcsDataClone[0], + dupTimelineDetails, TimelineType.default ); expect(replacement).toEqual('host.name: *'); @@ -188,7 +231,7 @@ describe('helpers', () => { test('it should NOT replace a query with a template value that is not part of the template fields array', () => { const replacement = replaceTemplateFieldFromQuery( 'user.id: placeholdertext', - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.default ); expect(replacement).toEqual('user.id: placeholdertext'); @@ -198,7 +241,7 @@ describe('helpers', () => { describe('replaceTemplateFieldFromMatchFilters', () => { test('given an empty query filter this will return an empty filter', () => { - const replacement = replaceTemplateFieldFromMatchFilters([], mockEcsDataClone[0]); + const replacement = replaceTemplateFieldFromMatchFilters([], mockTimelineDetails); expect(replacement).toEqual([]); }); @@ -216,7 +259,7 @@ describe('helpers', () => { query: { match_phrase: { 'host.name': 'Braden' } }, }, ]; - const replacement = replaceTemplateFieldFromMatchFilters(filters, mockEcsDataClone[0]); + const replacement = replaceTemplateFieldFromMatchFilters(filters, mockTimelineDetails); const expected: Filter[] = [ { meta: { @@ -247,7 +290,7 @@ describe('helpers', () => { query: { match_phrase: { 'user.id': 'Evan' } }, }, ]; - const replacement = replaceTemplateFieldFromMatchFilters(filters, mockEcsDataClone[0]); + const replacement = replaceTemplateFieldFromMatchFilters(filters, mockTimelineDetails); const expected: Filter[] = [ { meta: { @@ -275,7 +318,7 @@ describe('helpers', () => { mockDataProvider.queryMatch.value = 'Braden'; const replacement = reformatDataProviderWithNewValue( mockDataProvider, - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.default ); expect(replacement).toEqual({ @@ -297,7 +340,11 @@ describe('helpers', () => { }); test('it should replace a query with a template value such as apache from a mock data provider using a string in the data provider', () => { - mockEcsDataClone[0].host!.name = ('apache' as unknown) as string[]; // very unsafe cast for this test case + const dupTimelineDetails = [...mockTimelineDetails]; + dupTimelineDetails[0] = { + ...dupTimelineDetails[0], + values: ('apache' as unknown) as string[], + }; // very unsafe cast for this test case const mockDataProvider: DataProvider = mockDataProviders[0]; mockDataProvider.queryMatch.field = 'host.name'; mockDataProvider.id = 'Braden'; @@ -305,7 +352,7 @@ describe('helpers', () => { mockDataProvider.queryMatch.value = 'Braden'; const replacement = reformatDataProviderWithNewValue( mockDataProvider, - mockEcsDataClone[0], + dupTimelineDetails, TimelineType.default ); expect(replacement).toEqual({ @@ -334,7 +381,7 @@ describe('helpers', () => { mockDataProvider.queryMatch.value = 'Rebecca'; const replacement = reformatDataProviderWithNewValue( mockDataProvider, - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.default ); expect(replacement).toEqual({ @@ -366,7 +413,7 @@ describe('helpers', () => { mockDataProvider.type = DataProviderType.template; const replacement = reformatDataProviderWithNewValue( mockDataProvider, - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.template ); expect(replacement).toEqual({ @@ -396,7 +443,7 @@ describe('helpers', () => { mockDataProvider.type = DataProviderType.default; const replacement = reformatDataProviderWithNewValue( mockDataProvider, - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.template ); expect(replacement).toEqual({ @@ -418,7 +465,11 @@ describe('helpers', () => { }); test('it should replace a query with a template value such as apache from a mock data provider using a string in the data provider', () => { - mockEcsDataClone[0].host!.name = ('apache' as unknown) as string[]; // very unsafe cast for this test case + const dupTimelineDetails = [...mockTimelineDetails]; + dupTimelineDetails[0] = { + ...dupTimelineDetails[0], + values: ('apache' as unknown) as string[], + }; // very unsafe cast for this test case const mockDataProvider: DataProvider = mockDataProviders[0]; mockDataProvider.queryMatch.field = 'host.name'; mockDataProvider.id = 'Braden'; @@ -427,7 +478,7 @@ describe('helpers', () => { mockDataProvider.type = DataProviderType.template; const replacement = reformatDataProviderWithNewValue( mockDataProvider, - mockEcsDataClone[0], + dupTimelineDetails, TimelineType.template ); expect(replacement).toEqual({ @@ -457,7 +508,7 @@ describe('helpers', () => { mockDataProvider.type = DataProviderType.default; const replacement = reformatDataProviderWithNewValue( mockDataProvider, - mockEcsDataClone[0], + mockTimelineDetails, TimelineType.template ); expect(replacement).toEqual({ diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/helpers.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/helpers.ts index 084e4bff7e0ac..20c233a03a8cf 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/helpers.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/helpers.ts @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { get, isEmpty } from 'lodash/fp'; +import { isEmpty } from 'lodash/fp'; import { Filter, esKuery, KueryNode } from '../../../../../../../src/plugins/data/public'; import { DataProvider, DataProviderType, DataProvidersAnd, } from '../../../timelines/components/timeline/data_providers/data_provider'; -import { Ecs, TimelineType } from '../../../graphql/types'; +import { DetailItem, TimelineType } from '../../../graphql/types'; interface FindValueToChangeInQuery { field: string; @@ -47,8 +47,12 @@ const templateFields = [ * @param data The unknown data that is typically a ECS value to get the value * @param localConsole The local console which can be sent in to make this pure (for tests) or use the default console */ -export const getStringArray = (field: string, data: unknown, localConsole = console): string[] => { - const value: unknown | undefined = get(field, data); +export const getStringArray = ( + field: string, + data: DetailItem[], + localConsole = console +): string[] => { + const value: unknown | undefined = data.find((d) => d.field === field)?.values ?? null; if (value == null) { return []; } else if (typeof value === 'string') { @@ -104,14 +108,14 @@ export const findValueToChangeInQuery = ( export const replaceTemplateFieldFromQuery = ( query: string, - ecsData: Ecs, + eventData: DetailItem[], timelineType: TimelineType = TimelineType.default ): string => { if (timelineType === TimelineType.default) { if (query.trim() !== '') { const valueToChange = findValueToChangeInQuery(esKuery.fromKueryExpression(query)); return valueToChange.reduce((newQuery, vtc) => { - const newValue = getStringArray(vtc.field, ecsData); + const newValue = getStringArray(vtc.field, eventData); if (newValue.length) { return newQuery.replace(vtc.valueToChange, newValue[0]); } else { @@ -126,14 +130,17 @@ export const replaceTemplateFieldFromQuery = ( return query.trim(); }; -export const replaceTemplateFieldFromMatchFilters = (filters: Filter[], ecsData: Ecs): Filter[] => +export const replaceTemplateFieldFromMatchFilters = ( + filters: Filter[], + eventData: DetailItem[] +): Filter[] => filters.map((filter) => { if ( filter.meta.type === 'phrase' && filter.meta.key != null && templateFields.includes(filter.meta.key) ) { - const newValue = getStringArray(filter.meta.key, ecsData); + const newValue = getStringArray(filter.meta.key, eventData); if (newValue.length) { filter.meta.params = { query: newValue[0] }; filter.query = { match_phrase: { [filter.meta.key]: newValue[0] } }; @@ -144,13 +151,13 @@ export const replaceTemplateFieldFromMatchFilters = (filters: Filter[], ecsData: export const reformatDataProviderWithNewValue = ( dataProvider: T, - ecsData: Ecs, + eventData: DetailItem[], timelineType: TimelineType = TimelineType.default ): T => { // Support for legacy "template-like" timeline behavior that is using hardcoded list of templateFields if (timelineType !== TimelineType.template) { if (templateFields.includes(dataProvider.queryMatch.field)) { - const newValue = getStringArray(dataProvider.queryMatch.field, ecsData); + const newValue = getStringArray(dataProvider.queryMatch.field, eventData); if (newValue.length) { dataProvider.id = dataProvider.id.replace(dataProvider.name, newValue[0]); dataProvider.name = newValue[0]; @@ -168,7 +175,7 @@ export const reformatDataProviderWithNewValue = dataProviders.map((dataProvider) => { - const newDataProvider = reformatDataProviderWithNewValue(dataProvider, ecsData, timelineType); + const newDataProvider = reformatDataProviderWithNewValue(dataProvider, eventData, timelineType); if (newDataProvider.and != null && !isEmpty(newDataProvider.and)) { newDataProvider.and = newDataProvider.and.map((andDataProvider) => - reformatDataProviderWithNewValue(andDataProvider, ecsData, timelineType) + reformatDataProviderWithNewValue(andDataProvider, eventData, timelineType) ); } return newDataProvider; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index d93bad29f3348..66423259ec155 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -147,13 +147,14 @@ export const AlertsTableComponent: React.FC = ({ // Callback for creating a new timeline -- utilized by row/batch actions const createTimelineCallback = useCallback( - ({ from: fromTimeline, timeline, to: toTimeline, ruleNote }: CreateTimelineProps) => { + ({ from: fromTimeline, timeline, to: toTimeline, ruleNote, notes }: CreateTimelineProps) => { updateTimelineIsLoading({ id: 'timeline-1', isLoading: false }); updateTimeline({ duplicate: true, + forceNotes: true, from: fromTimeline, id: 'timeline-1', - notes: [], + notes, timeline: { ...timeline, show: true, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts index ebf1a6d3ed533..2e77e77f6b3d5 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts @@ -7,7 +7,7 @@ import ApolloClient from 'apollo-client'; import { Status } from '../../../../common/detection_engine/schemas/common/schemas'; -import { Ecs, TimelineNonEcsData } from '../../../graphql/types'; +import { Ecs, NoteResult, TimelineNonEcsData } from '../../../graphql/types'; import { TimelineModel } from '../../../timelines/store/timeline/model'; import { inputsModel } from '../../../common/store'; @@ -63,6 +63,7 @@ export interface CreateTimelineProps { from: string; timeline: TimelineModel; to: string; + notes: NoteResult[] | null; ruleNote?: string; } diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts index 0a08e45324b89..c2e23cc19d89e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts @@ -363,6 +363,7 @@ export const queryTimelineById = ({ export const dispatchUpdateTimeline = (dispatch: Dispatch): DispatchUpdateTimeline => ({ duplicate, id, + forceNotes = false, from, notes, timeline, @@ -407,7 +408,7 @@ export const dispatchUpdateTimeline = (dispatch: Dispatch): DispatchUpdateTimeli dispatch(dispatchAddGlobalTimelineNote({ noteId: newNote.id, id })); } - if (!duplicate) { + if (!duplicate || forceNotes) { dispatch( dispatchAddNotes({ notes: diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts index 8950f814d6965..769a0a1658a46 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts @@ -192,6 +192,7 @@ export interface OpenTimelineProps { export interface UpdateTimeline { duplicate: boolean; id: string; + forceNotes?: boolean; from: string; notes: NoteResult[] | null | undefined; timeline: TimelineModel; From d43d45d77a3cfba62c5f28b2906d33e3fc3eee01 Mon Sep 17 00:00:00 2001 From: Robert Austin Date: Thu, 6 Aug 2020 09:26:00 -0400 Subject: [PATCH 037/106] [Resolver] Safer types (#74366) All mappings in Elasticsearch support arrays. They can also return null values or be missing. For example, a `keyword` mapping could return `null` or `[null]` or `[]` or `'hi'`, or `['hi', 'there']`. We need to handle these cases in order to avoid throwing an error. Specific and nuanced handling of these cases isn't the goal of this PR. This PR just introduces some helper types that can be used to assist you in writing defensive code. When dealing with an value that comes from ES, wrap the underlying type in `ECSField`. For example, if you have a `keyword` or `text` value coming from ES, cast it to `ECSField`. ### Added New Resolver specific types `ResolverEvent` has a new safe equivalent `SafeResolverEvent`. The constituent parts of `ResolverEvent` also have safe equivalents: `SafeEndpointEvent` and `SafeLegacyEndpointEvent`. Use these in your code for added type safety. ### New safe event methods The event methods accept the unsafe `ResolverEvent`. Create new methods that accept the safe `SafeResolverEvent`. By keeping copies of both methods around we can gradually transition to the safe versions: * `isLegacyEvent` has `isLegacyEventSafeVersion` * `eventTimestamp` has `timestampSafeVersion` * `eventName` has `processNameSafeVersion` * `eventId` has `eventIDSafeVersion` * `entityId` has `entityIDSafeVersion` * `parentEntityId` has `parentEntityIDSafeVersion` --- .../endpoint/models/ecs_safety_helpers.ts | 61 +++ .../common/endpoint/models/event.ts | 57 ++- .../common/endpoint/types.ts | 126 ++++++ .../isometric_taxi_layout.test.ts.snap | 30 +- .../models/indexed_process_tree/index.ts | 49 ++- .../isometric_taxi_layout.ts | 68 +-- .../resolver/models/process_event.test.ts | 24 +- .../public/resolver/models/process_event.ts | 12 +- .../public/resolver/store/actions.ts | 4 +- .../public/resolver/store/data/selectors.ts | 21 +- .../public/resolver/store/methods.ts | 4 +- .../public/resolver/store/selectors.test.ts | 17 +- .../public/resolver/store/selectors.ts | 13 +- .../public/resolver/types.ts | 20 +- .../public/resolver/view/map.tsx | 4 +- .../panels/panel_content_process_list.tsx | 402 +++++++++--------- .../resolver/view/process_event_dot.tsx | 19 +- .../view/resolver_without_providers.tsx | 4 +- .../public/resolver/view/use_camera.test.tsx | 2 +- 19 files changed, 616 insertions(+), 321 deletions(-) create mode 100644 x-pack/plugins/security_solution/common/endpoint/models/ecs_safety_helpers.ts diff --git a/x-pack/plugins/security_solution/common/endpoint/models/ecs_safety_helpers.ts b/x-pack/plugins/security_solution/common/endpoint/models/ecs_safety_helpers.ts new file mode 100644 index 0000000000000..8b419e90a6ee9 --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/models/ecs_safety_helpers.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ECSField } from '../types'; + +/** + * Use these functions to accecss information held in `ECSField`s. + */ + +/** + * True if the field contains `expected`. If the field contains an array, this will be true if the array contains `expected`. + */ +export function hasValue(valueOrCollection: ECSField, expected: T): boolean { + if (Array.isArray(valueOrCollection)) { + return valueOrCollection.includes(expected); + } else { + return valueOrCollection === expected; + } +} + +/** + * Return first non-null value. If the field contains an array, this will return the first value that isn't null. If the field isn't an array it'll be returned unless it's null. + */ +export function firstNonNullValue(valueOrCollection: ECSField): T | undefined { + if (valueOrCollection === null) { + return undefined; + } else if (Array.isArray(valueOrCollection)) { + for (const value of valueOrCollection) { + if (value !== null) { + return value; + } + } + } else { + return valueOrCollection; + } +} + +/* + * Get an array of all non-null values. If there is just 1 value, return it wrapped in an array. If there are multiple values, return the non-null ones. + * Use this when you want to consistently access the value(s) as an array. + */ +export function values(valueOrCollection: ECSField): T[] { + if (Array.isArray(valueOrCollection)) { + const nonNullValues: T[] = []; + for (const value of valueOrCollection) { + if (value !== null) { + nonNullValues.push(value); + } + } + return nonNullValues; + } else if (valueOrCollection !== null) { + // if there is a single non-null value, wrap it in an array and return it. + return [valueOrCollection]; + } else { + // if the value was null, return `[]`. + return []; + } +} diff --git a/x-pack/plugins/security_solution/common/endpoint/models/event.ts b/x-pack/plugins/security_solution/common/endpoint/models/event.ts index 1168b5edb6ffd..b1a8524a9f9e7 100644 --- a/x-pack/plugins/security_solution/common/endpoint/models/event.ts +++ b/x-pack/plugins/security_solution/common/endpoint/models/event.ts @@ -3,8 +3,26 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { LegacyEndpointEvent, ResolverEvent } from '../types'; +import { + LegacyEndpointEvent, + ResolverEvent, + SafeResolverEvent, + SafeLegacyEndpointEvent, +} from '../types'; +import { firstNonNullValue } from './ecs_safety_helpers'; +/* + * Determine if a `ResolverEvent` is the legacy variety. Can be used to narrow `ResolverEvent` to `LegacyEndpointEvent`. + */ +export function isLegacyEventSafeVersion( + event: SafeResolverEvent +): event is SafeLegacyEndpointEvent { + return 'endgame' in event && event.endgame !== undefined; +} + +/* + * Determine if a `ResolverEvent` is the legacy variety. Can be used to narrow `ResolverEvent` to `LegacyEndpointEvent`. See `isLegacyEventSafeVersion` + */ export function isLegacyEvent(event: ResolverEvent): event is LegacyEndpointEvent { return (event as LegacyEndpointEvent).endgame !== undefined; } @@ -31,6 +49,12 @@ export function isProcessRunning(event: ResolverEvent): boolean { ); } +export function timestampSafeVersion(event: SafeResolverEvent): string | undefined | number { + return isLegacyEventSafeVersion(event) + ? firstNonNullValue(event.endgame?.timestamp_utc) + : firstNonNullValue(event?.['@timestamp']); +} + export function eventTimestamp(event: ResolverEvent): string | undefined | number { if (isLegacyEvent(event)) { return event.endgame.timestamp_utc; @@ -47,6 +71,14 @@ export function eventName(event: ResolverEvent): string { } } +export function processNameSafeVersion(event: SafeResolverEvent): string | undefined { + if (isLegacyEventSafeVersion(event)) { + return firstNonNullValue(event.endgame.process_name); + } else { + return firstNonNullValue(event.process?.name); + } +} + export function eventId(event: ResolverEvent): number | undefined | string { if (isLegacyEvent(event)) { return event.endgame.serial_event_id; @@ -54,6 +86,12 @@ export function eventId(event: ResolverEvent): number | undefined | string { return event.event.id; } +export function eventIDSafeVersion(event: SafeResolverEvent): number | undefined | string { + return firstNonNullValue( + isLegacyEventSafeVersion(event) ? event.endgame?.serial_event_id : event.event?.id + ); +} + export function entityId(event: ResolverEvent): string { if (isLegacyEvent(event)) { return event.endgame.unique_pid ? String(event.endgame.unique_pid) : ''; @@ -61,6 +99,16 @@ export function entityId(event: ResolverEvent): string { return event.process.entity_id; } +export function entityIDSafeVersion(event: SafeResolverEvent): string | undefined { + if (isLegacyEventSafeVersion(event)) { + return event.endgame?.unique_pid === undefined + ? undefined + : String(firstNonNullValue(event.endgame.unique_pid)); + } else { + return firstNonNullValue(event.process?.entity_id); + } +} + export function parentEntityId(event: ResolverEvent): string | undefined { if (isLegacyEvent(event)) { return event.endgame.unique_ppid ? String(event.endgame.unique_ppid) : undefined; @@ -68,6 +116,13 @@ export function parentEntityId(event: ResolverEvent): string | undefined { return event.process.parent?.entity_id; } +export function parentEntityIDSafeVersion(event: SafeResolverEvent): string | undefined { + if (isLegacyEventSafeVersion(event)) { + return String(firstNonNullValue(event.endgame.unique_ppid)); + } + return firstNonNullValue(event.process?.parent?.entity_id); +} + export function ancestryArray(event: ResolverEvent): string[] | undefined { if (isLegacyEvent(event)) { return undefined; diff --git a/x-pack/plugins/security_solution/common/endpoint/types.ts b/x-pack/plugins/security_solution/common/endpoint/types.ts index 1c24e1abe5a57..61ce672405fd5 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types.ts @@ -508,6 +508,8 @@ export interface EndpointEvent { ecs: { version: string; }; + // A legacy has `endgame` and an `EndpointEvent` (AKA ECS event) will never have it. This helps TS narrow `SafeResolverEvent`. + endgame?: never; event: { category: string | string[]; type: string | string[]; @@ -559,6 +561,130 @@ export interface EndpointEvent { export type ResolverEvent = EndpointEvent | LegacyEndpointEvent; +/** + * All mappings in Elasticsearch support arrays. They can also return null values or be missing. For example, a `keyword` mapping could return `null` or `[null]` or `[]` or `'hi'`, or `['hi', 'there']`. We need to handle these cases in order to avoid throwing an error. + * When dealing with an value that comes from ES, wrap the underlying type in `ECSField`. For example, if you have a `keyword` or `text` value coming from ES, cast it to `ECSField`. + */ +export type ECSField = T | null | Array; + +/** + * A more conservative version of `ResolverEvent` that treats fields as optional and use `ECSField` to type all ECS fields. + * Prefer this over `ResolverEvent`. + */ +export type SafeResolverEvent = SafeEndpointEvent | SafeLegacyEndpointEvent; + +/** + * Safer version of ResolverEvent. Please use this going forward. + */ +export type SafeEndpointEvent = Partial<{ + '@timestamp': ECSField; + agent: Partial<{ + id: ECSField; + version: ECSField; + type: ECSField; + }>; + ecs: Partial<{ + version: ECSField; + }>; + event: Partial<{ + category: ECSField; + type: ECSField; + id: ECSField; + kind: ECSField; + }>; + host: Partial<{ + id: ECSField; + hostname: ECSField; + name: ECSField; + ip: ECSField; + mac: ECSField; + architecture: ECSField; + os: Partial<{ + full: ECSField; + name: ECSField; + version: ECSField; + platform: ECSField; + family: ECSField; + Ext: Partial<{ + variant: ECSField; + }>; + }>; + }>; + network: Partial<{ + direction: ECSField; + forwarded_ip: ECSField; + }>; + dns: Partial<{ + question: Partial<{ name: ECSField }>; + }>; + process: Partial<{ + entity_id: ECSField; + name: ECSField; + executable: ECSField; + args: ECSField; + code_signature: Partial<{ + status: ECSField; + subject_name: ECSField; + }>; + pid: ECSField; + hash: Partial<{ + md5: ECSField; + }>; + parent: Partial<{ + entity_id: ECSField; + name: ECSField; + pid: ECSField; + }>; + /* + * The array has a special format. The entity_ids towards the beginning of the array are closer ancestors and the + * values towards the end of the array are more distant ancestors (grandparents). Therefore + * ancestry_array[0] == process.parent.entity_id and ancestry_array[1] == process.parent.parent.entity_id + */ + Ext: Partial<{ + ancestry: ECSField; + }>; + }>; + user: Partial<{ + domain: ECSField; + name: ECSField; + }>; + file: Partial<{ path: ECSField }>; + registry: Partial<{ path: ECSField; key: ECSField }>; +}>; + +export interface SafeLegacyEndpointEvent { + '@timestamp'?: ECSField; + /** + * 'legacy' events must have an `endgame` key. + */ + endgame: Partial<{ + pid: ECSField; + ppid: ECSField; + event_type_full: ECSField; + event_subtype_full: ECSField; + event_timestamp: ECSField; + event_type: ECSField; + unique_pid: ECSField; + unique_ppid: ECSField; + machine_id: ECSField; + process_name: ECSField; + process_path: ECSField; + timestamp_utc: ECSField; + serial_event_id: ECSField; + }>; + agent: Partial<{ + id: ECSField; + type: ECSField; + version: ECSField; + }>; + event: Partial<{ + action: ECSField; + type: ECSField; + category: ECSField; + id: ECSField; + }>; +} + /** * The response body for the resolver '/entity' index API */ diff --git a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/__snapshots__/isometric_taxi_layout.test.ts.snap b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/__snapshots__/isometric_taxi_layout.test.ts.snap index 6f26bfe063c05..db8d047c2ce86 100644 --- a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/__snapshots__/isometric_taxi_layout.test.ts.snap +++ b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/__snapshots__/isometric_taxi_layout.test.ts.snap @@ -182,7 +182,7 @@ Object { "edgeLineSegments": Array [ Object { "metadata": Object { - "uniqueId": "parentToMid", + "uniqueId": "parentToMidedge:0:1", }, "points": Array [ Array [ @@ -197,7 +197,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "midway", + "uniqueId": "midwayedge:0:1", }, "points": Array [ Array [ @@ -212,7 +212,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "", + "uniqueId": "edge:0:1", }, "points": Array [ Array [ @@ -227,7 +227,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "", + "uniqueId": "edge:0:2", }, "points": Array [ Array [ @@ -242,7 +242,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "", + "uniqueId": "edge:0:8", }, "points": Array [ Array [ @@ -257,7 +257,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "parentToMid13", + "uniqueId": "parentToMidedge:1:3", }, "points": Array [ Array [ @@ -272,7 +272,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "midway13", + "uniqueId": "midwayedge:1:3", }, "points": Array [ Array [ @@ -287,7 +287,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "13", + "uniqueId": "edge:1:3", }, "points": Array [ Array [ @@ -302,7 +302,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "14", + "uniqueId": "edge:1:4", }, "points": Array [ Array [ @@ -317,7 +317,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "parentToMid25", + "uniqueId": "parentToMidedge:2:5", }, "points": Array [ Array [ @@ -332,7 +332,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "midway25", + "uniqueId": "midwayedge:2:5", }, "points": Array [ Array [ @@ -347,7 +347,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "25", + "uniqueId": "edge:2:5", }, "points": Array [ Array [ @@ -362,7 +362,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "26", + "uniqueId": "edge:2:6", }, "points": Array [ Array [ @@ -377,7 +377,7 @@ Object { }, Object { "metadata": Object { - "uniqueId": "67", + "uniqueId": "edge:6:7", }, "points": Array [ Array [ @@ -584,7 +584,7 @@ Object { "edgeLineSegments": Array [ Object { "metadata": Object { - "uniqueId": "", + "uniqueId": "edge:0:1", }, "points": Array [ Array [ diff --git a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts index 060a014b8730f..f6b893ba25b78 100644 --- a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts +++ b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts @@ -4,10 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { uniquePidForProcess, uniqueParentPidForProcess, orderByTime } from '../process_event'; +import { orderByTime } from '../process_event'; import { IndexedProcessTree } from '../../types'; -import { ResolverEvent } from '../../../../common/endpoint/types'; +import { SafeResolverEvent } from '../../../../common/endpoint/types'; import { levelOrder as baseLevelOrder } from '../../lib/tree_sequencers'; +import * as eventModel from '../../../../common/endpoint/models/event'; /** * Create a new IndexedProcessTree from an array of ProcessEvents. @@ -15,24 +16,25 @@ import { levelOrder as baseLevelOrder } from '../../lib/tree_sequencers'; */ export function factory( // Array of processes to index as a tree - processes: ResolverEvent[] + processes: SafeResolverEvent[] ): IndexedProcessTree { - const idToChildren = new Map(); - const idToValue = new Map(); + const idToChildren = new Map(); + const idToValue = new Map(); for (const process of processes) { - const uniqueProcessPid = uniquePidForProcess(process); - idToValue.set(uniqueProcessPid, process); + const entityID: string | undefined = eventModel.entityIDSafeVersion(process); + if (entityID !== undefined) { + idToValue.set(entityID, process); - // NB: If the value was null or undefined, use `undefined` - const uniqueParentPid: string | undefined = uniqueParentPidForProcess(process) ?? undefined; + const uniqueParentPid: string | undefined = eventModel.parentEntityIDSafeVersion(process); - let childrenWithTheSameParent = idToChildren.get(uniqueParentPid); - if (!childrenWithTheSameParent) { - childrenWithTheSameParent = []; - idToChildren.set(uniqueParentPid, childrenWithTheSameParent); + let childrenWithTheSameParent = idToChildren.get(uniqueParentPid); + if (!childrenWithTheSameParent) { + childrenWithTheSameParent = []; + idToChildren.set(uniqueParentPid, childrenWithTheSameParent); + } + childrenWithTheSameParent.push(process); } - childrenWithTheSameParent.push(process); } // sort the children of each node @@ -49,7 +51,10 @@ export function factory( /** * Returns an array with any children `ProcessEvent`s of the passed in `process` */ -export function children(tree: IndexedProcessTree, parentID: string | undefined): ResolverEvent[] { +export function children( + tree: IndexedProcessTree, + parentID: string | undefined +): SafeResolverEvent[] { const currentProcessSiblings = tree.idToChildren.get(parentID); return currentProcessSiblings === undefined ? [] : currentProcessSiblings; } @@ -57,7 +62,7 @@ export function children(tree: IndexedProcessTree, parentID: string | undefined) /** * Get the indexed process event for the ID */ -export function processEvent(tree: IndexedProcessTree, entityID: string): ResolverEvent | null { +export function processEvent(tree: IndexedProcessTree, entityID: string): SafeResolverEvent | null { return tree.idToProcess.get(entityID) ?? null; } @@ -66,9 +71,9 @@ export function processEvent(tree: IndexedProcessTree, entityID: string): Resolv */ export function parent( tree: IndexedProcessTree, - childProcess: ResolverEvent -): ResolverEvent | undefined { - const uniqueParentPid = uniqueParentPidForProcess(childProcess); + childProcess: SafeResolverEvent +): SafeResolverEvent | undefined { + const uniqueParentPid = eventModel.parentEntityIDSafeVersion(childProcess); if (uniqueParentPid === undefined) { return undefined; } else { @@ -91,7 +96,7 @@ export function root(tree: IndexedProcessTree) { return null; } // any node will do - let current: ResolverEvent = tree.idToProcess.values().next().value; + let current: SafeResolverEvent = tree.idToProcess.values().next().value; // iteratively swap current w/ its parent while (parent(tree, current) !== undefined) { @@ -106,8 +111,8 @@ export function root(tree: IndexedProcessTree) { export function* levelOrder(tree: IndexedProcessTree) { const rootNode = root(tree); if (rootNode !== null) { - yield* baseLevelOrder(rootNode, (parentNode: ResolverEvent): ResolverEvent[] => - children(tree, uniquePidForProcess(parentNode)) + yield* baseLevelOrder(rootNode, (parentNode: SafeResolverEvent): SafeResolverEvent[] => + children(tree, eventModel.entityIDSafeVersion(parentNode)) ); } } diff --git a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/isometric_taxi_layout.ts b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/isometric_taxi_layout.ts index 1fc2ea0150aee..f0880fa635a24 100644 --- a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/isometric_taxi_layout.ts +++ b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/isometric_taxi_layout.ts @@ -14,12 +14,11 @@ import { Matrix3, IsometricTaxiLayout, } from '../../types'; -import * as event from '../../../../common/endpoint/models/event'; -import { ResolverEvent } from '../../../../common/endpoint/types'; +import * as eventModel from '../../../../common/endpoint/models/event'; +import { SafeResolverEvent } from '../../../../common/endpoint/types'; import * as vector2 from '../vector2'; import * as indexedProcessTreeModel from './index'; import { getFriendlyElapsedTime as elapsedTime } from '../../lib/date'; -import { uniquePidForProcess } from '../process_event'; /** * Graph the process tree @@ -30,25 +29,29 @@ export function isometricTaxiLayoutFactory( /** * Walk the tree in reverse level order, calculating the 'width' of subtrees. */ - const widths = widthsOfProcessSubtrees(indexedProcessTree); + const widths: Map = widthsOfProcessSubtrees(indexedProcessTree); /** * Walk the tree in level order. Using the precalculated widths, calculate the position of nodes. * Nodes are positioned relative to their parents and preceding siblings. */ - const positions = processPositions(indexedProcessTree, widths); + const positions: Map = processPositions(indexedProcessTree, widths); /** * With the widths and positions precalculated, we calculate edge line segments (arrays of vector2s) * which connect them in a 'pitchfork' design. */ - const edgeLineSegments = processEdgeLineSegments(indexedProcessTree, widths, positions); + const edgeLineSegments: EdgeLineSegment[] = processEdgeLineSegments( + indexedProcessTree, + widths, + positions + ); /** * Transform the positions of nodes and edges so they seem like they are on an isometric grid. */ const transformedEdgeLineSegments: EdgeLineSegment[] = []; - const transformedPositions = new Map(); + const transformedPositions = new Map(); for (const [processEvent, position] of positions) { transformedPositions.set( @@ -83,8 +86,8 @@ export function isometricTaxiLayoutFactory( /** * Calculate a level (starting at 1) for each node. */ -function ariaLevels(indexedProcessTree: IndexedProcessTree): Map { - const map: Map = new Map(); +function ariaLevels(indexedProcessTree: IndexedProcessTree): Map { + const map: Map = new Map(); for (const node of indexedProcessTreeModel.levelOrder(indexedProcessTree)) { const parentNode = indexedProcessTreeModel.parent(indexedProcessTree, node); if (parentNode === undefined) { @@ -143,20 +146,20 @@ function ariaLevels(indexedProcessTree: IndexedProcessTree): Map(); + const widths = new Map(); if (indexedProcessTreeModel.size(indexedProcessTree) === 0) { return widths; } - const processesInReverseLevelOrder: ResolverEvent[] = [ + const processesInReverseLevelOrder: SafeResolverEvent[] = [ ...indexedProcessTreeModel.levelOrder(indexedProcessTree), ].reverse(); for (const process of processesInReverseLevelOrder) { const children = indexedProcessTreeModel.children( indexedProcessTree, - uniquePidForProcess(process) + eventModel.entityIDSafeVersion(process) ); const sumOfWidthOfChildren = function sumOfWidthOfChildren() { @@ -167,7 +170,7 @@ function widthsOfProcessSubtrees(indexedProcessTree: IndexedProcessTree): Proces * Therefore a parent can always find a width for its children, since all of its children * will have been handled already. */ - return currentValue + widths.get(child)!; + return currentValue + (widths.get(child) ?? 0); }, 0); }; @@ -178,6 +181,9 @@ function widthsOfProcessSubtrees(indexedProcessTree: IndexedProcessTree): Proces return widths; } +/** + * Layout the graph. Note: if any process events are missing the `entity_id`, this will throw an Error. + */ function processEdgeLineSegments( indexedProcessTree: IndexedProcessTree, widths: ProcessWidths, @@ -196,9 +202,13 @@ function processEdgeLineSegments( const { process, parent, parentWidth } = metadata; const position = positions.get(process); const parentPosition = positions.get(parent); - const parentId = event.entityId(parent); - const processEntityId = event.entityId(process); - const edgeLineId = parentId ? parentId + processEntityId : parentId; + const parentID = eventModel.entityIDSafeVersion(parent); + const processEntityID = eventModel.entityIDSafeVersion(process); + + if (processEntityID === undefined) { + throw new Error('tried to graph a Resolver that had a process with no `process.entity_id`'); + } + const edgeLineID = `edge:${parentID ?? 'undefined'}:${processEntityID}`; if (position === undefined || parentPosition === undefined) { /** @@ -207,12 +217,12 @@ function processEdgeLineSegments( throw new Error(); } - const parentTime = event.eventTimestamp(parent); - const processTime = event.eventTimestamp(process); + const parentTime = eventModel.timestampSafeVersion(parent); + const processTime = eventModel.timestampSafeVersion(process); if (parentTime && processTime) { edgeLineMetadata.elapsedTime = elapsedTime(parentTime, processTime) ?? undefined; } - edgeLineMetadata.uniqueId = edgeLineId; + edgeLineMetadata.uniqueId = edgeLineID; /** * The point halfway between the parent and child on the y axis, we sometimes have a hard angle here in the edge line @@ -236,7 +246,7 @@ function processEdgeLineSegments( const siblings = indexedProcessTreeModel.children( indexedProcessTree, - uniquePidForProcess(parent) + eventModel.entityIDSafeVersion(parent) ); const isFirstChild = process === siblings[0]; @@ -260,7 +270,7 @@ function processEdgeLineSegments( const lineFromParentToMidwayLine: EdgeLineSegment = { points: [parentPosition, [parentPosition[0], midwayY]], - metadata: { uniqueId: `parentToMid${edgeLineId}` }, + metadata: { uniqueId: `parentToMid${edgeLineID}` }, }; const widthOfMidline = parentWidth - firstChildWidth / 2 - lastChildWidth / 2; @@ -281,7 +291,7 @@ function processEdgeLineSegments( midwayY, ], ], - metadata: { uniqueId: `midway${edgeLineId}` }, + metadata: { uniqueId: `midway${edgeLineID}` }, }; edgeLineSegments.push( @@ -303,13 +313,13 @@ function processPositions( indexedProcessTree: IndexedProcessTree, widths: ProcessWidths ): ProcessPositions { - const positions = new Map(); + const positions = new Map(); /** * This algorithm iterates the tree in level order. It keeps counters that are reset for each parent. * By keeping track of the last parent node, we can know when we are dealing with a new set of siblings and * reset the counters. */ - let lastProcessedParentNode: ResolverEvent | undefined; + let lastProcessedParentNode: SafeResolverEvent | undefined; /** * Nodes are positioned relative to their siblings. We walk this in level order, so we handle * children left -> right. @@ -431,7 +441,10 @@ function* levelOrderWithWidths( parentWidth, }; - const siblings = indexedProcessTreeModel.children(tree, uniquePidForProcess(parent)); + const siblings = indexedProcessTreeModel.children( + tree, + eventModel.entityIDSafeVersion(parent) + ); if (siblings.length === 1) { metadata.isOnlyChild = true; metadata.lastChildWidth = width; @@ -488,7 +501,10 @@ const distanceBetweenNodesInUnits = 2; */ const distanceBetweenNodes = distanceBetweenNodesInUnits * unit; -export function nodePosition(model: IsometricTaxiLayout, node: ResolverEvent): Vector2 | undefined { +export function nodePosition( + model: IsometricTaxiLayout, + node: SafeResolverEvent +): Vector2 | undefined { return model.processNodePositions.get(node); } diff --git a/x-pack/plugins/security_solution/public/resolver/models/process_event.test.ts b/x-pack/plugins/security_solution/public/resolver/models/process_event.test.ts index 4b1d555d0a7c3..4d48b34fb2841 100644 --- a/x-pack/plugins/security_solution/public/resolver/models/process_event.test.ts +++ b/x-pack/plugins/security_solution/public/resolver/models/process_event.test.ts @@ -6,7 +6,11 @@ import { eventType, orderByTime, userInfoForProcess } from './process_event'; import { mockProcessEvent } from './process_event_test_helpers'; -import { LegacyEndpointEvent, ResolverEvent } from '../../../common/endpoint/types'; +import { + LegacyEndpointEvent, + ResolverEvent, + SafeResolverEvent, +} from '../../../common/endpoint/types'; describe('process event', () => { describe('eventType', () => { @@ -42,7 +46,7 @@ describe('process event', () => { }); describe('orderByTime', () => { let mock: (time: number, eventID: string) => ResolverEvent; - let events: ResolverEvent[]; + let events: SafeResolverEvent[]; beforeEach(() => { mock = (time, eventID) => { return { @@ -56,14 +60,14 @@ describe('process event', () => { // each event has a unique id, a through h // order is arbitrary events = [ - mock(-1, 'a'), - mock(0, 'c'), - mock(1, 'e'), - mock(NaN, 'g'), - mock(-1, 'b'), - mock(0, 'd'), - mock(1, 'f'), - mock(NaN, 'h'), + mock(-1, 'a') as SafeResolverEvent, + mock(0, 'c') as SafeResolverEvent, + mock(1, 'e') as SafeResolverEvent, + mock(NaN, 'g') as SafeResolverEvent, + mock(-1, 'b') as SafeResolverEvent, + mock(0, 'd') as SafeResolverEvent, + mock(1, 'f') as SafeResolverEvent, + mock(NaN, 'h') as SafeResolverEvent, ]; }); it('sorts events as expected', () => { diff --git a/x-pack/plugins/security_solution/public/resolver/models/process_event.ts b/x-pack/plugins/security_solution/public/resolver/models/process_event.ts index 1a5c67f6a6f2f..ea588731a55c8 100644 --- a/x-pack/plugins/security_solution/public/resolver/models/process_event.ts +++ b/x-pack/plugins/security_solution/public/resolver/models/process_event.ts @@ -5,7 +5,7 @@ */ import * as event from '../../../common/endpoint/models/event'; -import { ResolverEvent } from '../../../common/endpoint/types'; +import { ResolverEvent, SafeResolverEvent } from '../../../common/endpoint/types'; import { ResolverProcessType } from '../types'; /** @@ -32,8 +32,8 @@ export function isTerminatedProcess(passedEvent: ResolverEvent) { * ms since Unix epoc, based on timestamp. * may return NaN if the timestamp wasn't present or was invalid. */ -export function datetime(passedEvent: ResolverEvent): number | null { - const timestamp = event.eventTimestamp(passedEvent); +export function datetime(passedEvent: SafeResolverEvent): number | null { + const timestamp = event.timestampSafeVersion(passedEvent); const time = timestamp === undefined ? 0 : new Date(timestamp).getTime(); @@ -178,13 +178,15 @@ export function argsForProcess(passedEvent: ResolverEvent): string | undefined { /** * used to sort events */ -export function orderByTime(first: ResolverEvent, second: ResolverEvent): number { +export function orderByTime(first: SafeResolverEvent, second: SafeResolverEvent): number { const firstDatetime: number | null = datetime(first); const secondDatetime: number | null = datetime(second); if (firstDatetime === secondDatetime) { // break ties using an arbitrary (stable) comparison of `eventId` (which should be unique) - return String(event.eventId(first)).localeCompare(String(event.eventId(second))); + return String(event.eventIDSafeVersion(first)).localeCompare( + String(event.eventIDSafeVersion(second)) + ); } else if (firstDatetime === null || secondDatetime === null) { // sort `null`'s as higher than numbers return (firstDatetime === null ? 1 : 0) - (secondDatetime === null ? 1 : 0); diff --git a/x-pack/plugins/security_solution/public/resolver/store/actions.ts b/x-pack/plugins/security_solution/public/resolver/store/actions.ts index 418eb0d837276..29c03215e9ff4 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/actions.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/actions.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { CameraAction } from './camera'; -import { ResolverEvent } from '../../../common/endpoint/types'; +import { ResolverEvent, SafeResolverEvent } from '../../../common/endpoint/types'; import { DataAction } from './data/action'; /** @@ -96,7 +96,7 @@ interface UserSelectedResolverNode { interface UserSelectedRelatedEventCategory { readonly type: 'userSelectedRelatedEventCategory'; readonly payload: { - subject: ResolverEvent; + subject: SafeResolverEvent; category?: string; }; } diff --git a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts index 272d0aae7eef4..569a24bb8537e 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts @@ -28,10 +28,11 @@ import { ResolverTree, ResolverNodeStats, ResolverRelatedEvents, + SafeResolverEvent, } from '../../../../common/endpoint/types'; import * as resolverTreeModel from '../../models/resolver_tree'; import * as isometricTaxiLayoutModel from '../../models/indexed_process_tree/isometric_taxi_layout'; -import { allEventCategories } from '../../../../common/endpoint/models/event'; +import * as eventModel from '../../../../common/endpoint/models/event'; import * as vector2 from '../../models/vector2'; /** @@ -145,7 +146,7 @@ export const tree = createSelector(graphableProcesses, function indexedTree( graphableProcesses /* eslint-enable no-shadow */ ) { - return indexedProcessTreeModel.factory(graphableProcesses); + return indexedProcessTreeModel.factory(graphableProcesses as SafeResolverEvent[]); }); /** @@ -194,7 +195,9 @@ export const relatedEventsByCategory: ( } return relatedById.events.reduce( (eventsByCategory: ResolverEvent[], candidate: ResolverEvent) => { - if ([candidate && allEventCategories(candidate)].flat().includes(ecsCategory)) { + if ( + [candidate && eventModel.allEventCategories(candidate)].flat().includes(ecsCategory) + ) { eventsByCategory.push(candidate); } return eventsByCategory; @@ -280,7 +283,7 @@ export const relatedEventInfoByEntityId: ( return []; } return eventsResponseForThisEntry.events.filter((resolverEvent) => { - for (const category of [allEventCategories(resolverEvent)].flat()) { + for (const category of [eventModel.allEventCategories(resolverEvent)].flat()) { if (category === eventCategory) { return true; } @@ -404,7 +407,7 @@ export const processEventForID: ( ) => (nodeID: string) => ResolverEvent | null = createSelector( tree, (indexedProcessTree) => (nodeID: string) => - indexedProcessTreeModel.processEvent(indexedProcessTree, nodeID) + indexedProcessTreeModel.processEvent(indexedProcessTree, nodeID) as ResolverEvent ); /** @@ -415,7 +418,7 @@ export const ariaLevel: (state: DataState) => (nodeID: string) => number | null processEventForID, ({ ariaLevels }, processEventGetter) => (nodeID: string) => { const node = processEventGetter(nodeID); - return node ? ariaLevels.get(node) ?? null : null; + return node ? ariaLevels.get(node as SafeResolverEvent) ?? null : null; } ); @@ -468,10 +471,10 @@ export const ariaFlowtoCandidate: ( for (const child of children) { if (previousChild !== null) { // Set the `child` as the following sibling of `previousChild`. - memo.set(uniquePidForProcess(previousChild), uniquePidForProcess(child)); + memo.set(uniquePidForProcess(previousChild), uniquePidForProcess(child as ResolverEvent)); } // Set the child as the previous child. - previousChild = child; + previousChild = child as ResolverEvent; } if (previousChild) { @@ -553,7 +556,7 @@ export const nodesAndEdgelines: ( maxX, maxY, }); - const visibleProcessNodePositions = new Map( + const visibleProcessNodePositions = new Map( entities .filter((entity): entity is IndexedProcessNode => entity.type === 'processNode') .map((node) => [node.entity, node.position]) diff --git a/x-pack/plugins/security_solution/public/resolver/store/methods.ts b/x-pack/plugins/security_solution/public/resolver/store/methods.ts index ad06ddf36161a..8dd15b1a44d0c 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/methods.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/methods.ts @@ -7,7 +7,7 @@ import { animatePanning } from './camera/methods'; import { layout } from './selectors'; import { ResolverState } from '../types'; -import { ResolverEvent } from '../../../common/endpoint/types'; +import { ResolverEvent, SafeResolverEvent } from '../../../common/endpoint/types'; const animationDuration = 1000; @@ -20,7 +20,7 @@ export function animateProcessIntoView( process: ResolverEvent ): ResolverState { const { processNodePositions } = layout(state); - const position = processNodePositions.get(process); + const position = processNodePositions.get(process as SafeResolverEvent); if (position) { return { ...state, diff --git a/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts b/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts index df365a078b27f..dfbc6bd290686 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts @@ -13,6 +13,7 @@ import { mockTreeWith2AncestorsAndNoChildren, mockTreeWithNoAncestorsAnd2Children, } from './mocks/resolver_tree'; +import { SafeResolverEvent } from '../../../common/endpoint/types'; describe('resolver selectors', () => { const actions: ResolverAction[] = []; @@ -114,7 +115,9 @@ describe('resolver selectors', () => { // find the position of the second child const secondChild = selectors.processEventForID(state())(secondChildID); - const positionOfSecondChild = layout.processNodePositions.get(secondChild!)!; + const positionOfSecondChild = layout.processNodePositions.get( + secondChild as SafeResolverEvent + )!; // the child is indexed by an AABB that extends -720/2 to the left const leftSideOfSecondChildAABB = positionOfSecondChild[0] - 720 / 2; @@ -130,19 +133,25 @@ describe('resolver selectors', () => { it('the origin should be in view', () => { const origin = selectors.processEventForID(state())(originID)!; expect( - selectors.visibleNodesAndEdgeLines(state())(0).processNodePositions.has(origin) + selectors + .visibleNodesAndEdgeLines(state())(0) + .processNodePositions.has(origin as SafeResolverEvent) ).toBe(true); }); it('the first child should be in view', () => { const firstChild = selectors.processEventForID(state())(firstChildID)!; expect( - selectors.visibleNodesAndEdgeLines(state())(0).processNodePositions.has(firstChild) + selectors + .visibleNodesAndEdgeLines(state())(0) + .processNodePositions.has(firstChild as SafeResolverEvent) ).toBe(true); }); it('the second child should not be in view', () => { const secondChild = selectors.processEventForID(state())(secondChildID)!; expect( - selectors.visibleNodesAndEdgeLines(state())(0).processNodePositions.has(secondChild) + selectors + .visibleNodesAndEdgeLines(state())(0) + .processNodePositions.has(secondChild as SafeResolverEvent) ).toBe(false); }); it('should return nothing as the flowto for the first child', () => { diff --git a/x-pack/plugins/security_solution/public/resolver/store/selectors.ts b/x-pack/plugins/security_solution/public/resolver/store/selectors.ts index 87ef8d5d095ef..70a461909a99b 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/selectors.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/selectors.ts @@ -9,8 +9,8 @@ import * as cameraSelectors from './camera/selectors'; import * as dataSelectors from './data/selectors'; import * as uiSelectors from './ui/selectors'; import { ResolverState, IsometricTaxiLayout } from '../types'; -import { uniquePidForProcess } from '../models/process_event'; import { ResolverEvent, ResolverNodeStats } from '../../../common/endpoint/types'; +import { entityIDSafeVersion } from '../../../common/endpoint/models/event'; /** * A matrix that when applied to a Vector2 will convert it from world coordinates to screen coordinates. @@ -271,9 +271,14 @@ export const ariaFlowtoNodeID: ( const { processNodePositions } = visibleNodesAndEdgeLinesAtTime(time); // get a `Set` containing their node IDs - const nodesVisibleAtTime: Set = new Set( - [...processNodePositions.keys()].map(uniquePidForProcess) - ); + const nodesVisibleAtTime: Set = new Set(); + // NB: in practice, any event that has been graphed is guaranteed to have an entity_id + for (const visibleEvent of processNodePositions.keys()) { + const nodeID = entityIDSafeVersion(visibleEvent); + if (nodeID !== undefined) { + nodesVisibleAtTime.add(nodeID); + } + } // return the ID of `nodeID`'s following sibling, if it is visible return (nodeID: string): string | null => { diff --git a/x-pack/plugins/security_solution/public/resolver/types.ts b/x-pack/plugins/security_solution/public/resolver/types.ts index c2871fdceb20a..30634e722050f 100644 --- a/x-pack/plugins/security_solution/public/resolver/types.ts +++ b/x-pack/plugins/security_solution/public/resolver/types.ts @@ -11,10 +11,10 @@ import { Middleware, Dispatch } from 'redux'; import { BBox } from 'rbush'; import { ResolverAction } from './store/actions'; import { - ResolverEvent, ResolverRelatedEvents, ResolverTree, ResolverEntityIndex, + SafeResolverEvent, } from '../../common/endpoint/types'; /** @@ -155,7 +155,7 @@ export interface IndexedEdgeLineSegment extends BBox { */ export interface IndexedProcessNode extends BBox { type: 'processNode'; - entity: ResolverEvent; + entity: SafeResolverEvent; position: Vector2; } @@ -280,21 +280,21 @@ export interface IndexedProcessTree { /** * Map of ID to a process's ordered children */ - idToChildren: Map; + idToChildren: Map; /** * Map of ID to process */ - idToProcess: Map; + idToProcess: Map; } /** * A map of `ProcessEvents` (representing process nodes) to the 'width' of their subtrees as calculated by `widthsOfProcessSubtrees` */ -export type ProcessWidths = Map; +export type ProcessWidths = Map; /** * Map of ProcessEvents (representing process nodes) to their positions. Calculated by `processPositions` */ -export type ProcessPositions = Map; +export type ProcessPositions = Map; export type DurationTypes = | 'millisecond' @@ -346,11 +346,11 @@ export interface EdgeLineSegment { * Used to provide pre-calculated info from `widthsOfProcessSubtrees`. These 'width' values are used in the layout of the graph. */ export type ProcessWithWidthMetadata = { - process: ResolverEvent; + process: SafeResolverEvent; width: number; } & ( | { - parent: ResolverEvent; + parent: SafeResolverEvent; parentWidth: number; isOnlyChild: boolean; firstChildWidth: number; @@ -433,7 +433,7 @@ export interface IsometricTaxiLayout { /** * A map of events to position. Each event represents its own node. */ - processNodePositions: Map; + processNodePositions: Map; /** * A map of edge-line segments, which graphically connect nodes. */ @@ -442,7 +442,7 @@ export interface IsometricTaxiLayout { /** * defines the aria levels for nodes. */ - ariaLevels: Map; + ariaLevels: Map; } /** diff --git a/x-pack/plugins/security_solution/public/resolver/view/map.tsx b/x-pack/plugins/security_solution/public/resolver/view/map.tsx index a965f06c04926..bbff2388af8b7 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/map.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/map.tsx @@ -20,7 +20,7 @@ import { SymbolDefinitions, useResolverTheme } from './assets'; import { useStateSyncingActions } from './use_state_syncing_actions'; import { useResolverQueryParams } from './use_resolver_query_params'; import { StyledMapContainer, StyledPanel, GraphContainer } from './styles'; -import { entityId } from '../../../common/endpoint/models/event'; +import { entityIDSafeVersion } from '../../../common/endpoint/models/event'; import { SideEffectContext } from './side_effect_context'; /** @@ -107,7 +107,7 @@ export const ResolverMap = React.memo(function ({ /> ))} {[...processNodePositions].map(([processEvent, position]) => { - const processEntityId = entityId(processEvent); + const processEntityId = entityIDSafeVersion(processEvent); return ( unknown; -}) { - interface ProcessTableView { - name: string; - timestamp?: Date; - event: ResolverEvent; - } - - const dispatch = useResolverDispatch(); - const { timestamp } = useContext(SideEffectContext); - const isProcessTerminated = useSelector(selectors.isProcessTerminated); - const handleBringIntoViewClick = useCallback( - (processTableViewItem) => { - dispatch({ - type: 'userBroughtProcessIntoView', - payload: { - time: timestamp(), - process: processTableViewItem.event, - }, - }); - pushToQueryParams({ crumbId: event.entityId(processTableViewItem.event), crumbEvent: '' }); - }, - [dispatch, timestamp, pushToQueryParams] - ); - - const columns = useMemo>>( - () => [ - { - field: 'name', - name: i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.table.row.processNameTitle', - { - defaultMessage: 'Process Name', - } - ), - sortable: true, - truncateText: true, - render(name: string, item: ProcessTableView) { - const entityId = event.entityId(item.event); - const isTerminated = isProcessTerminated(entityId); - return name === '' ? ( - - {i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.table.row.valueMissingDescription', - { - defaultMessage: 'Value is missing', - } - )} - - ) : ( - { - handleBringIntoViewClick(item); - pushToQueryParams({ crumbId: event.entityId(item.event), crumbEvent: '' }); - }} - > - - {name} - - ); - }, - }, - { - field: 'timestamp', - name: i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.table.row.timestampTitle', - { - defaultMessage: 'Timestamp', - } - ), - dataType: 'date', - sortable: true, - render(eventDate?: Date) { - return eventDate ? ( - formatter.format(eventDate) - ) : ( - - {i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.table.row.timestampInvalidLabel', - { - defaultMessage: 'invalid', - } - )} - - ); - }, - }, - ], - [pushToQueryParams, handleBringIntoViewClick, isProcessTerminated] - ); - - const { processNodePositions } = useSelector(selectors.layout); - const processTableView: ProcessTableView[] = useMemo( - () => - [...processNodePositions.keys()].map((processEvent) => { - let dateTime; - const eventTime = event.eventTimestamp(processEvent); - const name = event.eventName(processEvent); - if (eventTime) { - const date = new Date(eventTime); - if (isFinite(date.getTime())) { - dateTime = date; - } - } - return { - name, - timestamp: dateTime, - event: processEvent, - }; - }), - [processNodePositions] - ); - const numberOfProcesses = processTableView.length; - - const crumbs = useMemo(() => { - return [ - { - text: i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.processListWithCounts.events', - { - defaultMessage: 'All Process Events', - } - ), - onClick: () => {}, - }, - ]; - }, []); - - const children = useSelector(selectors.hasMoreChildren); - const ancestors = useSelector(selectors.hasMoreAncestors); - const showWarning = children === true || ancestors === true; - return ( - <> - - {showWarning && } - - - data-test-subj="resolver:panel:process-list" - items={processTableView} - columns={columns} - sorting - /> - - ); -}); -ProcessListWithCounts.displayName = 'ProcessListWithCounts'; +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React, { memo, useContext, useCallback, useMemo } from 'react'; +import { + EuiBasicTableColumn, + EuiBadge, + EuiButtonEmpty, + EuiSpacer, + EuiInMemoryTable, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useSelector } from 'react-redux'; +import styled from 'styled-components'; +import * as event from '../../../../common/endpoint/models/event'; +import * as selectors from '../../store/selectors'; +import { CrumbInfo, formatter, StyledBreadcrumbs } from './panel_content_utilities'; +import { useResolverDispatch } from '../use_resolver_dispatch'; +import { SideEffectContext } from '../side_effect_context'; +import { CubeForProcess } from './process_cube_icon'; +import { SafeResolverEvent } from '../../../../common/endpoint/types'; +import { LimitWarning } from '../limit_warnings'; + +const StyledLimitWarning = styled(LimitWarning)` + flex-flow: row wrap; + display: block; + align-items: baseline; + margin-top: 1em; + + & .euiCallOutHeader { + display: inline; + margin-right: 0.25em; + } + + & .euiText { + display: inline; + } + + & .euiText p { + display: inline; + } +`; + +/** + * The "default" view for the panel: A list of all the processes currently in the graph. + * + * @param {function} pushToQueryparams A function to update the hash value in the URL to control panel state + */ +export const ProcessListWithCounts = memo(function ProcessListWithCounts({ + pushToQueryParams, +}: { + pushToQueryParams: (queryStringKeyValuePair: CrumbInfo) => unknown; +}) { + interface ProcessTableView { + name?: string; + timestamp?: Date; + event: SafeResolverEvent; + } + + const dispatch = useResolverDispatch(); + const { timestamp } = useContext(SideEffectContext); + const isProcessTerminated = useSelector(selectors.isProcessTerminated); + const handleBringIntoViewClick = useCallback( + (processTableViewItem) => { + dispatch({ + type: 'userBroughtProcessIntoView', + payload: { + time: timestamp(), + process: processTableViewItem.event, + }, + }); + pushToQueryParams({ crumbId: event.entityId(processTableViewItem.event), crumbEvent: '' }); + }, + [dispatch, timestamp, pushToQueryParams] + ); + + const columns = useMemo>>( + () => [ + { + field: 'name', + name: i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.table.row.processNameTitle', + { + defaultMessage: 'Process Name', + } + ), + sortable: true, + truncateText: true, + render(name: string, item: ProcessTableView) { + const entityID = event.entityIDSafeVersion(item.event); + const isTerminated = entityID === undefined ? false : isProcessTerminated(entityID); + return name === '' ? ( + + {i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.table.row.valueMissingDescription', + { + defaultMessage: 'Value is missing', + } + )} + + ) : ( + { + handleBringIntoViewClick(item); + pushToQueryParams({ + // Take the user back to the list of nodes if this node has no ID + crumbId: event.entityIDSafeVersion(item.event) ?? '', + crumbEvent: '', + }); + }} + > + + {name} + + ); + }, + }, + { + field: 'timestamp', + name: i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.table.row.timestampTitle', + { + defaultMessage: 'Timestamp', + } + ), + dataType: 'date', + sortable: true, + render(eventDate?: Date) { + return eventDate ? ( + formatter.format(eventDate) + ) : ( + + {i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.table.row.timestampInvalidLabel', + { + defaultMessage: 'invalid', + } + )} + + ); + }, + }, + ], + [pushToQueryParams, handleBringIntoViewClick, isProcessTerminated] + ); + + const { processNodePositions } = useSelector(selectors.layout); + const processTableView: ProcessTableView[] = useMemo( + () => + [...processNodePositions.keys()].map((processEvent) => { + let dateTime; + const eventTime = event.timestampSafeVersion(processEvent); + const name = event.processNameSafeVersion(processEvent); + if (eventTime) { + const date = new Date(eventTime); + if (isFinite(date.getTime())) { + dateTime = date; + } + } + return { + name, + timestamp: dateTime, + event: processEvent, + }; + }), + [processNodePositions] + ); + const numberOfProcesses = processTableView.length; + + const crumbs = useMemo(() => { + return [ + { + text: i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.processListWithCounts.events', + { + defaultMessage: 'All Process Events', + } + ), + onClick: () => {}, + }, + ]; + }, []); + + const children = useSelector(selectors.hasMoreChildren); + const ancestors = useSelector(selectors.hasMoreAncestors); + const showWarning = children === true || ancestors === true; + return ( + <> + + {showWarning && } + + + data-test-subj="resolver:panel:process-list" + items={processTableView} + columns={columns} + sorting + /> + + ); +}); +ProcessListWithCounts.displayName = 'ProcessListWithCounts'; diff --git a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx index 24de45ee894dc..2a5d91028d9f5 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx @@ -14,10 +14,9 @@ import { NodeSubMenu, subMenuAssets } from './submenu'; import { applyMatrix3 } from '../models/vector2'; import { Vector2, Matrix3 } from '../types'; import { SymbolIds, useResolverTheme, calculateResolverFontSize } from './assets'; -import { ResolverEvent } from '../../../common/endpoint/types'; +import { ResolverEvent, SafeResolverEvent } from '../../../common/endpoint/types'; import { useResolverDispatch } from './use_resolver_dispatch'; import * as eventModel from '../../../common/endpoint/models/event'; -import * as processEventModel from '../models/process_event'; import * as selectors from '../store/selectors'; import { useResolverQueryParams } from './use_resolver_query_params'; @@ -85,7 +84,7 @@ const UnstyledProcessEventDot = React.memo( /** * An event which contains details about the process node. */ - event: ResolverEvent; + event: SafeResolverEvent; /** * projectionMatrix which can be used to convert `position` to screen coordinates. */ @@ -114,7 +113,11 @@ const UnstyledProcessEventDot = React.memo( // Node (html id=) IDs const ariaActiveDescendant = useSelector(selectors.ariaActiveDescendant); const selectedNode = useSelector(selectors.selectedNode); - const nodeID = processEventModel.uniquePidForProcess(event); + const nodeID: string | undefined = eventModel.entityIDSafeVersion(event); + if (nodeID === undefined) { + // NB: this component should be taking nodeID as a `string` instead of handling this logic here + throw new Error('Tried to render a node with no ID'); + } const relatedEventStats = useSelector(selectors.relatedEventsStats)(nodeID); // define a standard way of giving HTML IDs to nodes based on their entity_id/nodeID. @@ -287,7 +290,9 @@ const UnstyledProcessEventDot = React.memo( ? subMenuAssets.initialMenuStatus : relatedEventOptions; - const grandTotal: number | null = useSelector(selectors.relatedEventTotalForProcess)(event); + const grandTotal: number | null = useSelector(selectors.relatedEventTotalForProcess)( + event as ResolverEvent + ); /* eslint-disable jsx-a11y/click-events-have-key-events */ /** @@ -398,11 +403,11 @@ const UnstyledProcessEventDot = React.memo( maxWidth: `${isShowingEventActions ? 400 : 210 * xScale}px`, }} tabIndex={-1} - title={eventModel.eventName(event)} + title={eventModel.processNameSafeVersion(event)} > - {eventModel.eventName(event)} + {eventModel.processNameSafeVersion(event)} diff --git a/x-pack/plugins/security_solution/public/resolver/view/resolver_without_providers.tsx b/x-pack/plugins/security_solution/public/resolver/view/resolver_without_providers.tsx index e74502243ffc8..5f1e5f18e575d 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/resolver_without_providers.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/resolver_without_providers.tsx @@ -20,7 +20,7 @@ import { SymbolDefinitions, useResolverTheme } from './assets'; import { useStateSyncingActions } from './use_state_syncing_actions'; import { useResolverQueryParams } from './use_resolver_query_params'; import { StyledMapContainer, StyledPanel, GraphContainer } from './styles'; -import { entityId } from '../../../common/endpoint/models/event'; +import { entityIDSafeVersion } from '../../../common/endpoint/models/event'; import { SideEffectContext } from './side_effect_context'; import { ResolverProps } from '../types'; @@ -114,7 +114,7 @@ export const ResolverWithoutProviders = React.memo( ) )} {[...processNodePositions].map(([processEvent, position]) => { - const processEntityId = entityId(processEvent); + const processEntityId = entityIDSafeVersion(processEvent); return ( { } const processes: ResolverEvent[] = [ ...selectors.layout(store.getState()).processNodePositions.keys(), - ]; + ] as ResolverEvent[]; process = processes[processes.length - 1]; if (!process) { throw new Error('missing the process to bring into view'); From 3064c6eceb262d80174b6a13d356325b44182500 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 6 Aug 2020 15:34:32 +0200 Subject: [PATCH 038/106] Improve state sync error handling (#74264) Fixes #71461 regression since 7.7 New state syncing utils didn't properly handle errors, Errors happening during URL parsing or writing wasn't handled, so state syncing could stop or in worth case blow out. (see #71461) There are not much scenarios where missing proper error handling could really impact users, except the one described in #71461: Kibana users state:storeInSessionStorage Users often intuitively share hashed dashboard urls directly When someone opens those urls - there is a blank screen with warning In 7.6 - dashboard would still load with default state. Since 7.7 these still could be achieved by removing query params for URL, but it is not obvious for regular users. This PR makes sure that behaviour is similar to one we had before 7.7. Co-authored-by: Elastic Machine --- ...lic-state_sync.createkbnurlstatestorage.md | 4 +- .../public/application/legacy_app.js | 2 + .../public/application/angular/context.js | 1 + .../application/angular/context_state.ts | 11 +++ .../public/application/angular/discover.js | 1 + .../application/angular/discover_state.ts | 11 +++ .../kibana_utils/docs/state_sync/README.md | 1 + .../docs/state_sync/error_handling.md | 6 ++ .../state_sync/storages/kbn_url_storage.md | 57 ++++++++++++++- src/plugins/kibana_utils/public/index.ts | 1 + .../public/state_management/url/errors.ts | 62 ++++++++++++++++ .../public/state_management/url/index.ts | 1 + .../state_management/url/kbn_url_storage.ts | 10 +-- .../public/state_sync/public.api.md | 4 +- .../create_kbn_url_state_storage.test.ts | 73 ++++++++++++++++++- .../create_kbn_url_state_storage.ts | 40 ++++++++-- src/plugins/timelion/public/app.js | 3 +- src/plugins/visualize/public/plugin.ts | 8 +- .../functional/apps/discover/_shared_links.js | 62 ++++++++++------ test/functional/services/toasts.ts | 10 +++ x-pack/plugins/lens/public/app_plugin/app.tsx | 3 + .../maps/public/routing/maps_router.js | 13 +++- .../monitoring/public/angular/app_modules.ts | 11 ++- x-pack/plugins/monitoring/public/url_state.ts | 8 +- 24 files changed, 355 insertions(+), 48 deletions(-) create mode 100644 src/plugins/kibana_utils/docs/state_sync/error_handling.md create mode 100644 src/plugins/kibana_utils/public/state_management/url/errors.ts diff --git a/docs/development/plugins/kibana_utils/public/state_sync/kibana-plugin-plugins-kibana_utils-public-state_sync.createkbnurlstatestorage.md b/docs/development/plugins/kibana_utils/public/state_sync/kibana-plugin-plugins-kibana_utils-public-state_sync.createkbnurlstatestorage.md index 22f70ce22b574..478ba2d409acd 100644 --- a/docs/development/plugins/kibana_utils/public/state_sync/kibana-plugin-plugins-kibana_utils-public-state_sync.createkbnurlstatestorage.md +++ b/docs/development/plugins/kibana_utils/public/state_sync/kibana-plugin-plugins-kibana_utils-public-state_sync.createkbnurlstatestorage.md @@ -9,8 +9,10 @@ Creates [IKbnUrlStateStorage](./kibana-plugin-plugins-kibana_utils-public-state_ Signature: ```typescript -createKbnUrlStateStorage: ({ useHash, history }?: { +createKbnUrlStateStorage: ({ useHash, history, onGetError, onSetError, }?: { useHash: boolean; history?: History | undefined; + onGetError?: ((error: Error) => void) | undefined; + onSetError?: ((error: Error) => void) | undefined; }) => IKbnUrlStateStorage ``` diff --git a/src/plugins/dashboard/public/application/legacy_app.js b/src/plugins/dashboard/public/application/legacy_app.js index 8b8fdcb7a76ac..abe04fb8bd7e3 100644 --- a/src/plugins/dashboard/public/application/legacy_app.js +++ b/src/plugins/dashboard/public/application/legacy_app.js @@ -30,6 +30,7 @@ import { createKbnUrlStateStorage, redirectWhenMissing, SavedObjectNotFound, + withNotifyOnErrors, } from '../../../kibana_utils/public'; import { DashboardListing, EMPTY_FILTER } from './listing/dashboard_listing'; import { addHelpMenuToAppChrome } from './help_menu/help_menu_util'; @@ -65,6 +66,7 @@ export function initDashboardApp(app, deps) { createKbnUrlStateStorage({ history, useHash: deps.uiSettings.get('state:storeInSessionStorage'), + ...withNotifyOnErrors(deps.core.notifications.toasts), }) ); diff --git a/src/plugins/discover/public/application/angular/context.js b/src/plugins/discover/public/application/angular/context.js index a6f591eebb52d..6223090aa9f97 100644 --- a/src/plugins/discover/public/application/angular/context.js +++ b/src/plugins/discover/public/application/angular/context.js @@ -83,6 +83,7 @@ function ContextAppRouteController($routeParams, $scope, $route) { timeFieldName: indexPattern.timeFieldName, storeInSessionStorage: getServices().uiSettings.get('state:storeInSessionStorage'), history: getServices().history(), + toasts: getServices().core.notifications.toasts, }); this.state = { ...appState.getState() }; this.anchorId = $routeParams.id; diff --git a/src/plugins/discover/public/application/angular/context_state.ts b/src/plugins/discover/public/application/angular/context_state.ts index 7a92a6ace125b..5b05d8729c41d 100644 --- a/src/plugins/discover/public/application/angular/context_state.ts +++ b/src/plugins/discover/public/application/angular/context_state.ts @@ -18,11 +18,13 @@ */ import _ from 'lodash'; import { History } from 'history'; +import { NotificationsStart } from 'kibana/public'; import { createStateContainer, createKbnUrlStateStorage, syncStates, BaseStateContainer, + withNotifyOnErrors, } from '../../../../kibana_utils/public'; import { esFilters, FilterManager, Filter, Query } from '../../../../data/public'; @@ -74,6 +76,13 @@ interface GetStateParams { * History instance to use */ history: History; + + /** + * Core's notifications.toasts service + * In case it is passed in, + * kbnUrlStateStorage will use it notifying about inner errors + */ + toasts?: NotificationsStart['toasts']; } interface GetStateReturn { @@ -123,10 +132,12 @@ export function getState({ timeFieldName, storeInSessionStorage = false, history, + toasts, }: GetStateParams): GetStateReturn { const stateStorage = createKbnUrlStateStorage({ useHash: storeInSessionStorage, history, + ...(toasts && withNotifyOnErrors(toasts)), }); const globalStateInitial = stateStorage.get(GLOBAL_STATE_URL_KEY) as GlobalState; diff --git a/src/plugins/discover/public/application/angular/discover.js b/src/plugins/discover/public/application/angular/discover.js index 4a27f261a6220..22da3e877054a 100644 --- a/src/plugins/discover/public/application/angular/discover.js +++ b/src/plugins/discover/public/application/angular/discover.js @@ -220,6 +220,7 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise defaultAppState: getStateDefaults(), storeInSessionStorage: config.get('state:storeInSessionStorage'), history, + toasts: core.notifications.toasts, }); if (appStateContainer.getState().index !== $scope.indexPattern.id) { //used index pattern is different than the given by url/state which is invalid diff --git a/src/plugins/discover/public/application/angular/discover_state.ts b/src/plugins/discover/public/application/angular/discover_state.ts index 46500d9fdf85e..ff8fb9f80a723 100644 --- a/src/plugins/discover/public/application/angular/discover_state.ts +++ b/src/plugins/discover/public/application/angular/discover_state.ts @@ -18,12 +18,14 @@ */ import { isEqual } from 'lodash'; import { History } from 'history'; +import { NotificationsStart } from 'kibana/public'; import { createStateContainer, createKbnUrlStateStorage, syncState, ReduxLikeStateContainer, IKbnUrlStateStorage, + withNotifyOnErrors, } from '../../../../kibana_utils/public'; import { esFilters, Filter, Query } from '../../../../data/public'; import { migrateLegacyQuery } from '../../../../kibana_legacy/public'; @@ -68,6 +70,13 @@ interface GetStateParams { * Browser history */ history: History; + + /** + * Core's notifications.toasts service + * In case it is passed in, + * kbnUrlStateStorage will use it notifying about inner errors + */ + toasts?: NotificationsStart['toasts']; } export interface GetStateReturn { @@ -122,10 +131,12 @@ export function getState({ defaultAppState = {}, storeInSessionStorage = false, history, + toasts, }: GetStateParams): GetStateReturn { const stateStorage = createKbnUrlStateStorage({ useHash: storeInSessionStorage, history, + ...(toasts && withNotifyOnErrors(toasts)), }); const appStateFromUrl = stateStorage.get(APP_STATE_URL_KEY) as AppState; diff --git a/src/plugins/kibana_utils/docs/state_sync/README.md b/src/plugins/kibana_utils/docs/state_sync/README.md index acfe6dcf76fe9..c84bf7f236330 100644 --- a/src/plugins/kibana_utils/docs/state_sync/README.md +++ b/src/plugins/kibana_utils/docs/state_sync/README.md @@ -58,3 +58,4 @@ To run them, start kibana with `--run-examples` flag. - [On-the-fly state migrations](./on_fly_state_migrations.md). - [syncStates helper](./sync_states.md). - [Helpers for Data plugin (syncing TimeRange, RefreshInterval and Filters)](./data_plugin_helpers.md). +- [Error handling](./error_handling.md) diff --git a/src/plugins/kibana_utils/docs/state_sync/error_handling.md b/src/plugins/kibana_utils/docs/state_sync/error_handling.md new file mode 100644 index 0000000000000..b12e1040af260 --- /dev/null +++ b/src/plugins/kibana_utils/docs/state_sync/error_handling.md @@ -0,0 +1,6 @@ +# Error handling + +State syncing util doesn't have specific api for handling errors. +It expects that errors are handled on storage level. + +see [KbnUrlStateStorage](./storages/kbn_url_storage.md#) error handling section for details. diff --git a/src/plugins/kibana_utils/docs/state_sync/storages/kbn_url_storage.md b/src/plugins/kibana_utils/docs/state_sync/storages/kbn_url_storage.md index 3a31f5a326edb..ec27895eed666 100644 --- a/src/plugins/kibana_utils/docs/state_sync/storages/kbn_url_storage.md +++ b/src/plugins/kibana_utils/docs/state_sync/storages/kbn_url_storage.md @@ -65,7 +65,7 @@ To prevent bugs caused by missing history updates, make sure your app uses one i For example, if you use `react-router`: ```tsx -const App = props => { +const App = (props) => { useEffect(() => { const stateStorage = createKbnUrlStateStorage({ useHash: props.uiSettings.get('state:storeInSessionStorage'), @@ -160,3 +160,58 @@ const { start, stop } = syncStates([ ; ``` + +### Error handling + +Errors could occur both during `kbnUrlStateStorage.get()` and `kbnUrlStateStorage.set()` + +#### Handling kbnUrlStateStorage.get() errors + +Possible error scenarios during `kbnUrlStateStorage.get()`: + +1. Rison in URL is malformed. Parsing exception. +2. useHash is enabled and current hash is missing in `sessionStorage` + +In all the cases error is handled internally and `kbnUrlStateStorage.get()` returns `null`, just like if there is no state in the URL anymore + +You can pass callback to get notified about errors. Use it, for example, for notifying users + +```ts +const kbnUrlStateStorage = createKbnUrlStateStorage({ + history, + onGetError: (error) => { + alert(error.message); + }, +}); +``` + +#### Handling kbnUrlStateStorage.set() errors + +Possible errors during `kbnUrlStateStorage.set()`: + +1. `useHash` is enabled and can't store state in `sessionStorage` (overflow or no access) + +In all the cases error is handled internally and URL update is skipped + +You can pass callback to get notified about errors. Use it, for example, for notifying users: + +```ts +const kbnUrlStateStorage = createKbnUrlStateStorage({ + history, + onSetError: (error) => { + alert(error.message); + }, +}); +``` + +#### Helper to integrate with core.notifications.toasts + +The most common scenario is to notify users about issues with state syncing using toast service from core +There is a convenient helper for this: + +```ts +const kbnUrlStateStorage = createKbnUrlStateStorage({ + history, + ...withNotifyOnErrors(core.notifications.toasts), +}); +``` diff --git a/src/plugins/kibana_utils/public/index.ts b/src/plugins/kibana_utils/public/index.ts index e2d6ae647abb1..d1c9eec0e9906 100644 --- a/src/plugins/kibana_utils/public/index.ts +++ b/src/plugins/kibana_utils/public/index.ts @@ -57,6 +57,7 @@ export { getStateFromKbnUrl, getStatesFromKbnUrl, setStateToKbnUrl, + withNotifyOnErrors, } from './state_management/url'; export { syncState, diff --git a/src/plugins/kibana_utils/public/state_management/url/errors.ts b/src/plugins/kibana_utils/public/state_management/url/errors.ts new file mode 100644 index 0000000000000..b8b6523e8070c --- /dev/null +++ b/src/plugins/kibana_utils/public/state_management/url/errors.ts @@ -0,0 +1,62 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { NotificationsStart } from 'kibana/public'; + +export const restoreUrlErrorTitle = i18n.translate( + 'kibana_utils.stateManagement.url.restoreUrlErrorTitle', + { + defaultMessage: `Error restoring state from URL`, + } +); + +export const saveStateInUrlErrorTitle = i18n.translate( + 'kibana_utils.stateManagement.url.saveStateInUrlErrorTitle', + { + defaultMessage: `Error saving state in URL`, + } +); + +/** + * Helper for configuring {@link IKbnUrlStateStorage} to notify about inner errors + * + * @example + * ```ts + * const kbnUrlStateStorage = createKbnUrlStateStorage({ + * history, + * ...withNotifyOnErrors(core.notifications.toast)) + * } + * ``` + * @param toast - toastApi from core.notifications.toasts + */ +export const withNotifyOnErrors = (toasts: NotificationsStart['toasts']) => { + return { + onGetError: (error: Error) => { + toasts.addError(error, { + title: restoreUrlErrorTitle, + }); + }, + onSetError: (error: Error) => { + toasts.addError(error, { + title: saveStateInUrlErrorTitle, + }); + }, + }; +}; diff --git a/src/plugins/kibana_utils/public/state_management/url/index.ts b/src/plugins/kibana_utils/public/state_management/url/index.ts index e28d183c6560a..66fecd723e3ba 100644 --- a/src/plugins/kibana_utils/public/state_management/url/index.ts +++ b/src/plugins/kibana_utils/public/state_management/url/index.ts @@ -27,3 +27,4 @@ export { } from './kbn_url_storage'; export { createKbnUrlTracker } from './kbn_url_tracker'; export { createUrlTracker } from './url_tracker'; +export { withNotifyOnErrors, saveStateInUrlErrorTitle, restoreUrlErrorTitle } from './errors'; diff --git a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts index d9149095a2fa2..fefd5f668c6b3 100644 --- a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts +++ b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts @@ -103,7 +103,7 @@ export function setStateToKbnUrl( export interface IKbnUrlControls { /** * Listen for url changes - * @param cb - get's called when url has been changed + * @param cb - called when url has been changed */ listen: (cb: () => void) => () => void; @@ -142,12 +142,12 @@ export interface IKbnUrlControls { */ cancel: () => void; } -export type UrlUpdaterFnType = (currentUrl: string) => string; +export type UrlUpdaterFnType = (currentUrl: string) => string | undefined; export const createKbnUrlControls = ( history: History = createBrowserHistory() ): IKbnUrlControls => { - const updateQueue: Array<(currentUrl: string) => string> = []; + const updateQueue: UrlUpdaterFnType[] = []; // if we should replace or push with next async update, // if any call in a queue asked to push, then we should push @@ -188,7 +188,7 @@ export const createKbnUrlControls = ( function getPendingUrl() { if (updateQueue.length === 0) return undefined; const resultUrl = updateQueue.reduce( - (url, nextUpdate) => nextUpdate(url), + (url, nextUpdate) => nextUpdate(url) ?? url, getCurrentUrl(history) ); @@ -201,7 +201,7 @@ export const createKbnUrlControls = ( cb(); }), update: (newUrl: string, replace = false) => updateUrl(newUrl, replace), - updateAsync: (updater: (currentUrl: string) => string, replace = false) => { + updateAsync: (updater: UrlUpdaterFnType, replace = false) => { updateQueue.push(updater); if (shouldReplace) { shouldReplace = replace; diff --git a/src/plugins/kibana_utils/public/state_sync/public.api.md b/src/plugins/kibana_utils/public/state_sync/public.api.md index ae8c0e8e401b8..a4dfea82cdb59 100644 --- a/src/plugins/kibana_utils/public/state_sync/public.api.md +++ b/src/plugins/kibana_utils/public/state_sync/public.api.md @@ -8,9 +8,11 @@ import { History } from 'history'; import { Observable } from 'rxjs'; // @public -export const createKbnUrlStateStorage: ({ useHash, history }?: { +export const createKbnUrlStateStorage: ({ useHash, history, onGetError, onSetError, }?: { useHash: boolean; history?: History | undefined; + onGetError?: ((error: Error) => void) | undefined; + onSetError?: ((error: Error) => void) | undefined; }) => IKbnUrlStateStorage; // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "Storage" diff --git a/src/plugins/kibana_utils/public/state_sync/state_sync_state_storage/create_kbn_url_state_storage.test.ts b/src/plugins/kibana_utils/public/state_sync/state_sync_state_storage/create_kbn_url_state_storage.test.ts index cc708d14ea8b5..e222af91d7729 100644 --- a/src/plugins/kibana_utils/public/state_sync/state_sync_state_storage/create_kbn_url_state_storage.test.ts +++ b/src/plugins/kibana_utils/public/state_sync/state_sync_state_storage/create_kbn_url_state_storage.test.ts @@ -16,12 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -import '../../storage/hashed_item_store/mock'; +import { mockStorage } from '../../storage/hashed_item_store/mock'; import { createKbnUrlStateStorage, IKbnUrlStateStorage } from './create_kbn_url_state_storage'; import { History, createBrowserHistory } from 'history'; import { takeUntil, toArray } from 'rxjs/operators'; import { Subject } from 'rxjs'; import { ScopedHistory } from '../../../../../core/public'; +import { withNotifyOnErrors } from '../../state_management/url'; +import { coreMock } from '../../../../../core/public/mocks'; describe('KbnUrlStateStorage', () => { describe('useHash: false', () => { @@ -93,6 +95,37 @@ describe('KbnUrlStateStorage', () => { expect(await result).toEqual([{ test: 'test', ok: 1 }, { test: 'test', ok: 2 }, null]); }); + + it("shouldn't throw in case of parsing error", async () => { + const key = '_s'; + history.replace(`/#?${key}=(ok:2,test:`); // malformed rison + expect(() => urlStateStorage.get(key)).not.toThrow(); + expect(urlStateStorage.get(key)).toBeNull(); + }); + + it('should notify about errors', () => { + const cb = jest.fn(); + urlStateStorage = createKbnUrlStateStorage({ useHash: false, history, onGetError: cb }); + const key = '_s'; + history.replace(`/#?${key}=(ok:2,test:`); // malformed rison + expect(() => urlStateStorage.get(key)).not.toThrow(); + expect(cb).toBeCalledWith(expect.any(Error)); + }); + + describe('withNotifyOnErrors integration', () => { + test('toast is shown', () => { + const toasts = coreMock.createStart().notifications.toasts; + urlStateStorage = createKbnUrlStateStorage({ + useHash: true, + history, + ...withNotifyOnErrors(toasts), + }); + const key = '_s'; + history.replace(`/#?${key}=(ok:2,test:`); // malformed rison + expect(() => urlStateStorage.get(key)).not.toThrow(); + expect(toasts.addError).toBeCalled(); + }); + }); }); describe('useHash: true', () => { @@ -128,6 +161,44 @@ describe('KbnUrlStateStorage', () => { expect(await result).toEqual([{ test: 'test', ok: 1 }, { test: 'test', ok: 2 }, null]); }); + + describe('hashStorage overflow exception', () => { + let oldLimit: number; + beforeAll(() => { + oldLimit = mockStorage.getStubbedSizeLimit(); + mockStorage.clear(); + mockStorage.setStubbedSizeLimit(0); + }); + afterAll(() => { + mockStorage.setStubbedSizeLimit(oldLimit); + }); + + it("shouldn't throw in case of error", async () => { + expect(() => urlStateStorage.set('_s', { test: 'test' })).not.toThrow(); + await expect(urlStateStorage.set('_s', { test: 'test' })).resolves; // not rejects + expect(getCurrentUrl()).toBe('/'); // url wasn't updated with hash + }); + + it('should notify about errors', async () => { + const cb = jest.fn(); + urlStateStorage = createKbnUrlStateStorage({ useHash: true, history, onSetError: cb }); + await expect(urlStateStorage.set('_s', { test: 'test' })).resolves; // not rejects + expect(cb).toBeCalledWith(expect.any(Error)); + }); + + describe('withNotifyOnErrors integration', () => { + test('toast is shown', async () => { + const toasts = coreMock.createStart().notifications.toasts; + urlStateStorage = createKbnUrlStateStorage({ + useHash: true, + history, + ...withNotifyOnErrors(toasts), + }); + await expect(urlStateStorage.set('_s', { test: 'test' })).resolves; // not rejects + expect(toasts.addError).toBeCalled(); + }); + }); + }); }); describe('ScopedHistory integration', () => { diff --git a/src/plugins/kibana_utils/public/state_sync/state_sync_state_storage/create_kbn_url_state_storage.ts b/src/plugins/kibana_utils/public/state_sync/state_sync_state_storage/create_kbn_url_state_storage.ts index 0c74e1eb9f421..460720b98e30f 100644 --- a/src/plugins/kibana_utils/public/state_sync/state_sync_state_storage/create_kbn_url_state_storage.ts +++ b/src/plugins/kibana_utils/public/state_sync/state_sync_state_storage/create_kbn_url_state_storage.ts @@ -17,8 +17,8 @@ * under the License. */ -import { Observable } from 'rxjs'; -import { map, share } from 'rxjs/operators'; +import { Observable, of } from 'rxjs'; +import { catchError, map, share } from 'rxjs/operators'; import { History } from 'history'; import { IStateStorage } from './types'; import { @@ -68,7 +68,19 @@ export interface IKbnUrlStateStorage extends IStateStorage { * @public */ export const createKbnUrlStateStorage = ( - { useHash = false, history }: { useHash: boolean; history?: History } = { useHash: false } + { + useHash = false, + history, + onGetError, + onSetError, + }: { + useHash: boolean; + history?: History; + onGetError?: (error: Error) => void; + onSetError?: (error: Error) => void; + } = { + useHash: false, + } ): IKbnUrlStateStorage => { const url = createKbnUrlControls(history); return { @@ -78,15 +90,23 @@ export const createKbnUrlStateStorage = ( { replace = false }: { replace: boolean } = { replace: false } ) => { // syncState() utils doesn't wait for this promise - return url.updateAsync( - (currentUrl) => setStateToKbnUrl(key, state, { useHash }, currentUrl), - replace - ); + return url.updateAsync((currentUrl) => { + try { + return setStateToKbnUrl(key, state, { useHash }, currentUrl); + } catch (error) { + if (onSetError) onSetError(error); + } + }, replace); }, get: (key) => { // if there is a pending url update, then state will be extracted from that pending url, // otherwise current url will be used to retrieve state from - return getStateFromKbnUrl(key, url.getPendingUrl()); + try { + return getStateFromKbnUrl(key, url.getPendingUrl()); + } catch (e) { + if (onGetError) onGetError(e); + return null; + } }, change$: (key: string) => new Observable((observer) => { @@ -99,6 +119,10 @@ export const createKbnUrlStateStorage = ( }; }).pipe( map(() => getStateFromKbnUrl(key)), + catchError((error) => { + if (onGetError) onGetError(error); + return of(null); + }), share() ), flush: ({ replace = false }: { replace?: boolean } = {}) => { diff --git a/src/plugins/timelion/public/app.js b/src/plugins/timelion/public/app.js index 0294e71084f98..614a7539de44c 100644 --- a/src/plugins/timelion/public/app.js +++ b/src/plugins/timelion/public/app.js @@ -23,7 +23,7 @@ import { i18n } from '@kbn/i18n'; import { createHashHistory } from 'history'; -import { createKbnUrlStateStorage } from '../../kibana_utils/public'; +import { createKbnUrlStateStorage, withNotifyOnErrors } from '../../kibana_utils/public'; import { syncQueryStateWithUrl } from '../../data/public'; import { getSavedSheetBreadcrumbs, getCreateBreadcrumbs } from './breadcrumbs'; @@ -63,6 +63,7 @@ export function initTimelionApp(app, deps) { createKbnUrlStateStorage({ history, useHash: deps.core.uiSettings.get('state:storeInSessionStorage'), + ...withNotifyOnErrors(deps.core.notifications.toasts), }) ); app.config(watchMultiDecorator); diff --git a/src/plugins/visualize/public/plugin.ts b/src/plugins/visualize/public/plugin.ts index fd9a67599414f..3299319e613a0 100644 --- a/src/plugins/visualize/public/plugin.ts +++ b/src/plugins/visualize/public/plugin.ts @@ -31,7 +31,12 @@ import { ScopedHistory, } from 'kibana/public'; -import { Storage, createKbnUrlTracker, createKbnUrlStateStorage } from '../../kibana_utils/public'; +import { + Storage, + createKbnUrlTracker, + createKbnUrlStateStorage, + withNotifyOnErrors, +} from '../../kibana_utils/public'; import { DataPublicPluginStart, DataPublicPluginSetup, esFilters } from '../../data/public'; import { NavigationPublicPluginStart as NavigationStart } from '../../navigation/public'; import { SharePluginStart } from '../../share/public'; @@ -150,6 +155,7 @@ export class VisualizePlugin kbnUrlStateStorage: createKbnUrlStateStorage({ history, useHash: coreStart.uiSettings.get('state:storeInSessionStorage'), + ...withNotifyOnErrors(coreStart.notifications.toasts), }), kibanaLegacy: pluginsStart.kibanaLegacy, pluginInitializerContext: this.initializerContext, diff --git a/test/functional/apps/discover/_shared_links.js b/test/functional/apps/discover/_shared_links.js index 5c6a70450a0aa..94409a94e9257 100644 --- a/test/functional/apps/discover/_shared_links.js +++ b/test/functional/apps/discover/_shared_links.js @@ -26,6 +26,7 @@ export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects(['common', 'discover', 'share', 'timePicker']); const browser = getService('browser'); + const toasts = getService('toasts'); describe('shared links', function describeIndexTests() { let baseUrl; @@ -132,28 +133,47 @@ export default function ({ getService, getPageObjects }) { await teardown(); }); - describe('permalink', function () { - it('should allow for copying the snapshot URL as a short URL and should open it', async function () { - const re = new RegExp(baseUrl + '/goto/[0-9a-f]{32}$'); - await PageObjects.share.checkShortenUrl(); - let actualUrl; - await retry.try(async () => { - actualUrl = await PageObjects.share.getSharedUrl(); - expect(actualUrl).to.match(re); - }); + it('should allow for copying the snapshot URL as a short URL and should open it', async function () { + const re = new RegExp(baseUrl + '/goto/[0-9a-f]{32}$'); + await PageObjects.share.checkShortenUrl(); + let actualUrl; + await retry.try(async () => { + actualUrl = await PageObjects.share.getSharedUrl(); + expect(actualUrl).to.match(re); + }); - const actualTime = await PageObjects.timePicker.getTimeConfig(); - - await browser.clearSessionStorage(); - await browser.get(actualUrl, false); - await retry.waitFor('shortUrl resolves and opens', async () => { - const resolvedUrl = await browser.getCurrentUrl(); - expect(resolvedUrl).to.match(/discover/); - const resolvedTime = await PageObjects.timePicker.getTimeConfig(); - expect(resolvedTime.start).to.equal(actualTime.start); - expect(resolvedTime.end).to.equal(actualTime.end); - return true; - }); + const actualTime = await PageObjects.timePicker.getTimeConfig(); + + await browser.clearSessionStorage(); + await browser.get(actualUrl, false); + await retry.waitFor('shortUrl resolves and opens', async () => { + const resolvedUrl = await browser.getCurrentUrl(); + expect(resolvedUrl).to.match(/discover/); + const resolvedTime = await PageObjects.timePicker.getTimeConfig(); + expect(resolvedTime.start).to.equal(actualTime.start); + expect(resolvedTime.end).to.equal(actualTime.end); + return true; + }); + }); + + it("sharing hashed url shouldn't crash the app", async () => { + const currentUrl = await browser.getCurrentUrl(); + const timeBeforeReload = await PageObjects.timePicker.getTimeConfig(); + await browser.clearSessionStorage(); + await browser.get(currentUrl, false); + await retry.waitFor('discover to open', async () => { + const resolvedUrl = await browser.getCurrentUrl(); + expect(resolvedUrl).to.match(/discover/); + const { message } = await toasts.getErrorToast(); + expect(message).to.contain( + 'Unable to completely restore the URL, be sure to use the share functionality.' + ); + await toasts.dismissAllToasts(); + const timeAfterReload = await PageObjects.timePicker.getTimeConfig(); + expect(timeBeforeReload.start).not.to.be(timeAfterReload.start); + expect(timeBeforeReload.end).not.to.be(timeAfterReload.end); + await PageObjects.timePicker.setDefaultAbsoluteRange(); + return true; }); }); }); diff --git a/test/functional/services/toasts.ts b/test/functional/services/toasts.ts index 92f1f726fa039..a70e4ba464ae8 100644 --- a/test/functional/services/toasts.ts +++ b/test/functional/services/toasts.ts @@ -53,6 +53,16 @@ export function ToastsProvider({ getService }: FtrProviderContext) { await dismissButton.click(); } + public async dismissAllToasts() { + const list = await this.getGlobalToastList(); + const toasts = await list.findAllByCssSelector(`.euiToast`); + for (const toast of toasts) { + await toast.moveMouseTo(); + const dismissButton = await testSubjects.findDescendant('toastCloseButton', toast); + await dismissButton.click(); + } + } + private async getToastElement(index: number) { const list = await this.getGlobalToastList(); return await list.findByCssSelector(`.euiToast:nth-child(${index})`); diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index 4a8694862642b..4a6dbd4a91fbf 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -19,6 +19,7 @@ import { import { createKbnUrlStateStorage, IStorageWrapper, + withNotifyOnErrors, } from '../../../../../src/plugins/kibana_utils/public'; import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; import { @@ -152,6 +153,7 @@ export function App({ const kbnUrlStateStorage = createKbnUrlStateStorage({ history, useHash: core.uiSettings.get('state:storeInSessionStorage'), + ...withNotifyOnErrors(core.notifications.toasts), }); const { stop: stopSyncingQueryServiceStateWithUrl } = syncQueryStateWithUrl( data.query, @@ -166,6 +168,7 @@ export function App({ }, [ data.query.filterManager, data.query.timefilter.timefilter, + core.notifications.toasts, core.uiSettings, data.query, history, diff --git a/x-pack/plugins/maps/public/routing/maps_router.js b/x-pack/plugins/maps/public/routing/maps_router.js index 30b2137399c1e..9992bd7a92ab1 100644 --- a/x-pack/plugins/maps/public/routing/maps_router.js +++ b/x-pack/plugins/maps/public/routing/maps_router.js @@ -7,8 +7,11 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { Router, Switch, Route, Redirect } from 'react-router-dom'; -import { getCoreI18n } from '../kibana_services'; -import { createKbnUrlStateStorage } from '../../../../../src/plugins/kibana_utils/public'; +import { getCoreI18n, getToasts } from '../kibana_services'; +import { + createKbnUrlStateStorage, + withNotifyOnErrors, +} from '../../../../../src/plugins/kibana_utils/public'; import { getStore } from './store_operations'; import { Provider } from 'react-redux'; import { LoadListAndRender } from './routes/list/load_list_and_render'; @@ -19,7 +22,11 @@ export let kbnUrlStateStorage; export async function renderApp(context, { appBasePath, element, history, onAppLeave }) { goToSpecifiedPath = (path) => history.push(path); - kbnUrlStateStorage = createKbnUrlStateStorage({ useHash: false, history }); + kbnUrlStateStorage = createKbnUrlStateStorage({ + useHash: false, + history, + ...withNotifyOnErrors(getToasts()), + }); render(, element); diff --git a/x-pack/plugins/monitoring/public/angular/app_modules.ts b/x-pack/plugins/monitoring/public/angular/app_modules.ts index f3d77b196b26e..499610045d771 100644 --- a/x-pack/plugins/monitoring/public/angular/app_modules.ts +++ b/x-pack/plugins/monitoring/public/angular/app_modules.ts @@ -23,7 +23,7 @@ import { GlobalState } from '../url_state'; import { getSafeForExternalLink } from '../lib/get_safe_for_external_link'; // @ts-ignore -import { formatNumber, formatMetric } from '../lib/format_number'; +import { formatMetric, formatNumber } from '../lib/format_number'; // @ts-ignore import { extractIp } from '../lib/extract_ip'; // @ts-ignore @@ -65,7 +65,7 @@ export const localAppModule = ({ createLocalPrivateModule(); createLocalStorage(); createLocalConfigModule(core); - createLocalStateModule(query); + createLocalStateModule(query, core.notifications.toasts); createLocalTopNavModule(navigation); createHrefModule(core); createMonitoringAppServices(); @@ -97,7 +97,10 @@ function createMonitoringAppConfigConstants( keys.map(([key, value]) => (constantsModule = constantsModule.constant(key as string, value))); } -function createLocalStateModule(query: any) { +function createLocalStateModule( + query: MonitoringStartPluginDependencies['data']['query'], + toasts: MonitoringStartPluginDependencies['core']['notifications']['toasts'] +) { angular .module('monitoring/State', ['monitoring/Private']) .service('globalState', function ( @@ -106,7 +109,7 @@ function createLocalStateModule(query: any) { $location: ng.ILocationService ) { function GlobalStateProvider(this: any) { - const state = new GlobalState(query, $rootScope, $location, this); + const state = new GlobalState(query, toasts, $rootScope, $location, this); const initialState: any = state.getState(); for (const key in initialState) { if (!initialState.hasOwnProperty(key)) { diff --git a/x-pack/plugins/monitoring/public/url_state.ts b/x-pack/plugins/monitoring/public/url_state.ts index e53497d751f9b..65e48223d7a64 100644 --- a/x-pack/plugins/monitoring/public/url_state.ts +++ b/x-pack/plugins/monitoring/public/url_state.ts @@ -23,6 +23,7 @@ import { IKbnUrlStateStorage, ISyncStateRef, syncState, + withNotifyOnErrors, } from '../../../../src/plugins/kibana_utils/public'; interface Route { @@ -71,6 +72,7 @@ export class GlobalState { constructor( queryService: MonitoringStartPluginDependencies['data']['query'], + toasts: MonitoringStartPluginDependencies['core']['notifications']['toasts'], rootScope: ng.IRootScopeService, ngLocation: ng.ILocationService, externalState: RawObject @@ -78,7 +80,11 @@ export class GlobalState { this.timefilterRef = queryService.timefilter.timefilter; const history: History = createHashHistory(); - this.stateStorage = createKbnUrlStateStorage({ useHash: false, history }); + this.stateStorage = createKbnUrlStateStorage({ + useHash: false, + history, + ...withNotifyOnErrors(toasts), + }); const initialStateFromUrl = this.stateStorage.get(GLOBAL_STATE_KEY) as MonitoringAppState; From 11c74bc03f73c1bcec02d6ba7914bcfd442127ee Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Thu, 6 Aug 2020 15:35:53 +0200 Subject: [PATCH 039/106] [ML] Fix analytics list on management page. (#74254) The analytics job page in the Kibana management section didn't have the context provided by React Router and Kibana's own history object so the page crashed on load. The context is necessary to construct the correct URLs to navigate to the ML plugin itself. This PR fixes it by wrapping the management page in . Also adds functional tests to cover navigating to the jobs list pages in stack management. --- .../jobs_list_page/jobs_list_page.tsx | 96 +++++++++++-------- .../application/management/jobs_list/index.ts | 10 +- x-pack/test/functional/apps/ml/pages.ts | 12 +++ .../test/functional/services/ml/navigation.ts | 27 ++++++ 4 files changed, 101 insertions(+), 44 deletions(-) diff --git a/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx b/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx index 33bb78c51e013..0af6030df28b1 100644 --- a/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx +++ b/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx @@ -5,6 +5,7 @@ */ import React, { useEffect, useState, Fragment, FC } from 'react'; +import { Router } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import { CoreStart } from 'kibana/public'; @@ -20,6 +21,8 @@ import { EuiTitle, } from '@elastic/eui'; +import { ManagementAppMountParams } from '../../../../../../../../../src/plugins/management/public/'; + import { checkGetManagementMlJobsResolver } from '../../../../capabilities/check_capabilities'; import { KibanaContextProvider } from '../../../../../../../../../src/plugins/kibana_react/public'; @@ -30,6 +33,7 @@ import { DataFrameAnalyticsList } from '../../../../data_frame_analytics/pages/a import { AccessDeniedPage } from '../access_denied_page'; interface Tab { + 'data-test-subj': string; id: string; name: string; content: any; @@ -38,6 +42,7 @@ interface Tab { function getTabs(isMlEnabledInSpace: boolean): Tab[] { return [ { + 'data-test-subj': 'mlStackManagementJobsListAnomalyDetectionTab', id: 'anomaly_detection_jobs', name: i18n.translate('xpack.ml.management.jobsList.anomalyDetectionTab', { defaultMessage: 'Anomaly detection', @@ -50,6 +55,7 @@ function getTabs(isMlEnabledInSpace: boolean): Tab[] { ), }, { + 'data-test-subj': 'mlStackManagementJobsListAnalyticsTab', id: 'analytics_jobs', name: i18n.translate('xpack.ml.management.jobsList.analyticsTab', { defaultMessage: 'Analytics', @@ -67,7 +73,10 @@ function getTabs(isMlEnabledInSpace: boolean): Tab[] { ]; } -export const JobsListPage: FC<{ coreStart: CoreStart }> = ({ coreStart }) => { +export const JobsListPage: FC<{ + coreStart: CoreStart; + history: ManagementAppMountParams['history']; +}> = ({ coreStart, history }) => { const [initialized, setInitialized] = useState(false); const [accessDenied, setAccessDenied] = useState(false); const [isMlEnabledInSpace, setIsMlEnabledInSpace] = useState(false); @@ -128,46 +137,51 @@ export const JobsListPage: FC<{ coreStart: CoreStart }> = ({ coreStart }) => { return ( - - - - -

    - {i18n.translate('xpack.ml.management.jobsList.jobsListTitle', { - defaultMessage: 'Machine Learning Jobs', - })} -

    - - - - {currentTabId === 'anomaly_detection_jobs' - ? anomalyDetectionDocsLabel - : analyticsDocsLabel} - - - - - - - - {i18n.translate('xpack.ml.management.jobsList.jobsListTagline', { - defaultMessage: 'View machine learning analytics and anomaly detection jobs.', - })} - - - - {renderTabs()} - + + + + + +

    + {i18n.translate('xpack.ml.management.jobsList.jobsListTitle', { + defaultMessage: 'Machine Learning Jobs', + })} +

    +
    + + + {currentTabId === 'anomaly_detection_jobs' + ? anomalyDetectionDocsLabel + : analyticsDocsLabel} + + +
    +
    + + + + {i18n.translate('xpack.ml.management.jobsList.jobsListTagline', { + defaultMessage: 'View machine learning analytics and anomaly detection jobs.', + })} + + + + {renderTabs()} +
    +
    ); diff --git a/x-pack/plugins/ml/public/application/management/jobs_list/index.ts b/x-pack/plugins/ml/public/application/management/jobs_list/index.ts index 81190a412abc0..afea5a573b8b5 100644 --- a/x-pack/plugins/ml/public/application/management/jobs_list/index.ts +++ b/x-pack/plugins/ml/public/application/management/jobs_list/index.ts @@ -14,8 +14,12 @@ import { getJobsListBreadcrumbs } from '../breadcrumbs'; import { setDependencyCache, clearCache } from '../../util/dependency_cache'; import './_index.scss'; -const renderApp = (element: HTMLElement, coreStart: CoreStart) => { - ReactDOM.render(React.createElement(JobsListPage, { coreStart }), element); +const renderApp = ( + element: HTMLElement, + history: ManagementAppMountParams['history'], + coreStart: CoreStart +) => { + ReactDOM.render(React.createElement(JobsListPage, { coreStart, history }), element); return () => { unmountComponentAtNode(element); clearCache(); @@ -37,5 +41,5 @@ export async function mountApp( params.setBreadcrumbs(getJobsListBreadcrumbs()); - return renderApp(params.element, coreStart); + return renderApp(params.element, params.history, coreStart); } diff --git a/x-pack/test/functional/apps/ml/pages.ts b/x-pack/test/functional/apps/ml/pages.ts index e2c80c8dab558..3691e6b1afcdc 100644 --- a/x-pack/test/functional/apps/ml/pages.ts +++ b/x-pack/test/functional/apps/ml/pages.ts @@ -53,5 +53,17 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataVisualizer.assertDataVisualizerImportDataCardExists(); await ml.dataVisualizer.assertDataVisualizerIndexDataCardExists(); }); + + it('should load the stack management with the ML menu item being present', async () => { + await ml.navigation.navigateToStackManagement(); + }); + + it('should load the jobs list page in stack management', async () => { + await ml.navigation.navigateToStackManagementJobsListPage(); + }); + + it('should load the analytics jobs list page in stack management', async () => { + await ml.navigation.navigateToStackManagementJobsListPageAnalyticsTab(); + }); }); } diff --git a/x-pack/test/functional/services/ml/navigation.ts b/x-pack/test/functional/services/ml/navigation.ts index 9b67a369f055f..f52197d4b2256 100644 --- a/x-pack/test/functional/services/ml/navigation.ts +++ b/x-pack/test/functional/services/ml/navigation.ts @@ -23,6 +23,13 @@ export function MachineLearningNavigationProvider({ }); }, + async navigateToStackManagement() { + await retry.tryForTime(60 * 1000, async () => { + await PageObjects.common.navigateToApp('management'); + await testSubjects.existOrFail('jobsListLink', { timeout: 2000 }); + }); + }, + async assertTabsExist(tabTypeSubject: string, areaSubjects: string[]) { await retry.tryForTime(10000, async () => { const allTabs = await testSubjects.findAll(`~${tabTypeSubject}`, 3); @@ -76,5 +83,25 @@ export function MachineLearningNavigationProvider({ async navigateToSettings() { await this.navigateToArea('~mlMainTab & ~settings', 'mlPageSettings'); }, + + async navigateToStackManagementJobsListPage() { + // clicks the jobsListLink and loads the jobs list page + await testSubjects.click('jobsListLink'); + await retry.tryForTime(60 * 1000, async () => { + // verify that the overall page is present + await testSubjects.existOrFail('mlPageStackManagementJobsList'); + // verify that the default tab with the anomaly detection jobs list got loaded + await testSubjects.existOrFail('ml-jobs-list'); + }); + }, + + async navigateToStackManagementJobsListPageAnalyticsTab() { + // clicks the `Analytics` tab and loads the analytics list page + await testSubjects.click('mlStackManagementJobsListAnalyticsTab'); + await retry.tryForTime(60 * 1000, async () => { + // verify that the empty prompt for analytics jobs list got loaded + await testSubjects.existOrFail('mlNoDataFrameAnalyticsFound'); + }); + }, }; } From b3202a0e4cba43a54183f732d3092368f9e63fd1 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Thu, 6 Aug 2020 17:02:27 +0200 Subject: [PATCH 040/106] fix tsvb validation (#74344) --- src/plugins/vis_type_timeseries/common/vis_schema.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/vis_type_timeseries/common/vis_schema.ts b/src/plugins/vis_type_timeseries/common/vis_schema.ts index a462e488c6732..c1730e6a15435 100644 --- a/src/plugins/vis_type_timeseries/common/vis_schema.ts +++ b/src/plugins/vis_type_timeseries/common/vis_schema.ts @@ -119,6 +119,10 @@ export const metricsItems = schema.object({ type: stringRequired, value: stringOptionalNullable, values: schema.maybe(schema.nullable(schema.arrayOf(schema.nullable(schema.string())))), + size: stringOptionalNullable, + agg_with: stringOptionalNullable, + order: stringOptionalNullable, + order_by: stringOptionalNullable, }); const splitFiltersItems = schema.object({ From d00035422a554524b544fb5bd30cc6c78b346bbb Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Date: Thu, 6 Aug 2020 11:44:14 -0400 Subject: [PATCH 041/106] [SECURITY] Fix imports (#74528) * simple solution to avoid duplicate request * fix import of deepEqual --- .../public/common/containers/matrix_histogram/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts index 2122eab23957a..c4702e915c076 100644 --- a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts +++ b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ +import deepEqual from 'fast-deep-equal'; import { isEmpty } from 'lodash/fp'; import { useEffect, useMemo, useState, useRef } from 'react'; -import { deepEqual } from 'hoek'; import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; import { MatrixHistogramQueryProps } from '../../components/matrix_histogram/types'; import { errorToToaster, useStateToaster } from '../../components/toasters'; From 0600f000be1986bc00f09aef73b738e27cf57437 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Thu, 6 Aug 2020 08:58:06 -0700 Subject: [PATCH 042/106] [DOCS] Add Kibana privileges to glossary (#74410) --- docs/glossary.asciidoc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/glossary.asciidoc b/docs/glossary.asciidoc index 07c0bfcf35cb7..51470513198b9 100644 --- a/docs/glossary.asciidoc +++ b/docs/glossary.asciidoc @@ -214,6 +214,13 @@ syslog, Apache, and other webserver logs. See [[k_glos]] == K +[[glossary-kibana-privileges]] {kib} privileges :: +// tag::kibana-privileges-def[] +Enable administrators to grant users read-only, read-write, or no access to +individual features within <> in {kib}. See +{kibana-ref}/kibana-privileges.html[{kib} privileges]. +// end::kibana-privileges-def[] + [[glossary-kql]] {kib} Query Language (KQL) :: // tag::kql-def[] The default language for querying in {kib}. KQL provides From d7644991d9cfde0ee1629b5cb72ffa9678d93c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Thu, 6 Aug 2020 18:06:13 +0200 Subject: [PATCH 043/106] [ILM] Convert node allocation component to TS and use hooks (#72888) * [ILM] Convert node allocation component to TS and use hooks * [ILM] Fix jest tests * [ILM] Fix i18n check * [ILM] Implement code review suggestions * [ILM] Fix type check, docs link and button maxWidth in NodeAllocation component * Fix internaliation error * [ILM] Change error message when unable to load node attributes * [ILM] Delete a period in error callout Co-authored-by: Elastic Machine --- .../__jest__/components/edit_policy.test.js | 147 ++++++++------- .../components/helpers/http_requests.ts | 48 +++++ .../sections/components/learn_more_link.js | 33 ---- .../sections/components/learn_more_link.tsx | 29 +++ .../node_allocation/{index.js => index.ts} | 2 +- .../node_allocation.container.js | 20 -- .../node_allocation/node_allocation.js | 120 ------------ .../node_allocation/node_allocation.tsx | 177 ++++++++++++++++++ .../{form_errors.js => form_errors.tsx} | 20 +- .../public/application/services/api.ts | 10 +- .../public/application/services/http.ts | 7 +- .../public/application/store/actions/nodes.js | 20 +- .../application/store/reducers/nodes.js | 8 - .../application/store/selectors/nodes.js | 20 -- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 16 files changed, 365 insertions(+), 298 deletions(-) create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/components/helpers/http_requests.ts delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/components/learn_more_link.js create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/components/learn_more_link.tsx rename x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/{index.js => index.ts} (79%) delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.container.js delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.js create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.tsx rename x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/{form_errors.js => form_errors.tsx} (57%) diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js index 943f663a025d8..c6da347ed8cfe 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js +++ b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js @@ -5,16 +5,23 @@ */ import React from 'react'; +import { act } from 'react-dom/test-utils'; import moment from 'moment-timezone'; import { Provider } from 'react-redux'; // axios has a $http like interface so using it to simulate $http import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; -import sinon from 'sinon'; import { findTestSubject } from '@elastic/eui/lib/test'; +import { init as initHttpRequests } from './helpers/http_requests'; +import { + notificationServiceMock, + fatalErrorsServiceMock, +} from '../../../../../src/core/public/mocks'; +import { usageCollectionPluginMock } from '../../../../../src/plugins/usage_collection/public/mocks'; + import { mountWithIntl } from '../../../../test_utils/enzyme_helpers'; -import { fetchedPolicies, fetchedNodes } from '../../public/application/store/actions'; +import { fetchedPolicies } from '../../public/application/store/actions'; import { indexLifecycleManagementStore } from '../../public/application/store'; import { EditPolicy } from '../../public/application/sections/edit_policy'; import { init as initHttp } from '../../public/application/services/http'; @@ -33,15 +40,17 @@ import { policyNameMustBeDifferentErrorMessage, policyNameAlreadyUsedErrorMessage, maximumDocumentsRequiredMessage, -} from '../../public/application/store/selectors/lifecycle'; +} from '../../public/application/store/selectors'; -initHttp(axios.create({ adapter: axiosXhrAdapter }), (path) => path); -initUiMetric({ reportUiStats: () => {} }); -initNotification({ - addDanger: () => {}, -}); +initHttp(axios.create({ adapter: axiosXhrAdapter })); +initUiMetric(usageCollectionPluginMock.createSetupContract()); +initNotification( + notificationServiceMock.createSetupContract().toasts, + fatalErrorsServiceMock.createSetupContract() +); let server; +let httpRequestsMockHelpers; let store; const policy = { phases: { @@ -70,9 +79,11 @@ for (let i = 0; i < 105; i++) { window.scrollTo = jest.fn(); window.TextEncoder = null; let component; -const activatePhase = (rendered, phase) => { +const activatePhase = async (rendered, phase) => { const testSubject = `enablePhaseSwitch-${phase}`; - findTestSubject(rendered, testSubject).simulate('click'); + await act(async () => { + await findTestSubject(rendered, testSubject).simulate('click'); + }); rendered.update(); }; const expectedErrorMessages = (rendered, expectedErrorMessages) => { @@ -120,16 +131,13 @@ describe('edit policy', () => { store = indexLifecycleManagementStore(); component = ( - {}} /> + {} }} getUrlForApp={() => {}} /> ); store.dispatch(fetchedPolicies(policies)); - server = sinon.fakeServer.create(); - server.respondWith('/api/index_lifecycle_management/policies', [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(policies), - ]); + ({ server, httpRequestsMockHelpers } = initHttpRequests()); + + httpRequestsMockHelpers.setPoliciesResponse(policies); }); describe('top level form', () => { test('should show error when trying to save empty form', () => { @@ -242,48 +250,53 @@ describe('edit policy', () => { }); }); describe('warm phase', () => { - test('should show number required error when trying to save empty warm phase', () => { + beforeEach(() => { + server.respondImmediately = true; + httpRequestsMockHelpers.setNodesListResponse({}); + }); + + test('should show number required error when trying to save empty warm phase', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); setPhaseAfter(rendered, 'warm', ''); save(rendered); expectedErrorMessages(rendered, [numberRequiredMessage]); }); - test('should allow 0 for phase timing', () => { + test('should allow 0 for phase timing', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); setPhaseAfter(rendered, 'warm', 0); save(rendered); expectedErrorMessages(rendered, []); }); - test('should show positive number required error when trying to save warm phase with -1 for after', () => { + test('should show positive number required error when trying to save warm phase with -1 for after', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); setPhaseAfter(rendered, 'warm', -1); save(rendered); expectedErrorMessages(rendered, [positiveNumberRequiredMessage]); }); - test('should show positive number required error when trying to save warm phase with -1 for index priority', () => { + test('should show positive number required error when trying to save warm phase with -1 for index priority', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); setPhaseAfter(rendered, 'warm', 1); setPhaseIndexPriority(rendered, 'warm', -1); save(rendered); expectedErrorMessages(rendered, [positiveNumberRequiredMessage]); }); - test('should show positive number required above zero error when trying to save warm phase with 0 for shrink', () => { + test('should show positive number required above zero error when trying to save warm phase with 0 for shrink', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); findTestSubject(rendered, 'shrinkSwitch').simulate('click'); rendered.update(); setPhaseAfter(rendered, 'warm', 1); @@ -293,11 +306,11 @@ describe('edit policy', () => { save(rendered); expectedErrorMessages(rendered, [positiveNumbersAboveZeroErrorMessage]); }); - test('should show positive number above 0 required error when trying to save warm phase with -1 for shrink', () => { + test('should show positive number above 0 required error when trying to save warm phase with -1 for shrink', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); setPhaseAfter(rendered, 'warm', 1); findTestSubject(rendered, 'shrinkSwitch').simulate('click'); rendered.update(); @@ -307,11 +320,11 @@ describe('edit policy', () => { save(rendered); expectedErrorMessages(rendered, [positiveNumbersAboveZeroErrorMessage]); }); - test('should show positive number required above zero error when trying to save warm phase with 0 for force merge', () => { + test('should show positive number required above zero error when trying to save warm phase with 0 for force merge', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); setPhaseAfter(rendered, 'warm', 1); findTestSubject(rendered, 'forceMergeSwitch').simulate('click'); rendered.update(); @@ -321,11 +334,11 @@ describe('edit policy', () => { save(rendered); expectedErrorMessages(rendered, [positiveNumbersAboveZeroErrorMessage]); }); - test('should show positive number above 0 required error when trying to save warm phase with -1 for force merge', () => { + test('should show positive number above 0 required error when trying to save warm phase with -1 for force merge', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); setPhaseAfter(rendered, 'warm', 1); findTestSubject(rendered, 'forceMergeSwitch').simulate('click'); rendered.update(); @@ -335,43 +348,43 @@ describe('edit policy', () => { save(rendered); expectedErrorMessages(rendered, [positiveNumbersAboveZeroErrorMessage]); }); - test('should show spinner for node attributes input when loading', () => { + test('should show spinner for node attributes input when loading', async () => { + server.respondImmediately = false; const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeTruthy(); expect(rendered.find('.euiCallOut--warning').exists()).toBeFalsy(); expect(getNodeAttributeSelect(rendered, 'warm').exists()).toBeFalsy(); }); - test('should show warning instead of node attributes input when none exist', () => { - store.dispatch(fetchedNodes({})); + test('should show warning instead of node attributes input when none exist', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); expect(rendered.find('.euiCallOut--warning').exists()).toBeTruthy(); expect(getNodeAttributeSelect(rendered, 'warm').exists()).toBeFalsy(); }); - test('should show node attributes input when attributes exist', () => { - store.dispatch(fetchedNodes({ 'attribute:true': ['node1'] })); + test('should show node attributes input when attributes exist', async () => { + httpRequestsMockHelpers.setNodesListResponse({ 'attribute:true': ['node1'] }); const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); expect(rendered.find('.euiCallOut--warning').exists()).toBeFalsy(); const nodeAttributesSelect = getNodeAttributeSelect(rendered, 'warm'); expect(nodeAttributesSelect.exists()).toBeTruthy(); expect(nodeAttributesSelect.find('option').length).toBe(2); }); - test('should show view node attributes link when attribute selected and show flyout when clicked', () => { - store.dispatch(fetchedNodes({ 'attribute:true': ['node1'] })); + test('should show view node attributes link when attribute selected and show flyout when clicked', async () => { + httpRequestsMockHelpers.setNodesListResponse({ 'attribute:true': ['node1'] }); const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'warm'); + await activatePhase(rendered, 'warm'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); expect(rendered.find('.euiCallOut--warning').exists()).toBeFalsy(); const nodeAttributesSelect = getNodeAttributeSelect(rendered, 'warm'); @@ -388,61 +401,65 @@ describe('edit policy', () => { }); }); describe('cold phase', () => { - test('should allow 0 for phase timing', () => { + beforeEach(() => { + server.respondImmediately = true; + httpRequestsMockHelpers.setNodesListResponse({}); + }); + test('should allow 0 for phase timing', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'cold'); + await activatePhase(rendered, 'cold'); setPhaseAfter(rendered, 'cold', 0); save(rendered); expectedErrorMessages(rendered, []); }); - test('should show positive number required error when trying to save cold phase with -1 for after', () => { + test('should show positive number required error when trying to save cold phase with -1 for after', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'cold'); + await activatePhase(rendered, 'cold'); setPhaseAfter(rendered, 'cold', -1); save(rendered); expectedErrorMessages(rendered, [positiveNumberRequiredMessage]); }); - test('should show spinner for node attributes input when loading', () => { + test('should show spinner for node attributes input when loading', async () => { + server.respondImmediately = false; const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'cold'); + await activatePhase(rendered, 'cold'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeTruthy(); expect(rendered.find('.euiCallOut--warning').exists()).toBeFalsy(); expect(getNodeAttributeSelect(rendered, 'cold').exists()).toBeFalsy(); }); - test('should show warning instead of node attributes input when none exist', () => { - store.dispatch(fetchedNodes({})); + test('should show warning instead of node attributes input when none exist', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'cold'); + await activatePhase(rendered, 'cold'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); expect(rendered.find('.euiCallOut--warning').exists()).toBeTruthy(); expect(getNodeAttributeSelect(rendered, 'cold').exists()).toBeFalsy(); }); - test('should show node attributes input when attributes exist', () => { - store.dispatch(fetchedNodes({ 'attribute:true': ['node1'] })); + test('should show node attributes input when attributes exist', async () => { + httpRequestsMockHelpers.setNodesListResponse({ 'attribute:true': ['node1'] }); const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'cold'); + await activatePhase(rendered, 'cold'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); expect(rendered.find('.euiCallOut--warning').exists()).toBeFalsy(); const nodeAttributesSelect = getNodeAttributeSelect(rendered, 'cold'); expect(nodeAttributesSelect.exists()).toBeTruthy(); expect(nodeAttributesSelect.find('option').length).toBe(2); }); - test('should show view node attributes link when attribute selected and show flyout when clicked', () => { - store.dispatch(fetchedNodes({ 'attribute:true': ['node1'] })); + test('should show view node attributes link when attribute selected and show flyout when clicked', async () => { + httpRequestsMockHelpers.setNodesListResponse({ 'attribute:true': ['node1'] }); const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'cold'); + await activatePhase(rendered, 'cold'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); expect(rendered.find('.euiCallOut--warning').exists()).toBeFalsy(); const nodeAttributesSelect = getNodeAttributeSelect(rendered, 'cold'); @@ -457,11 +474,11 @@ describe('edit policy', () => { rendered.update(); expect(rendered.find('.euiFlyout').exists()).toBeTruthy(); }); - test('should show positive number required error when trying to save with -1 for index priority', () => { + test('should show positive number required error when trying to save with -1 for index priority', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'cold'); + await activatePhase(rendered, 'cold'); setPhaseAfter(rendered, 'cold', 1); setPhaseIndexPriority(rendered, 'cold', -1); save(rendered); @@ -469,20 +486,20 @@ describe('edit policy', () => { }); }); describe('delete phase', () => { - test('should allow 0 for phase timing', () => { + test('should allow 0 for phase timing', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'delete'); + await activatePhase(rendered, 'delete'); setPhaseAfter(rendered, 'delete', 0); save(rendered); expectedErrorMessages(rendered, []); }); - test('should show positive number required error when trying to save delete phase with -1 for after', () => { + test('should show positive number required error when trying to save delete phase with -1 for after', async () => { const rendered = mountWithIntl(component); noRollover(rendered); setPolicyName(rendered, 'mypolicy'); - activatePhase(rendered, 'delete'); + await activatePhase(rendered, 'delete'); setPhaseAfter(rendered, 'delete', -1); save(rendered); expectedErrorMessages(rendered, [positiveNumberRequiredMessage]); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/components/helpers/http_requests.ts b/x-pack/plugins/index_lifecycle_management/__jest__/components/helpers/http_requests.ts new file mode 100644 index 0000000000000..b5c941beef181 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/__jest__/components/helpers/http_requests.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import sinon, { SinonFakeServer } from 'sinon'; + +type HttpResponse = Record | any[]; + +const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { + const setPoliciesResponse = (response: HttpResponse = []) => { + server.respondWith('/api/index_lifecycle_management/policies', [ + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify(response), + ]); + }; + + const setNodesListResponse = (response: HttpResponse = []) => { + server.respondWith('/api/index_lifecycle_management/nodes/list', [ + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify(response), + ]); + }; + + return { + setPoliciesResponse, + setNodesListResponse, + }; +}; + +export const init = () => { + const server = sinon.fakeServer.create(); + + // Define default response for unhandled requests. + // We make requests to APIs which don't impact the component under test, e.g. UI metric telemetry, + // and we can mock them all with a 200 instead of mocking each one individually. + server.respondWith([200, {}, 'DefaultSinonMockServerResponse']); + + const httpRequestsMockHelpers = registerHttpRequestMockHelpers(server); + + return { + server, + httpRequestsMockHelpers, + }; +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/components/learn_more_link.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/components/learn_more_link.js deleted file mode 100644 index 2284b9e39835c..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/components/learn_more_link.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { EuiLink } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; - -import { createDocLink } from '../../services/documentation'; - -export class LearnMoreLink extends React.PureComponent { - render() { - const { href, docPath, text } = this.props; - let url; - if (docPath) { - url = createDocLink(docPath); - } else { - url = href; - } - const content = text ? ( - text - ) : ( - - ); - return ( - - {content} - - ); - } -} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/components/learn_more_link.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/components/learn_more_link.tsx new file mode 100644 index 0000000000000..623ff982438d7 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/components/learn_more_link.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { ReactNode } from 'react'; +import { EuiLink } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { createDocLink } from '../../services/documentation'; + +interface Props { + docPath: string; + text?: ReactNode; +} + +export const LearnMoreLink: React.FunctionComponent = ({ docPath, text }) => { + const content = text ? ( + text + ) : ( + + ); + return ( + + {content} + + ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/index.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/index.ts similarity index 79% rename from x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/index.js rename to x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/index.ts index 9138c6a30cfad..4675ab46ee501 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/index.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { NodeAllocation } from './node_allocation.container'; +export { NodeAllocation } from './node_allocation'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.container.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.container.js deleted file mode 100644 index 0ddfcbb940aa4..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.container.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { connect } from 'react-redux'; - -import { getNodeOptions } from '../../../../store/selectors'; -import { fetchNodes } from '../../../../store/actions'; -import { NodeAllocation as PresentationComponent } from './node_allocation'; - -export const NodeAllocation = connect( - (state) => ({ - nodeOptions: getNodeOptions(state), - }), - { - fetchNodes, - } -)(PresentationComponent); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.js deleted file mode 100644 index 95c1878776688..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.js +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { Component, Fragment } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; -import { EuiSelect, EuiButtonEmpty, EuiCallOut, EuiSpacer, EuiLoadingSpinner } from '@elastic/eui'; - -import { PHASE_NODE_ATTRS } from '../../../../constants'; -import { LearnMoreLink } from '../../../components/learn_more_link'; -import { ErrableFormRow } from '../../form_errors'; - -const learnMoreLinks = ( - - - - - } - docPath="shards-allocation.html" - /> - -); - -export class NodeAllocation extends Component { - componentDidMount() { - this.props.fetchNodes(); - } - - render() { - const { - phase, - setPhaseData, - isShowingErrors, - phaseData, - showNodeDetailsFlyout, - nodeOptions, - errors, - } = this.props; - if (!nodeOptions) { - return ( - - - - - ); - } - if (!nodeOptions.length) { - return ( - - - } - color="warning" - > - - {learnMoreLinks} - - - - - ); - } - - return ( - - - { - setPhaseData(PHASE_NODE_ATTRS, e.target.value); - }} - /> - - {!!phaseData[PHASE_NODE_ATTRS] ? ( - showNodeDetailsFlyout(phaseData[PHASE_NODE_ATTRS])} - > - - - ) : ( -
    - )} - {learnMoreLinks} - - - ); - } -} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.tsx new file mode 100644 index 0000000000000..208f6b2aa6131 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation/node_allocation.tsx @@ -0,0 +1,177 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { Fragment } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { + EuiSelect, + EuiButtonEmpty, + EuiCallOut, + EuiSpacer, + EuiLoadingSpinner, + EuiButton, +} from '@elastic/eui'; + +import { PHASE_NODE_ATTRS } from '../../../../constants'; +import { LearnMoreLink } from '../../../components/learn_more_link'; +import { ErrableFormRow } from '../../form_errors'; +import { useLoadNodes } from '../../../../services/api'; + +interface Props { + phase: string; + setPhaseData: (dataKey: string, value: any) => void; + showNodeDetailsFlyout: (nodeAttrs: any) => void; + errors: any; + phaseData: any; + isShowingErrors: boolean; +} + +const learnMoreLink = ( + + + + } + docPath="modules-cluster.html#cluster-shard-allocation-settings" + /> + +); + +export const NodeAllocation: React.FunctionComponent = ({ + phase, + setPhaseData, + showNodeDetailsFlyout, + errors, + phaseData, + isShowingErrors, +}) => { + const { isLoading, data: nodes, error, sendRequest } = useLoadNodes(); + + if (isLoading) { + return ( + + + + + ); + } + + if (error) { + const { statusCode, message } = error; + return ( + + + } + color="danger" + > +

    + {message} ({statusCode}) +

    + + + +
    + + +
    + ); + } + + let nodeOptions = Object.keys(nodes).map((attrs) => ({ + text: `${attrs} (${nodes[attrs].length})`, + value: attrs, + })); + + nodeOptions.sort((a, b) => a.value.localeCompare(b.value)); + if (nodeOptions.length) { + nodeOptions = [ + { + text: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.defaultNodeAllocation', { + defaultMessage: "Default allocation (don't use attributes)", + }), + value: '', + }, + ...nodeOptions, + ]; + } + if (!nodeOptions.length) { + return ( + + + } + color="warning" + > + + {learnMoreLink} + + + + + ); + } + + return ( + + + { + setPhaseData(PHASE_NODE_ATTRS, e.target.value); + }} + /> + + {!!phaseData[PHASE_NODE_ATTRS] ? ( + showNodeDetailsFlyout(phaseData[PHASE_NODE_ATTRS])} + > + + + ) : null} + {learnMoreLink} + + + ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_errors.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_errors.tsx similarity index 57% rename from x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_errors.js rename to x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_errors.tsx index 28ebad209ad96..a3278b6c231b9 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_errors.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_errors.tsx @@ -4,10 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { cloneElement, Children, Fragment } from 'react'; -import { EuiFormRow } from '@elastic/eui'; +import React, { cloneElement, Children, Fragment, ReactElement } from 'react'; +import { EuiFormRow, EuiFormRowProps } from '@elastic/eui'; -export const ErrableFormRow = ({ errorKey, isShowingErrors, errors, children, ...rest }) => { +type Props = EuiFormRowProps & { + errorKey: string; + isShowingErrors: boolean; + errors: Record; +}; + +export const ErrableFormRow: React.FunctionComponent = ({ + errorKey, + isShowingErrors, + errors, + children, + ...rest +}) => { return ( 0} @@ -16,7 +28,7 @@ export const ErrableFormRow = ({ errorKey, isShowingErrors, errors, children, .. > {Children.map(children, (child) => - cloneElement(child, { + cloneElement(child as ReactElement, { isInvalid: isShowingErrors && errors[errorKey].length > 0, }) )} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/api.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/api.ts index 30c341baa6194..8838caa960b0c 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/api.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/api.ts @@ -21,9 +21,13 @@ interface GenericObject { [key: string]: any; } -export async function loadNodes() { - return await sendGet(`nodes/list`); -} +export const useLoadNodes = () => { + return useRequest({ + path: `nodes/list`, + method: 'get', + initialData: [], + }); +}; export async function loadNodeDetails(selectedNodeAttrs: string) { return await sendGet(`nodes/${selectedNodeAttrs}/details`); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/http.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/http.ts index 0b5f39a52c13f..fb1a651b5f550 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/http.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/http.ts @@ -8,7 +8,6 @@ import { HttpSetup } from 'src/core/public'; import { UseRequestConfig, useRequest as _useRequest, - Error, } from '../../../../../../src/plugins/es_ui_shared/public'; interface GenericObject { @@ -43,6 +42,8 @@ export function sendDelete(path: string) { return _httpClient.delete(getFullPath(path)); } -export const useRequest = (config: UseRequestConfig) => { - return _useRequest(_httpClient, { ...config, path: getFullPath(config.path) }); +export const useRequest = ( + config: UseRequestConfig +) => { + return _useRequest(_httpClient, { ...config, path: getFullPath(config.path) }); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/store/actions/nodes.js b/x-pack/plugins/index_lifecycle_management/public/application/store/actions/nodes.js index f2520abc7a441..0b4026f019210 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/store/actions/nodes.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/store/actions/nodes.js @@ -6,30 +6,12 @@ import { i18n } from '@kbn/i18n'; import { createAction } from 'redux-actions'; import { showApiError } from '../../services/api_errors'; -import { loadNodes, loadNodeDetails } from '../../services/api'; +import { loadNodeDetails } from '../../services/api'; import { SET_SELECTED_NODE_ATTRS } from '../../constants'; export const setSelectedNodeAttrs = createAction(SET_SELECTED_NODE_ATTRS); export const setSelectedPrimaryShardCount = createAction('SET_SELECTED_PRIMARY_SHARED_COUNT'); export const setSelectedReplicaCount = createAction('SET_SELECTED_REPLICA_COUNT'); -export const fetchedNodes = createAction('FETCHED_NODES'); -let fetchingNodes = false; -export const fetchNodes = () => async (dispatch) => { - try { - if (!fetchingNodes) { - fetchingNodes = true; - const nodes = await loadNodes(); - dispatch(fetchedNodes(nodes)); - } - } catch (err) { - const title = i18n.translate('xpack.indexLifecycleMgmt.editPolicy.nodeInfoErrorMessage', { - defaultMessage: 'Error loading node attribute information', - }); - showApiError(err, title); - } finally { - fetchingNodes = false; - } -}; export const fetchedNodeDetails = createAction( 'FETCHED_NODE_DETAILS', diff --git a/x-pack/plugins/index_lifecycle_management/public/application/store/reducers/nodes.js b/x-pack/plugins/index_lifecycle_management/public/application/store/reducers/nodes.js index 443b257b6fb7e..06d173e9901f8 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/store/reducers/nodes.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/store/reducers/nodes.js @@ -6,7 +6,6 @@ import { handleActions } from 'redux-actions'; import { - fetchedNodes, setSelectedNodeAttrs, setSelectedPrimaryShardCount, setSelectedReplicaCount, @@ -24,13 +23,6 @@ const defaultState = { export const nodes = handleActions( { - [fetchedNodes](state, { payload: nodes }) { - return { - ...state, - isLoading: false, - nodes, - }; - }, [fetchedNodeDetails](state, { payload }) { const { selectedNodeAttrs, details } = payload; return { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/nodes.js b/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/nodes.js index 63d849217f59e..561681bf7d93d 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/nodes.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/nodes.js @@ -4,28 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { createSelector } from 'reselect'; - export const getNodes = (state) => state.nodes.nodes; -export const getNodeOptions = createSelector([(state) => getNodes(state)], (nodes) => { - if (!nodes) { - return null; - } - - const options = Object.keys(nodes).map((attrs) => ({ - text: `${attrs} (${nodes[attrs].length})`, - value: attrs, - })); - - options.sort((a, b) => a.value.localeCompare(b.value)); - if (options.length) { - return [{ text: "Default allocation (don't use attributes)", value: '' }, ...options]; - } else { - return options; - } -}); - export const getSelectedPrimaryShardCount = (state) => state.nodes.selectedPrimaryShardCount; export const getSelectedReplicaCount = (state) => diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 8218904f77df9..c2f180f5268d4 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -8207,7 +8207,6 @@ "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingDescription": "ノード属性なしではシャードの割り当てをコントロールできません。", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingLabel": "elasticsearch.yml でノード属性が構成されていません", "xpack.indexLifecycleMgmt.editPolicy.nodeDetailErrorMessage": "ノード属性の詳細の読み込み中にエラーが発生しました", - "xpack.indexLifecycleMgmt.editPolicy.nodeInfoErrorMessage": "ノード属性の情報の読み込み中にエラーが発生しました", "xpack.indexLifecycleMgmt.editPolicy.numberRequiredError": "数字が必要です。", "xpack.indexLifecycleMgmt.editPolicy.phaseCold.minimumAgeLabel": "コールドフェーズのタイミング", "xpack.indexLifecycleMgmt.editPolicy.phaseCold.minimumAgeUnitsAriaLabel": "コールドフェーズのタイミングの単位", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 21a42362bcdd3..84c3eab8db9e7 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -8209,7 +8209,6 @@ "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingDescription": "没有节点属性,将无法控制分片分配。", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingLabel": "elasticsearch.yml 中未配置任何节点属性", "xpack.indexLifecycleMgmt.editPolicy.nodeDetailErrorMessage": "加载节点属性详细信息时出错", - "xpack.indexLifecycleMgmt.editPolicy.nodeInfoErrorMessage": "加载节点属性信息时出错", "xpack.indexLifecycleMgmt.editPolicy.numberRequiredError": "数字必填。", "xpack.indexLifecycleMgmt.editPolicy.phaseCold.minimumAgeLabel": "冷阶段计时", "xpack.indexLifecycleMgmt.editPolicy.phaseCold.minimumAgeUnitsAriaLabel": "冷阶段计时单位", From 042254f026bd77e4411d056c2af305588c8974ed Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Thu, 6 Aug 2020 09:17:20 -0700 Subject: [PATCH 044/106] [Ingest Manager] Update `dataset.*` to `data_stream.*` in package config SO attributes (#74414) * Update `dataset.*` to `data_stream.*` in full agent config yaml * Replace `dataset.*` with `data_stream.*` in package config saved object attributes --- .../common/services/config_to_yaml.ts | 1 + .../package_configs_to_agent_inputs.test.ts | 14 +++++------ .../package_configs_to_agent_inputs.ts | 4 ++-- .../common/services/package_to_config.test.ts | 24 ++++++++++--------- .../common/services/package_to_config.ts | 15 +++++------- .../common/types/models/agent_config.ts | 6 ++--- .../common/types/models/package_config.ts | 4 ++-- .../components/package_config_input_panel.tsx | 11 +++++---- .../services/validate_package_config.ts | 2 +- .../validate_package_config.ts.test.ts | 24 +++++++++---------- .../step_configure_package.tsx | 8 +++---- .../server/saved_objects/index.ts | 4 ++-- .../server/services/package_config.test.ts | 8 +++---- .../server/services/package_config.ts | 4 ++-- .../server/types/models/package_config.ts | 2 +- .../server/lib/hosts/mock.ts | 2 +- .../es_archives/fleet/agents/mappings.json | 4 ++-- .../es_archives/lists/mappings.json | 4 ++-- .../canvas_disallowed_url/mappings.json | 4 ++-- .../es_archives/export_rule/mappings.json | 4 ++-- .../apps/endpoint/policy_details.ts | 2 +- 21 files changed, 76 insertions(+), 75 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/services/config_to_yaml.ts b/x-pack/plugins/ingest_manager/common/services/config_to_yaml.ts index 1fb6fead454ef..e2e6393738d1f 100644 --- a/x-pack/plugins/ingest_manager/common/services/config_to_yaml.ts +++ b/x-pack/plugins/ingest_manager/common/services/config_to_yaml.ts @@ -10,6 +10,7 @@ const CONFIG_KEYS_ORDER = [ 'id', 'name', 'revision', + 'dataset', 'type', 'outputs', 'agent', diff --git a/x-pack/plugins/ingest_manager/common/services/package_configs_to_agent_inputs.test.ts b/x-pack/plugins/ingest_manager/common/services/package_configs_to_agent_inputs.test.ts index a4d87f54b0915..d6c09f058ab85 100644 --- a/x-pack/plugins/ingest_manager/common/services/package_configs_to_agent_inputs.test.ts +++ b/x-pack/plugins/ingest_manager/common/services/package_configs_to_agent_inputs.test.ts @@ -39,7 +39,7 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => { { id: 'test-logs-foo', enabled: true, - dataset: { name: 'foo', type: 'logs' }, + data_stream: { dataset: 'foo', type: 'logs' }, vars: { fooVar: { value: 'foo-value' }, fooVar2: { value: [1, 2] }, @@ -52,7 +52,7 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => { { id: 'test-logs-bar', enabled: true, - dataset: { name: 'bar', type: 'logs' }, + data_stream: { dataset: 'bar', type: 'logs' }, vars: { barVar: { value: 'bar-value' }, barVar2: { value: [1, 2] }, @@ -118,7 +118,7 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => { id: 'some-uuid', name: 'mock-package-config', type: 'test-logs', - dataset: { namespace: 'default' }, + data_stream: { namespace: 'default' }, use_output: 'default', meta: { package: { @@ -129,13 +129,13 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => { streams: [ { id: 'test-logs-foo', - dataset: { name: 'foo', type: 'logs' }, + data_stream: { dataset: 'foo', type: 'logs' }, fooKey: 'fooValue1', fooKey2: ['fooValue2'], }, { id: 'test-logs-bar', - dataset: { name: 'bar', type: 'logs' }, + data_stream: { dataset: 'bar', type: 'logs' }, }, ], }, @@ -160,12 +160,12 @@ describe('Ingest Manager - storedPackageConfigsToAgentInputs', () => { id: 'some-uuid', name: 'mock-package-config', type: 'test-logs', - dataset: { namespace: 'default' }, + data_stream: { namespace: 'default' }, use_output: 'default', streams: [ { id: 'test-logs-foo', - dataset: { name: 'foo', type: 'logs' }, + data_stream: { dataset: 'foo', type: 'logs' }, fooKey: 'fooValue1', fooKey2: ['fooValue2'], }, diff --git a/x-pack/plugins/ingest_manager/common/services/package_configs_to_agent_inputs.ts b/x-pack/plugins/ingest_manager/common/services/package_configs_to_agent_inputs.ts index 64ba6b8a52b57..b94fc39e0567c 100644 --- a/x-pack/plugins/ingest_manager/common/services/package_configs_to_agent_inputs.ts +++ b/x-pack/plugins/ingest_manager/common/services/package_configs_to_agent_inputs.ts @@ -24,7 +24,7 @@ export const storedPackageConfigsToAgentInputs = ( id: packageConfig.id || packageConfig.name, name: packageConfig.name, type: input.type, - dataset: { + data_stream: { namespace: packageConfig.namespace || 'default', }, use_output: DEFAULT_OUTPUT.name, @@ -37,7 +37,7 @@ export const storedPackageConfigsToAgentInputs = ( .map((stream) => { const fullStream: FullAgentConfigInputStream = { id: stream.id, - dataset: stream.dataset, + data_stream: stream.data_stream, ...stream.compiled_stream, ...Object.entries(stream.config || {}).reduce((acc, [key, { value }]) => { acc[key] = value; diff --git a/x-pack/plugins/ingest_manager/common/services/package_to_config.test.ts b/x-pack/plugins/ingest_manager/common/services/package_to_config.test.ts index e0cd32df1535e..1f4cd43247be1 100644 --- a/x-pack/plugins/ingest_manager/common/services/package_to_config.test.ts +++ b/x-pack/plugins/ingest_manager/common/services/package_to_config.test.ts @@ -83,14 +83,16 @@ describe('Ingest Manager - packageToConfig', () => { { type: 'foo', enabled: true, - streams: [{ id: 'foo-foo', enabled: true, dataset: { name: 'foo', type: 'logs' } }], + streams: [ + { id: 'foo-foo', enabled: true, data_stream: { dataset: 'foo', type: 'logs' } }, + ], }, { type: 'bar', enabled: true, streams: [ - { id: 'bar-bar', enabled: true, dataset: { name: 'bar', type: 'logs' } }, - { id: 'bar-bar2', enabled: true, dataset: { name: 'bar2', type: 'logs' } }, + { id: 'bar-bar', enabled: true, data_stream: { dataset: 'bar', type: 'logs' } }, + { id: 'bar-bar2', enabled: true, data_stream: { dataset: 'bar2', type: 'logs' } }, ], }, ]); @@ -141,7 +143,7 @@ describe('Ingest Manager - packageToConfig', () => { { id: 'foo-foo', enabled: true, - dataset: { name: 'foo', type: 'logs' }, + data_stream: { dataset: 'foo', type: 'logs' }, vars: { 'var-name': { value: 'foo-var-value' } }, }, ], @@ -153,13 +155,13 @@ describe('Ingest Manager - packageToConfig', () => { { id: 'bar-bar', enabled: true, - dataset: { name: 'bar', type: 'logs' }, + data_stream: { dataset: 'bar', type: 'logs' }, vars: { 'var-name': { type: 'text', value: 'bar-var-value' } }, }, { id: 'bar-bar2', enabled: true, - dataset: { name: 'bar2', type: 'logs' }, + data_stream: { dataset: 'bar2', type: 'logs' }, vars: { 'var-name': { type: 'yaml', value: 'bar2-var-value' } }, }, ], @@ -257,7 +259,7 @@ describe('Ingest Manager - packageToConfig', () => { { id: 'foo-foo', enabled: true, - dataset: { name: 'foo', type: 'logs' }, + data_stream: { dataset: 'foo', type: 'logs' }, vars: { 'var-name': { value: 'foo-var-value' }, }, @@ -275,7 +277,7 @@ describe('Ingest Manager - packageToConfig', () => { { id: 'bar-bar', enabled: true, - dataset: { name: 'bar', type: 'logs' }, + data_stream: { dataset: 'bar', type: 'logs' }, vars: { 'var-name': { value: 'bar-var-value' }, }, @@ -283,7 +285,7 @@ describe('Ingest Manager - packageToConfig', () => { { id: 'bar-bar2', enabled: true, - dataset: { name: 'bar2', type: 'logs' }, + data_stream: { dataset: 'bar2', type: 'logs' }, vars: { 'var-name': { value: 'bar2-var-value' }, }, @@ -297,7 +299,7 @@ describe('Ingest Manager - packageToConfig', () => { { id: 'with-disabled-streams-disabled', enabled: false, - dataset: { name: 'disabled', type: 'logs' }, + data_stream: { dataset: 'disabled', type: 'logs' }, vars: { 'var-name': { value: [] }, }, @@ -305,7 +307,7 @@ describe('Ingest Manager - packageToConfig', () => { { id: 'with-disabled-streams-disabled2', enabled: false, - dataset: { name: 'disabled2', type: 'logs' }, + data_stream: { dataset: 'disabled2', type: 'logs' }, }, ], }, diff --git a/x-pack/plugins/ingest_manager/common/services/package_to_config.ts b/x-pack/plugins/ingest_manager/common/services/package_to_config.ts index 5957267c7304c..184b44cb9e530 100644 --- a/x-pack/plugins/ingest_manager/common/services/package_to_config.ts +++ b/x-pack/plugins/ingest_manager/common/services/package_to_config.ts @@ -19,17 +19,17 @@ import { const getStreamsForInputType = ( inputType: string, packageInfo: PackageInfo -): Array => { - const streams: Array = []; +): Array => { + const streams: Array = []; (packageInfo.datasets || []).forEach((dataset) => { (dataset.streams || []).forEach((stream) => { if (stream.input === inputType) { streams.push({ ...stream, - dataset: { + data_stream: { type: dataset.type, - name: dataset.name, + dataset: dataset.name, }, }); } @@ -76,12 +76,9 @@ export const packageToPackageConfigInputs = (packageInfo: PackageInfo): PackageC packageInfo ).map((packageStream) => { const stream: PackageConfigInputStream = { - id: `${packageInput.type}-${packageStream.dataset.name}`, + id: `${packageInput.type}-${packageStream.data_stream.dataset}`, enabled: packageStream.enabled === false ? false : true, - dataset: { - name: packageStream.dataset.name, - type: packageStream.dataset.type, - }, + data_stream: packageStream.data_stream, }; if (packageStream.vars && packageStream.vars.length) { stream.vars = packageStream.vars.reduce(varsReducer, {}); diff --git a/x-pack/plugins/ingest_manager/common/types/models/agent_config.ts b/x-pack/plugins/ingest_manager/common/types/models/agent_config.ts index 00ba51fc1843a..cdaea1cc5f9a4 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/agent_config.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/agent_config.ts @@ -32,8 +32,8 @@ export type AgentConfigSOAttributes = Omit; export interface FullAgentConfigInputStream { id: string; - dataset: { - name: string; + data_stream: { + dataset: string; type: string; }; [key: string]: any; @@ -43,7 +43,7 @@ export interface FullAgentConfigInput { id: string; name: string; type: string; - dataset: { namespace: string }; + data_stream: { namespace: string }; use_output: string; meta?: { package?: Pick; diff --git a/x-pack/plugins/ingest_manager/common/types/models/package_config.ts b/x-pack/plugins/ingest_manager/common/types/models/package_config.ts index 0ff56e6d05d37..635afbd47850e 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/package_config.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/package_config.ts @@ -20,8 +20,8 @@ export type PackageConfigConfigRecord = Record, + packageInputStreams: Array, packageConfigInput: PackageConfigInput ): boolean => { return ( @@ -52,7 +52,7 @@ const shouldShowStreamsByDefault = ( hasInvalidButRequiredVar( stream.vars, packageConfigInput.streams.find( - (pkgStream) => stream.dataset.name === pkgStream.dataset.name + (pkgStream) => stream.data_stream.dataset === pkgStream.data_stream.dataset )?.vars ) ) @@ -62,7 +62,7 @@ const shouldShowStreamsByDefault = ( export const PackageConfigInputPanel: React.FunctionComponent<{ packageInput: RegistryInput; - packageInputStreams: Array; + packageInputStreams: Array; packageConfigInput: PackageConfigInput; updatePackageConfigInput: (updatedInput: Partial) => void; inputValidationResults: PackageConfigInputValidationResults; @@ -90,7 +90,7 @@ export const PackageConfigInputPanel: React.FunctionComponent<{ return { packageInputStream, packageConfigInputStream: packageConfigInput.streams.find( - (stream) => stream.dataset.name === packageInputStream.dataset.name + (stream) => stream.data_stream.dataset === packageInputStream.data_stream.dataset ), }; }) @@ -201,7 +201,8 @@ export const PackageConfigInputPanel: React.FunctionComponent<{ updatedStream: Partial ) => { const indexOfUpdatedStream = packageConfigInput.streams.findIndex( - (stream) => stream.dataset.name === packageInputStream.dataset.name + (stream) => + stream.data_stream.dataset === packageInputStream.data_stream.dataset ); const newStreams = [...packageConfigInput.streams]; newStreams[indexOfUpdatedStream] = { diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/services/validate_package_config.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/services/validate_package_config.ts index bd9d216ca969a..0514ad574a8cd 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/services/validate_package_config.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/services/validate_package_config.ts @@ -134,7 +134,7 @@ export const validatePackageConfig = ( if (stream.vars) { const streamVarsByName = ( ( - registryStreamsByDataset[stream.dataset.name].find( + registryStreamsByDataset[stream.data_stream.dataset].find( (registryStream) => registryStream.input === input.type ) || {} ).vars || [] diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/services/validate_package_config.ts.test.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/services/validate_package_config.ts.test.ts index 41d46f03dca23..47874525b8a5a 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/services/validate_package_config.ts.test.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/services/validate_package_config.ts.test.ts @@ -159,7 +159,7 @@ describe('Ingest Manager - validatePackageConfig()', () => { streams: [ { id: 'foo-foo', - dataset: { name: 'foo', type: 'logs' }, + data_stream: { dataset: 'foo', type: 'logs' }, enabled: true, vars: { 'var-name': { value: 'test_yaml: value', type: 'yaml' } }, }, @@ -175,13 +175,13 @@ describe('Ingest Manager - validatePackageConfig()', () => { streams: [ { id: 'bar-bar', - dataset: { name: 'bar', type: 'logs' }, + data_stream: { dataset: 'bar', type: 'logs' }, enabled: true, vars: { 'var-name': { value: 'test_yaml: value', type: 'yaml' } }, }, { id: 'bar-bar2', - dataset: { name: 'bar2', type: 'logs' }, + data_stream: { dataset: 'bar2', type: 'logs' }, enabled: true, vars: { 'var-name': { value: undefined, type: 'text' } }, }, @@ -198,13 +198,13 @@ describe('Ingest Manager - validatePackageConfig()', () => { streams: [ { id: 'with-disabled-streams-disabled', - dataset: { name: 'disabled', type: 'logs' }, + data_stream: { dataset: 'disabled', type: 'logs' }, enabled: false, vars: { 'var-name': { value: undefined, type: 'text' } }, }, { id: 'with-disabled-streams-disabled-without-vars', - dataset: { name: 'disabled2', type: 'logs' }, + data_stream: { dataset: 'disabled2', type: 'logs' }, enabled: false, }, ], @@ -218,7 +218,7 @@ describe('Ingest Manager - validatePackageConfig()', () => { streams: [ { id: 'with-no-stream-vars-bar', - dataset: { name: 'bar', type: 'logs' }, + data_stream: { dataset: 'bar', type: 'logs' }, enabled: true, }, ], @@ -241,7 +241,7 @@ describe('Ingest Manager - validatePackageConfig()', () => { streams: [ { id: 'foo-foo', - dataset: { name: 'foo', type: 'logs' }, + data_stream: { dataset: 'foo', type: 'logs' }, enabled: true, vars: { 'var-name': { value: 'invalidyaml: test\n foo bar:', type: 'yaml' } }, }, @@ -257,13 +257,13 @@ describe('Ingest Manager - validatePackageConfig()', () => { streams: [ { id: 'bar-bar', - dataset: { name: 'bar', type: 'logs' }, + data_stream: { dataset: 'bar', type: 'logs' }, enabled: true, vars: { 'var-name': { value: ' \n\n', type: 'yaml' } }, }, { id: 'bar-bar2', - dataset: { name: 'bar2', type: 'logs' }, + data_stream: { dataset: 'bar2', type: 'logs' }, enabled: true, vars: { 'var-name': { value: undefined, type: 'text' } }, }, @@ -280,7 +280,7 @@ describe('Ingest Manager - validatePackageConfig()', () => { streams: [ { id: 'with-disabled-streams-disabled', - dataset: { name: 'disabled', type: 'logs' }, + data_stream: { dataset: 'disabled', type: 'logs' }, enabled: false, vars: { 'var-name': { @@ -291,7 +291,7 @@ describe('Ingest Manager - validatePackageConfig()', () => { }, { id: 'with-disabled-streams-disabled-without-vars', - dataset: { name: 'disabled2', type: 'logs' }, + data_stream: { dataset: 'disabled2', type: 'logs' }, enabled: false, }, ], @@ -305,7 +305,7 @@ describe('Ingest Manager - validatePackageConfig()', () => { streams: [ { id: 'with-no-stream-vars-bar', - dataset: { name: 'bar', type: 'logs' }, + data_stream: { dataset: 'bar', type: 'logs' }, enabled: true, }, ], diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_configure_package.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_configure_package.tsx index 380a03e15695b..a41d4d72db34c 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_configure_package.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_configure_package.tsx @@ -14,16 +14,16 @@ import { CreatePackageConfigFrom } from './types'; const findStreamsForInputType = ( inputType: string, packageInfo: PackageInfo -): Array => { - const streams: Array = []; +): Array => { + const streams: Array = []; (packageInfo.datasets || []).forEach((dataset) => { (dataset.streams || []).forEach((stream) => { if (stream.input === inputType) { streams.push({ ...stream, - dataset: { - name: dataset.name, + data_stream: { + dataset: dataset.name, }, }); } diff --git a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts index aa2b73194067a..eca2711363c85 100644 --- a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts +++ b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts @@ -211,9 +211,9 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = { properties: { id: { type: 'keyword' }, enabled: { type: 'boolean' }, - dataset: { + data_stream: { properties: { - name: { type: 'keyword' }, + dataset: { type: 'keyword' }, type: { type: 'keyword' }, }, }, diff --git a/x-pack/plugins/ingest_manager/server/services/package_config.test.ts b/x-pack/plugins/ingest_manager/server/services/package_config.test.ts index e86e2608e252d..28aa0d773d75b 100644 --- a/x-pack/plugins/ingest_manager/server/services/package_config.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/package_config.test.ts @@ -65,7 +65,7 @@ describe('Package config service', () => { streams: [ { id: 'dataset01', - dataset: { name: 'package.dataset1', type: 'logs' }, + data_stream: { dataset: 'package.dataset1', type: 'logs' }, enabled: true, vars: { paths: { @@ -85,7 +85,7 @@ describe('Package config service', () => { streams: [ { id: 'dataset01', - dataset: { name: 'package.dataset1', type: 'logs' }, + data_stream: { dataset: 'package.dataset1', type: 'logs' }, enabled: true, vars: { paths: { @@ -131,7 +131,7 @@ describe('Package config service', () => { streams: [ { id: 'dataset01', - dataset: { name: 'package.dataset1', type: 'logs' }, + data_stream: { dataset: 'package.dataset1', type: 'logs' }, enabled: true, }, ], @@ -151,7 +151,7 @@ describe('Package config service', () => { streams: [ { id: 'dataset01', - dataset: { name: 'package.dataset1', type: 'logs' }, + data_stream: { dataset: 'package.dataset1', type: 'logs' }, enabled: true, compiled_stream: { metricset: ['dataset1'], diff --git a/x-pack/plugins/ingest_manager/server/services/package_config.ts b/x-pack/plugins/ingest_manager/server/services/package_config.ts index a369aa5c41cd4..665c08316588c 100644 --- a/x-pack/plugins/ingest_manager/server/services/package_config.ts +++ b/x-pack/plugins/ingest_manager/server/services/package_config.ts @@ -379,14 +379,14 @@ async function _assignPackageStreamToStream( if (!stream.enabled) { return { ...stream, compiled_stream: undefined }; } - const datasetPath = getDataset(stream.dataset.name); + const datasetPath = getDataset(stream.data_stream.dataset); const packageDatasets = pkgInfo.datasets; if (!packageDatasets) { throw new Error('Stream template not found, no datasets'); } const packageDataset = packageDatasets.find( - (pkgDataset) => pkgDataset.name === stream.dataset.name + (pkgDataset) => pkgDataset.name === stream.data_stream.dataset ); if (!packageDataset) { throw new Error(`Stream template not found, unable to find dataset ${datasetPath}`); diff --git a/x-pack/plugins/ingest_manager/server/types/models/package_config.ts b/x-pack/plugins/ingest_manager/server/types/models/package_config.ts index 0823ccd85a32b..9b7ffb4f78175 100644 --- a/x-pack/plugins/ingest_manager/server/types/models/package_config.ts +++ b/x-pack/plugins/ingest_manager/server/types/models/package_config.ts @@ -45,7 +45,7 @@ const PackageConfigBaseSchema = { schema.object({ id: schema.string(), enabled: schema.boolean(), - dataset: schema.object({ name: schema.string(), type: schema.string() }), + data_stream: schema.object({ dataset: schema.string(), type: schema.string() }), vars: schema.maybe(ConfigRecordSchema), config: schema.maybe( schema.recordOf( diff --git a/x-pack/plugins/security_solution/server/lib/hosts/mock.ts b/x-pack/plugins/security_solution/server/lib/hosts/mock.ts index 44767563c6b75..97aa68c0f9bbf 100644 --- a/x-pack/plugins/security_solution/server/lib/hosts/mock.ts +++ b/x-pack/plugins/security_solution/server/lib/hosts/mock.ts @@ -588,7 +588,7 @@ export const mockEndpointMetadata = { type: 'endpoint', version: '7.9.0-SNAPSHOT', }, - dataset: { name: 'endpoint.metadata', namespace: 'default', type: 'metrics' }, + data_stream: { dataset: 'endpoint.metadata', namespace: 'default', type: 'metrics' }, ecs: { version: '1.5.0' }, elastic: { agent: { id: '' } }, event: { diff --git a/x-pack/test/functional/es_archives/fleet/agents/mappings.json b/x-pack/test/functional/es_archives/fleet/agents/mappings.json index 23b404a53703f..12d3be3e2a971 100644 --- a/x-pack/test/functional/es_archives/fleet/agents/mappings.json +++ b/x-pack/test/functional/es_archives/fleet/agents/mappings.json @@ -1870,9 +1870,9 @@ "config": { "type": "flattened" }, - "dataset": { + "data_stream": { "properties": { - "name": { + "dataset": { "type": "keyword" }, "type": { diff --git a/x-pack/test/functional/es_archives/lists/mappings.json b/x-pack/test/functional/es_archives/lists/mappings.json index 3b4d915cc1ca5..ba4e1b276d45e 100644 --- a/x-pack/test/functional/es_archives/lists/mappings.json +++ b/x-pack/test/functional/es_archives/lists/mappings.json @@ -1310,9 +1310,9 @@ "config": { "type": "flattened" }, - "dataset": { + "data_stream": { "properties": { - "name": { + "dataset": { "type": "keyword" }, "type": { diff --git a/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json b/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json index 3519103d06814..2380154277e55 100644 --- a/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json +++ b/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json @@ -1246,9 +1246,9 @@ "config": { "type": "flattened" }, - "dataset": { + "data_stream": { "properties": { - "name": { + "dataset": { "type": "keyword" }, "type": { diff --git a/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json b/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json index bb63d29503663..249b03981386d 100644 --- a/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json +++ b/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json @@ -1320,9 +1320,9 @@ "config": { "type": "flattened" }, - "dataset": { + "data_stream": { "properties": { - "name": { + "dataset": { "type": "keyword" }, "type": { diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts index d4947222a6cc0..02f893029f819 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts @@ -108,7 +108,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { inputs: [ { id: policyInfo.packageConfig.id, - dataset: { namespace: 'default' }, + data_stream: { namespace: 'default' }, name: 'Protect East Coast', meta: { package: { From fa2251dd31ff6292e7f99aec1f42d3b427d7d39a Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 6 Aug 2020 18:52:21 +0200 Subject: [PATCH 045/106] [Lens] Add functional tests on chart transitions and pie chart (#74083) --- .../change_indexpattern.tsx | 2 +- .../pie_visualization/pie_visualization.tsx | 4 + .../xy_visualization/xy_config_panel.test.tsx | 6 +- .../xy_visualization/xy_config_panel.tsx | 2 +- .../api_integration/apis/lens/telemetry.ts | 3 +- x-pack/test/functional/apps/lens/dashboard.ts | 64 ++++++ x-pack/test/functional/apps/lens/index.ts | 1 + .../test/functional/apps/lens/smokescreen.ts | 203 +++++++++--------- .../es_archives/lens/basic/data.json.gz | Bin 4183 -> 4623 bytes .../test/functional/page_objects/lens_page.ts | 76 ++++++- 10 files changed, 255 insertions(+), 106 deletions(-) create mode 100644 x-pack/test/functional/apps/lens/dashboard.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx index 5e2fe9d7bbc14..a62db353e2baf 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx @@ -57,7 +57,7 @@ export function ChangeIndexPattern({ panelPaddingSize="s" ownFocus > -
    +
    {i18n.translate('xpack.lens.indexPattern.changeIndexPatternTitle', { defaultMessage: 'Change index pattern', diff --git a/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx b/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx index 369ab28293fbc..5a68516db6aa3 100644 --- a/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx @@ -122,6 +122,7 @@ export const pieVisualization: Visualization { ); const options = component - .find('[data-test-subj="lnsXY_seriesType"]') + .find(EuiButtonGroup) .first() .prop('options') as EuiButtonGroupProps['options']; @@ -79,7 +79,7 @@ describe('XY Config panels', () => { ); const options = component - .find('[data-test-subj="lnsXY_seriesType"]') + .find(EuiButtonGroup) .first() .prop('options') as EuiButtonGroupProps['options']; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 6d5bc7808a678..e4bc6de5cc68a 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -95,13 +95,13 @@ export function LayerContextMenu(props: VisualizationLayerWidgetProps) { })} name="chartType" className="eui-displayInlineBlock" - data-test-subj="lnsXY_seriesType" options={visualizationTypes .filter((t) => isHorizontalSeries(t.id as SeriesType) === horizontalOnly) .map((t) => ({ id: t.id, label: t.label, iconType: t.icon || 'empty', + 'data-test-subj': `lnsXY_seriesType-${t.id}`, }))} idSelected={layer.seriesType} onChange={(seriesType) => { diff --git a/x-pack/test/api_integration/apis/lens/telemetry.ts b/x-pack/test/api_integration/apis/lens/telemetry.ts index 2c05b02cf470f..0ae4753cd2967 100644 --- a/x-pack/test/api_integration/apis/lens/telemetry.ts +++ b/x-pack/test/api_integration/apis/lens/telemetry.ts @@ -191,8 +191,9 @@ export default ({ getService }: FtrProviderContext) => { expect(results.saved_overall).to.eql({ lnsMetric: 1, bar_stacked: 1, + lnsPie: 1, }); - expect(results.saved_overall_total).to.eql(2); + expect(results.saved_overall_total).to.eql(3); await esArchiver.unload('lens/basic'); }); diff --git a/x-pack/test/functional/apps/lens/dashboard.ts b/x-pack/test/functional/apps/lens/dashboard.ts new file mode 100644 index 0000000000000..ccf2f88a9d0ed --- /dev/null +++ b/x-pack/test/functional/apps/lens/dashboard.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['header', 'common', 'dashboard', 'timePicker', 'lens']); + + const find = getService('find'); + const dashboardAddPanel = getService('dashboardAddPanel'); + const elasticChart = getService('elasticChart'); + const browser = getService('browser'); + const retry = getService('retry'); + const testSubjects = getService('testSubjects'); + const filterBar = getService('filterBar'); + + async function clickInChart(x: number, y: number) { + const el = await elasticChart.getCanvas(); + await browser.getActions().move({ x, y, origin: el._webElement }).click().perform(); + } + + describe('lens dashboard tests', () => { + it('metric should be embeddable', async () => { + await PageObjects.common.navigateToApp('dashboard'); + await PageObjects.dashboard.clickNewDashboard(); + await dashboardAddPanel.clickOpenAddPanel(); + await dashboardAddPanel.filterEmbeddableNames('Artistpreviouslyknownaslens'); + await find.clickByButtonText('Artistpreviouslyknownaslens'); + await dashboardAddPanel.closeAddPanel(); + await PageObjects.lens.goToTimeRange(); + await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); + }); + + it('should be able to add filters/timerange by clicking in XYChart', async () => { + await PageObjects.common.navigateToApp('dashboard'); + await PageObjects.dashboard.clickNewDashboard(); + await dashboardAddPanel.clickOpenAddPanel(); + await dashboardAddPanel.filterEmbeddableNames('lnsXYvis'); + await find.clickByButtonText('lnsXYvis'); + await dashboardAddPanel.closeAddPanel(); + await PageObjects.lens.goToTimeRange(); + await clickInChart(5, 5); // hardcoded position of bar + + await retry.try(async () => { + await testSubjects.click('applyFiltersPopoverButton'); + await testSubjects.missingOrFail('applyFiltersPopoverButton'); + }); + + await PageObjects.lens.assertExactText( + '[data-test-subj="embeddablePanelHeading-lnsXYvis"]', + 'lnsXYvis' + ); + const time = await PageObjects.timePicker.getTimeConfig(); + expect(time.start).to.equal('Sep 21, 2015 @ 09:00:00.000'); + expect(time.end).to.equal('Sep 21, 2015 @ 12:00:00.000'); + const hasIpFilter = await filterBar.hasFilter('ip', '97.220.3.248'); + expect(hasIpFilter).to.be(true); + }); + }); +} diff --git a/x-pack/test/functional/apps/lens/index.ts b/x-pack/test/functional/apps/lens/index.ts index b17b7d856841c..f2dcf28c01743 100644 --- a/x-pack/test/functional/apps/lens/index.ts +++ b/x-pack/test/functional/apps/lens/index.ts @@ -28,6 +28,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { this.tags(['ciGroup4', 'skipFirefox']); loadTestFile(require.resolve('./smokescreen')); + loadTestFile(require.resolve('./dashboard')); loadTestFile(require.resolve('./persistent_context')); loadTestFile(require.resolve('./lens_reporting')); }); diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index 1e93636161067..77b9aa1e25edd 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -8,115 +8,20 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { - const PageObjects = getPageObjects([ - 'header', - 'common', - 'visualize', - 'dashboard', - 'header', - 'timePicker', - 'lens', - ]); + const PageObjects = getPageObjects(['visualize', 'lens']); const find = getService('find'); - const dashboardAddPanel = getService('dashboardAddPanel'); - const elasticChart = getService('elasticChart'); - const browser = getService('browser'); - const retry = getService('retry'); - const testSubjects = getService('testSubjects'); - const filterBar = getService('filterBar'); const listingTable = getService('listingTable'); - async function assertExpectedMetric(metricCount: string = '19,986') { - await PageObjects.lens.assertExactText( - '[data-test-subj="lns_metric_title"]', - 'Maximum of bytes' - ); - await PageObjects.lens.assertExactText('[data-test-subj="lns_metric_value"]', metricCount); - } - - async function assertExpectedTable() { - await PageObjects.lens.assertExactText( - '[data-test-subj="lnsDataTable"] thead .euiTableCellContent__text', - 'Maximum of bytes' - ); - await PageObjects.lens.assertExactText( - '[data-test-subj="lnsDataTable"] [data-test-subj="lnsDataTableCellValue"]', - '19,986' - ); - } - - async function assertExpectedChart() { - await PageObjects.lens.assertExactText( - '[data-test-subj="embeddablePanelHeading-lnsXYvis"]', - 'lnsXYvis' - ); - } - - async function assertExpectedTimerange() { - const time = await PageObjects.timePicker.getTimeConfig(); - expect(time.start).to.equal('Sep 21, 2015 @ 09:00:00.000'); - expect(time.end).to.equal('Sep 21, 2015 @ 12:00:00.000'); - } - - async function clickOnBarHistogram() { - const el = await elasticChart.getCanvas(); - await browser.getActions().move({ x: 5, y: 5, origin: el._webElement }).click().perform(); - } - describe('lens smokescreen tests', () => { it('should allow editing saved visualizations', async () => { await PageObjects.visualize.gotoVisualizationLandingPage(); await listingTable.searchForItemWithName('Artistpreviouslyknownaslens'); await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens'); await PageObjects.lens.goToTimeRange(); - await assertExpectedMetric(); - }); - - it('metric should be embeddable in dashboards', async () => { - await PageObjects.common.navigateToApp('dashboard'); - await PageObjects.dashboard.clickNewDashboard(); - await dashboardAddPanel.clickOpenAddPanel(); - await dashboardAddPanel.filterEmbeddableNames('Artistpreviouslyknownaslens'); - await find.clickByButtonText('Artistpreviouslyknownaslens'); - await dashboardAddPanel.closeAddPanel(); - await PageObjects.lens.goToTimeRange(); - await assertExpectedMetric(); + await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); }); - it('click on the bar in XYChart adds proper filters/timerange in dashboard', async () => { - await PageObjects.common.navigateToApp('dashboard'); - await PageObjects.dashboard.clickNewDashboard(); - await dashboardAddPanel.clickOpenAddPanel(); - await dashboardAddPanel.filterEmbeddableNames('lnsXYvis'); - await find.clickByButtonText('lnsXYvis'); - await dashboardAddPanel.closeAddPanel(); - await PageObjects.lens.goToTimeRange(); - await clickOnBarHistogram(); - - await retry.try(async () => { - await testSubjects.click('applyFiltersPopoverButton'); - await testSubjects.missingOrFail('applyFiltersPopoverButton'); - }); - - await assertExpectedChart(); - await assertExpectedTimerange(); - const hasIpFilter = await filterBar.hasFilter('ip', '97.220.3.248'); - expect(hasIpFilter).to.be(true); - }); - - it('should allow seamless transition to and from table view', async () => { - await PageObjects.visualize.gotoVisualizationLandingPage(); - await listingTable.searchForItemWithName('Artistpreviouslyknownaslens'); - await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens'); - await PageObjects.lens.goToTimeRange(); - await assertExpectedMetric(); - await PageObjects.lens.switchToVisualization('lnsDatatable'); - await assertExpectedTable(); - await PageObjects.lens.switchToVisualization('lnsMetric'); - await assertExpectedMetric(); - }); - - it('should allow creation of lens visualizations', async () => { + it('should allow creation of lens xy chart', async () => { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickVisType('lens'); await PageObjects.lens.goToTimeRange(); @@ -165,6 +70,19 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await find.allByCssSelector('.echLegendItem')).to.have.length(3); }); + it('should allow seamless transition to and from table view', async () => { + await PageObjects.visualize.gotoVisualizationLandingPage(); + await listingTable.searchForItemWithName('Artistpreviouslyknownaslens'); + await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens'); + await PageObjects.lens.goToTimeRange(); + await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); + await PageObjects.lens.switchToVisualization('lnsDatatable'); + expect(await PageObjects.lens.getDatatableHeaderText()).to.eql('Maximum of bytes'); + expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('19,986'); + await PageObjects.lens.switchToVisualization('lnsMetric'); + await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); + }); + it('should switch from a multi-layer stacked bar to a multi-layer line chart', async () => { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickVisType('lens'); @@ -190,5 +108,94 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await PageObjects.lens.getLayerCount()).to.eql(2); }); + + it('should allow transition from line chart to donut chart and to bar chart', async () => { + await PageObjects.visualize.gotoVisualizationLandingPage(); + await listingTable.searchForItemWithName('lnsXYvis'); + await PageObjects.lens.clickVisualizeListItemTitle('lnsXYvis'); + await PageObjects.lens.goToTimeRange(); + expect(await PageObjects.lens.hasChartSwitchWarning('donut')).to.eql(true); + await PageObjects.lens.switchToVisualization('donut'); + + expect(await PageObjects.lens.getTitle()).to.eql('lnsXYvis'); + expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sliceByDimensionPanel')).to.eql( + 'Top values of ip' + ); + expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sizeByDimensionPanel')).to.eql( + 'Average of bytes' + ); + + expect(await PageObjects.lens.hasChartSwitchWarning('bar')).to.eql(false); + await PageObjects.lens.switchToVisualization('bar'); + expect(await PageObjects.lens.getTitle()).to.eql('lnsXYvis'); + expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_xDimensionPanel')).to.eql( + 'Top values of ip' + ); + expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_yDimensionPanel')).to.eql( + 'Average of bytes' + ); + }); + + it('should allow seamless transition from bar chart to line chart using layer chart switch', async () => { + await PageObjects.visualize.gotoVisualizationLandingPage(); + await listingTable.searchForItemWithName('lnsXYvis'); + await PageObjects.lens.clickVisualizeListItemTitle('lnsXYvis'); + await PageObjects.lens.goToTimeRange(); + await PageObjects.lens.switchLayerSeriesType('line'); + expect(await PageObjects.lens.getTitle()).to.eql('lnsXYvis'); + expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_xDimensionPanel')).to.eql( + '@timestamp' + ); + expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_yDimensionPanel')).to.eql( + 'Average of bytes' + ); + expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_splitDimensionPanel')).to.eql( + 'Top values of ip' + ); + }); + + it('should allow seamless transition from pie chart to treemap chart', async () => { + await PageObjects.visualize.gotoVisualizationLandingPage(); + await listingTable.searchForItemWithName('lnsPieVis'); + await PageObjects.lens.clickVisualizeListItemTitle('lnsPieVis'); + await PageObjects.lens.goToTimeRange(); + expect(await PageObjects.lens.hasChartSwitchWarning('treemap')).to.eql(false); + await PageObjects.lens.switchToVisualization('treemap'); + expect( + await PageObjects.lens.getDimensionTriggerText('lnsPie_groupByDimensionPanel', 0) + ).to.eql('Top values of geo.dest'); + expect( + await PageObjects.lens.getDimensionTriggerText('lnsPie_groupByDimensionPanel', 1) + ).to.eql('Top values of geo.src'); + expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sizeByDimensionPanel')).to.eql( + 'Average of bytes' + ); + }); + + it('should allow creating a pie chart and switching to datatable', async () => { + await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.clickVisType('lens'); + await PageObjects.lens.goToTimeRange(); + await PageObjects.lens.switchToVisualization('pie'); + await PageObjects.lens.configureDimension({ + dimension: 'lnsPie_sliceByDimensionPanel > lns-empty-dimension', + operation: 'date_histogram', + field: '@timestamp', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsPie_sizeByDimensionPanel > lns-empty-dimension', + operation: 'avg', + field: 'bytes', + }); + + expect(await PageObjects.lens.hasChartSwitchWarning('lnsDatatable')).to.eql(false); + await PageObjects.lens.switchToVisualization('lnsDatatable'); + + expect(await PageObjects.lens.getDatatableHeaderText()).to.eql('@timestamp per 3 hours'); + expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('2015-09-20 00:00'); + expect(await PageObjects.lens.getDatatableHeaderText(1)).to.eql('Average of bytes'); + expect(await PageObjects.lens.getDatatableCellText(0, 1)).to.eql('6,011.351'); + }); }); } diff --git a/x-pack/test/functional/es_archives/lens/basic/data.json.gz b/x-pack/test/functional/es_archives/lens/basic/data.json.gz index 4ed7c29f7391e4b01ea2737a318cb533d72bf63a..ddf4a27289dffdaf1c605b0db01cfa9554a2b209 100644 GIT binary patch literal 4623 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 diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index 79548db0e2630..bed0e3a159e23 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -176,9 +176,26 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont */ async hasChartSwitchWarning(subVisualizationId: string) { await this.openChartSwitchPopover(); - const element = await testSubjects.find(`lnsChartSwitchPopover_${subVisualizationId}`); - return await testSubjects.descendantExists('euiKeyPadMenuItem__betaBadgeWrapper', element); + return await find.descendantExistsByCssSelector( + '.euiKeyPadMenuItem__betaBadgeWrapper', + element + ); + }, + + /** + * Uses the Lens layer switcher to switch seriesType for xy charts. + * + * @param subVisualizationId - the ID of the sub-visualization to switch to, such as + * line, + */ + async switchLayerSeriesType(seriesType: string) { + await retry.try(async () => { + await testSubjects.click('lns_layer_settings'); + await testSubjects.exists(`lnsXY_seriesType-${seriesType}`); + }); + + return await testSubjects.click(`lnsXY_seriesType-${seriesType}`); }, /** @@ -205,5 +222,60 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont await PageObjects.header.waitUntilLoadingHasFinished(); await testSubjects.missingOrFail('lnsApp_saveAndReturnButton'); }, + /** + * Gets label of dimension trigger in dimension panel + * + * @param dimension - the selector of the dimension + */ + async getDimensionTriggerText(dimension: string, index = 0) { + const dimensionElements = await testSubjects.findAll(dimension); + const trigger = await testSubjects.findDescendant( + 'lns-dimensionTrigger', + dimensionElements[index] + ); + return await trigger.getVisibleText(); + }, + + /** + * Gets text of the specified datatable header cell + * + * @param index - index of th element in datatable + */ + async getDatatableHeaderText(index = 0) { + return find + .byCssSelector( + `[data-test-subj="lnsDataTable"] thead th:nth-child(${ + index + 1 + }) .euiTableCellContent__text` + ) + .then((el) => el.getVisibleText()); + }, + + /** + * Gets text of the specified datatable cell + * + * @param rowIndex - index of row of the cell + * @param colIndex - index of column of the cell + */ + async getDatatableCellText(rowIndex = 0, colIndex = 0) { + return find + .byCssSelector( + `[data-test-subj="lnsDataTable"] tr:nth-child(${rowIndex + 1}) td:nth-child(${ + colIndex + 1 + })` + ) + .then((el) => el.getVisibleText()); + }, + + /** + * Asserts that metric has expected title and count + * + * @param title - expected title + * @param count - expected count of metric + */ + async assertMetric(title: string, count: string) { + await this.assertExactText('[data-test-subj="lns_metric_title"]', title); + await this.assertExactText('[data-test-subj="lns_metric_value"]', count); + }, }); } From dad5c72a0c2313b3dde78d10817c05917cbda5d0 Mon Sep 17 00:00:00 2001 From: Devon Thomson Date: Thu, 6 Aug 2020 13:24:54 -0400 Subject: [PATCH 046/106] [Fix] Lose OriginatingApp Connection on Save After Create new (#74420) Fixed typo created in #72725 which caused the originatingApp connection not to be lost properly after Create new --- .../application/utils/get_top_nav_config.tsx | 2 +- .../dashboard/edit_embeddable_redirects.js | 19 +++++++++++++++++++ x-pack/plugins/lens/public/app_plugin/app.tsx | 4 +--- .../dashboard_mode/dashboard_empty_screen.js | 18 ++++++++++++++++-- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx b/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx index 392168a530087..da9ba66a914dd 100644 --- a/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx +++ b/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx @@ -114,7 +114,7 @@ export const getTopNavConfig = ( application.navigateToApp(originatingApp); } } else { - if (setOriginatingApp && originatingApp && savedVis.copyOnSave) { + if (setOriginatingApp && originatingApp && newlyCreated) { setOriginatingApp(undefined); } chrome.docTitle.change(savedVis.lastSavedTitle); diff --git a/test/functional/apps/dashboard/edit_embeddable_redirects.js b/test/functional/apps/dashboard/edit_embeddable_redirects.js index 6d3d43890a962..fcc504ea24f31 100644 --- a/test/functional/apps/dashboard/edit_embeddable_redirects.js +++ b/test/functional/apps/dashboard/edit_embeddable_redirects.js @@ -21,8 +21,10 @@ import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['dashboard', 'header', 'visualize', 'settings', 'common']); const esArchiver = getService('esArchiver'); + const testSubjects = getService('testSubjects'); const kibanaServer = getService('kibanaServer'); const dashboardPanelActions = getService('dashboardPanelActions'); + const dashboardVisualizations = getService('dashboardVisualizations'); describe('edit embeddable redirects', () => { before(async () => { @@ -81,6 +83,23 @@ export default function ({ getService, getPageObjects }) { await PageObjects.header.waitUntilLoadingHasFinished(); await dashboardPanelActions.openContextMenu(); await dashboardPanelActions.clickEdit(); + await PageObjects.visualize.linkedToOriginatingApp(); + await PageObjects.visualize.saveVisualizationExpectSuccess(newTitle, { + saveAsNew: true, + redirectToOrigin: false, + }); + await PageObjects.visualize.notLinkedToOriginatingApp(); + await PageObjects.common.navigateToApp('dashboard'); + }); + + it('loses originatingApp connection after first save when redirectToOrigin is false', async () => { + const newTitle = 'test create panel originatingApp'; + await PageObjects.dashboard.loadSavedDashboard('few panels'); + await PageObjects.dashboard.switchToEditMode(); + await testSubjects.exists('dashboardAddNewPanelButton'); + await testSubjects.click('dashboardAddNewPanelButton'); + await dashboardVisualizations.ensureNewVisualizationDialogIsShowing(); + await PageObjects.visualize.clickMarkdownWidget(); await PageObjects.visualize.saveVisualizationExpectSuccess(newTitle, { saveAsNew: true, redirectToOrigin: false, diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index 4a6dbd4a91fbf..ffab84a51a229 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -336,9 +336,7 @@ export function App({ ...s, isSaveModalVisible: false, originatingApp: - saveProps.newCopyOnSave && !saveProps.returnToOrigin - ? undefined - : currentOriginatingApp, + newlyCreated && !saveProps.returnToOrigin ? undefined : currentOriginatingApp, persistedDoc: newDoc, lastKnownDoc: newDoc, })); diff --git a/x-pack/test/functional/apps/dashboard_mode/dashboard_empty_screen.js b/x-pack/test/functional/apps/dashboard_mode/dashboard_empty_screen.js index 62e07a08d1762..bd35374643e9b 100644 --- a/x-pack/test/functional/apps/dashboard_mode/dashboard_empty_screen.js +++ b/x-pack/test/functional/apps/dashboard_mode/dashboard_empty_screen.js @@ -27,7 +27,7 @@ export default function ({ getPageObjects, getService }) { await PageObjects.dashboard.gotoDashboardLandingPage(); }); - async function createAndAddLens(title) { + async function createAndAddLens(title, saveAsNew = false, redirectToOrigin = true) { log.debug(`createAndAddLens(${title})`); const inViewMode = await PageObjects.dashboard.getIsInViewMode(); if (inViewMode) { @@ -52,7 +52,7 @@ export default function ({ getPageObjects, getService }) { operation: 'terms', field: 'ip', }); - await PageObjects.lens.save(title, false, true); + await PageObjects.lens.save(title, saveAsNew, redirectToOrigin); } it('adds Lens visualization to empty dashboard', async () => { @@ -100,6 +100,8 @@ export default function ({ getPageObjects, getService }) { }); it('loses originatingApp connection after save as when redirectToOrigin is false', async () => { + await PageObjects.dashboard.saveDashboard('empty dashboard test'); + await PageObjects.dashboard.switchToEditMode(); const newTitle = 'wowee, my title just got cooler again'; await PageObjects.dashboard.waitForRenderComplete(); await dashboardPanelActions.openContextMenu(); @@ -108,5 +110,17 @@ export default function ({ getPageObjects, getService }) { await PageObjects.lens.notLinkedToOriginatingApp(); await PageObjects.common.navigateToApp('dashboard'); }); + + it('loses originatingApp connection after first save when redirectToOrigin is false', async () => { + const title = 'non-dashboard Test Lens'; + await PageObjects.dashboard.loadSavedDashboard('empty dashboard test'); + await PageObjects.dashboard.switchToEditMode(); + await testSubjects.exists('dashboardAddNewPanelButton'); + await testSubjects.click('dashboardAddNewPanelButton'); + await dashboardVisualizations.ensureNewVisualizationDialogIsShowing(); + await createAndAddLens(title, false, false); + await PageObjects.lens.notLinkedToOriginatingApp(); + await PageObjects.common.navigateToApp('dashboard'); + }); }); } From 79713b9b71bdac049d1dbc754bb2ee1a3861e116 Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 6 Aug 2020 10:57:29 -0700 Subject: [PATCH 047/106] [browserslist] remove user-agent sniffing for IE support hint (#74464) Co-authored-by: spalger --- package.json | 2 - packages/kbn-optimizer/README.md | 4 +- .../server/http/base_path_proxy_server.ts | 36 +----------------- yarn.lock | 38 ++++--------------- 4 files changed, 11 insertions(+), 69 deletions(-) diff --git a/package.json b/package.json index aaa7ae7ee4684..fa34fc3d0936a 100644 --- a/package.json +++ b/package.json @@ -159,7 +159,6 @@ "bluebird": "3.5.5", "boom": "^7.2.0", "brace": "0.11.1", - "browserslist-useragent": "^3.0.2", "cache-loader": "^4.1.0", "chalk": "^2.4.2", "check-disk-space": "^2.1.0", @@ -319,7 +318,6 @@ "@types/babel__core": "^7.1.2", "@types/bluebird": "^3.1.1", "@types/boom": "^7.2.0", - "@types/browserslist-useragent": "^3.0.0", "@types/chance": "^1.0.0", "@types/cheerio": "^0.22.10", "@types/chromedriver": "^81.0.0", diff --git a/packages/kbn-optimizer/README.md b/packages/kbn-optimizer/README.md index 5d5c5e3b6eb74..13be836f0ea88 100644 --- a/packages/kbn-optimizer/README.md +++ b/packages/kbn-optimizer/README.md @@ -10,9 +10,9 @@ The [Webpack config][WebpackConfig] is designed to provide the majority of what Source maps are enabled except when building the distributable. They show the code actually being executed by the browser to strike a balance between debuggability and performance. They are not configurable at this time but will be configurable once we have a developer configuration solution that doesn't rely on the server (see [#55656](https://github.com/elastic/kibana/issues/55656)). -### IE Support +### Browser Support -To make front-end code easier to debug the optimizer uses the `BROWSERSLIST_ENV=dev` environment variable (by default) to build JS and CSS that is compatible with modern browsers. In order to support older browsers like IE in development you will need to specify the `BROWSERSLIST_ENV=production` environment variable or build a distributable for testing. +To make front-end code easier to debug the optimizer uses the `BROWSERSLIST_ENV=dev` environment variable (by default) to build JS and CSS that is compatible with modern browsers. In order to support all browsers that we support with the distributable you will need to specify the `BROWSERSLIST_ENV=production` environment variable or build a distributable for testing. ## Running the optimizer diff --git a/src/core/server/http/base_path_proxy_server.ts b/src/core/server/http/base_path_proxy_server.ts index eccc9d013176c..acb83962bd457 100644 --- a/src/core/server/http/base_path_proxy_server.ts +++ b/src/core/server/http/base_path_proxy_server.ts @@ -22,10 +22,9 @@ import { Agent as HttpsAgent, ServerOptions as TlsOptions } from 'https'; import apm from 'elastic-apm-node'; import { ByteSizeValue } from '@kbn/config-schema'; -import { Server, Request, ResponseToolkit } from 'hapi'; +import { Server, Request } from 'hapi'; import HapiProxy from 'h2o2'; import { sampleSize } from 'lodash'; -import BrowserslistUserAgent from 'browserslist-useragent'; import * as Rx from 'rxjs'; import { take } from 'rxjs/operators'; @@ -41,34 +40,6 @@ export interface BasePathProxyServerOptions { delayUntil: () => Rx.Observable; } -// Before we proxy request to a target port we may want to wait until some -// condition is met (e.g. until target listener is ready). -const checkForBrowserCompat = (log: Logger) => async (request: Request, h: ResponseToolkit) => { - if (!request.headers['user-agent'] || process.env.BROWSERSLIST_ENV === 'production') { - return h.continue; - } - - const matches = BrowserslistUserAgent.matchesUA(request.headers['user-agent'], { - env: 'dev', - allowHigherVersions: true, - ignoreMinor: true, - ignorePath: true, - }); - - if (!matches) { - log.warn(` - Request with user-agent [${request.headers['user-agent']}] - seems like it is coming from a browser that is not supported by the dev browserlist. - - Please run Kibana with the environment variable BROWSERSLIST_ENV=production to enable - support for all production browsers (like IE). - - `); - } - - return h.continue; -}; - export class BasePathProxyServer { private server?: Server; private httpsAgent?: HttpsAgent; @@ -155,9 +126,6 @@ export class BasePathProxyServer { }, method: 'GET', path: '/', - options: { - pre: [checkForBrowserCompat(this.log)], - }, }); this.server.route({ @@ -175,7 +143,6 @@ export class BasePathProxyServer { method: '*', options: { pre: [ - checkForBrowserCompat(this.log), // Before we proxy request to a target port we may want to wait until some // condition is met (e.g. until target listener is ready). async (request, responseToolkit) => { @@ -210,7 +177,6 @@ export class BasePathProxyServer { method: '*', options: { pre: [ - checkForBrowserCompat(this.log), // Before we proxy request to a target port we may want to wait until some // condition is met (e.g. until target listener is ready). async (request, responseToolkit) => { diff --git a/yarn.lock b/yarn.lock index 7aff34fab23ce..f17418f07c5cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4306,11 +4306,6 @@ resolved "https://registry.yarnpkg.com/@types/boom/-/boom-7.2.0.tgz#19c36cbb5811a7493f0f2e37f31d42b28df1abc1" integrity sha512-HonbGsHFbskh9zRAzA6tabcw18mCOsSEOL2ibGAuVqk6e7nElcRmWO5L4UfIHpDbWBWw+eZYFdsQ1+MEGgpcVA== -"@types/browserslist-useragent@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/browserslist-useragent/-/browserslist-useragent-3.0.0.tgz#d425c9818182ce71ce53866798cee9c7d41d6e53" - integrity sha512-ZBvKzg3yyWNYEkwxAzdmUzp27sFvw+1m080/+2lwrt+eltNefn1f4fnpMyrjOla31p8zLleCYqQXw+3EETfn0w== - "@types/cacheable-request@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" @@ -8601,15 +8596,6 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist-useragent@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/browserslist-useragent/-/browserslist-useragent-3.0.2.tgz#f0e209b2742baa5de0e451b52e678e8b4402617c" - integrity sha512-/UPzK9xZnk5mwwWx4wcuBKAKx/mD3MNY8sUuZ2NPqnr4RVFWZogX+8mOP0cQEYo8j78sHk0hiDNaVXZ1U3hM9A== - dependencies: - browserslist "^4.6.6" - semver "^6.3.0" - useragent "^2.3.0" - browserslist@4.6.6: version "4.6.6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" @@ -8629,7 +8615,7 @@ browserslist@^4.12.0: node-releases "^1.1.53" pkg-up "^2.0.0" -browserslist@^4.6.6, browserslist@^4.8.3: +browserslist@^4.8.3: version "4.8.5" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.5.tgz#691af4e327ac877b25e7a3f7ee869c4ef36cdea3" integrity sha512-4LMHuicxkabIB+n9874jZX/az1IaZ5a+EUuvD7KFOu9x/Bd5YHyO0DIz2ls/Kl8g0ItS4X/ilEgf4T1Br0lgSg== @@ -29564,13 +29550,6 @@ tmp@0.0.30: dependencies: os-tmpdir "~1.0.1" -tmp@0.0.x, tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - tmp@0.1.0, tmp@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" @@ -29585,6 +29564,13 @@ tmp@^0.0.29: dependencies: os-tmpdir "~1.0.1" +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -30711,14 +30697,6 @@ user-home@^2.0.0: dependencies: os-homedir "^1.0.0" -useragent@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972" - integrity sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw== - dependencies: - lru-cache "4.1.x" - tmp "0.0.x" - utif@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/utif/-/utif-2.0.1.tgz#9e1582d9bbd20011a6588548ed3266298e711759" From b71b9c249adaa1c43abda2e60bd1c95b3e24c9e9 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 6 Aug 2020 12:08:57 -0600 Subject: [PATCH 048/106] [maps] fix swap hidden/show icons in layer action panel (#74549) --- .../toc_entry_actions_popover.test.tsx.snap | 134 +++++++++++++++++- .../toc_entry_actions_popover.test.tsx | 25 +++- .../toc_entry_actions_popover.tsx | 2 +- 3 files changed, 151 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap index 388712e1ebcca..8a5b7cf9186a8 100644 --- a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap @@ -82,7 +82,7 @@ exports[`TOCEntryActionsPopover is rendered 1`] = ` "data-test-subj": "layerVisibilityToggleButton", "icon": , "name": "Hide layer", "onClick": [Function], @@ -210,7 +210,7 @@ exports[`TOCEntryActionsPopover should disable fit to data when supportsFitToBou "data-test-subj": "layerVisibilityToggleButton", "icon": , "name": "Hide layer", "onClick": [Function], @@ -256,7 +256,7 @@ exports[`TOCEntryActionsPopover should disable fit to data when supportsFitToBou `; -exports[`TOCEntryActionsPopover should not show edit actions in read only mode 1`] = ` +exports[`TOCEntryActionsPopover should have "show layer" action when layer is not visible 1`] = ` , + "name": "Show layer", + "onClick": [Function], + "toolTipContent": null, + }, + Object { + "data-test-subj": "editLayerButton", + "disabled": false, + "icon": , + "name": "Edit layer", + "onClick": [Function], + "toolTipContent": null, + }, + Object { + "data-test-subj": "cloneLayerButton", + "icon": , + "name": "Clone layer", + "onClick": [Function], + "toolTipContent": null, + }, + Object { + "data-test-subj": "removeLayerButton", + "icon": , + "name": "Remove layer", + "onClick": [Function], + "toolTipContent": null, + }, + ], + "title": "Layer actions", + }, + ] + } + /> + +`; + +exports[`TOCEntryActionsPopover should not show edit actions in read only mode 1`] = ` + + simulated tooltip content at zoom: 0 +
    + + mockFootnoteIcon + + + simulated footnote at isUsingSearch: true +
    + + } + delay="regular" + position="top" + title="layer 1" + > + + + + mockIcon + + + layer 1 + + + + + mockFootnoteIcon + + + + + } + className="mapLayTocActions" + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + id="contextMenu" + isOpen={false} + ownFocus={false} + panelPaddingSize="none" + withTitle={true} +> + , + "name": "Fit to data", + "onClick": [Function], + "toolTipContent": null, + }, + Object { + "data-test-subj": "layerVisibilityToggleButton", + "icon": , "name": "Hide layer", "onClick": [Function], "toolTipContent": null, diff --git a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx index c7ed5ec74ac7a..95f13574105b7 100644 --- a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx @@ -6,7 +6,7 @@ /* eslint-disable max-classes-per-file */ import React from 'react'; -import { shallowWithIntl } from 'test_utils/enzyme_helpers'; +import { shallow } from 'enzyme'; import { AbstractLayer, ILayer } from '../../../../../../classes/layers/layer'; import { AbstractSource, ISource } from '../../../../../../classes/sources/source'; import { AbstractStyle, IStyle } from '../../../../../../classes/styles/style'; @@ -76,7 +76,7 @@ describe('TOCEntryActionsPopover', () => { }); test('is rendered', async () => { - const component = shallowWithIntl(); + const component = shallow(); // Ensure all promises resolve await new Promise((resolve) => process.nextTick(resolve)); @@ -87,9 +87,7 @@ describe('TOCEntryActionsPopover', () => { }); test('should not show edit actions in read only mode', async () => { - const component = shallowWithIntl( - - ); + const component = shallow(); // Ensure all promises resolve await new Promise((resolve) => process.nextTick(resolve)); @@ -101,7 +99,22 @@ describe('TOCEntryActionsPopover', () => { test('should disable fit to data when supportsFitToBounds is false', async () => { supportsFitToBounds = false; - const component = shallowWithIntl(); + const component = shallow(); + + // Ensure all promises resolve + await new Promise((resolve) => process.nextTick(resolve)); + // Ensure the state changes are reflected + component.update(); + + expect(component).toMatchSnapshot(); + }); + + test('should have "show layer" action when layer is not visible', async () => { + const layer = new LayerMock(); + layer.isVisible = () => { + return false; + }; + const component = shallow(); // Ensure all promises resolve await new Promise((resolve) => process.nextTick(resolve)); diff --git a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 5baac0a474ffa..a1b9026fc57da 100644 --- a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -158,7 +158,7 @@ export class TOCEntryActionsPopover extends Component { : i18n.translate('xpack.maps.layerTocActions.showLayerTitle', { defaultMessage: 'Show layer', }), - icon: , + icon: , 'data-test-subj': 'layerVisibilityToggleButton', toolTipContent: null, onClick: () => { From ebe46c0580bf397dad6e8e8abc72aca1875f76cc Mon Sep 17 00:00:00 2001 From: Sonja Krause-Harder Date: Thu, 6 Aug 2020 21:30:24 +0200 Subject: [PATCH 049/106] Make test less brittle when registry is changed. (#74554) --- x-pack/test/ingest_manager_api_integration/apis/epm/list.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts index 0b6a37d77387e..bfe1954e46c9f 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts @@ -29,7 +29,7 @@ export default function ({ getService }: FtrProviderContext) { return response.body; }; const listResponse = await fetchPackageList(); - expect(listResponse.response.length).to.be(8); + expect(listResponse.response.length).not.to.be(0); } else { warnAndSkipTest(this, log); } From e807ddd1c1f8edcb0708fe2f365c511557986435 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Thu, 6 Aug 2020 15:33:24 -0400 Subject: [PATCH 050/106] [Monitoring] Handle getClient call throwing an exception (#74550) * This call can throw an exception in dist builds with ssl disabled * Fix typo --- .../lib/cluster/get_clusters_from_request.js | 106 +++++++++--------- x-pack/plugins/monitoring/server/plugin.ts | 18 ++- 2 files changed, 70 insertions(+), 54 deletions(-) diff --git a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.js b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.js index 18db738bba38e..16d42d896ca11 100644 --- a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.js +++ b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.js @@ -119,65 +119,67 @@ export async function getClustersFromRequest( // add alerts data if (isInCodePath(codePaths, [CODE_PATH_ALERTS])) { const alertsClient = req.getAlertsClient(); - for (const cluster of clusters) { - const verification = verifyMonitoringLicense(req.server); - if (!verification.enabled) { - // return metadata detailing that alerts is disabled because of the monitoring cluster license - cluster.alerts = { - alertsMeta: { - enabled: verification.enabled, - message: verification.message, // NOTE: this is only defined when the alert feature is disabled - }, - list: {}, - }; - continue; - } + if (alertsClient) { + for (const cluster of clusters) { + const verification = verifyMonitoringLicense(req.server); + if (!verification.enabled) { + // return metadata detailing that alerts is disabled because of the monitoring cluster license + cluster.alerts = { + alertsMeta: { + enabled: verification.enabled, + message: verification.message, // NOTE: this is only defined when the alert feature is disabled + }, + list: {}, + }; + continue; + } + + // check the license type of the production cluster for alerts feature support + const license = cluster.license || {}; + const prodLicenseInfo = checkLicenseForAlerts( + license.type, + license.status === 'active', + 'production' + ); + if (prodLicenseInfo.clusterAlerts.enabled) { + cluster.alerts = { + list: await fetchStatus( + alertsClient, + req.server.plugins.monitoring.info, + undefined, + cluster.cluster_uuid, + start, + end, + [] + ), + alertsMeta: { + enabled: true, + }, + }; + continue; + } - // check the license type of the production cluster for alerts feature support - const license = cluster.license || {}; - const prodLicenseInfo = checkLicenseForAlerts( - license.type, - license.status === 'active', - 'production' - ); - if (prodLicenseInfo.clusterAlerts.enabled) { cluster.alerts = { - list: await fetchStatus( - alertsClient, - req.server.plugins.monitoring.info, - undefined, - cluster.cluster_uuid, - start, - end, - [] - ), + list: {}, alertsMeta: { enabled: true, }, + clusterMeta: { + enabled: false, + message: i18n.translate( + 'xpack.monitoring.clusterAlerts.unsupportedClusterAlertsDescription', + { + defaultMessage: + 'Cluster [{clusterName}] license type [{licenseType}] does not support Cluster Alerts', + values: { + clusterName: cluster.cluster_name, + licenseType: `${license.type}`, + }, + } + ), + }, }; - continue; } - - cluster.alerts = { - list: {}, - alertsMeta: { - enabled: true, - }, - clusterMeta: { - enabled: false, - message: i18n.translate( - 'xpack.monitoring.clusterAlerts.unsupportedClusterAlertsDescription', - { - defaultMessage: - 'Cluster [{clusterName}] license type [{licenseType}] does not support Cluster Alerts', - values: { - clusterName: cluster.cluster_name, - licenseType: `${license.type}`, - }, - } - ), - }, - }; } } } diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index ed091d4b8d7a7..3aedb6831e7ab 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -325,8 +325,22 @@ export class Plugin { getKibanaStatsCollector: () => this.legacyShimDependencies.kibanaStatsCollector, getUiSettingsService: () => context.core.uiSettings.client, getActionTypeRegistry: () => context.actions?.listTypes(), - getAlertsClient: () => plugins.alerts.getAlertsClientWithRequest(req), - getActionsClient: () => plugins.actions.getActionsClientWithRequest(req), + getAlertsClient: () => { + try { + return plugins.alerts.getAlertsClientWithRequest(req); + } catch (err) { + // If security is disabled, this call will throw an error unless a certain config is set for dist builds + return null; + } + }, + getActionsClient: () => { + try { + return plugins.actions.getActionsClientWithRequest(req); + } catch (err) { + // If security is disabled, this call will throw an error unless a certain config is set for dist builds + return null; + } + }, server: { config: legacyConfigWrapper, newPlatform: { From 47fdd59e1c168a820260e2bd28a71843e4a0f3c1 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Thu, 6 Aug 2020 23:00:40 +0300 Subject: [PATCH 051/106] bump babel deps to support TS v4 (#74495) --- package.json | 10 +- packages/elastic-datemath/package.json | 4 +- packages/kbn-analytics/package.json | 2 +- packages/kbn-babel-preset/package.json | 16 +- packages/kbn-i18n/package.json | 4 +- packages/kbn-interpreter/package.json | 10 +- packages/kbn-optimizer/package.json | 2 +- packages/kbn-plugin-helpers/package.json | 2 +- packages/kbn-pm/package.json | 10 +- packages/kbn-test/package.json | 2 +- packages/kbn-ui-framework/package.json | 2 +- x-pack/package.json | 6 +- yarn.lock | 1289 +++++++++++----------- 13 files changed, 696 insertions(+), 663 deletions(-) diff --git a/package.json b/package.json index fa34fc3d0936a..fc3af14ecae09 100644 --- a/package.json +++ b/package.json @@ -117,9 +117,9 @@ ] }, "dependencies": { - "@babel/core": "^7.10.2", - "@babel/plugin-transform-modules-commonjs": "^7.10.1", - "@babel/register": "^7.10.1", + "@babel/core": "^7.11.1", + "@babel/plugin-transform-modules-commonjs": "^7.10.4", + "@babel/register": "^7.10.5", "@elastic/apm-rum": "^5.2.0", "@elastic/charts": "19.8.1", "@elastic/datemath": "5.0.3", @@ -289,8 +289,8 @@ "yauzl": "2.10.0" }, "devDependencies": { - "@babel/parser": "^7.10.2", - "@babel/types": "^7.10.2", + "@babel/parser": "^7.11.2", + "@babel/types": "^7.11.0", "@elastic/eslint-config-kibana": "0.15.0", "@elastic/eslint-plugin-eui": "0.0.2", "@elastic/github-checks-reporter": "0.0.20b3", diff --git a/packages/elastic-datemath/package.json b/packages/elastic-datemath/package.json index 15040a6243ff2..ad4190f981439 100644 --- a/packages/elastic-datemath/package.json +++ b/packages/elastic-datemath/package.json @@ -11,8 +11,8 @@ "kbn:watch": "yarn build --watch" }, "devDependencies": { - "@babel/cli": "^7.10.1", - "@babel/preset-env": "^7.10.2", + "@babel/cli": "^7.10.5", + "@babel/preset-env": "^7.11.0", "babel-plugin-add-module-exports": "^1.0.2", "moment": "^2.24.0" }, diff --git a/packages/kbn-analytics/package.json b/packages/kbn-analytics/package.json index bd3f5832b7140..873252ceb0a1a 100644 --- a/packages/kbn-analytics/package.json +++ b/packages/kbn-analytics/package.json @@ -14,7 +14,7 @@ "kbn:watch": "node scripts/build --source-maps --watch" }, "devDependencies": { - "@babel/cli": "^7.10.1", + "@babel/cli": "^7.10.5", "@kbn/dev-utils": "1.0.0", "@kbn/babel-preset": "1.0.0", "typescript": "3.9.5" diff --git a/packages/kbn-babel-preset/package.json b/packages/kbn-babel-preset/package.json index 83530beffd2b2..db1f2161b6e38 100644 --- a/packages/kbn-babel-preset/package.json +++ b/packages/kbn-babel-preset/package.json @@ -4,14 +4,14 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "@babel/plugin-proposal-class-properties": "^7.10.1", - "@babel/plugin-proposal-export-namespace-from": "^7.10.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1", - "@babel/plugin-proposal-optional-chaining": "^7.10.1", - "@babel/plugin-proposal-private-methods": "^7.10.1", - "@babel/preset-env": "^7.10.2", - "@babel/preset-react": "^7.10.1", - "@babel/preset-typescript": "^7.10.1", + "@babel/plugin-proposal-class-properties": "^7.10.4", + "@babel/plugin-proposal-export-namespace-from": "^7.10.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", + "@babel/plugin-proposal-optional-chaining": "^7.11.0", + "@babel/plugin-proposal-private-methods": "^7.10.4", + "@babel/preset-env": "^7.11.0", + "@babel/preset-react": "^7.10.4", + "@babel/preset-typescript": "^7.10.4", "babel-plugin-add-module-exports": "^1.0.2", "babel-plugin-filter-imports": "^3.0.0", "babel-plugin-styled-components": "^1.10.7", diff --git a/packages/kbn-i18n/package.json b/packages/kbn-i18n/package.json index c5da144688c3c..0f830acb284a0 100644 --- a/packages/kbn-i18n/package.json +++ b/packages/kbn-i18n/package.json @@ -12,8 +12,8 @@ "kbn:watch": "node scripts/build --watch --source-maps" }, "devDependencies": { - "@babel/cli": "^7.10.1", - "@babel/core": "^7.10.2", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.11.1", "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "@types/intl-relativeformat": "^2.1.0", diff --git a/packages/kbn-interpreter/package.json b/packages/kbn-interpreter/package.json index c6bb06e68b9c0..aef63229ebe96 100644 --- a/packages/kbn-interpreter/package.json +++ b/packages/kbn-interpreter/package.json @@ -9,16 +9,16 @@ "kbn:watch": "node scripts/build --dev --watch" }, "dependencies": { - "@babel/runtime": "^7.10.2", + "@babel/runtime": "^7.11.2", "@kbn/i18n": "1.0.0", "lodash": "^4.17.15", "uuid": "3.3.2" }, "devDependencies": { - "@babel/cli": "^7.10.1", - "@babel/core": "^7.10.2", - "@babel/plugin-transform-modules-commonjs": "^7.10.1", - "@babel/plugin-transform-runtime": "^7.10.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.11.1", + "@babel/plugin-transform-modules-commonjs": "^7.10.4", + "@babel/plugin-transform-runtime": "^7.11.0", "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "babel-loader": "^8.0.6", diff --git a/packages/kbn-optimizer/package.json b/packages/kbn-optimizer/package.json index e6eb5de31abd8..84e5c79e2e358 100644 --- a/packages/kbn-optimizer/package.json +++ b/packages/kbn-optimizer/package.json @@ -10,7 +10,7 @@ "kbn:watch": "yarn build --watch" }, "dependencies": { - "@babel/cli": "^7.10.1", + "@babel/cli": "^7.10.5", "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "@kbn/ui-shared-deps": "1.0.0", diff --git a/packages/kbn-plugin-helpers/package.json b/packages/kbn-plugin-helpers/package.json index f370265876df3..45582ad2af97a 100644 --- a/packages/kbn-plugin-helpers/package.json +++ b/packages/kbn-plugin-helpers/package.json @@ -12,7 +12,7 @@ "plugin-helpers": "bin/plugin-helpers.js" }, "dependencies": { - "@babel/core": "^7.10.2", + "@babel/core": "^7.11.1", "argv-split": "^2.0.1", "commander": "^3.0.0", "del": "^5.1.0", diff --git a/packages/kbn-pm/package.json b/packages/kbn-pm/package.json index 188db0a8321a2..3e40bf40222e6 100644 --- a/packages/kbn-pm/package.json +++ b/packages/kbn-pm/package.json @@ -10,11 +10,11 @@ "prettier": "prettier --write './src/**/*.ts'" }, "devDependencies": { - "@babel/core": "^7.10.2", - "@babel/plugin-proposal-class-properties": "^7.10.1", - "@babel/plugin-proposal-object-rest-spread": "^7.10.1", - "@babel/preset-env": "^7.10.2", - "@babel/preset-typescript": "^7.10.1", + "@babel/core": "^7.11.1", + "@babel/plugin-proposal-class-properties": "^7.10.4", + "@babel/plugin-proposal-object-rest-spread": "^7.11.0", + "@babel/preset-env": "^7.11.0", + "@babel/preset-typescript": "^7.10.4", "@types/cmd-shim": "^2.0.0", "@types/cpy": "^5.1.0", "@types/dedent": "^0.7.0", diff --git a/packages/kbn-test/package.json b/packages/kbn-test/package.json index 38e4668fc1e42..9482ea83cc257 100644 --- a/packages/kbn-test/package.json +++ b/packages/kbn-test/package.json @@ -10,7 +10,7 @@ "kbn:watch": "yarn build --watch" }, "devDependencies": { - "@babel/cli": "^7.10.1", + "@babel/cli": "^7.10.5", "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "@types/joi": "^13.4.2", diff --git a/packages/kbn-ui-framework/package.json b/packages/kbn-ui-framework/package.json index 7933ce06d6847..a095d9ac2a77f 100644 --- a/packages/kbn-ui-framework/package.json +++ b/packages/kbn-ui-framework/package.json @@ -30,7 +30,7 @@ "enzyme-adapter-react-16": "^1.9.1" }, "devDependencies": { - "@babel/core": "^7.10.2", + "@babel/core": "^7.11.1", "@elastic/eui": "0.0.55", "@kbn/babel-preset": "1.0.0", "@kbn/optimizer": "1.0.0", diff --git a/x-pack/package.json b/x-pack/package.json index dcba01a771fd5..8fbb94c97c143 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -199,9 +199,9 @@ "yargs": "4.8.1" }, "dependencies": { - "@babel/core": "^7.10.2", - "@babel/register": "^7.10.1", - "@babel/runtime": "^7.10.2", + "@babel/core": "^7.11.1", + "@babel/register": "^7.10.5", + "@babel/runtime": "^7.11.2", "@elastic/apm-rum-react": "^1.1.2", "@elastic/datemath": "5.0.3", "@elastic/ems-client": "7.9.3", diff --git a/yarn.lock b/yarn.lock index f17418f07c5cc..33083667a3c5e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,16 +2,16 @@ # yarn lockfile v1 -"@babel/cli@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.10.1.tgz#b6e5cd43a17b8f639442ab027976408ebe6d79a0" - integrity sha512-cVB+dXeGhMOqViIaZs3A9OUAe4pKw4SBNdMw6yHJMYR7s4TB+Cei7ThquV/84O19PdIFWuwe03vxxES0BHUm5g== +"@babel/cli@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.10.5.tgz#57df2987c8cf89d0fc7d4b157ec59d7619f1b77a" + integrity sha512-j9H9qSf3kLdM0Ao3aGPbGZ73mEA9XazuupcS6cDGWuiyAcANoguhP0r2Lx32H5JGw4sSSoHG3x/mxVnHgvOoyA== dependencies: commander "^4.0.1" convert-source-map "^1.1.0" fs-readdir-recursive "^1.1.0" glob "^7.0.0" - lodash "^4.17.13" + lodash "^4.17.19" make-dir "^2.1.0" slash "^2.0.0" source-map "^0.5.0" @@ -32,17 +32,17 @@ dependencies: "@babel/highlight" "^7.8.3" -"@babel/code-frame@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.1.tgz#d5481c5095daa1c57e16e54c6f9198443afb49ff" - integrity sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw== +"@babel/code-frame@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== dependencies: - "@babel/highlight" "^7.10.1" + "@babel/highlight" "^7.10.4" -"@babel/compat-data@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.1.tgz#b1085ffe72cd17bf2c0ee790fc09f9626011b2db" - integrity sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw== +"@babel/compat-data@^7.10.4", "@babel/compat-data@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c" + integrity sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ== dependencies: browserslist "^4.12.0" invariant "^2.2.4" @@ -79,24 +79,24 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.10.2": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.2.tgz#bd6786046668a925ac2bd2fd95b579b92a23b36a" - integrity sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ== - dependencies: - "@babel/code-frame" "^7.10.1" - "@babel/generator" "^7.10.2" - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helpers" "^7.10.1" - "@babel/parser" "^7.10.2" - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.2" +"@babel/core@^7.11.1": + version "7.11.1" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.1.tgz#2c55b604e73a40dc21b0e52650b11c65cf276643" + integrity sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.0" + "@babel/helper-module-transforms" "^7.11.0" + "@babel/helpers" "^7.10.4" + "@babel/parser" "^7.11.1" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.11.0" + "@babel/types" "^7.11.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" json5 "^2.1.2" - lodash "^4.17.13" + lodash "^4.17.19" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" @@ -111,14 +111,13 @@ lodash "^4.17.13" source-map "^0.5.0" -"@babel/generator@^7.10.1", "@babel/generator@^7.10.2": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.2.tgz#0fa5b5b2389db8bfdfcc3492b551ee20f5dd69a9" - integrity sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA== +"@babel/generator@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.0.tgz#4b90c78d8c12825024568cbe83ee6c9af193585c" + integrity sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ== dependencies: - "@babel/types" "^7.10.2" + "@babel/types" "^7.11.0" jsesc "^2.5.1" - lodash "^4.17.13" source-map "^0.5.0" "@babel/generator@^7.9.5": @@ -138,20 +137,20 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-annotate-as-pure@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz#f6d08acc6f70bbd59b436262553fb2e259a1a268" - integrity sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw== +"@babel/helper-annotate-as-pure@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" + integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.4" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz#0ec7d9be8174934532661f87783eb18d72290059" - integrity sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" + integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-explode-assignable-expression" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/helper-builder-binary-assignment-operator-visitor@^7.8.3": version "7.8.3" @@ -161,14 +160,14 @@ "@babel/helper-explode-assignable-expression" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-builder-react-jsx-experimental@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.1.tgz#9a7d58ad184d3ac3bafb1a452cec2bad7e4a0bc8" - integrity sha512-irQJ8kpQUV3JasXPSFQ+LCCtJSc5ceZrPFVj6TElR6XCHssi3jV8ch3odIrNtjJFRZZVbrOEfJMI79TPU/h1pQ== +"@babel/helper-builder-react-jsx-experimental@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.5.tgz#f35e956a19955ff08c1258e44a515a6d6248646b" + integrity sha512-Buewnx6M4ttG+NLkKyt7baQn7ScC/Td+e99G914fRU8fGIUivDDgVIQeDHFa5e4CRSJQt58WpNHhsAZgtzVhsg== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-module-imports" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/types" "^7.10.5" "@babel/helper-builder-react-jsx-experimental@^7.9.0": version "7.9.0" @@ -179,13 +178,13 @@ "@babel/helper-module-imports" "^7.8.3" "@babel/types" "^7.9.0" -"@babel/helper-builder-react-jsx@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.1.tgz#a327f0cf983af5554701b1215de54a019f09b532" - integrity sha512-KXzzpyWhXgzjXIlJU1ZjIXzUPdej1suE6vzqgImZ/cpAsR/CC8gUcX4EWRmDfWz/cs6HOCPMBIJ3nKoXt3BFuw== +"@babel/helper-builder-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz#8095cddbff858e6fa9c326daee54a2f2732c1d5d" + integrity sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/helper-builder-react-jsx@^7.9.0": version "7.9.0" @@ -195,12 +194,12 @@ "@babel/helper-annotate-as-pure" "^7.8.3" "@babel/types" "^7.9.0" -"@babel/helper-compilation-targets@^7.10.2": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz#a17d9723b6e2c750299d2a14d4637c76936d8285" - integrity sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA== +"@babel/helper-compilation-targets@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" + integrity sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ== dependencies: - "@babel/compat-data" "^7.10.1" + "@babel/compat-data" "^7.10.4" browserslist "^4.12.0" invariant "^2.2.4" levenary "^1.1.1" @@ -217,17 +216,17 @@ levenary "^1.1.1" semver "^5.5.0" -"@babel/helper-create-class-features-plugin@^7.10.1": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz#7474295770f217dbcf288bf7572eb213db46ee67" - integrity sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ== +"@babel/helper-create-class-features-plugin@^7.10.4", "@babel/helper-create-class-features-plugin@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" + integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/helper-member-expression-to-functions" "^7.10.1" - "@babel/helper-optimise-call-expression" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-replace-supers" "^7.10.1" - "@babel/helper-split-export-declaration" "^7.10.1" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.10.5" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" "@babel/helper-create-class-features-plugin@^7.8.3": version "7.8.6" @@ -241,13 +240,13 @@ "@babel/helper-replace-supers" "^7.8.6" "@babel/helper-split-export-declaration" "^7.8.3" -"@babel/helper-create-regexp-features-plugin@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz#1b8feeab1594cbcfbf3ab5a3bbcabac0468efdbd" - integrity sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA== +"@babel/helper-create-regexp-features-plugin@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" + integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-regex" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-regex" "^7.10.4" regexpu-core "^4.7.0" "@babel/helper-create-regexp-features-plugin@^7.8.3", "@babel/helper-create-regexp-features-plugin@^7.8.8": @@ -259,14 +258,14 @@ "@babel/helper-regex" "^7.8.3" regexpu-core "^4.7.0" -"@babel/helper-define-map@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz#5e69ee8308648470dd7900d159c044c10285221d" - integrity sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg== +"@babel/helper-define-map@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" + integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/types" "^7.10.1" - lodash "^4.17.13" + "@babel/helper-function-name" "^7.10.4" + "@babel/types" "^7.10.5" + lodash "^4.17.19" "@babel/helper-define-map@^7.8.3": version "7.8.3" @@ -277,13 +276,13 @@ "@babel/types" "^7.8.3" lodash "^4.17.13" -"@babel/helper-explode-assignable-expression@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz#e9d76305ee1162ca467357ae25df94f179af2b7e" - integrity sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg== +"@babel/helper-explode-assignable-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz#40a1cd917bff1288f699a94a75b37a1a2dbd8c7c" + integrity sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A== dependencies: - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/helper-explode-assignable-expression@^7.8.3": version "7.8.3" @@ -293,14 +292,14 @@ "@babel/traverse" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-function-name@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz#92bd63829bfc9215aca9d9defa85f56b539454f4" - integrity sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ== +"@babel/helper-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" + integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== dependencies: - "@babel/helper-get-function-arity" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/helper-function-name@^7.8.3": version "7.8.3" @@ -320,12 +319,12 @@ "@babel/template" "^7.8.3" "@babel/types" "^7.9.5" -"@babel/helper-get-function-arity@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz#7303390a81ba7cb59613895a192b93850e373f7d" - integrity sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw== +"@babel/helper-get-function-arity@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" + integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.4" "@babel/helper-get-function-arity@^7.8.3": version "7.8.3" @@ -334,12 +333,12 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-hoist-variables@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz#7e77c82e5dcae1ebf123174c385aaadbf787d077" - integrity sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg== +"@babel/helper-hoist-variables@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" + integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.4" "@babel/helper-hoist-variables@^7.8.3": version "7.8.3" @@ -348,12 +347,12 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-member-expression-to-functions@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz#432967fd7e12a4afef66c4687d4ca22bc0456f15" - integrity sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g== +"@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" + integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.11.0" "@babel/helper-member-expression-to-functions@^7.8.3": version "7.8.3" @@ -369,25 +368,25 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-module-imports@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz#dd331bd45bccc566ce77004e9d05fe17add13876" - integrity sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg== +"@babel/helper-module-imports@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" + integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.4" -"@babel/helper-module-transforms@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz#24e2f08ee6832c60b157bb0936c86bef7210c622" - integrity sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg== +"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" + integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== dependencies: - "@babel/helper-module-imports" "^7.10.1" - "@babel/helper-replace-supers" "^7.10.1" - "@babel/helper-simple-access" "^7.10.1" - "@babel/helper-split-export-declaration" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/types" "^7.10.1" - lodash "^4.17.13" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/template" "^7.10.4" + "@babel/types" "^7.11.0" + lodash "^4.17.19" "@babel/helper-module-transforms@^7.9.0": version "7.9.0" @@ -402,12 +401,12 @@ "@babel/types" "^7.9.0" lodash "^4.17.13" -"@babel/helper-optimise-call-expression@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz#b4a1f2561870ce1247ceddb02a3860fa96d72543" - integrity sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg== +"@babel/helper-optimise-call-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" + integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.4" "@babel/helper-optimise-call-expression@^7.8.3": version "7.8.3" @@ -421,17 +420,17 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== -"@babel/helper-plugin-utils@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz#ec5a5cf0eec925b66c60580328b122c01230a127" - integrity sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA== +"@babel/helper-plugin-utils@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== -"@babel/helper-regex@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.1.tgz#021cf1a7ba99822f993222a001cc3fec83255b96" - integrity sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g== +"@babel/helper-regex@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0" + integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg== dependencies: - lodash "^4.17.13" + lodash "^4.17.19" "@babel/helper-regex@^7.8.3": version "7.8.3" @@ -440,16 +439,16 @@ dependencies: lodash "^4.17.13" -"@babel/helper-remap-async-to-generator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz#bad6aaa4ff39ce8d4b82ccaae0bfe0f7dbb5f432" - integrity sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A== +"@babel/helper-remap-async-to-generator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz#fce8bea4e9690bbe923056ded21e54b4e8b68ed5" + integrity sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-wrap-function" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-wrap-function" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/helper-remap-async-to-generator@^7.8.3": version "7.8.3" @@ -462,15 +461,15 @@ "@babel/traverse" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-replace-supers@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz#ec6859d20c5d8087f6a2dc4e014db7228975f13d" - integrity sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A== +"@babel/helper-replace-supers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" + integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.1" - "@babel/helper-optimise-call-expression" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-member-expression-to-functions" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/helper-replace-supers@^7.8.3", "@babel/helper-replace-supers@^7.8.6": version "7.8.6" @@ -482,13 +481,13 @@ "@babel/traverse" "^7.8.6" "@babel/types" "^7.8.6" -"@babel/helper-simple-access@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz#08fb7e22ace9eb8326f7e3920a1c2052f13d851e" - integrity sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw== +"@babel/helper-simple-access@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" + integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== dependencies: - "@babel/template" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/helper-simple-access@^7.8.3": version "7.8.3" @@ -498,12 +497,19 @@ "@babel/template" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-split-export-declaration@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz#c6f4be1cbc15e3a868e4c64a17d5d31d754da35f" - integrity sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g== +"@babel/helper-skip-transparent-expression-wrappers@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" + integrity sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" + integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.11.0" "@babel/helper-split-export-declaration@^7.8.3": version "7.8.3" @@ -512,10 +518,10 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-validator-identifier@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz#5770b0c1a826c4f53f5ede5e153163e0318e94b5" - integrity sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw== +"@babel/helper-validator-identifier@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" + integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== "@babel/helper-validator-identifier@^7.9.0": version "7.9.0" @@ -527,15 +533,15 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== -"@babel/helper-wrap-function@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz#956d1310d6696257a7afd47e4c42dfda5dfcedc9" - integrity sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ== +"@babel/helper-wrap-function@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" + integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-function-name" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/helper-wrap-function@^7.8.3": version "7.8.3" @@ -547,14 +553,14 @@ "@babel/traverse" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helpers@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.1.tgz#a6827b7cb975c9d9cef5fd61d919f60d8844a973" - integrity sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw== +"@babel/helpers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" + integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== dependencies: - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/helpers@^7.9.0": version "7.9.2" @@ -574,12 +580,12 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/highlight@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.1.tgz#841d098ba613ba1a427a2b383d79e35552c38ae0" - integrity sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg== +"@babel/highlight@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== dependencies: - "@babel/helper-validator-identifier" "^7.10.1" + "@babel/helper-validator-identifier" "^7.10.4" chalk "^2.0.0" js-tokens "^4.0.0" @@ -588,18 +594,18 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== -"@babel/parser@^7.10.1", "@babel/parser@^7.10.2": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.2.tgz#871807f10442b92ff97e4783b9b54f6a0ca812d0" - integrity sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ== +"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1", "@babel/parser@^7.11.2": + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.2.tgz#0882ab8a455df3065ea2dcb4c753b2460a24bead" + integrity sha512-Vuj/+7vLo6l1Vi7uuO+1ngCDNeVmNbTngcJFKCR/oEtz8tKz0CJxZEGmPt9KcIloZhOZ3Zit6xbpXT2MDlS9Vw== -"@babel/plugin-proposal-async-generator-functions@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz#6911af5ba2e615c4ff3c497fe2f47b35bf6d7e55" - integrity sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw== +"@babel/plugin-proposal-async-generator-functions@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" + integrity sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-remap-async-to-generator" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" "@babel/plugin-syntax-async-generators" "^7.8.0" "@babel/plugin-proposal-async-generator-functions@^7.8.3": @@ -611,13 +617,13 @@ "@babel/helper-remap-async-to-generator" "^7.8.3" "@babel/plugin-syntax-async-generators" "^7.8.0" -"@babel/plugin-proposal-class-properties@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz#046bc7f6550bb08d9bd1d4f060f5f5a4f1087e01" - integrity sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw== +"@babel/plugin-proposal-class-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" + integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-proposal-class-properties@^7.7.0": version "7.8.3" @@ -627,12 +633,12 @@ "@babel/helper-create-class-features-plugin" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-proposal-dynamic-import@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz#e36979dc1dc3b73f6d6816fc4951da2363488ef0" - integrity sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA== +"@babel/plugin-proposal-dynamic-import@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" + integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-dynamic-import" "^7.8.0" "@babel/plugin-proposal-dynamic-import@^7.8.3": @@ -643,20 +649,20 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-dynamic-import" "^7.8.0" -"@babel/plugin-proposal-export-namespace-from@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.1.tgz#512ee069cd866256600bdf89639cf7e1b51fbfe9" - integrity sha512-eR4CoYb6mh5y9LWjnb4CyUatuhtZ8pNLXLDi46GkqtF7WPafFqXycHdvF5qWviozZVGRSAmHzdayc8wUReCdjA== +"@babel/plugin-proposal-export-namespace-from@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz#570d883b91031637b3e2958eea3c438e62c05f54" + integrity sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz#b1e691ee24c651b5a5e32213222b2379734aff09" - integrity sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg== +"@babel/plugin-proposal-json-strings@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" + integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.0" "@babel/plugin-proposal-json-strings@^7.8.3": @@ -667,12 +673,20 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-json-strings" "^7.8.0" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz#02dca21673842ff2fe763ac253777f235e9bbf78" - integrity sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA== +"@babel/plugin-proposal-logical-assignment-operators@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz#9f80e482c03083c87125dee10026b58527ea20c8" + integrity sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" + integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" "@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3": @@ -683,13 +697,13 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/plugin-proposal-numeric-separator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz#a9a38bc34f78bdfd981e791c27c6fdcec478c123" - integrity sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA== +"@babel/plugin-proposal-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz#ce1590ff0a65ad12970a609d78855e9a4c1aef06" + integrity sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-numeric-separator" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-proposal-numeric-separator@^7.8.3": version "7.8.3" @@ -699,14 +713,14 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-numeric-separator" "^7.8.3" -"@babel/plugin-proposal-object-rest-spread@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz#cba44908ac9f142650b4a65b8aa06bf3478d5fb6" - integrity sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ== +"@babel/plugin-proposal-object-rest-spread@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz#bd81f95a1f746760ea43b6c2d3d62b11790ad0af" + integrity sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.10.1" + "@babel/plugin-transform-parameters" "^7.10.4" "@babel/plugin-proposal-object-rest-spread@^7.6.2", "@babel/plugin-proposal-object-rest-spread@^7.9.0": version "7.9.0" @@ -716,12 +730,12 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" -"@babel/plugin-proposal-optional-catch-binding@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz#c9f86d99305f9fa531b568ff5ab8c964b8b223d2" - integrity sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA== +"@babel/plugin-proposal-optional-catch-binding@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" + integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" "@babel/plugin-proposal-optional-catch-binding@^7.8.3": @@ -732,12 +746,13 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz#15f5d6d22708629451a91be28f8facc55b0e818c" - integrity sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA== +"@babel/plugin-proposal-optional-chaining@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz#de5866d0646f6afdaab8a566382fe3a221755076" + integrity sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" "@babel/plugin-syntax-optional-chaining" "^7.8.0" "@babel/plugin-proposal-optional-chaining@^7.9.0": @@ -748,21 +763,21 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-private-methods@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz#ed85e8058ab0fe309c3f448e5e1b73ca89cdb598" - integrity sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg== +"@babel/plugin-proposal-private-methods@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" + integrity sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-unicode-property-regex@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz#dc04feb25e2dd70c12b05d680190e138fa2c0c6f" - integrity sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ== +"@babel/plugin-proposal-unicode-property-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" + integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.8.3": version "7.8.8" @@ -786,12 +801,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz#d5bc0645913df5b17ad7eda0fa2308330bde34c5" - integrity sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ== +"@babel/plugin-syntax-class-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz#6644e6a0baa55a61f9e3231f6c9eeb6ee46c124c" + integrity sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-class-properties@^7.8.3": version "7.8.3" @@ -828,12 +843,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.1.tgz#0ae371134a42b91d5418feb3c8c8d43e1565d2da" - integrity sha512-+OxyOArpVFXQeXKLO9o+r2I4dIoVoy6+Uu0vKELrlweDM3QJADZj+Z+5ERansZqIZBcLj42vHnDI8Rz9BnRIuQ== +"@babel/plugin-syntax-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz#39abaae3cbf710c4373d8429484e6ba21340166c" + integrity sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-jsx@^7.8.3": version "7.8.3" @@ -842,6 +857,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz#3995d7d7ffff432f6ddc742b47e730c054599897" @@ -856,12 +878,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz#25761ee7410bc8cf97327ba741ee94e4a61b7d99" - integrity sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg== +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-numeric-separator@^7.8.0", "@babel/plugin-syntax-numeric-separator@^7.8.3": version "7.8.3" @@ -891,12 +913,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz#8b8733f8c57397b3eaa47ddba8841586dcaef362" - integrity sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ== +"@babel/plugin-syntax-top-level-await@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz#4bbeb8917b54fcf768364e0a81f560e33a3ef57d" + integrity sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-top-level-await@^7.8.3": version "7.8.3" @@ -905,19 +927,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-typescript@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.10.1.tgz#5e82bc27bb4202b93b949b029e699db536733810" - integrity sha512-X/d8glkrAtra7CaQGMiGs/OGa6XgUzqPcBXCIGFCpCqnfGlT0Wfbzo/B89xHhnInTaItPK8LALblVXcUOEh95Q== +"@babel/plugin-syntax-typescript@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.10.4.tgz#2f55e770d3501e83af217d782cb7517d7bb34d25" + integrity sha512-oSAEz1YkBCAKr5Yiq8/BNtvSAPwkp/IyUnwZogd8p+F0RuYQQrLeRUzIQhueQTTBy/F+a40uS7OFKxnkRvmvFQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-arrow-functions@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz#cb5ee3a36f0863c06ead0b409b4cc43a889b295b" - integrity sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA== +"@babel/plugin-transform-arrow-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" + integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-arrow-functions@^7.8.3": version "7.8.3" @@ -926,14 +948,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-async-to-generator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz#e5153eb1a3e028f79194ed8a7a4bf55f862b2062" - integrity sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg== +"@babel/plugin-transform-async-to-generator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" + integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== dependencies: - "@babel/helper-module-imports" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-remap-async-to-generator" "^7.10.1" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" "@babel/plugin-transform-async-to-generator@^7.8.3": version "7.8.3" @@ -944,12 +966,12 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-remap-async-to-generator" "^7.8.3" -"@babel/plugin-transform-block-scoped-functions@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz#146856e756d54b20fff14b819456b3e01820b85d" - integrity sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q== +"@babel/plugin-transform-block-scoped-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" + integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-block-scoped-functions@^7.8.3": version "7.8.3" @@ -958,13 +980,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-block-scoping@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz#47092d89ca345811451cd0dc5d91605982705d5e" - integrity sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw== +"@babel/plugin-transform-block-scoping@^7.10.4": + version "7.11.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz#5b7efe98852bef8d652c0b28144cd93a9e4b5215" + integrity sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - lodash "^4.17.13" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-block-scoping@^7.8.3": version "7.8.3" @@ -974,18 +995,18 @@ "@babel/helper-plugin-utils" "^7.8.3" lodash "^4.17.13" -"@babel/plugin-transform-classes@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz#6e11dd6c4dfae70f540480a4702477ed766d733f" - integrity sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-define-map" "^7.10.1" - "@babel/helper-function-name" "^7.10.1" - "@babel/helper-optimise-call-expression" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-replace-supers" "^7.10.1" - "@babel/helper-split-export-declaration" "^7.10.1" +"@babel/plugin-transform-classes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" + integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-define-map" "^7.10.4" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" globals "^11.1.0" "@babel/plugin-transform-classes@^7.9.0": @@ -1002,12 +1023,12 @@ "@babel/helper-split-export-declaration" "^7.8.3" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz#59aa399064429d64dce5cf76ef9b90b7245ebd07" - integrity sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ== +"@babel/plugin-transform-computed-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" + integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-computed-properties@^7.8.3": version "7.8.3" @@ -1016,12 +1037,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-destructuring@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz#abd58e51337815ca3a22a336b85f62b998e71907" - integrity sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA== +"@babel/plugin-transform-destructuring@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" + integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-destructuring@^7.8.3": version "7.8.8" @@ -1030,13 +1051,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-dotall-regex@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz#920b9fec2d78bb57ebb64a644d5c2ba67cc104ee" - integrity sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA== +"@babel/plugin-transform-dotall-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" + integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.8.3": version "7.8.3" @@ -1046,12 +1067,12 @@ "@babel/helper-create-regexp-features-plugin" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-duplicate-keys@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz#c900a793beb096bc9d4d0a9d0cde19518ffc83b9" - integrity sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA== +"@babel/plugin-transform-duplicate-keys@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" + integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-duplicate-keys@^7.8.3": version "7.8.3" @@ -1060,13 +1081,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-exponentiation-operator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz#279c3116756a60dd6e6f5e488ba7957db9c59eb3" - integrity sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA== +"@babel/plugin-transform-exponentiation-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" + integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-exponentiation-operator@^7.8.3": version "7.8.3" @@ -1084,12 +1105,12 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-flow" "^7.8.3" -"@babel/plugin-transform-for-of@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz#ff01119784eb0ee32258e8646157ba2501fcfda5" - integrity sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w== +"@babel/plugin-transform-for-of@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" + integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-for-of@^7.9.0": version "7.9.0" @@ -1098,13 +1119,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-function-name@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz#4ed46fd6e1d8fde2a2ec7b03c66d853d2c92427d" - integrity sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw== +"@babel/plugin-transform-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" + integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-function-name@^7.8.3": version "7.8.3" @@ -1114,12 +1135,12 @@ "@babel/helper-function-name" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-literals@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz#5794f8da82846b22e4e6631ea1658bce708eb46a" - integrity sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw== +"@babel/plugin-transform-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" + integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-literals@^7.8.3": version "7.8.3" @@ -1128,12 +1149,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-member-expression-literals@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz#90347cba31bca6f394b3f7bd95d2bbfd9fce2f39" - integrity sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA== +"@babel/plugin-transform-member-expression-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" + integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-member-expression-literals@^7.8.3": version "7.8.3" @@ -1142,13 +1163,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-modules-amd@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz#65950e8e05797ebd2fe532b96e19fc5482a1d52a" - integrity sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw== +"@babel/plugin-transform-modules-amd@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" + integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== dependencies: - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-amd@^7.9.0": @@ -1160,14 +1181,14 @@ "@babel/helper-plugin-utils" "^7.8.3" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-commonjs@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz#d5ff4b4413ed97ffded99961056e1fb980fb9301" - integrity sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg== +"@babel/plugin-transform-modules-commonjs@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" + integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== dependencies: - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-simple-access" "^7.10.1" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-commonjs@^7.9.0": @@ -1180,14 +1201,14 @@ "@babel/helper-simple-access" "^7.8.3" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-systemjs@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz#9962e4b0ac6aaf2e20431ada3d8ec72082cbffb6" - integrity sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA== +"@babel/plugin-transform-modules-systemjs@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz#6270099c854066681bae9e05f87e1b9cadbe8c85" + integrity sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw== dependencies: - "@babel/helper-hoist-variables" "^7.10.1" - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-hoist-variables" "^7.10.4" + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-systemjs@^7.9.0": @@ -1200,13 +1221,13 @@ "@babel/helper-plugin-utils" "^7.8.3" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-umd@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz#ea080911ffc6eb21840a5197a39ede4ee67b1595" - integrity sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA== +"@babel/plugin-transform-modules-umd@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" + integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== dependencies: - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-modules-umd@^7.9.0": version "7.9.0" @@ -1216,6 +1237,13 @@ "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" +"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" + integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz#a2a72bffa202ac0e2d0506afd0939c5ecbc48c6c" @@ -1223,12 +1251,12 @@ dependencies: "@babel/helper-create-regexp-features-plugin" "^7.8.3" -"@babel/plugin-transform-new-target@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz#6ee41a5e648da7632e22b6fb54012e87f612f324" - integrity sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw== +"@babel/plugin-transform-new-target@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" + integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-new-target@^7.8.3": version "7.8.3" @@ -1237,13 +1265,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-object-super@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz#2e3016b0adbf262983bf0d5121d676a5ed9c4fde" - integrity sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw== +"@babel/plugin-transform-object-super@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" + integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-replace-supers" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" "@babel/plugin-transform-object-super@^7.8.3": version "7.8.3" @@ -1253,13 +1281,13 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-replace-supers" "^7.8.3" -"@babel/plugin-transform-parameters@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz#b25938a3c5fae0354144a720b07b32766f683ddd" - integrity sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg== +"@babel/plugin-transform-parameters@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz#59d339d58d0b1950435f4043e74e2510005e2c4a" + integrity sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw== dependencies: - "@babel/helper-get-function-arity" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-parameters@^7.8.7": version "7.9.3" @@ -1269,12 +1297,12 @@ "@babel/helper-get-function-arity" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-property-literals@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz#cffc7315219230ed81dc53e4625bf86815b6050d" - integrity sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA== +"@babel/plugin-transform-property-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" + integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-property-literals@^7.8.3": version "7.8.3" @@ -1290,12 +1318,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-react-display-name@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.1.tgz#e6a33f6d48dfb213dda5e007d0c7ff82b6a3d8ef" - integrity sha512-rBjKcVwjk26H3VX8pavMxGf33LNlbocMHdSeldIEswtQ/hrjyTG8fKKILW1cSkODyRovckN/uZlGb2+sAV9JUQ== +"@babel/plugin-transform-react-display-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.4.tgz#b5795f4e3e3140419c3611b7a2a3832b9aef328d" + integrity sha512-Zd4X54Mu9SBfPGnEcaGcOrVAYOtjT2on8QZkLKEq1S/tHexG39d9XXGZv19VfRrDjPJzFmPfTAqOQS1pfFOujw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-react-display-name@^7.8.3": version "7.8.3" @@ -1304,14 +1332,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-react-jsx-development@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.1.tgz#1ac6300d8b28ef381ee48e6fec430cc38047b7f3" - integrity sha512-XwDy/FFoCfw9wGFtdn5Z+dHh6HXKHkC6DwKNWpN74VWinUagZfDcEJc3Y8Dn5B3WMVnAllX8Kviaw7MtC5Epwg== +"@babel/plugin-transform-react-jsx-development@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.4.tgz#6ec90f244394604623880e15ebc3c34c356258ba" + integrity sha512-RM3ZAd1sU1iQ7rI2dhrZRZGv0aqzNQMbkIUCS1txYpi9wHQ2ZHNjo5TwX+UD6pvFW4AbWqLVYvKy5qJSAyRGjQ== dependencies: - "@babel/helper-builder-react-jsx-experimental" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-jsx" "^7.10.1" + "@babel/helper-builder-react-jsx-experimental" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" "@babel/plugin-transform-react-jsx-development@^7.9.0": version "7.9.0" @@ -1322,13 +1350,13 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-jsx" "^7.8.3" -"@babel/plugin-transform-react-jsx-self@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.1.tgz#22143e14388d72eb88649606bb9e46f421bc3821" - integrity sha512-4p+RBw9d1qV4S749J42ZooeQaBomFPrSxa9JONLHJ1TxCBo3TzJ79vtmG2S2erUT8PDDrPdw4ZbXGr2/1+dILA== +"@babel/plugin-transform-react-jsx-self@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.4.tgz#cd301a5fed8988c182ed0b9d55e9bd6db0bd9369" + integrity sha512-yOvxY2pDiVJi0axdTWHSMi5T0DILN+H+SaeJeACHKjQLezEzhLx9nEF9xgpBLPtkZsks9cnb5P9iBEi21En3gg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-jsx" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" "@babel/plugin-transform-react-jsx-self@^7.9.0": version "7.9.0" @@ -1338,13 +1366,13 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-jsx" "^7.8.3" -"@babel/plugin-transform-react-jsx-source@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.1.tgz#30db3d4ee3cdebbb26a82a9703673714777a4273" - integrity sha512-neAbaKkoiL+LXYbGDvh6PjPG+YeA67OsZlE78u50xbWh2L1/C81uHiNP5d1fw+uqUIoiNdCC8ZB+G4Zh3hShJA== +"@babel/plugin-transform-react-jsx-source@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.5.tgz#34f1779117520a779c054f2cdd9680435b9222b4" + integrity sha512-wTeqHVkN1lfPLubRiZH3o73f4rfon42HpgxUSs86Nc+8QIcm/B9s8NNVXu/gwGcOyd7yDib9ikxoDLxJP0UiDA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-jsx" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" "@babel/plugin-transform-react-jsx-source@^7.9.0": version "7.9.0" @@ -1354,15 +1382,15 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-jsx" "^7.8.3" -"@babel/plugin-transform-react-jsx@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.1.tgz#91f544248ba131486decb5d9806da6a6e19a2896" - integrity sha512-MBVworWiSRBap3Vs39eHt+6pJuLUAaK4oxGc8g+wY+vuSJvLiEQjW1LSTqKb8OUPtDvHCkdPhk7d6sjC19xyFw== +"@babel/plugin-transform-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz#673c9f913948764a4421683b2bef2936968fddf2" + integrity sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A== dependencies: - "@babel/helper-builder-react-jsx" "^7.10.1" - "@babel/helper-builder-react-jsx-experimental" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-jsx" "^7.10.1" + "@babel/helper-builder-react-jsx" "^7.10.4" + "@babel/helper-builder-react-jsx-experimental" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" "@babel/plugin-transform-react-jsx@^7.9.4": version "7.9.4" @@ -1374,18 +1402,18 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-jsx" "^7.8.3" -"@babel/plugin-transform-react-pure-annotations@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.1.tgz#f5e7c755d3e7614d4c926e144f501648a5277b70" - integrity sha512-mfhoiai083AkeewsBHUpaS/FM1dmUENHBMpS/tugSJ7VXqXO5dCN1Gkint2YvM1Cdv1uhmAKt1ZOuAjceKmlLA== +"@babel/plugin-transform-react-pure-annotations@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.4.tgz#3eefbb73db94afbc075f097523e445354a1c6501" + integrity sha512-+njZkqcOuS8RaPakrnR9KvxjoG1ASJWpoIv/doyWngId88JoFlPlISenGXjrVacZUIALGUr6eodRs1vmPnF23A== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-regenerator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz#10e175cbe7bdb63cc9b39f9b3f823c5c7c5c5490" - integrity sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw== +"@babel/plugin-transform-regenerator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" + integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== dependencies: regenerator-transform "^0.14.2" @@ -1396,12 +1424,12 @@ dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz#0fc1027312b4d1c3276a57890c8ae3bcc0b64a86" - integrity sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ== +"@babel/plugin-transform-reserved-words@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" + integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-reserved-words@^7.8.3": version "7.8.3" @@ -1410,22 +1438,22 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-runtime@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.1.tgz#fd1887f749637fb2ed86dc278e79eb41df37f4b1" - integrity sha512-4w2tcglDVEwXJ5qxsY++DgWQdNJcCCsPxfT34wCUwIf2E7dI7pMpH8JczkMBbgBTNzBX62SZlNJ9H+De6Zebaw== +"@babel/plugin-transform-runtime@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.0.tgz#e27f78eb36f19448636e05c33c90fd9ad9b8bccf" + integrity sha512-LFEsP+t3wkYBlis8w6/kmnd6Kb1dxTd+wGJ8MlxTGzQo//ehtqlVL4S9DNUa53+dtPSQobN2CXx4d81FqC58cw== dependencies: - "@babel/helper-module-imports" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" resolve "^1.8.1" semver "^5.5.1" -"@babel/plugin-transform-shorthand-properties@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz#e8b54f238a1ccbae482c4dce946180ae7b3143f3" - integrity sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g== +"@babel/plugin-transform-shorthand-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" + integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-shorthand-properties@^7.8.3": version "7.8.3" @@ -1434,12 +1462,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-spread@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz#0c6d618a0c4461a274418460a28c9ccf5239a7c8" - integrity sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw== +"@babel/plugin-transform-spread@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz#fa84d300f5e4f57752fe41a6d1b3c554f13f17cc" + integrity sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" "@babel/plugin-transform-spread@^7.8.3": version "7.8.3" @@ -1448,13 +1477,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-sticky-regex@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz#90fc89b7526228bed9842cff3588270a7a393b00" - integrity sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA== +"@babel/plugin-transform-sticky-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" + integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-regex" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-regex" "^7.10.4" "@babel/plugin-transform-sticky-regex@^7.8.3": version "7.8.3" @@ -1464,13 +1493,13 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-regex" "^7.8.3" -"@babel/plugin-transform-template-literals@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz#914c7b7f4752c570ea00553b4284dad8070e8628" - integrity sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg== +"@babel/plugin-transform-template-literals@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz#78bc5d626a6642db3312d9d0f001f5e7639fde8c" + integrity sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-template-literals@^7.8.3": version "7.8.3" @@ -1480,12 +1509,12 @@ "@babel/helper-annotate-as-pure" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-typeof-symbol@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz#60c0239b69965d166b80a84de7315c1bc7e0bb0e" - integrity sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g== +"@babel/plugin-transform-typeof-symbol@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" + integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-typeof-symbol@^7.8.4": version "7.8.4" @@ -1494,29 +1523,29 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-typescript@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.10.1.tgz#2c54daea231f602468686d9faa76f182a94507a6" - integrity sha512-v+QWKlmCnsaimLeqq9vyCsVRMViZG1k2SZTlcZvB+TqyH570Zsij8nvVUZzOASCRiQFUxkLrn9Wg/kH0zgy5OQ== +"@babel/plugin-transform-typescript@^7.10.4": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.11.0.tgz#2b4879676af37342ebb278216dd090ac67f13abb" + integrity sha512-edJsNzTtvb3MaXQwj8403B7mZoGu9ElDJQZOKjGUnvilquxBA3IQoEIOvkX/1O8xfAsnHS/oQhe2w/IXrr+w0w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-typescript" "^7.10.1" + "@babel/helper-create-class-features-plugin" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-typescript" "^7.10.4" -"@babel/plugin-transform-unicode-escapes@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz#add0f8483dab60570d9e03cecef6c023aa8c9940" - integrity sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw== +"@babel/plugin-transform-unicode-escapes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" + integrity sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-unicode-regex@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz#6b58f2aea7b68df37ac5025d9c88752443a6b43f" - integrity sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw== +"@babel/plugin-transform-unicode-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" + integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-unicode-regex@^7.8.3": version "7.8.3" @@ -1592,70 +1621,74 @@ levenary "^1.1.1" semver "^5.5.0" -"@babel/preset-env@^7.10.2": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.2.tgz#715930f2cf8573b0928005ee562bed52fb65fdfb" - integrity sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA== - dependencies: - "@babel/compat-data" "^7.10.1" - "@babel/helper-compilation-targets" "^7.10.2" - "@babel/helper-module-imports" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-proposal-async-generator-functions" "^7.10.1" - "@babel/plugin-proposal-class-properties" "^7.10.1" - "@babel/plugin-proposal-dynamic-import" "^7.10.1" - "@babel/plugin-proposal-json-strings" "^7.10.1" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.1" - "@babel/plugin-proposal-numeric-separator" "^7.10.1" - "@babel/plugin-proposal-object-rest-spread" "^7.10.1" - "@babel/plugin-proposal-optional-catch-binding" "^7.10.1" - "@babel/plugin-proposal-optional-chaining" "^7.10.1" - "@babel/plugin-proposal-private-methods" "^7.10.1" - "@babel/plugin-proposal-unicode-property-regex" "^7.10.1" +"@babel/preset-env@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.0.tgz#860ee38f2ce17ad60480c2021ba9689393efb796" + integrity sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg== + dependencies: + "@babel/compat-data" "^7.11.0" + "@babel/helper-compilation-targets" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-proposal-async-generator-functions" "^7.10.4" + "@babel/plugin-proposal-class-properties" "^7.10.4" + "@babel/plugin-proposal-dynamic-import" "^7.10.4" + "@babel/plugin-proposal-export-namespace-from" "^7.10.4" + "@babel/plugin-proposal-json-strings" "^7.10.4" + "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" + "@babel/plugin-proposal-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-object-rest-spread" "^7.11.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" + "@babel/plugin-proposal-optional-chaining" "^7.11.0" + "@babel/plugin-proposal-private-methods" "^7.10.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.10.1" + "@babel/plugin-syntax-class-properties" "^7.10.4" "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - "@babel/plugin-syntax-numeric-separator" "^7.10.1" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.10.1" - "@babel/plugin-transform-arrow-functions" "^7.10.1" - "@babel/plugin-transform-async-to-generator" "^7.10.1" - "@babel/plugin-transform-block-scoped-functions" "^7.10.1" - "@babel/plugin-transform-block-scoping" "^7.10.1" - "@babel/plugin-transform-classes" "^7.10.1" - "@babel/plugin-transform-computed-properties" "^7.10.1" - "@babel/plugin-transform-destructuring" "^7.10.1" - "@babel/plugin-transform-dotall-regex" "^7.10.1" - "@babel/plugin-transform-duplicate-keys" "^7.10.1" - "@babel/plugin-transform-exponentiation-operator" "^7.10.1" - "@babel/plugin-transform-for-of" "^7.10.1" - "@babel/plugin-transform-function-name" "^7.10.1" - "@babel/plugin-transform-literals" "^7.10.1" - "@babel/plugin-transform-member-expression-literals" "^7.10.1" - "@babel/plugin-transform-modules-amd" "^7.10.1" - "@babel/plugin-transform-modules-commonjs" "^7.10.1" - "@babel/plugin-transform-modules-systemjs" "^7.10.1" - "@babel/plugin-transform-modules-umd" "^7.10.1" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3" - "@babel/plugin-transform-new-target" "^7.10.1" - "@babel/plugin-transform-object-super" "^7.10.1" - "@babel/plugin-transform-parameters" "^7.10.1" - "@babel/plugin-transform-property-literals" "^7.10.1" - "@babel/plugin-transform-regenerator" "^7.10.1" - "@babel/plugin-transform-reserved-words" "^7.10.1" - "@babel/plugin-transform-shorthand-properties" "^7.10.1" - "@babel/plugin-transform-spread" "^7.10.1" - "@babel/plugin-transform-sticky-regex" "^7.10.1" - "@babel/plugin-transform-template-literals" "^7.10.1" - "@babel/plugin-transform-typeof-symbol" "^7.10.1" - "@babel/plugin-transform-unicode-escapes" "^7.10.1" - "@babel/plugin-transform-unicode-regex" "^7.10.1" + "@babel/plugin-syntax-top-level-await" "^7.10.4" + "@babel/plugin-transform-arrow-functions" "^7.10.4" + "@babel/plugin-transform-async-to-generator" "^7.10.4" + "@babel/plugin-transform-block-scoped-functions" "^7.10.4" + "@babel/plugin-transform-block-scoping" "^7.10.4" + "@babel/plugin-transform-classes" "^7.10.4" + "@babel/plugin-transform-computed-properties" "^7.10.4" + "@babel/plugin-transform-destructuring" "^7.10.4" + "@babel/plugin-transform-dotall-regex" "^7.10.4" + "@babel/plugin-transform-duplicate-keys" "^7.10.4" + "@babel/plugin-transform-exponentiation-operator" "^7.10.4" + "@babel/plugin-transform-for-of" "^7.10.4" + "@babel/plugin-transform-function-name" "^7.10.4" + "@babel/plugin-transform-literals" "^7.10.4" + "@babel/plugin-transform-member-expression-literals" "^7.10.4" + "@babel/plugin-transform-modules-amd" "^7.10.4" + "@babel/plugin-transform-modules-commonjs" "^7.10.4" + "@babel/plugin-transform-modules-systemjs" "^7.10.4" + "@babel/plugin-transform-modules-umd" "^7.10.4" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" + "@babel/plugin-transform-new-target" "^7.10.4" + "@babel/plugin-transform-object-super" "^7.10.4" + "@babel/plugin-transform-parameters" "^7.10.4" + "@babel/plugin-transform-property-literals" "^7.10.4" + "@babel/plugin-transform-regenerator" "^7.10.4" + "@babel/plugin-transform-reserved-words" "^7.10.4" + "@babel/plugin-transform-shorthand-properties" "^7.10.4" + "@babel/plugin-transform-spread" "^7.11.0" + "@babel/plugin-transform-sticky-regex" "^7.10.4" + "@babel/plugin-transform-template-literals" "^7.10.4" + "@babel/plugin-transform-typeof-symbol" "^7.10.4" + "@babel/plugin-transform-unicode-escapes" "^7.10.4" + "@babel/plugin-transform-unicode-regex" "^7.10.4" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.10.2" + "@babel/types" "^7.11.0" browserslist "^4.12.0" core-js-compat "^3.6.2" invariant "^2.2.2" @@ -1693,34 +1726,34 @@ "@babel/plugin-transform-react-jsx-self" "^7.9.0" "@babel/plugin-transform-react-jsx-source" "^7.9.0" -"@babel/preset-react@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.10.1.tgz#e2ab8ae9a363ec307b936589f07ed753192de041" - integrity sha512-Rw0SxQ7VKhObmFjD/cUcKhPTtzpeviEFX1E6PgP+cYOhQ98icNqtINNFANlsdbQHrmeWnqdxA4Tmnl1jy5tp3Q== +"@babel/preset-react@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.10.4.tgz#92e8a66d816f9911d11d4cc935be67adfc82dbcf" + integrity sha512-BrHp4TgOIy4M19JAfO1LhycVXOPWdDbTRep7eVyatf174Hff+6Uk53sDyajqZPu8W1qXRBiYOfIamek6jA7YVw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-transform-react-display-name" "^7.10.1" - "@babel/plugin-transform-react-jsx" "^7.10.1" - "@babel/plugin-transform-react-jsx-development" "^7.10.1" - "@babel/plugin-transform-react-jsx-self" "^7.10.1" - "@babel/plugin-transform-react-jsx-source" "^7.10.1" - "@babel/plugin-transform-react-pure-annotations" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-react-display-name" "^7.10.4" + "@babel/plugin-transform-react-jsx" "^7.10.4" + "@babel/plugin-transform-react-jsx-development" "^7.10.4" + "@babel/plugin-transform-react-jsx-self" "^7.10.4" + "@babel/plugin-transform-react-jsx-source" "^7.10.4" + "@babel/plugin-transform-react-pure-annotations" "^7.10.4" -"@babel/preset-typescript@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.10.1.tgz#a8d8d9035f55b7d99a2461a0bdc506582914d07e" - integrity sha512-m6GV3y1ShiqxnyQj10600ZVOFrSSAa8HQ3qIUk2r+gcGtHTIRw0dJnFLt1WNXpKjtVw7yw1DAPU/6ma2ZvgJuA== +"@babel/preset-typescript@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.10.4.tgz#7d5d052e52a682480d6e2cc5aa31be61c8c25e36" + integrity sha512-SdYnvGPv+bLlwkF2VkJnaX/ni1sMNetcGI1+nThF1gyv6Ph8Qucc4ZZAjM5yZcE/AKRXIOTZz7eSRDWOEjPyRQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-transform-typescript" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-typescript" "^7.10.4" -"@babel/register@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.10.1.tgz#b6567c5cb5049f44bbf8c35d6ff68ca3c43238ed" - integrity sha512-sl96+kB3IA2B9EzpwwBmYadOT14vw3KaXOknGDbJaZCOj52GDA4Tivudq9doCJcB+bEIKCEARZYwRgBBsCGXyg== +"@babel/register@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.10.5.tgz#354f3574895f1307f79efe37a51525e52fd38d89" + integrity sha512-eYHdLv43nyvmPn9bfNfrcC4+iYNwdQ8Pxk1MFJuU/U5LpSYl/PH4dFMazCYZDFVi8ueG3shvO+AQfLrxpYulQw== dependencies: find-cache-dir "^2.0.0" - lodash "^4.17.13" + lodash "^4.17.19" make-dir "^2.1.0" pirates "^4.0.0" source-map-support "^0.5.16" @@ -1747,10 +1780,10 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.10.2": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.2.tgz#d103f21f2602497d38348a32e008637d506db839" - integrity sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg== +"@babel/runtime@^7.11.2": + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" + integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== dependencies: regenerator-runtime "^0.13.4" @@ -1775,14 +1808,14 @@ "@babel/parser" "^7.8.6" "@babel/types" "^7.8.6" -"@babel/template@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.1.tgz#e167154a94cb5f14b28dc58f5356d2162f539811" - integrity sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig== +"@babel/template@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" + integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== dependencies: - "@babel/code-frame" "^7.10.1" - "@babel/parser" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.4.5", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": version "7.9.0" @@ -1799,20 +1832,20 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/traverse@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.1.tgz#bbcef3031e4152a6c0b50147f4958df54ca0dd27" - integrity sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ== - dependencies: - "@babel/code-frame" "^7.10.1" - "@babel/generator" "^7.10.1" - "@babel/helper-function-name" "^7.10.1" - "@babel/helper-split-export-declaration" "^7.10.1" - "@babel/parser" "^7.10.1" - "@babel/types" "^7.10.1" +"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24" + integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.0" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/parser" "^7.11.0" + "@babel/types" "^7.11.0" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.13" + lodash "^4.17.19" "@babel/traverse@^7.7.4": version "7.9.5" @@ -1838,13 +1871,13 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@babel/types@^7.10.1", "@babel/types@^7.10.2": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.2.tgz#30283be31cad0dbf6fb00bd40641ca0ea675172d" - integrity sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng== +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" + integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA== dependencies: - "@babel/helper-validator-identifier" "^7.10.1" - lodash "^4.17.13" + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" to-fast-properties "^2.0.0" "@babel/types@^7.3.3": @@ -20330,7 +20363,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.11, lodash@4.17.19, lodash@>4.17.4, lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5: +lodash@4.17.11, lodash@4.17.19, lodash@>4.17.4, lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.19, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== From 810ff87afbac92aa8b655dc944b27894f1c4682a Mon Sep 17 00:00:00 2001 From: Kevin Qualters <56408403+kqualters-elastic@users.noreply.github.com> Date: Thu, 6 Aug 2020 16:29:09 -0400 Subject: [PATCH 052/106] [Security Solution][Resolver] standardize resolver panel component naming (#74537) --- ...ess_cube_icon.tsx => cube_for_process.tsx} | 90 +-- ...ounts.tsx => event_counts_for_process.tsx} | 288 +++---- .../view/{panel.tsx => panels/index.tsx} | 28 +- ...process_detail.tsx => process_details.tsx} | 2 +- ...elated_list.tsx => process_event_list.tsx} | 580 +++++++------- ..._list.tsx => process_list_with_counts.tsx} | 2 +- ...ed_detail.tsx => related_event_detail.tsx} | 750 +++++++++--------- .../public/resolver/view/styles.tsx | 2 +- 8 files changed, 871 insertions(+), 871 deletions(-) rename x-pack/plugins/security_solution/public/resolver/view/panels/{process_cube_icon.tsx => cube_for_process.tsx} (96%) rename x-pack/plugins/security_solution/public/resolver/view/panels/{panel_content_related_counts.tsx => event_counts_for_process.tsx} (97%) rename x-pack/plugins/security_solution/public/resolver/view/{panel.tsx => panels/index.tsx} (90%) rename x-pack/plugins/security_solution/public/resolver/view/panels/{panel_content_process_detail.tsx => process_details.tsx} (98%) rename x-pack/plugins/security_solution/public/resolver/view/panels/{panel_content_related_list.tsx => process_event_list.tsx} (95%) rename x-pack/plugins/security_solution/public/resolver/view/panels/{panel_content_process_list.tsx => process_list_with_counts.tsx} (99%) rename x-pack/plugins/security_solution/public/resolver/view/panels/{panel_content_related_detail.tsx => related_event_detail.tsx} (97%) diff --git a/x-pack/plugins/security_solution/public/resolver/view/panels/process_cube_icon.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/cube_for_process.tsx similarity index 96% rename from x-pack/plugins/security_solution/public/resolver/view/panels/process_cube_icon.tsx rename to x-pack/plugins/security_solution/public/resolver/view/panels/cube_for_process.tsx index b073324b27f9b..0d8f65b4e39e6 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panels/process_cube_icon.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/cube_for_process.tsx @@ -1,45 +1,45 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { memo } from 'react'; -import { useResolverTheme } from '../assets'; - -/** - * During user testing, one user indicated they wanted to see stronger visual relationships between - * Nodes on the graph and what's in the table. Using the same symbol in both places (as below) could help with that. - */ -export const CubeForProcess = memo(function CubeForProcess({ - isProcessTerminated, -}: { - isProcessTerminated: boolean; -}) { - const { cubeAssetsForNode } = useResolverTheme(); - const { cubeSymbol, descriptionText } = cubeAssetsForNode(isProcessTerminated, false); - - return ( - <> - - {descriptionText} - - - - ); -}); +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { memo } from 'react'; +import { useResolverTheme } from '../assets'; + +/** + * During user testing, one user indicated they wanted to see stronger visual relationships between + * Nodes on the graph and what's in the table. Using the same symbol in both places (as below) could help with that. + */ +export const CubeForProcess = memo(function CubeForProcess({ + isProcessTerminated, +}: { + isProcessTerminated: boolean; +}) { + const { cubeAssetsForNode } = useResolverTheme(); + const { cubeSymbol, descriptionText } = cubeAssetsForNode(isProcessTerminated, false); + + return ( + <> + + {descriptionText} + + + + ); +}); diff --git a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_related_counts.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/event_counts_for_process.tsx similarity index 97% rename from x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_related_counts.tsx rename to x-pack/plugins/security_solution/public/resolver/view/panels/event_counts_for_process.tsx index 880ee1dc7a10a..129aff776808a 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_related_counts.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/event_counts_for_process.tsx @@ -1,144 +1,144 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { memo, useMemo } from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiBasicTableColumn, EuiButtonEmpty, EuiSpacer, EuiInMemoryTable } from '@elastic/eui'; -import { FormattedMessage } from 'react-intl'; -import { CrumbInfo, StyledBreadcrumbs } from './panel_content_utilities'; - -import * as event from '../../../../common/endpoint/models/event'; -import { ResolverEvent, ResolverNodeStats } from '../../../../common/endpoint/types'; - -/** - * This view gives counts for all the related events of a process grouped by related event type. - * It should look something like: - * - * | Count | Event Type | - * | :--------------------- | :------------------------- | - * | 5 | DNS | - * | 12 | Registry | - * | 2 | Network | - * - */ -export const EventCountsForProcess = memo(function EventCountsForProcess({ - processEvent, - pushToQueryParams, - relatedStats, -}: { - processEvent: ResolverEvent; - pushToQueryParams: (queryStringKeyValuePair: CrumbInfo) => unknown; - relatedStats: ResolverNodeStats; -}) { - interface EventCountsTableView { - name: string; - count: number; - } - - const relatedEventsState = { stats: relatedStats.events.byCategory }; - const processName = processEvent && event.eventName(processEvent); - const processEntityId = event.entityId(processEvent); - /** - * totalCount: This will reflect the aggregated total by category for all related events - * e.g. [dns,file],[dns,file],[registry] will have an aggregate total of 5. This is to keep the - * total number consistent with the "broken out" totals we see elsewhere in the app. - * E.g. on the rleated list by type, the above would show as: - * 2 dns - * 2 file - * 1 registry - * So it would be extremely disorienting to show the user a "3" above that as a total. - */ - const totalCount = Object.values(relatedStats.events.byCategory).reduce( - (sum, val) => sum + val, - 0 - ); - const eventsString = i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.processEventCounts.events', - { - defaultMessage: 'Events', - } - ); - const crumbs = useMemo(() => { - return [ - { - text: eventsString, - onClick: () => { - pushToQueryParams({ crumbId: '', crumbEvent: '' }); - }, - }, - { - text: processName, - onClick: () => { - pushToQueryParams({ crumbId: processEntityId, crumbEvent: '' }); - }, - }, - { - text: ( - <> - - - ), - onClick: () => { - pushToQueryParams({ crumbId: processEntityId, crumbEvent: '' }); - }, - }, - ]; - }, [processName, totalCount, processEntityId, pushToQueryParams, eventsString]); - const rows = useMemo(() => { - return Object.entries(relatedEventsState.stats).map( - ([eventType, count]): EventCountsTableView => { - return { - name: eventType, - count, - }; - } - ); - }, [relatedEventsState]); - const columns = useMemo>>( - () => [ - { - field: 'count', - name: i18n.translate('xpack.securitySolution.endpoint.resolver.panel.table.row.count', { - defaultMessage: 'Count', - }), - width: '20%', - sortable: true, - }, - { - field: 'name', - name: i18n.translate('xpack.securitySolution.endpoint.resolver.panel.table.row.eventType', { - defaultMessage: 'Event Type', - }), - width: '80%', - sortable: true, - render(name: string) { - return ( - { - pushToQueryParams({ crumbId: event.entityId(processEvent), crumbEvent: name }); - }} - > - {name} - - ); - }, - }, - ], - [pushToQueryParams, processEvent] - ); - return ( - <> - - - items={rows} columns={columns} sorting /> - - ); -}); -EventCountsForProcess.displayName = 'EventCountsForProcess'; +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { memo, useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiBasicTableColumn, EuiButtonEmpty, EuiSpacer, EuiInMemoryTable } from '@elastic/eui'; +import { FormattedMessage } from 'react-intl'; +import { CrumbInfo, StyledBreadcrumbs } from './panel_content_utilities'; + +import * as event from '../../../../common/endpoint/models/event'; +import { ResolverEvent, ResolverNodeStats } from '../../../../common/endpoint/types'; + +/** + * This view gives counts for all the related events of a process grouped by related event type. + * It should look something like: + * + * | Count | Event Type | + * | :--------------------- | :------------------------- | + * | 5 | DNS | + * | 12 | Registry | + * | 2 | Network | + * + */ +export const EventCountsForProcess = memo(function EventCountsForProcess({ + processEvent, + pushToQueryParams, + relatedStats, +}: { + processEvent: ResolverEvent; + pushToQueryParams: (queryStringKeyValuePair: CrumbInfo) => unknown; + relatedStats: ResolverNodeStats; +}) { + interface EventCountsTableView { + name: string; + count: number; + } + + const relatedEventsState = { stats: relatedStats.events.byCategory }; + const processName = processEvent && event.eventName(processEvent); + const processEntityId = event.entityId(processEvent); + /** + * totalCount: This will reflect the aggregated total by category for all related events + * e.g. [dns,file],[dns,file],[registry] will have an aggregate total of 5. This is to keep the + * total number consistent with the "broken out" totals we see elsewhere in the app. + * E.g. on the rleated list by type, the above would show as: + * 2 dns + * 2 file + * 1 registry + * So it would be extremely disorienting to show the user a "3" above that as a total. + */ + const totalCount = Object.values(relatedStats.events.byCategory).reduce( + (sum, val) => sum + val, + 0 + ); + const eventsString = i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.processEventCounts.events', + { + defaultMessage: 'Events', + } + ); + const crumbs = useMemo(() => { + return [ + { + text: eventsString, + onClick: () => { + pushToQueryParams({ crumbId: '', crumbEvent: '' }); + }, + }, + { + text: processName, + onClick: () => { + pushToQueryParams({ crumbId: processEntityId, crumbEvent: '' }); + }, + }, + { + text: ( + <> + + + ), + onClick: () => { + pushToQueryParams({ crumbId: processEntityId, crumbEvent: '' }); + }, + }, + ]; + }, [processName, totalCount, processEntityId, pushToQueryParams, eventsString]); + const rows = useMemo(() => { + return Object.entries(relatedEventsState.stats).map( + ([eventType, count]): EventCountsTableView => { + return { + name: eventType, + count, + }; + } + ); + }, [relatedEventsState]); + const columns = useMemo>>( + () => [ + { + field: 'count', + name: i18n.translate('xpack.securitySolution.endpoint.resolver.panel.table.row.count', { + defaultMessage: 'Count', + }), + width: '20%', + sortable: true, + }, + { + field: 'name', + name: i18n.translate('xpack.securitySolution.endpoint.resolver.panel.table.row.eventType', { + defaultMessage: 'Event Type', + }), + width: '80%', + sortable: true, + render(name: string) { + return ( + { + pushToQueryParams({ crumbId: event.entityId(processEvent), crumbEvent: name }); + }} + > + {name} + + ); + }, + }, + ], + [pushToQueryParams, processEvent] + ); + return ( + <> + + + items={rows} columns={columns} sorting /> + + ); +}); +EventCountsForProcess.displayName = 'EventCountsForProcess'; diff --git a/x-pack/plugins/security_solution/public/resolver/view/panel.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/index.tsx similarity index 90% rename from x-pack/plugins/security_solution/public/resolver/view/panel.tsx rename to x-pack/plugins/security_solution/public/resolver/view/panels/index.tsx index f378ab36bac94..7e7e8b757baf7 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panel.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/index.tsx @@ -7,17 +7,17 @@ import React, { memo, useMemo, useContext, useLayoutEffect, useState } from 'react'; import { useSelector } from 'react-redux'; import { EuiPanel } from '@elastic/eui'; -import * as selectors from '../store/selectors'; -import { useResolverDispatch } from './use_resolver_dispatch'; -import * as event from '../../../common/endpoint/models/event'; -import { ResolverEvent, ResolverNodeStats } from '../../../common/endpoint/types'; -import { SideEffectContext } from './side_effect_context'; -import { ProcessEventListNarrowedByType } from './panels/panel_content_related_list'; -import { EventCountsForProcess } from './panels/panel_content_related_counts'; -import { ProcessDetails } from './panels/panel_content_process_detail'; -import { ProcessListWithCounts } from './panels/panel_content_process_list'; -import { RelatedEventDetail } from './panels/panel_content_related_detail'; -import { useResolverQueryParams } from './use_resolver_query_params'; +import * as selectors from '../../store/selectors'; +import { useResolverDispatch } from '../use_resolver_dispatch'; +import * as event from '../../../../common/endpoint/models/event'; +import { ResolverEvent, ResolverNodeStats } from '../../../../common/endpoint/types'; +import { SideEffectContext } from '../side_effect_context'; +import { ProcessEventList } from './process_event_list'; +import { EventCountsForProcess } from './event_counts_for_process'; +import { ProcessDetails } from './process_details'; +import { ProcessListWithCounts } from './process_list_with_counts'; +import { RelatedEventDetail } from './related_event_detail'; +import { useResolverQueryParams } from '../use_resolver_query_params'; /** * The team decided to use this table to determine which breadcrumbs/view to display: @@ -145,7 +145,7 @@ const PanelContent = memo(function PanelContent() { */ if (crumbEvent && crumbEvent.length && uiSelectedEvent) { - return 'processEventListNarrowedByType'; + return 'processEventList'; } } @@ -179,9 +179,9 @@ const PanelContent = memo(function PanelContent() { ); } - if (panelToShow === 'processEventListNarrowedByType') { + if (panelToShow === 'processEventList') { return ( - void; -} - -const StyledRelatedLimitWarning = styled(RelatedEventLimitWarning)` - flex-flow: row wrap; - display: block; - align-items: baseline; - margin-top: 1em; - - & .euiCallOutHeader { - display: inline; - margin-right: 0.25em; - } - - & .euiText { - display: inline; - } - - & .euiText p { - display: inline; - } -`; - -const DisplayList = memo(function DisplayList({ - crumbs, - matchingEventEntries, - eventType, - processEntityId, -}: { - crumbs: Array<{ text: string | JSX.Element; onClick: () => void }>; - matchingEventEntries: MatchingEventEntry[]; - eventType: string; - processEntityId: string; -}) { - const relatedLookupsByCategory = useSelector(selectors.relatedEventInfoByEntityId); - const lookupsForThisNode = relatedLookupsByCategory(processEntityId); - const shouldShowLimitWarning = lookupsForThisNode?.shouldShowLimitForCategory(eventType); - const numberDisplayed = lookupsForThisNode?.numberActuallyDisplayedForCategory(eventType); - const numberMissing = lookupsForThisNode?.numberNotDisplayedForCategory(eventType); - - return ( - <> - - {shouldShowLimitWarning && typeof numberDisplayed !== 'undefined' && numberMissing ? ( - - ) : null} - - <> - {matchingEventEntries.map((eventView, index) => { - const { subject, descriptor = '' } = eventView.name; - return ( - - - - - - - - - - - - - - {index === matchingEventEntries.length - 1 ? null : } - - ); - })} - - - ); -}); - -export const ProcessEventListNarrowedByType = memo(function ProcessEventListNarrowedByType({ - processEvent, - eventType, - relatedStats, - pushToQueryParams, -}: { - processEvent: ResolverEvent; - pushToQueryParams: (arg0: CrumbInfo) => unknown; - eventType: string; - relatedStats: ResolverNodeStats; -}) { - const processName = processEvent && event.eventName(processEvent); - const processEntityId = event.entityId(processEvent); - const totalCount = Object.values(relatedStats.events.byCategory).reduce( - (sum, val) => sum + val, - 0 - ); - const eventsString = i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.processEventListByType.events', - { - defaultMessage: 'Events', - } - ); - const waitingString = i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.processEventListByType.wait', - { - defaultMessage: 'Waiting For Events...', - } - ); - - const relatedsReadyMap = useSelector(selectors.relatedEventsReady); - const relatedsReady = relatedsReadyMap.get(processEntityId); - - const dispatch = useResolverDispatch(); - - useEffect(() => { - if (typeof relatedsReady === 'undefined') { - dispatch({ - type: 'appDetectedMissingEventData', - payload: processEntityId, - }); - } - }, [relatedsReady, dispatch, processEntityId]); - - const waitCrumbs = useMemo(() => { - return [ - { - text: eventsString, - onClick: () => { - pushToQueryParams({ crumbId: '', crumbEvent: '' }); - }, - }, - ]; - }, [pushToQueryParams, eventsString]); - - const relatedByCategory = useSelector(selectors.relatedEventsByCategory); - - /** - * A list entry will be displayed for each of these - */ - const matchingEventEntries: MatchingEventEntry[] = useMemo(() => { - const relateds = relatedByCategory(processEntityId)(eventType).map((resolverEvent) => { - const eventTime = event.eventTimestamp(resolverEvent); - const formattedDate = typeof eventTime === 'undefined' ? '' : formatDate(eventTime); - const entityId = event.eventId(resolverEvent); - - return { - formattedDate, - eventCategory: `${eventType}`, - eventType: `${event.ecsEventType(resolverEvent)}`, - name: event.descriptiveName(resolverEvent), - setQueryParams: () => { - pushToQueryParams({ - crumbId: entityId === undefined ? '' : String(entityId), - crumbEvent: processEntityId, - }); - }, - }; - }); - return relateds; - }, [relatedByCategory, eventType, processEntityId, pushToQueryParams]); - - const crumbs = useMemo(() => { - return [ - { - text: eventsString, - onClick: () => { - pushToQueryParams({ crumbId: '', crumbEvent: '' }); - }, - }, - { - text: processName, - onClick: () => { - pushToQueryParams({ crumbId: processEntityId, crumbEvent: '' }); - }, - }, - { - text: ( - <> - - - ), - onClick: () => { - pushToQueryParams({ crumbId: processEntityId, crumbEvent: 'all' }); - }, - }, - { - text: ( - <> - - - ), - onClick: () => {}, - }, - ]; - }, [ - eventType, - eventsString, - matchingEventEntries.length, - processEntityId, - processName, - pushToQueryParams, - totalCount, - ]); - - /** - * Wait here until the effect resolves... - */ - if (!relatedsReady) { - return ( - <> - - - -

    {waitingString}

    -
    - - ); - } - - return ( - - ); -}); -ProcessEventListNarrowedByType.displayName = 'ProcessEventListNarrowedByType'; +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { memo, useMemo, useEffect, Fragment } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiTitle, EuiSpacer, EuiText, EuiButtonEmpty, EuiHorizontalRule } from '@elastic/eui'; +import { useSelector } from 'react-redux'; +import { FormattedMessage } from 'react-intl'; +import styled from 'styled-components'; +import { + CrumbInfo, + formatDate, + StyledBreadcrumbs, + BoldCode, + StyledTime, +} from './panel_content_utilities'; +import * as event from '../../../../common/endpoint/models/event'; +import { ResolverEvent, ResolverNodeStats } from '../../../../common/endpoint/types'; +import * as selectors from '../../store/selectors'; +import { useResolverDispatch } from '../use_resolver_dispatch'; +import { RelatedEventLimitWarning } from '../limit_warnings'; + +/** + * This view presents a list of related events of a given type for a given process. + * It will appear like: + * + * | | + * | :----------------------------------------------------- | + * | **registry deletion** @ *3:32PM..* *HKLM/software...* | + * | **file creation** @ *3:34PM..* *C:/directory/file.exe* | + */ + +interface MatchingEventEntry { + formattedDate: string; + eventType: string; + eventCategory: string; + name: { subject: string; descriptor?: string }; + setQueryParams: () => void; +} + +const StyledRelatedLimitWarning = styled(RelatedEventLimitWarning)` + flex-flow: row wrap; + display: block; + align-items: baseline; + margin-top: 1em; + + & .euiCallOutHeader { + display: inline; + margin-right: 0.25em; + } + + & .euiText { + display: inline; + } + + & .euiText p { + display: inline; + } +`; + +const DisplayList = memo(function DisplayList({ + crumbs, + matchingEventEntries, + eventType, + processEntityId, +}: { + crumbs: Array<{ text: string | JSX.Element; onClick: () => void }>; + matchingEventEntries: MatchingEventEntry[]; + eventType: string; + processEntityId: string; +}) { + const relatedLookupsByCategory = useSelector(selectors.relatedEventInfoByEntityId); + const lookupsForThisNode = relatedLookupsByCategory(processEntityId); + const shouldShowLimitWarning = lookupsForThisNode?.shouldShowLimitForCategory(eventType); + const numberDisplayed = lookupsForThisNode?.numberActuallyDisplayedForCategory(eventType); + const numberMissing = lookupsForThisNode?.numberNotDisplayedForCategory(eventType); + + return ( + <> + + {shouldShowLimitWarning && typeof numberDisplayed !== 'undefined' && numberMissing ? ( + + ) : null} + + <> + {matchingEventEntries.map((eventView, index) => { + const { subject, descriptor = '' } = eventView.name; + return ( + + + + + + + + + + + + + + {index === matchingEventEntries.length - 1 ? null : } + + ); + })} + + + ); +}); + +export const ProcessEventList = memo(function ProcessEventList({ + processEvent, + eventType, + relatedStats, + pushToQueryParams, +}: { + processEvent: ResolverEvent; + pushToQueryParams: (arg0: CrumbInfo) => unknown; + eventType: string; + relatedStats: ResolverNodeStats; +}) { + const processName = processEvent && event.eventName(processEvent); + const processEntityId = event.entityId(processEvent); + const totalCount = Object.values(relatedStats.events.byCategory).reduce( + (sum, val) => sum + val, + 0 + ); + const eventsString = i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.processEventListByType.events', + { + defaultMessage: 'Events', + } + ); + const waitingString = i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.processEventListByType.wait', + { + defaultMessage: 'Waiting For Events...', + } + ); + + const relatedsReadyMap = useSelector(selectors.relatedEventsReady); + const relatedsReady = relatedsReadyMap.get(processEntityId); + + const dispatch = useResolverDispatch(); + + useEffect(() => { + if (typeof relatedsReady === 'undefined') { + dispatch({ + type: 'appDetectedMissingEventData', + payload: processEntityId, + }); + } + }, [relatedsReady, dispatch, processEntityId]); + + const waitCrumbs = useMemo(() => { + return [ + { + text: eventsString, + onClick: () => { + pushToQueryParams({ crumbId: '', crumbEvent: '' }); + }, + }, + ]; + }, [pushToQueryParams, eventsString]); + + const relatedByCategory = useSelector(selectors.relatedEventsByCategory); + + /** + * A list entry will be displayed for each of these + */ + const matchingEventEntries: MatchingEventEntry[] = useMemo(() => { + const relateds = relatedByCategory(processEntityId)(eventType).map((resolverEvent) => { + const eventTime = event.eventTimestamp(resolverEvent); + const formattedDate = typeof eventTime === 'undefined' ? '' : formatDate(eventTime); + const entityId = event.eventId(resolverEvent); + + return { + formattedDate, + eventCategory: `${eventType}`, + eventType: `${event.ecsEventType(resolverEvent)}`, + name: event.descriptiveName(resolverEvent), + setQueryParams: () => { + pushToQueryParams({ + crumbId: entityId === undefined ? '' : String(entityId), + crumbEvent: processEntityId, + }); + }, + }; + }); + return relateds; + }, [relatedByCategory, eventType, processEntityId, pushToQueryParams]); + + const crumbs = useMemo(() => { + return [ + { + text: eventsString, + onClick: () => { + pushToQueryParams({ crumbId: '', crumbEvent: '' }); + }, + }, + { + text: processName, + onClick: () => { + pushToQueryParams({ crumbId: processEntityId, crumbEvent: '' }); + }, + }, + { + text: ( + <> + + + ), + onClick: () => { + pushToQueryParams({ crumbId: processEntityId, crumbEvent: 'all' }); + }, + }, + { + text: ( + <> + + + ), + onClick: () => {}, + }, + ]; + }, [ + eventType, + eventsString, + matchingEventEntries.length, + processEntityId, + processName, + pushToQueryParams, + totalCount, + ]); + + /** + * Wait here until the effect resolves... + */ + if (!relatedsReady) { + return ( + <> + + + +

    {waitingString}

    +
    + + ); + } + + return ( + + ); +}); +ProcessEventList.displayName = 'ProcessEventList'; diff --git a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_list.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/process_list_with_counts.tsx similarity index 99% rename from x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_list.tsx rename to x-pack/plugins/security_solution/public/resolver/view/panels/process_list_with_counts.tsx index 70422a6919e51..046c840470262 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_list.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/process_list_with_counts.tsx @@ -19,7 +19,7 @@ import * as selectors from '../../store/selectors'; import { CrumbInfo, formatter, StyledBreadcrumbs } from './panel_content_utilities'; import { useResolverDispatch } from '../use_resolver_dispatch'; import { SideEffectContext } from '../side_effect_context'; -import { CubeForProcess } from './process_cube_icon'; +import { CubeForProcess } from './cube_for_process'; import { SafeResolverEvent } from '../../../../common/endpoint/types'; import { LimitWarning } from '../limit_warnings'; diff --git a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_related_detail.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/related_event_detail.tsx similarity index 97% rename from x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_related_detail.tsx rename to x-pack/plugins/security_solution/public/resolver/view/panels/related_event_detail.tsx index 10e57a09b5da4..3579b1b2f69b8 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_related_detail.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/related_event_detail.tsx @@ -1,375 +1,375 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { memo, useMemo, useEffect, Fragment } from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiSpacer, EuiText, EuiDescriptionList, EuiTextColor, EuiTitle } from '@elastic/eui'; -import styled from 'styled-components'; -import { useSelector } from 'react-redux'; -import { FormattedMessage } from 'react-intl'; -import { - CrumbInfo, - formatDate, - StyledBreadcrumbs, - BoldCode, - StyledTime, -} from './panel_content_utilities'; -import * as event from '../../../../common/endpoint/models/event'; -import { ResolverEvent } from '../../../../common/endpoint/types'; -import * as selectors from '../../store/selectors'; -import { useResolverDispatch } from '../use_resolver_dispatch'; -import { PanelContentError } from './panel_content_error'; - -/** - * A helper function to turn objects into EuiDescriptionList entries. - * This reflects the strategy of more or less "dumping" metadata for related processes - * in description lists with little/no 'prettification'. This has the obvious drawback of - * data perhaps appearing inscrutable/daunting, but the benefit of presenting these fields - * to the user "as they occur" in ECS, which may help them with e.g. EQL queries. - * - * Given an object like: {a:{b: 1}, c: 'd'} it will yield title/description entries like so: - * {title: "a.b", description: "1"}, {title: "c", description: "d"} - * - * @param {object} obj The object to turn into `
    ` entries - */ -const objectToDescriptionListEntries = function* ( - obj: object, - prefix = '' -): Generator<{ title: string; description: string }> { - const nextPrefix = prefix.length ? `${prefix}.` : ''; - for (const [metaKey, metaValue] of Object.entries(obj)) { - if (typeof metaValue === 'number' || typeof metaValue === 'string') { - yield { title: nextPrefix + metaKey, description: `${metaValue}` }; - } else if (metaValue instanceof Array) { - yield { - title: nextPrefix + metaKey, - description: metaValue - .filter((arrayEntry) => { - return typeof arrayEntry === 'number' || typeof arrayEntry === 'string'; - }) - .join(','), - }; - } else if (typeof metaValue === 'object') { - yield* objectToDescriptionListEntries(metaValue, nextPrefix + metaKey); - } - } -}; - -// Adding some styles to prevent horizontal scrollbars, per request from UX review -const StyledDescriptionList = memo(styled(EuiDescriptionList)` - &.euiDescriptionList.euiDescriptionList--column dt.euiDescriptionList__title.desc-title { - max-width: 8em; - } - &.euiDescriptionList.euiDescriptionList--column dd.euiDescriptionList__description { - max-width: calc(100% - 8.5em); - overflow-wrap: break-word; - } -`); - -// Styling subtitles, per UX review: -const StyledFlexTitle = memo(styled('h3')` - display: flex; - flex-flow: row; - font-size: 1.2em; -`); -const StyledTitleRule = memo(styled('hr')` - &.euiHorizontalRule.euiHorizontalRule--full.euiHorizontalRule--marginSmall.override { - display: block; - flex: 1; - margin-left: 0.5em; - } -`); - -const TitleHr = memo(() => { - return ( - - ); -}); -TitleHr.displayName = 'TitleHR'; - -/** - * This view presents a detailed view of all the available data for a related event, split and titled by the "section" - * it appears in the underlying ResolverEvent - */ -export const RelatedEventDetail = memo(function RelatedEventDetail({ - relatedEventId, - parentEvent, - pushToQueryParams, - countForParent, -}: { - relatedEventId: string; - parentEvent: ResolverEvent; - pushToQueryParams: (queryStringKeyValuePair: CrumbInfo) => unknown; - countForParent: number | undefined; -}) { - const processName = (parentEvent && event.eventName(parentEvent)) || '*'; - const processEntityId = parentEvent && event.entityId(parentEvent); - const totalCount = countForParent || 0; - const eventsString = i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.events', - { - defaultMessage: 'Events', - } - ); - const naString = i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.NA', - { - defaultMessage: 'N/A', - } - ); - - const relatedsReadyMap = useSelector(selectors.relatedEventsReady); - const relatedsReady = relatedsReadyMap.get(processEntityId!); - const dispatch = useResolverDispatch(); - - /** - * If we don't have the related events for the parent yet, use this effect - * to request them. - */ - useEffect(() => { - if (typeof relatedsReady === 'undefined') { - dispatch({ - type: 'appDetectedMissingEventData', - payload: processEntityId, - }); - } - }, [relatedsReady, dispatch, processEntityId]); - - const relatedEventsForThisProcess = useSelector(selectors.relatedEventsByEntityId).get( - processEntityId! - ); - - const [relatedEventToShowDetailsFor, countBySameCategory, relatedEventCategory] = useMemo(() => { - if (!relatedEventsForThisProcess) { - return [undefined, 0]; - } - const specificEvent = relatedEventsForThisProcess.events.find( - (evt) => event.eventId(evt) === relatedEventId - ); - // For breadcrumbs: - const specificCategory = specificEvent && event.primaryEventCategory(specificEvent); - const countOfCategory = relatedEventsForThisProcess.events.reduce((sumtotal, evt) => { - return event.primaryEventCategory(evt) === specificCategory ? sumtotal + 1 : sumtotal; - }, 0); - return [specificEvent, countOfCategory, specificCategory || naString]; - }, [relatedEventsForThisProcess, naString, relatedEventId]); - - const [sections, formattedDate] = useMemo(() => { - if (!relatedEventToShowDetailsFor) { - // This could happen if user relaods from URL param and requests an eventId that no longer exists - return [[], naString]; - } - // Assuming these details (agent, ecs, process) aren't as helpful, can revisit - const { - agent, - ecs, - process, - ...relevantData - } = relatedEventToShowDetailsFor as ResolverEvent & { - // Type this with various unknown keys so that ts will let us delete those keys - ecs: unknown; - process: unknown; - }; - let displayDate = ''; - const sectionData: Array<{ - sectionTitle: string; - entries: Array<{ title: string; description: string }>; - }> = Object.entries(relevantData) - .map(([sectionTitle, val]) => { - if (sectionTitle === '@timestamp') { - displayDate = formatDate(val); - return { sectionTitle: '', entries: [] }; - } - if (typeof val !== 'object') { - return { sectionTitle, entries: [{ title: sectionTitle, description: `${val}` }] }; - } - return { sectionTitle, entries: [...objectToDescriptionListEntries(val)] }; - }) - .filter((v) => v.sectionTitle !== '' && v.entries.length); - return [sectionData, displayDate]; - }, [relatedEventToShowDetailsFor, naString]); - - const waitCrumbs = useMemo(() => { - return [ - { - text: eventsString, - onClick: () => { - pushToQueryParams({ crumbId: '', crumbEvent: '' }); - }, - }, - ]; - }, [pushToQueryParams, eventsString]); - - const { subject = '', descriptor = '' } = relatedEventToShowDetailsFor - ? event.descriptiveName(relatedEventToShowDetailsFor) - : {}; - const crumbs = useMemo(() => { - return [ - { - text: eventsString, - onClick: () => { - pushToQueryParams({ crumbId: '', crumbEvent: '' }); - }, - }, - { - text: processName, - onClick: () => { - pushToQueryParams({ crumbId: processEntityId!, crumbEvent: '' }); - }, - }, - { - text: ( - <> - - - ), - onClick: () => { - pushToQueryParams({ crumbId: processEntityId!, crumbEvent: 'all' }); - }, - }, - { - text: ( - <> - - - ), - onClick: () => { - pushToQueryParams({ - crumbId: processEntityId!, - crumbEvent: relatedEventCategory || 'all', - }); - }, - }, - { - text: relatedEventToShowDetailsFor ? ( - - ) : ( - naString - ), - onClick: () => {}, - }, - ]; - }, [ - processName, - processEntityId, - eventsString, - pushToQueryParams, - totalCount, - countBySameCategory, - naString, - relatedEventCategory, - relatedEventToShowDetailsFor, - subject, - descriptor, - ]); - - /** - * If the ship hasn't come in yet, wait on the dock - */ - if (!relatedsReady) { - const waitingString = i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.relatedDetail.wait', - { - defaultMessage: 'Waiting For Events...', - } - ); - return ( - <> - - - -

    {waitingString}

    -
    - - ); - } - - /** - * Could happen if user e.g. loads a URL with a bad crumbEvent - */ - if (!relatedEventToShowDetailsFor) { - const errString = i18n.translate( - 'xpack.securitySolution.endpoint.resolver.panel.relatedDetail.missing', - { - defaultMessage: 'Related event not found.', - } - ); - return ( - - ); - } - - return ( - <> - - - - - - - - - - - - - - - - {sections.map(({ sectionTitle, entries }, index) => { - return ( - - {index === 0 ? null : } - - - - {sectionTitle} - - - - - - - {index === sections.length - 1 ? null : } - - ); - })} - - ); -}); +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { memo, useMemo, useEffect, Fragment } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiSpacer, EuiText, EuiDescriptionList, EuiTextColor, EuiTitle } from '@elastic/eui'; +import styled from 'styled-components'; +import { useSelector } from 'react-redux'; +import { FormattedMessage } from 'react-intl'; +import { + CrumbInfo, + formatDate, + StyledBreadcrumbs, + BoldCode, + StyledTime, +} from './panel_content_utilities'; +import * as event from '../../../../common/endpoint/models/event'; +import { ResolverEvent } from '../../../../common/endpoint/types'; +import * as selectors from '../../store/selectors'; +import { useResolverDispatch } from '../use_resolver_dispatch'; +import { PanelContentError } from './panel_content_error'; + +/** + * A helper function to turn objects into EuiDescriptionList entries. + * This reflects the strategy of more or less "dumping" metadata for related processes + * in description lists with little/no 'prettification'. This has the obvious drawback of + * data perhaps appearing inscrutable/daunting, but the benefit of presenting these fields + * to the user "as they occur" in ECS, which may help them with e.g. EQL queries. + * + * Given an object like: {a:{b: 1}, c: 'd'} it will yield title/description entries like so: + * {title: "a.b", description: "1"}, {title: "c", description: "d"} + * + * @param {object} obj The object to turn into `
    ` entries + */ +const objectToDescriptionListEntries = function* ( + obj: object, + prefix = '' +): Generator<{ title: string; description: string }> { + const nextPrefix = prefix.length ? `${prefix}.` : ''; + for (const [metaKey, metaValue] of Object.entries(obj)) { + if (typeof metaValue === 'number' || typeof metaValue === 'string') { + yield { title: nextPrefix + metaKey, description: `${metaValue}` }; + } else if (metaValue instanceof Array) { + yield { + title: nextPrefix + metaKey, + description: metaValue + .filter((arrayEntry) => { + return typeof arrayEntry === 'number' || typeof arrayEntry === 'string'; + }) + .join(','), + }; + } else if (typeof metaValue === 'object') { + yield* objectToDescriptionListEntries(metaValue, nextPrefix + metaKey); + } + } +}; + +// Adding some styles to prevent horizontal scrollbars, per request from UX review +const StyledDescriptionList = memo(styled(EuiDescriptionList)` + &.euiDescriptionList.euiDescriptionList--column dt.euiDescriptionList__title.desc-title { + max-width: 8em; + } + &.euiDescriptionList.euiDescriptionList--column dd.euiDescriptionList__description { + max-width: calc(100% - 8.5em); + overflow-wrap: break-word; + } +`); + +// Styling subtitles, per UX review: +const StyledFlexTitle = memo(styled('h3')` + display: flex; + flex-flow: row; + font-size: 1.2em; +`); +const StyledTitleRule = memo(styled('hr')` + &.euiHorizontalRule.euiHorizontalRule--full.euiHorizontalRule--marginSmall.override { + display: block; + flex: 1; + margin-left: 0.5em; + } +`); + +const TitleHr = memo(() => { + return ( + + ); +}); +TitleHr.displayName = 'TitleHR'; + +/** + * This view presents a detailed view of all the available data for a related event, split and titled by the "section" + * it appears in the underlying ResolverEvent + */ +export const RelatedEventDetail = memo(function RelatedEventDetail({ + relatedEventId, + parentEvent, + pushToQueryParams, + countForParent, +}: { + relatedEventId: string; + parentEvent: ResolverEvent; + pushToQueryParams: (queryStringKeyValuePair: CrumbInfo) => unknown; + countForParent: number | undefined; +}) { + const processName = (parentEvent && event.eventName(parentEvent)) || '*'; + const processEntityId = parentEvent && event.entityId(parentEvent); + const totalCount = countForParent || 0; + const eventsString = i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.events', + { + defaultMessage: 'Events', + } + ); + const naString = i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.NA', + { + defaultMessage: 'N/A', + } + ); + + const relatedsReadyMap = useSelector(selectors.relatedEventsReady); + const relatedsReady = relatedsReadyMap.get(processEntityId!); + const dispatch = useResolverDispatch(); + + /** + * If we don't have the related events for the parent yet, use this effect + * to request them. + */ + useEffect(() => { + if (typeof relatedsReady === 'undefined') { + dispatch({ + type: 'appDetectedMissingEventData', + payload: processEntityId, + }); + } + }, [relatedsReady, dispatch, processEntityId]); + + const relatedEventsForThisProcess = useSelector(selectors.relatedEventsByEntityId).get( + processEntityId! + ); + + const [relatedEventToShowDetailsFor, countBySameCategory, relatedEventCategory] = useMemo(() => { + if (!relatedEventsForThisProcess) { + return [undefined, 0]; + } + const specificEvent = relatedEventsForThisProcess.events.find( + (evt) => event.eventId(evt) === relatedEventId + ); + // For breadcrumbs: + const specificCategory = specificEvent && event.primaryEventCategory(specificEvent); + const countOfCategory = relatedEventsForThisProcess.events.reduce((sumtotal, evt) => { + return event.primaryEventCategory(evt) === specificCategory ? sumtotal + 1 : sumtotal; + }, 0); + return [specificEvent, countOfCategory, specificCategory || naString]; + }, [relatedEventsForThisProcess, naString, relatedEventId]); + + const [sections, formattedDate] = useMemo(() => { + if (!relatedEventToShowDetailsFor) { + // This could happen if user relaods from URL param and requests an eventId that no longer exists + return [[], naString]; + } + // Assuming these details (agent, ecs, process) aren't as helpful, can revisit + const { + agent, + ecs, + process, + ...relevantData + } = relatedEventToShowDetailsFor as ResolverEvent & { + // Type this with various unknown keys so that ts will let us delete those keys + ecs: unknown; + process: unknown; + }; + let displayDate = ''; + const sectionData: Array<{ + sectionTitle: string; + entries: Array<{ title: string; description: string }>; + }> = Object.entries(relevantData) + .map(([sectionTitle, val]) => { + if (sectionTitle === '@timestamp') { + displayDate = formatDate(val); + return { sectionTitle: '', entries: [] }; + } + if (typeof val !== 'object') { + return { sectionTitle, entries: [{ title: sectionTitle, description: `${val}` }] }; + } + return { sectionTitle, entries: [...objectToDescriptionListEntries(val)] }; + }) + .filter((v) => v.sectionTitle !== '' && v.entries.length); + return [sectionData, displayDate]; + }, [relatedEventToShowDetailsFor, naString]); + + const waitCrumbs = useMemo(() => { + return [ + { + text: eventsString, + onClick: () => { + pushToQueryParams({ crumbId: '', crumbEvent: '' }); + }, + }, + ]; + }, [pushToQueryParams, eventsString]); + + const { subject = '', descriptor = '' } = relatedEventToShowDetailsFor + ? event.descriptiveName(relatedEventToShowDetailsFor) + : {}; + const crumbs = useMemo(() => { + return [ + { + text: eventsString, + onClick: () => { + pushToQueryParams({ crumbId: '', crumbEvent: '' }); + }, + }, + { + text: processName, + onClick: () => { + pushToQueryParams({ crumbId: processEntityId!, crumbEvent: '' }); + }, + }, + { + text: ( + <> + + + ), + onClick: () => { + pushToQueryParams({ crumbId: processEntityId!, crumbEvent: 'all' }); + }, + }, + { + text: ( + <> + + + ), + onClick: () => { + pushToQueryParams({ + crumbId: processEntityId!, + crumbEvent: relatedEventCategory || 'all', + }); + }, + }, + { + text: relatedEventToShowDetailsFor ? ( + + ) : ( + naString + ), + onClick: () => {}, + }, + ]; + }, [ + processName, + processEntityId, + eventsString, + pushToQueryParams, + totalCount, + countBySameCategory, + naString, + relatedEventCategory, + relatedEventToShowDetailsFor, + subject, + descriptor, + ]); + + /** + * If the ship hasn't come in yet, wait on the dock + */ + if (!relatedsReady) { + const waitingString = i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.relatedDetail.wait', + { + defaultMessage: 'Waiting For Events...', + } + ); + return ( + <> + + + +

    {waitingString}

    +
    + + ); + } + + /** + * Could happen if user e.g. loads a URL with a bad crumbEvent + */ + if (!relatedEventToShowDetailsFor) { + const errString = i18n.translate( + 'xpack.securitySolution.endpoint.resolver.panel.relatedDetail.missing', + { + defaultMessage: 'Related event not found.', + } + ); + return ( + + ); + } + + return ( + <> + + + + + + + + + + + + + + + + {sections.map(({ sectionTitle, entries }, index) => { + return ( + + {index === 0 ? null : } + + + + {sectionTitle} + + + + + + + {index === sections.length - 1 ? null : } + + ); + })} + + ); +}); diff --git a/x-pack/plugins/security_solution/public/resolver/view/styles.tsx b/x-pack/plugins/security_solution/public/resolver/view/styles.tsx index 4cdb29b283f1e..dfc2f970f1e6f 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/styles.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/styles.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import styled from 'styled-components'; -import { Panel } from './panel'; +import { Panel } from './panels'; /** * The top level DOM element for Resolver From ccf8e2b045869f0274534fd6350b896055e8313f Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 6 Aug 2020 22:45:55 +0200 Subject: [PATCH 053/106] [uptime] Ping Redirects (#65292) --- .../uptime/common/runtime_types/ping/ping.ts | 2 +- .../__snapshots__/expanded_row.test.tsx.snap | 26 +++-- .../monitor/ping_list/expanded_row.tsx | 8 +- .../monitor/ping_list/ping_list.tsx | 1 + .../monitor/ping_list/ping_redirects.tsx | 97 +++++++++++++++++++ .../status_bar/monitor_redirects.tsx | 58 +++++++++++ .../status_details/status_bar/status_bar.tsx | 2 + .../__tests__/get_latest_monitor.test.ts | 2 +- .../server/lib/requests/get_latest_monitor.ts | 2 +- .../rest/fixtures/monitor_latest_status.json | 28 +++++- .../functional/apps/uptime/certificates.ts | 2 +- x-pack/test/functional/apps/uptime/index.ts | 4 + .../test/functional/apps/uptime/locations.ts | 5 +- .../functional/apps/uptime/ping_redirects.ts | 74 ++++++++++++++ .../functional/page_objects/uptime_page.ts | 3 +- .../services/uptime/certificates.ts | 8 -- .../test/functional/services/uptime/common.ts | 8 ++ .../functional/services/uptime/monitor.ts | 28 +++++- 18 files changed, 332 insertions(+), 26 deletions(-) create mode 100644 x-pack/plugins/uptime/public/components/monitor/ping_list/ping_redirects.tsx create mode 100644 x-pack/plugins/uptime/public/components/monitor/status_details/status_bar/monitor_redirects.tsx create mode 100644 x-pack/test/functional/apps/uptime/ping_redirects.ts diff --git a/x-pack/plugins/uptime/common/runtime_types/ping/ping.ts b/x-pack/plugins/uptime/common/runtime_types/ping/ping.ts index 5ed71acaf7739..0a4d6310927c4 100644 --- a/x-pack/plugins/uptime/common/runtime_types/ping/ping.ts +++ b/x-pack/plugins/uptime/common/runtime_types/ping/ping.ts @@ -143,7 +143,7 @@ export const PingType = t.intersection([ response: t.partial({ body: HttpResponseBodyType, bytes: t.number, - redirects: t.string, + redirects: t.array(t.string), status_code: t.number, }), version: t.string, diff --git a/x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap index 004de391a51a4..11bdf134bd0e8 100644 --- a/x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap @@ -1,7 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`PingListExpandedRow doesn't render list items if the body field is undefined 1`] = ` - + + + + +
    + { }); } return ( - + + {ping?.http?.response?.redirects && ( + + + + )} diff --git a/x-pack/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx index 576810bba24fd..09782c1b76edb 100644 --- a/x-pack/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx @@ -237,6 +237,7 @@ export const PingListComponent = (props: Props) => { render: (item: Ping) => { return ( toggleDetails(item, expandedRows, setExpandedRows)} disabled={!item.error && !(item.http?.response?.body?.bytes ?? 0 > 0)} aria-label={ diff --git a/x-pack/plugins/uptime/public/components/monitor/ping_list/ping_redirects.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/ping_redirects.tsx new file mode 100644 index 0000000000000..b3e59615cbce5 --- /dev/null +++ b/x-pack/plugins/uptime/public/components/monitor/ping_list/ping_redirects.tsx @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import styled from 'styled-components'; +import { EuiListGroup, EuiListGroupItemProps, EuiPanel, EuiSpacer, EuiText } from '@elastic/eui'; +import { Ping } from '../../../../common/runtime_types/ping'; + +const ListGroup = styled(EuiListGroup)` + &&& { + a { + padding-left: 0; + } + } +`; + +interface Props { + monitorStatus: Ping | null; + showTitle?: boolean; +} + +export const PingRedirects: React.FC = ({ monitorStatus, showTitle }) => { + const monitorUrl = monitorStatus?.url?.full; + + const list = monitorStatus?.http?.response?.redirects; + + const listOfRedirects: EuiListGroupItemProps[] = [ + { + label: monitorUrl, + href: monitorUrl, + iconType: 'globe', + size: 's', + target: '_blank', + extraAction: { + color: 'subdued', + iconType: 'popout', + iconSize: 's', + alwaysShow: true, + 'aria-label': i18n.translate('xpack.uptime.monitorList.redirects.openWindow', { + defaultMessage: 'Link will open in new window.', + }), + }, + }, + ]; + + (list ?? []).forEach((url: string) => { + listOfRedirects.push({ + label: url, + href: url, + iconType: 'sortDown', + size: 's', + target: '_blank', + extraAction: { + color: 'subdued', + iconType: 'popout', + iconSize: 's', + 'aria-label': i18n.translate('xpack.uptime.monitorList.redirects.openWindow', { + defaultMessage: 'Link will open in new window.', + }), + alwaysShow: true, + }, + }); + }); + + const Panel = showTitle ? EuiPanel : 'div'; + + return list ? ( + + {showTitle && ( + +

    + {i18n.translate('xpack.uptime.monitorList.redirects.title', { + defaultMessage: 'Redirects', + })} +

    +
    + )} + + { + + {i18n.translate('xpack.uptime.monitorList.redirects.description', { + defaultMessage: 'Heartbeat followed {number} redirects while executing ping.', + values: { + number: list?.length ?? 0, + }, + })} + + } + + +
    + ) : null; +}; diff --git a/x-pack/plugins/uptime/public/components/monitor/status_details/status_bar/monitor_redirects.tsx b/x-pack/plugins/uptime/public/components/monitor/status_details/status_bar/monitor_redirects.tsx new file mode 100644 index 0000000000000..5129db9c2135b --- /dev/null +++ b/x-pack/plugins/uptime/public/components/monitor/status_details/status_bar/monitor_redirects.tsx @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiPopover } from '@elastic/eui'; +import styled from 'styled-components'; +import { Ping } from '../../../../../common/runtime_types'; +import { PingRedirects } from '../../ping_list/ping_redirects'; +import { MonListDescription, MonListTitle } from './status_bar'; + +interface Props { + monitorStatus: Ping | null; +} + +const RedirectBtn = styled.span` + cursor: pointer; +`; + +export const MonitorRedirects: React.FC = ({ monitorStatus }) => { + const list = monitorStatus?.http?.response?.redirects; + + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + const button = ( + + setIsPopoverOpen(!isPopoverOpen)} + data-test-subj="uptimeMonitorRedirectInfo" + > + {i18n.translate('xpack.uptime.monitorList.redirects.title.number', { + defaultMessage: '{number}', + values: { + number: list?.length ?? 0, + }, + })} + + + ); + + return list ? ( + <> + Redirects + setIsPopoverOpen(false)} + > + + + + ) : null; +}; diff --git a/x-pack/plugins/uptime/public/components/monitor/status_details/status_bar/status_bar.tsx b/x-pack/plugins/uptime/public/components/monitor/status_details/status_bar/status_bar.tsx index afcc8fae7a8ac..4ea383567d71c 100644 --- a/x-pack/plugins/uptime/public/components/monitor/status_details/status_bar/status_bar.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/status_details/status_bar/status_bar.tsx @@ -23,6 +23,7 @@ import { MonitorIDLabel, OverallAvailability } from '../translations'; import { URL_LABEL } from '../../../common/translations'; import { MonitorLocations } from '../../../../../common/runtime_types/monitor'; import { formatAvailabilityValue } from '../availability_reporting/availability_reporting'; +import { MonitorRedirects } from './monitor_redirects'; export const MonListTitle = styled(EuiDescriptionListTitle)` &&& { @@ -76,6 +77,7 @@ export const MonitorStatusBar: React.FC = () => { {MonitorIDLabel} {monitorId} +
    ); diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts index 01384ec145236..669033fc6524a 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts @@ -32,7 +32,7 @@ describe('getLatestMonitor', () => { }, }, size: 1, - _source: ['url', 'monitor', 'observer', '@timestamp', 'tls.*'], + _source: ['url', 'monitor', 'observer', '@timestamp', 'tls.*', 'http'], sort: { '@timestamp': { order: 'desc' }, }, diff --git a/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts b/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts index a58208fc2bb96..3b4aeaf92c508 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts @@ -45,7 +45,7 @@ export const getLatestMonitor: UMElasticsearchQueryFn { }); it('can navigate to cert page', async () => { - await uptimeService.cert.isUptimeDataMissing(); + await uptimeService.common.waitUntilDataIsLoaded(); await uptimeService.cert.hasViewCertButton(); await uptimeService.navigation.goToCertificates(); }); diff --git a/x-pack/test/functional/apps/uptime/index.ts b/x-pack/test/functional/apps/uptime/index.ts index 6b2b61cba2b64..261f685eeb9cc 100644 --- a/x-pack/test/functional/apps/uptime/index.ts +++ b/x-pack/test/functional/apps/uptime/index.ts @@ -56,6 +56,10 @@ export default ({ loadTestFile, getService }: FtrProviderContext) => { loadTestFile(require.resolve('./certificates')); }); + describe('with generated data but no data reset', () => { + loadTestFile(require.resolve('./ping_redirects')); + }); + describe('with real-world data', () => { before(async () => { await esArchiver.unload(ARCHIVE); diff --git a/x-pack/test/functional/apps/uptime/locations.ts b/x-pack/test/functional/apps/uptime/locations.ts index 8aefca6a70195..6bfa19c6ef578 100644 --- a/x-pack/test/functional/apps/uptime/locations.ts +++ b/x-pack/test/functional/apps/uptime/locations.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import moment from 'moment'; import { makeChecksWithStatus } from '../../../api_integration/apis/uptime/rest/helper/make_checks'; import { FtrProviderContext } from '../../ftr_provider_context'; @@ -40,8 +39,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }; describe('Observer location', () => { - const start = moment().subtract('15', 'm').toISOString(); - const end = moment().toISOString(); + const start = '~ 15 minutes ago'; + const end = 'now'; before(async () => { await addMonitorWithNoLocation(); diff --git a/x-pack/test/functional/apps/uptime/ping_redirects.ts b/x-pack/test/functional/apps/uptime/ping_redirects.ts new file mode 100644 index 0000000000000..b87e8c1748c82 --- /dev/null +++ b/x-pack/test/functional/apps/uptime/ping_redirects.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { makeChecksWithStatus } from '../../../api_integration/apis/uptime/rest/helper/make_checks'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + +export default ({ getPageObjects, getService }: FtrProviderContext) => { + const { uptime: uptimePage, header } = getPageObjects(['uptime', 'header']); + const uptime = getService('uptime'); + const esArchiver = getService('esArchiver'); + + const archive = 'uptime/blank'; + + const monitor = () => uptime.monitor; + + describe('Ping redirects', () => { + const start = '~ 15 minutes ago'; + const end = 'now'; + + const MONITOR_ID = 'redirect-testing-id'; + + before(async () => { + await esArchiver.loadIfNeeded(archive); + }); + + after('unload', async () => { + await esArchiver.unload(archive); + }); + + beforeEach(async () => { + await makeChecksWithStatus( + getService('legacyEs'), + MONITOR_ID, + 5, + 2, + 10000, + { + http: { + rtt: { total: { us: 157784 } }, + response: { + status_code: 200, + redirects: ['http://localhost:3000/first', 'https://www.washingtonpost.com/'], + body: { + bytes: 642102, + hash: '597a8cfb33ff8e09bff16283306553c3895282aaf5386e1843d466d44979e28a', + }, + }, + }, + }, + 'up' + ); + await delay(1000); + }); + + it('loads and goes to details page', async () => { + await uptime.navigation.goToUptime(); + await uptimePage.loadDataAndGoToMonitorPage(start, end, MONITOR_ID); + }); + + it('display redirect info in detail panel', async () => { + await header.waitUntilLoadingHasFinished(); + await monitor().hasRedirectInfo(); + }); + + it('displays redirects in ping list expand row', async () => { + await monitor().hasRedirectInfoInPingList(); + }); + }); +}; diff --git a/x-pack/test/functional/page_objects/uptime_page.ts b/x-pack/test/functional/page_objects/uptime_page.ts index 074a2d598be8a..8102d8b95680e 100644 --- a/x-pack/test/functional/page_objects/uptime_page.ts +++ b/x-pack/test/functional/page_objects/uptime_page.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../ftr_provider_context'; export function UptimePageProvider({ getPageObjects, getService }: FtrProviderContext) { - const pageObjects = getPageObjects(['common', 'timePicker']); + const pageObjects = getPageObjects(['common', 'timePicker', 'header']); const { common: commonService, monitor, navigation } = getService('uptime'); const retry = getService('retry'); @@ -42,6 +42,7 @@ export function UptimePageProvider({ getPageObjects, getService }: FtrProviderCo } public async loadDataAndGoToMonitorPage(dateStart: string, dateEnd: string, monitorId: string) { + await pageObjects.header.waitUntilLoadingHasFinished(); await this.setDateRange(dateStart, dateEnd); await navigation.goToMonitor(monitorId); } diff --git a/x-pack/test/functional/services/uptime/certificates.ts b/x-pack/test/functional/services/uptime/certificates.ts index 06de9be5af7e9..ab43604786282 100644 --- a/x-pack/test/functional/services/uptime/certificates.ts +++ b/x-pack/test/functional/services/uptime/certificates.ts @@ -24,14 +24,6 @@ export function UptimeCertProvider({ getService, getPageObjects }: FtrProviderCo }; return { - async isUptimeDataMissing() { - return retry.tryForTime(60 * 1000, async () => { - if (await testSubjects.exists('data-missing', { timeout: 0 })) { - await refreshApp(); - } - await testSubjects.missingOrFail('data-missing'); - }); - }, async hasViewCertButton() { return retry.tryForTime(15000, async () => { await testSubjects.existOrFail('uptimeCertificatesLink'); diff --git a/x-pack/test/functional/services/uptime/common.ts b/x-pack/test/functional/services/uptime/common.ts index 5f544b5e46010..13c9ead89d09d 100644 --- a/x-pack/test/functional/services/uptime/common.ts +++ b/x-pack/test/functional/services/uptime/common.ts @@ -91,5 +91,13 @@ export function UptimeCommonProvider({ getService }: FtrProviderContext) { 5000 ); }, + async waitUntilDataIsLoaded() { + return retry.tryForTime(60 * 1000, async () => { + if (await testSubjects.exists('data-missing')) { + await testSubjects.click('superDatePickerApplyTimeButton'); + } + await testSubjects.missingOrFail('data-missing'); + }); + }, }; } diff --git a/x-pack/test/functional/services/uptime/monitor.ts b/x-pack/test/functional/services/uptime/monitor.ts index 593950fbb7619..c45454e731696 100644 --- a/x-pack/test/functional/services/uptime/monitor.ts +++ b/x-pack/test/functional/services/uptime/monitor.ts @@ -7,11 +7,13 @@ import expect from '@kbn/expect/expect.js'; import { FtrProviderContext } from '../../ftr_provider_context'; -export function UptimeMonitorProvider({ getService }: FtrProviderContext) { +export function UptimeMonitorProvider({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const retry = getService('retry'); const find = getService('find'); + const PageObjects = getPageObjects(['header']); + return { async locationMissingExists() { return await testSubjects.existOrFail('xpack.uptime.locationMap.locationMissing', { @@ -56,5 +58,29 @@ export function UptimeMonitorProvider({ getService }: FtrProviderContext) { async toggleToMapView() { await testSubjects.click('uptimeMonitorToggleMapBtn'); }, + async hasRedirectInfo() { + return retry.tryForTime(30000, async () => { + await testSubjects.existOrFail('uptimeMonitorRedirectInfo'); + }); + }, + async expandPingRow() { + return retry.tryForTime( + 60 * 3000, + async () => { + await testSubjects.existOrFail('uptimePingListExpandBtn', { timeout: 5000 }); + await testSubjects.click('uptimePingListExpandBtn'); + }, + async () => { + await testSubjects.click('superDatePickerApplyTimeButton'); + await PageObjects.header.waitUntilLoadingHasFinished(); + } + ); + }, + async hasRedirectInfoInPingList() { + await this.expandPingRow(); + return retry.tryForTime(60 * 1000, async () => { + await testSubjects.existOrFail('uptimeMonitorPingListRedirectInfo'); + }); + }, }; } From 979bdaa56f4aa42f9e962cb803133aaea80d6977 Mon Sep 17 00:00:00 2001 From: Yara Tercero Date: Thu, 6 Aug 2020 19:37:38 -0400 Subject: [PATCH 054/106] [Security Solution][Tech Debt] - Cleans up error formatter to not return duplicate error messages (#74600) ## Summary Using the `formatErrors` util would result in duplicate error messages sometimes. Was noticing this in particular when using union types, where the type validation would check every item in a union and report an error for each one. This resulted in large, repeating errors. Used `uniq` to filter out duplicates. Updated unit tests. --- .../lists/common/schemas/types/comment.test.ts | 3 --- .../schemas/types/default_comments_array.test.ts | 2 -- .../types/default_update_comments_array.test.ts | 2 -- .../lists/common/schemas/types/entries.test.ts | 7 ------- .../types/non_empty_entries_array.test.ts | 4 ---- .../types/non_empty_nested_entries_array.test.ts | 15 --------------- .../common/schemas/types/update_comment.test.ts | 2 -- .../request/create_rules_bulk_schema.test.ts | 1 - .../request/update_rules_bulk_schema.test.ts | 1 - .../common/format_errors.test.ts | 16 ++++++++++++++++ .../security_solution/common/format_errors.ts | 4 +++- .../routes/export_timelines_route.test.ts | 2 +- .../routes/import_timelines_route.test.ts | 10 ++-------- 13 files changed, 22 insertions(+), 47 deletions(-) diff --git a/x-pack/plugins/lists/common/schemas/types/comment.test.ts b/x-pack/plugins/lists/common/schemas/types/comment.test.ts index 081bb9b4bae54..9b6f0e76bdd54 100644 --- a/x-pack/plugins/lists/common/schemas/types/comment.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/comment.test.ts @@ -60,7 +60,6 @@ describe('Comment', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "undefined" supplied to "({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)"', - 'Invalid value "undefined" supplied to "({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)"', ]); expect(message.schema).toEqual({}); }); @@ -200,7 +199,6 @@ describe('Comment', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', - 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', ]); expect(message.schema).toEqual({}); }); @@ -232,7 +230,6 @@ describe('Comment', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', - 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/default_comments_array.test.ts b/x-pack/plugins/lists/common/schemas/types/default_comments_array.test.ts index ee2dc0cf2a478..0f5ed2ee4a98b 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_comments_array.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_comments_array.test.ts @@ -39,7 +39,6 @@ describe('default_comments_array', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', - 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', ]); expect(message.schema).toEqual({}); }); @@ -51,7 +50,6 @@ describe('default_comments_array', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "some string" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', - 'Invalid value "some string" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.test.ts b/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.test.ts index 25c84af8c9ee3..a0f6a2b2a6eaa 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.test.ts @@ -39,7 +39,6 @@ describe('default_update_comments_array', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', - 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', ]); expect(message.schema).toEqual({}); }); @@ -51,7 +50,6 @@ describe('default_update_comments_array', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "some string" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', - 'Invalid value "some string" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/entries.test.ts b/x-pack/plugins/lists/common/schemas/types/entries.test.ts index f5c022c7a394f..0537b0b9c6c6a 100644 --- a/x-pack/plugins/lists/common/schemas/types/entries.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/entries.test.ts @@ -61,17 +61,10 @@ describe('Entries', () => { const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "operator"', - 'Invalid value "nested" supplied to "type"', - 'Invalid value "undefined" supplied to "value"', 'Invalid value "undefined" supplied to "operator"', 'Invalid value "nested" supplied to "type"', 'Invalid value "undefined" supplied to "value"', 'Invalid value "undefined" supplied to "list"', - 'Invalid value "undefined" supplied to "operator"', - 'Invalid value "nested" supplied to "type"', - 'Invalid value "undefined" supplied to "operator"', - 'Invalid value "nested" supplied to "type"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts index 42d476a9fefb2..d81509d080056 100644 --- a/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts @@ -125,10 +125,6 @@ describe('non_empty_entries_array', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "1" supplied to "NonEmptyEntriesArray"', - 'Invalid value "1" supplied to "NonEmptyEntriesArray"', - 'Invalid value "1" supplied to "NonEmptyEntriesArray"', - 'Invalid value "1" supplied to "NonEmptyEntriesArray"', - 'Invalid value "1" supplied to "NonEmptyEntriesArray"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.test.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.test.ts index 7dbc3465610c0..2e54590368959 100644 --- a/x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.test.ts @@ -86,19 +86,6 @@ describe('non_empty_nested_entries_array', () => { 'Invalid value "undefined" supplied to "operator"', 'Invalid value "nested" supplied to "type"', 'Invalid value "undefined" supplied to "value"', - 'Invalid value "undefined" supplied to "operator"', - 'Invalid value "nested" supplied to "type"', - 'Invalid value "undefined" supplied to "value"', - 'Invalid value "undefined" supplied to "operator"', - 'Invalid value "nested" supplied to "type"', - 'Invalid value "undefined" supplied to "operator"', - 'Invalid value "nested" supplied to "type"', - 'Invalid value "undefined" supplied to "value"', - 'Invalid value "undefined" supplied to "operator"', - 'Invalid value "nested" supplied to "type"', - 'Invalid value "undefined" supplied to "value"', - 'Invalid value "undefined" supplied to "operator"', - 'Invalid value "nested" supplied to "type"', ]); expect(message.schema).toEqual({}); }); @@ -123,8 +110,6 @@ describe('non_empty_nested_entries_array', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "1" supplied to "NonEmptyNestedEntriesArray"', - 'Invalid value "1" supplied to "NonEmptyNestedEntriesArray"', - 'Invalid value "1" supplied to "NonEmptyNestedEntriesArray"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/update_comment.test.ts b/x-pack/plugins/lists/common/schemas/types/update_comment.test.ts index ac4d0304cbb8e..ba07421fe60f4 100644 --- a/x-pack/plugins/lists/common/schemas/types/update_comment.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/update_comment.test.ts @@ -110,7 +110,6 @@ describe('CommentsUpdate', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', - 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', ]); expect(message.schema).toEqual({}); }); @@ -142,7 +141,6 @@ describe('CommentsUpdate', () => { expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', - 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts index 00854f1ed5526..d335cafdb7885 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts @@ -127,7 +127,6 @@ describe('create_rules_bulk_schema', () => { const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ 'Invalid value "undefined" supplied to "risk_score"', - 'Invalid value "undefined" supplied to "risk_score"', ]); expect(output.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts index 4cb38889045fc..33a22d9a5f805 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts @@ -123,7 +123,6 @@ describe('update_rules_bulk_schema', () => { const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ 'Invalid value "undefined" supplied to "risk_score"', - 'Invalid value "undefined" supplied to "risk_score"', ]); expect(output.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/format_errors.test.ts b/x-pack/plugins/security_solution/common/format_errors.test.ts index c8cd72b72816b..06bdf67097764 100644 --- a/x-pack/plugins/security_solution/common/format_errors.test.ts +++ b/x-pack/plugins/security_solution/common/format_errors.test.ts @@ -41,6 +41,22 @@ describe('utils', () => { expect(output).toEqual(['some error 1', 'some error 2']); }); + test('it filters out duplicate error messages', () => { + const validationError1: t.ValidationError = { + value: 'Some existing error 1', + context: [], + message: 'some error 1', + }; + const validationError2: t.ValidationError = { + value: 'Some existing error 1', + context: [], + message: 'some error 1', + }; + const errors: t.Errors = [validationError1, validationError2]; + const output = formatErrors(errors); + expect(output).toEqual(['some error 1']); + }); + test('will use message before context if it is set', () => { const context: t.Context = ([{ key: 'some string key' }] as unknown) as t.Context; const validationError1: t.ValidationError = { diff --git a/x-pack/plugins/security_solution/common/format_errors.ts b/x-pack/plugins/security_solution/common/format_errors.ts index ba963f34f2983..4e1f5e4796152 100644 --- a/x-pack/plugins/security_solution/common/format_errors.ts +++ b/x-pack/plugins/security_solution/common/format_errors.ts @@ -8,7 +8,7 @@ import * as t from 'io-ts'; import { isObject } from 'lodash/fp'; export const formatErrors = (errors: t.Errors): string[] => { - return errors.map((error) => { + const err = errors.map((error) => { if (error.message != null) { return error.message; } else { @@ -26,4 +26,6 @@ export const formatErrors = (errors: t.Errors): string[] => { return `Invalid value "${value}" supplied to "${suppliedValue}"`; } }); + + return [...new Set(err)]; }; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/export_timelines_route.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/export_timelines_route.test.ts index a6f0ce232fa7b..5a976ee7521af 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/export_timelines_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/export_timelines_route.test.ts @@ -110,7 +110,7 @@ describe('export timelines', () => { const result = server.validate(request); expect(result.badRequest.mock.calls[0][0]).toEqual( - 'Invalid value "someId" supplied to "ids",Invalid value "someId" supplied to "ids",Invalid value "{"ids":"someId"}" supplied to "(Partial<{ ids: (Array | null) }> | null)"' + 'Invalid value "someId" supplied to "ids",Invalid value "{"ids":"someId"}" supplied to "(Partial<{ ids: (Array | null) }> | null)"' ); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/import_timelines_route.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/import_timelines_route.test.ts index 2ad6c5d6fff60..ff76045db90cb 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/import_timelines_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/import_timelines_route.test.ts @@ -494,10 +494,7 @@ describe('import timelines', () => { const result = server.validate(request); expect(result.badRequest).toHaveBeenCalledWith( - [ - 'Invalid value "undefined" supplied to "file"', - 'Invalid value "undefined" supplied to "file"', - ].join(',') + 'Invalid value "undefined" supplied to "file"' ); }); }); @@ -923,10 +920,7 @@ describe('import timeline templates', () => { const result = server.validate(request); expect(result.badRequest).toHaveBeenCalledWith( - [ - 'Invalid value "undefined" supplied to "file"', - 'Invalid value "undefined" supplied to "file"', - ].join(',') + 'Invalid value "undefined" supplied to "file"' ); }); }); From fbd79ea72677bb4d7aca1c5fc809c2f710e05071 Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Date: Thu, 6 Aug 2020 19:41:18 -0400 Subject: [PATCH 055/106] skip query of detections page when we do not have .siem-signals index (#74580) * skip query of detections page when we do not have .siem-signals index * review I --- .../timelines/containers/helpers.test.ts | 54 +++++++++++++++++++ .../public/timelines/containers/helpers.ts | 17 ++++++ .../public/timelines/containers/index.tsx | 7 ++- 3 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/timelines/containers/helpers.test.ts create mode 100644 x-pack/plugins/security_solution/public/timelines/containers/helpers.ts diff --git a/x-pack/plugins/security_solution/public/timelines/containers/helpers.test.ts b/x-pack/plugins/security_solution/public/timelines/containers/helpers.test.ts new file mode 100644 index 0000000000000..043b5fe39a8bf --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/containers/helpers.test.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { TimelineId } from '../../../common/types/timeline'; +import { skipQueryForDetectionsPage } from './helpers'; + +describe('skipQueryForDetectionsPage', () => { + test('Make sure to NOT skip the query when it is not a timeline from a detection pages', () => { + expect(skipQueryForDetectionsPage(TimelineId.active, ['auditbeat-*', 'filebeat-*'])).toBe( + false + ); + expect( + skipQueryForDetectionsPage(TimelineId.hostsPageEvents, ['auditbeat-*', 'filebeat-*']) + ).toBe(false); + expect( + skipQueryForDetectionsPage(TimelineId.hostsPageExternalAlerts, ['auditbeat-*', 'filebeat-*']) + ).toBe(false); + expect( + skipQueryForDetectionsPage(TimelineId.networkPageExternalAlerts, [ + 'auditbeat-*', + 'filebeat-*', + ]) + ).toBe(false); + }); + + test('Make sure to SKIP the query when it is a timeline from a detection pages without the siem-signals', () => { + expect( + skipQueryForDetectionsPage(TimelineId.detectionsPage, ['auditbeat-*', 'filebeat-*']) + ).toBe(true); + expect( + skipQueryForDetectionsPage(TimelineId.detectionsRulesDetailsPage, [ + 'auditbeat-*', + 'filebeat-*', + ]) + ).toBe(true); + }); + + test('Make sure to NOT skip the query when it is a timeline from a detection pages with the siem-signals', () => { + expect( + skipQueryForDetectionsPage(TimelineId.detectionsPage, [ + 'auditbeat-*', + '.siem-signals-rainbow-butterfly', + ]) + ).toBe(false); + expect( + skipQueryForDetectionsPage(TimelineId.detectionsRulesDetailsPage, [ + '.siem-signals-rainbow-butterfly', + ]) + ).toBe(false); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/containers/helpers.ts b/x-pack/plugins/security_solution/public/timelines/containers/helpers.ts new file mode 100644 index 0000000000000..aef6f4df6f41b --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/containers/helpers.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { TimelineId } from '../../../common/types/timeline'; + +export const detectionsTimelineIds = [ + TimelineId.detectionsPage, + TimelineId.detectionsRulesDetailsPage, +]; + +export const skipQueryForDetectionsPage = (id: string, defaultIndex: string[]) => + id != null && + detectionsTimelineIds.some((timelineId) => timelineId === id) && + !defaultIndex.some((di) => di.toLowerCase().startsWith('.siem-signals')); diff --git a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx index 562999108b4b0..de7175f0a7f97 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx @@ -11,7 +11,6 @@ import { Query } from 'react-apollo'; import { compose, Dispatch } from 'redux'; import { connect, ConnectedProps } from 'react-redux'; -import { TimelineId } from '../../../common/types/timeline'; import { DEFAULT_INDEX_KEY } from '../../../common/constants'; import { IIndexPattern } from '../../../../../../src/plugins/data/common/index_patterns'; import { @@ -28,8 +27,7 @@ import { QueryTemplate, QueryTemplateProps } from '../../common/containers/query import { EventType } from '../../timelines/store/timeline/model'; import { timelineQuery } from './index.gql_query'; import { timelineActions } from '../../timelines/store/timeline'; - -const timelineIds = [TimelineId.detectionsPage, TimelineId.detectionsRulesDetailsPage]; +import { detectionsTimelineIds, skipQueryForDetectionsPage } from './helpers'; export interface TimelineArgs { events: TimelineItem[]; @@ -130,6 +128,7 @@ class TimelineQueryComponent extends QueryTemplate< query={timelineQuery} fetchPolicy="network-only" notifyOnNetworkStatusChange + skip={skipQueryForDetectionsPage(id, defaultIndex)} variables={variables} > {({ data, loading, fetchMore, refetch }) => { @@ -202,7 +201,7 @@ const makeMapStateToProps = () => { const mapDispatchToProps = (dispatch: Dispatch) => ({ clearSignalsState: ({ id }: { id?: string }) => { - if (id != null && timelineIds.some((timelineId) => timelineId === id)) { + if (id != null && detectionsTimelineIds.some((timelineId) => timelineId === id)) { dispatch(timelineActions.clearEventsLoading({ id })); dispatch(timelineActions.clearEventsDeleted({ id })); } From 5d9f329a36d8be7fe8601498beadb1e8f7cfd072 Mon Sep 17 00:00:00 2001 From: Sandra Gonzales Date: Fri, 7 Aug 2020 08:03:13 -0500 Subject: [PATCH 056/106] [Ingest Manager] Integration tests for updating a package (#74593) * add integration tests for updating a package's assets * update to update tests and change to dataset to data_stream * add datastream test --- .../services/epm/elasticsearch/ilm/install.ts | 1 - .../apis/epm/data_stream.ts | 130 ++++++++ .../apis/epm/index.js | 2 + .../apis/epm/install_remove_assets.ts | 5 +- .../apis/epm/update_assets.ts | 299 ++++++++++++++++++ .../0.1.0/dataset/test_logs/fields/ecs.yml | 3 + .../0.1.0/dataset/test_metrics/fields/ecs.yml | 3 + .../visualization/sample_visualization.json | 2 +- .../elasticsearch/ilm_policy/all_assets.json | 15 + .../elasticsearch/ingest_pipeline/default.yml | 7 + .../0.2.0/dataset/test_logs/fields/ecs.yml | 6 + .../0.2.0/dataset/test_logs/fields/fields.yml | 16 + .../0.2.0/dataset/test_logs/manifest.yml | 9 + .../0.2.0/dataset/test_logs2/fields/ecs.yml | 3 + .../dataset/test_logs2/fields/fields.yml | 16 + .../0.2.0/dataset/test_logs2/manifest.yml | 3 + .../0.2.0/dataset/test_metrics/fields/ecs.yml | 3 + .../dataset/test_metrics/fields/fields.yml | 16 + .../0.2.0/dataset/test_metrics/manifest.yml | 3 + .../all_assets/0.2.0/docs/README.md | 3 + .../0.2.0/img/logo_overrides_64_color.svg | 7 + .../kibana/dashboard/sample_dashboard.json | 16 + .../0.2.0/kibana/search/sample_search2.json | 24 ++ .../visualization/sample_visualization.json | 11 + .../all_assets/0.2.0/manifest.yml | 20 ++ .../elasticsearch/ilm_policy/all_assets.json | 15 + .../elasticsearch/ingest_pipeline/default.yml | 7 + .../0.1.0/dataset/test_logs/fields/ecs.yml | 3 + .../0.1.0/dataset/test_logs/fields/fields.yml | 16 + .../0.1.0/dataset/test_logs/manifest.yml | 9 + .../0.1.0/dataset/test_metrics/fields/ecs.yml | 3 + .../dataset/test_metrics/fields/fields.yml | 16 + .../0.1.0/dataset/test_metrics/manifest.yml | 3 + .../datastreams/0.1.0/docs/README.md | 3 + .../datastreams/0.1.0/manifest.yml | 20 ++ .../elasticsearch/ilm_policy/all_assets.json | 15 + .../elasticsearch/ingest_pipeline/default.yml | 7 + .../0.2.0/dataset/test_logs/fields/ecs.yml | 6 + .../0.2.0/dataset/test_logs/fields/fields.yml | 16 + .../0.2.0/dataset/test_logs/manifest.yml | 9 + .../0.2.0/dataset/test_metrics/fields/ecs.yml | 6 + .../dataset/test_metrics/fields/fields.yml | 16 + .../0.2.0/dataset/test_metrics/manifest.yml | 3 + .../datastreams/0.2.0/docs/README.md | 3 + .../datastreams/0.2.0/manifest.yml | 20 ++ 45 files changed, 816 insertions(+), 3 deletions(-) create mode 100644 x-pack/test/ingest_manager_api_integration/apis/epm/data_stream.ts create mode 100644 x-pack/test/ingest_manager_api_integration/apis/epm/update_assets.ts create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/docs/README.md create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/img/logo_overrides_64_color.svg create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/dashboard/sample_dashboard.json create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/search/sample_search2.json create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/visualization/sample_visualization.json create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/docs/README.md create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/docs/README.md create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/manifest.yml diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ilm/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ilm/install.ts index 9590167657d98..c5253e4902cab 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ilm/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ilm/install.ts @@ -16,7 +16,6 @@ export async function installILMPolicy(paths: string[], callCluster: CallESAsCur const { file } = Registry.pathParts(path); const name = file.substr(0, file.lastIndexOf('.')); try { - if (await policyExists(name, callCluster)) return; await callCluster('transport.request', { method: 'PUT', path: '/_ilm/policy/' + name, diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/data_stream.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/data_stream.ts new file mode 100644 index 0000000000000..68a4812d4af40 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/data_stream.ts @@ -0,0 +1,130 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { skipIfNoDockerRegistry } from '../../helpers'; + +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; + const supertest = getService('supertest'); + const es = getService('es'); + const pkgName = 'datastreams'; + const pkgVersion = '0.1.0'; + const pkgUpdateVersion = '0.2.0'; + const pkgKey = `${pkgName}-${pkgVersion}`; + const pkgUpdateKey = `${pkgName}-${pkgUpdateVersion}`; + const logsTemplateName = `logs-${pkgName}.test_logs`; + const metricsTemplateName = `metrics-${pkgName}.test_metrics`; + + const uninstallPackage = async (pkg: string) => { + await supertest.delete(`/api/ingest_manager/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + }; + const installPackage = async (pkg: string) => { + await supertest + .post(`/api/ingest_manager/epm/packages/${pkg}`) + .set('kbn-xsrf', 'xxxx') + .send({ force: true }); + }; + + describe('datastreams', async () => { + skipIfNoDockerRegistry(providerContext); + before(async () => { + await installPackage(pkgKey); + await es.transport.request({ + method: 'POST', + path: `/${logsTemplateName}-default/_doc`, + body: { + '@timestamp': '2015-01-01', + logs_test_name: 'test', + data_stream: { + dataset: `${pkgName}.test_logs`, + namespace: 'default', + type: 'logs', + }, + }, + }); + await es.transport.request({ + method: 'POST', + path: `/${metricsTemplateName}-default/_doc`, + body: { + '@timestamp': '2015-01-01', + logs_test_name: 'test', + data_stream: { + dataset: `${pkgName}.test_metrics`, + namespace: 'default', + type: 'metrics', + }, + }, + }); + }); + after(async () => { + await uninstallPackage(pkgUpdateKey); + await es.transport.request({ + method: 'DELETE', + path: `/_data_stream/${logsTemplateName}-default`, + }); + await es.transport.request({ + method: 'DELETE', + path: `/_data_stream/${metricsTemplateName}-default`, + }); + }); + describe('get datastreams after data sent', async () => { + skipIfNoDockerRegistry(providerContext); + let resLogsDatastream: any; + let resMetricsDatastream: any; + before(async () => { + resLogsDatastream = await es.transport.request({ + method: 'GET', + path: `/_data_stream/${logsTemplateName}-default`, + }); + resMetricsDatastream = await es.transport.request({ + method: 'GET', + path: `/_data_stream/${metricsTemplateName}-default`, + }); + }); + it('should list the logs datastream', async function () { + expect(resLogsDatastream.body.data_streams.length).equal(1); + expect(resLogsDatastream.body.data_streams[0].indices.length).equal(1); + expect(resLogsDatastream.body.data_streams[0].indices[0].index_name).equal( + `.ds-${logsTemplateName}-default-000001` + ); + }); + it('should list the metrics datastream', async function () { + expect(resMetricsDatastream.body.data_streams.length).equal(1); + expect(resMetricsDatastream.body.data_streams[0].indices.length).equal(1); + expect(resMetricsDatastream.body.data_streams[0].indices[0].index_name).equal( + `.ds-${metricsTemplateName}-default-000001` + ); + }); + }); + describe('rollover datastream when mappings are not compatible', async () => { + skipIfNoDockerRegistry(providerContext); + let resLogsDatastream: any; + let resMetricsDatastream: any; + before(async () => { + await installPackage(pkgUpdateKey); + resLogsDatastream = await es.transport.request({ + method: 'GET', + path: `/_data_stream/${logsTemplateName}-default`, + }); + resMetricsDatastream = await es.transport.request({ + method: 'GET', + path: `/_data_stream/${metricsTemplateName}-default`, + }); + }); + it('should have rolled over logs datastream', async function () { + expect(resLogsDatastream.body.data_streams[0].indices.length).equal(2); + expect(resLogsDatastream.body.data_streams[0].indices[1].index_name).equal( + `.ds-${logsTemplateName}-default-000002` + ); + }); + it('should have not rolled over metrics datastream', async function () { + expect(resMetricsDatastream.body.data_streams[0].indices.length).equal(1); + }); + }); + }); +} diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/index.js b/x-pack/test/ingest_manager_api_integration/apis/epm/index.js index 1582f72dd1cd8..0f32d2b4ae703 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/epm/index.js +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/index.js @@ -13,5 +13,7 @@ export default function loadTests({ loadTestFile }) { loadTestFile(require.resolve('./install_overrides')); loadTestFile(require.resolve('./install_remove_assets')); loadTestFile(require.resolve('./install_update')); + loadTestFile(require.resolve('./update_assets')); + loadTestFile(require.resolve('./data_stream')); }); } diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts index 35058de0684b2..03d0b6abb4802 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts @@ -23,7 +23,10 @@ export default function (providerContext: FtrProviderContext) { await supertest.delete(`/api/ingest_manager/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); }; const installPackage = async (pkg: string) => { - await supertest.post(`/api/ingest_manager/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + await supertest + .post(`/api/ingest_manager/epm/packages/${pkg}`) + .set('kbn-xsrf', 'xxxx') + .send({ force: true }); }; describe('installs and uninstalls all assets', async () => { diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/update_assets.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/update_assets.ts new file mode 100644 index 0000000000000..59ad7a9744ae1 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/update_assets.ts @@ -0,0 +1,299 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { skipIfNoDockerRegistry } from '../../helpers'; + +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; + const kibanaServer = getService('kibanaServer'); + const supertest = getService('supertest'); + const es = getService('es'); + const pkgName = 'all_assets'; + const pkgVersion = '0.1.0'; + const pkgUpdateVersion = '0.2.0'; + const pkgKey = `${pkgName}-${pkgVersion}`; + const pkgUpdateKey = `${pkgName}-${pkgUpdateVersion}`; + const logsTemplateName = `logs-${pkgName}.test_logs`; + const logsTemplateName2 = `logs-${pkgName}.test_logs2`; + const metricsTemplateName = `metrics-${pkgName}.test_metrics`; + + const uninstallPackage = async (pkg: string) => { + await supertest.delete(`/api/ingest_manager/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + }; + const installPackage = async (pkg: string) => { + await supertest + .post(`/api/ingest_manager/epm/packages/${pkg}`) + .set('kbn-xsrf', 'xxxx') + .send({ force: true }); + }; + + describe('updates all assets when updating a package to a different version', async () => { + skipIfNoDockerRegistry(providerContext); + before(async () => { + await installPackage(pkgKey); + await installPackage(pkgUpdateKey); + }); + after(async () => { + await uninstallPackage(pkgUpdateKey); + }); + it('should have updated the ILM policy', async function () { + const resPolicy = await es.transport.request({ + method: 'GET', + path: `/_ilm/policy/all_assets`, + }); + expect(resPolicy.body.all_assets.policy).eql({ + phases: { + hot: { + min_age: '1ms', + actions: { + rollover: { + max_size: '50gb', + max_age: '31d', + }, + }, + }, + }, + }); + }); + it('should have updated the index templates', async function () { + const resLogsTemplate = await es.transport.request({ + method: 'GET', + path: `/_index_template/${logsTemplateName}`, + }); + expect(resLogsTemplate.statusCode).equal(200); + expect( + resLogsTemplate.body.index_templates[0].index_template.template.mappings.properties + ).eql({ + '@timestamp': { + type: 'date', + }, + logs_test_name: { + type: 'text', + }, + new_field_name: { + ignore_above: 1024, + type: 'keyword', + }, + data_stream: { + properties: { + dataset: { + type: 'constant_keyword', + }, + namespace: { + type: 'constant_keyword', + }, + type: { + type: 'constant_keyword', + }, + }, + }, + }); + const resMetricsTemplate = await es.transport.request({ + method: 'GET', + path: `/_index_template/${metricsTemplateName}`, + }); + expect(resMetricsTemplate.statusCode).equal(200); + expect( + resMetricsTemplate.body.index_templates[0].index_template.template.mappings.properties + ).eql({ + '@timestamp': { + type: 'date', + }, + metrics_test_name2: { + ignore_above: 1024, + type: 'keyword', + }, + data_stream: { + properties: { + dataset: { + type: 'constant_keyword', + }, + namespace: { + type: 'constant_keyword', + }, + type: { + type: 'constant_keyword', + }, + }, + }, + }); + }); + it('should have installed the new index template', async function () { + const resLogsTemplate = await es.transport.request({ + method: 'GET', + path: `/_index_template/${logsTemplateName2}`, + }); + expect(resLogsTemplate.statusCode).equal(200); + expect( + resLogsTemplate.body.index_templates[0].index_template.template.mappings.properties + ).eql({ + '@timestamp': { + type: 'date', + }, + test_logs2: { + ignore_above: 1024, + type: 'keyword', + }, + data_stream: { + properties: { + dataset: { + type: 'constant_keyword', + }, + namespace: { + type: 'constant_keyword', + }, + type: { + type: 'constant_keyword', + }, + }, + }, + }); + }); + it('should have installed the new versionized pipeline', async function () { + const res = await es.transport.request({ + method: 'GET', + path: `/_ingest/pipeline/${logsTemplateName}-${pkgUpdateVersion}`, + }); + expect(res.statusCode).equal(200); + }); + it('should have removed the old versionized pipelines', async function () { + let res; + try { + res = await es.transport.request({ + method: 'GET', + path: `/_ingest/pipeline/${logsTemplateName}-${pkgVersion}`, + }); + } catch (err) { + res = err; + } + expect(res.statusCode).equal(404); + }); + it('should have updated the template components', async function () { + const res = await es.transport.request({ + method: 'GET', + path: `/_component_template/${logsTemplateName}-mappings`, + }); + expect(res.statusCode).equal(200); + expect(res.body.component_templates[0].component_template.template.mappings).eql({ + dynamic: true, + properties: { '@timestamp': { type: 'date' } }, + }); + const resSettings = await es.transport.request({ + method: 'GET', + path: `/_component_template/${logsTemplateName}-settings`, + }); + expect(res.statusCode).equal(200); + expect(resSettings.body.component_templates[0].component_template.template.settings).eql({ + index: { lifecycle: { name: 'reference2' } }, + }); + }); + it('should have updated the index patterns', async function () { + const resIndexPatternLogs = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'logs-*', + }); + const fields = JSON.parse(resIndexPatternLogs.attributes.fields); + const updated = fields.filter((field: { name: string }) => field.name === 'new_field_name'); + expect(!!updated.length).equal(true); + const resIndexPatternMetrics = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'metrics-*', + }); + const fieldsMetrics = JSON.parse(resIndexPatternMetrics.attributes.fields); + const updatedMetrics = fieldsMetrics.filter( + (field: { name: string }) => field.name === 'metrics_test_name2' + ); + expect(!!updatedMetrics.length).equal(true); + }); + it('should have updated the kibana assets', async function () { + const resDashboard = await kibanaServer.savedObjects.get({ + type: 'dashboard', + id: 'sample_dashboard', + }); + expect(resDashboard.id).equal('sample_dashboard'); + let resDashboard2; + try { + resDashboard2 = await kibanaServer.savedObjects.get({ + type: 'dashboard', + id: 'sample_dashboard2', + }); + } catch (err) { + resDashboard2 = err; + } + expect(resDashboard2.response.data.statusCode).equal(404); + const resVis = await kibanaServer.savedObjects.get({ + type: 'visualization', + id: 'sample_visualization', + }); + expect(resVis.attributes.description).equal('sample visualization 0.2.0'); + let resSearch; + try { + resSearch = await kibanaServer.savedObjects.get({ + type: 'search', + id: 'sample_search', + }); + } catch (err) { + resSearch = err; + } + expect(resSearch.response.data.statusCode).equal(404); + const resSearch2 = await kibanaServer.savedObjects.get({ + type: 'search', + id: 'sample_search2', + }); + expect(resSearch2.id).equal('sample_search2'); + }); + it('should have updated the saved object', async function () { + const res = await kibanaServer.savedObjects.get({ + type: 'epm-packages', + id: 'all_assets', + }); + expect(res.attributes).eql({ + installed_kibana: [ + { + id: 'sample_dashboard', + type: 'dashboard', + }, + { + id: 'sample_search2', + type: 'search', + }, + { + id: 'sample_visualization', + type: 'visualization', + }, + ], + installed_es: [ + { + id: 'logs-all_assets.test_logs-0.2.0', + type: 'ingest_pipeline', + }, + { + id: 'logs-all_assets.test_logs', + type: 'index_template', + }, + { + id: 'logs-all_assets.test_logs2', + type: 'index_template', + }, + { + id: 'metrics-all_assets.test_metrics', + type: 'index_template', + }, + ], + es_index_patterns: { + test_logs: 'logs-all_assets.test_logs-*', + test_metrics: 'metrics-all_assets.test_metrics-*', + }, + name: 'all_assets', + version: '0.2.0', + internal: false, + removable: true, + }); + }); + }); +} diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/ecs.yml new file mode 100644 index 0000000000000..3d88fe5dfefb6 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/ecs.yml @@ -0,0 +1,3 @@ +- name: logs_test_name + title: logs_test_title + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/ecs.yml new file mode 100644 index 0000000000000..a30e3c7a87856 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/ecs.yml @@ -0,0 +1,3 @@ +- name: metrics_test_name + title: metrics_test_title + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/kibana/visualization/sample_visualization.json b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/kibana/visualization/sample_visualization.json index e814b83bbf324..917479fd7d120 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/kibana/visualization/sample_visualization.json +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/kibana/visualization/sample_visualization.json @@ -1,6 +1,6 @@ { "attributes": { - "description": "sample visualization", + "description": "sample visualization update", "title": "sample vis title", "uiStateJSON": "{}", "version": 1, diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json new file mode 100644 index 0000000000000..d8bab8a75f680 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json @@ -0,0 +1,15 @@ +{ + "policy": { + "phases": { + "hot": { + "min_age": "1ms", + "actions": { + "rollover": { + "max_size": "50gb", + "max_age": "31d" + } + } + } + } + } +} \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml new file mode 100644 index 0000000000000..580db049d0d5d --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml @@ -0,0 +1,7 @@ +--- +description: Pipeline for parsing test logs + plugins. +processors: +- set: + field: error.message + value: '{{ _ingest.on_failure_message }}' \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/fields/ecs.yml new file mode 100644 index 0000000000000..7df52cc11fd20 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/fields/ecs.yml @@ -0,0 +1,6 @@ +- name: logs_test_name + title: logs_test_title + type: text +- name: new_field_name + title: new_field_title + type: keyword diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/manifest.yml new file mode 100644 index 0000000000000..8a53f9e26e827 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs/manifest.yml @@ -0,0 +1,9 @@ +title: Test Dataset + +type: logs + +elasticsearch: + index_template.mappings: + dynamic: true + index_template.settings: + index.lifecycle.name: reference2 \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/fields/ecs.yml new file mode 100644 index 0000000000000..c5819deb1ee37 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/fields/ecs.yml @@ -0,0 +1,3 @@ +- name: test_logs2 + title: test_logs2 + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/manifest.yml new file mode 100644 index 0000000000000..e12f454657ea2 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_logs2/manifest.yml @@ -0,0 +1,3 @@ +title: Test Dataset + +type: logs \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/fields/ecs.yml new file mode 100644 index 0000000000000..9529c3a8eaf1a --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/fields/ecs.yml @@ -0,0 +1,3 @@ +- name: metrics_test_name2 + title: metrics_test_title2 + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/manifest.yml new file mode 100644 index 0000000000000..6bc20442bd432 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/dataset/test_metrics/manifest.yml @@ -0,0 +1,3 @@ +title: Test Dataset + +type: metrics \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/docs/README.md b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/docs/README.md new file mode 100644 index 0000000000000..2617f1fcabe11 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/docs/README.md @@ -0,0 +1,3 @@ +# Test package + +For testing that a package installs its elasticsearch assets when installed for the first time (not updating) and removing the package diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/img/logo_overrides_64_color.svg b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/img/logo_overrides_64_color.svg new file mode 100644 index 0000000000000..b03007a76ffcc --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/img/logo_overrides_64_color.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/dashboard/sample_dashboard.json b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/dashboard/sample_dashboard.json new file mode 100644 index 0000000000000..ef08d69324210 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/dashboard/sample_dashboard.json @@ -0,0 +1,16 @@ +{ + "attributes": { + "description": "Sample dashboard", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"highlightAll\":true,\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false}", + "panelsJSON": "[{\"embeddableConfig\":{},\"gridData\":{\"h\":12,\"i\":\"1\",\"w\":24,\"x\":0,\"y\":0},\"panelIndex\":\"1\",\"panelRefName\":\"panel_0\",\"version\":\"7.3.0\"},{\"embeddableConfig\":{\"columns\":[\"kafka.log.class\",\"kafka.log.trace.class\",\"kafka.log.trace.full\"],\"sort\":[\"@timestamp\",\"desc\"]},\"gridData\":{\"h\":12,\"i\":\"2\",\"w\":24,\"x\":24,\"y\":0},\"panelIndex\":\"2\",\"panelRefName\":\"panel_1\",\"version\":\"7.3.0\"},{\"embeddableConfig\":{\"columns\":[\"log.level\",\"kafka.log.component\",\"message\"],\"sort\":[\"@timestamp\",\"desc\"]},\"gridData\":{\"h\":20,\"i\":\"3\",\"w\":48,\"x\":0,\"y\":20},\"panelIndex\":\"3\",\"panelRefName\":\"panel_2\",\"version\":\"7.3.0\"},{\"embeddableConfig\":{},\"gridData\":{\"h\":8,\"i\":\"4\",\"w\":48,\"x\":0,\"y\":12},\"panelIndex\":\"4\",\"panelRefName\":\"panel_3\",\"version\":\"7.3.0\"}]", + "timeRestore": false, + "title": "[Logs Sample] Overview ECS", + "version": 1 + }, + "id": "sample_dashboard", + "type": "dashboard" +} \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/search/sample_search2.json b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/search/sample_search2.json new file mode 100644 index 0000000000000..aa5cea19208a4 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/search/sample_search2.json @@ -0,0 +1,24 @@ +{ + "attributes": { + "columns": [ + "log.level", + "kafka.log.component", + "message" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"$state\":{\"store\":\"appState\"},\"meta\":{\"alias\":null,\"disabled\":false,\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\",\"key\":\"dataset.name\",\"negate\":false,\"params\":{\"query\":\"kafka.log\",\"type\":\"phrase\"},\"type\":\"phrase\",\"value\":\"log\"},\"query\":{\"match\":{\"dataset.name\":{\"query\":\"kafka.log\",\"type\":\"phrase\"}}}}],\"highlightAll\":true,\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"version\":true}" + }, + "sort": [ + [ + "@timestamp", + "desc" + ] + ], + "title": "All logs [Logs Kafka] ECS", + "version": 1 + }, + "id": "sample_search2", + "type": "search" +} \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/visualization/sample_visualization.json b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/visualization/sample_visualization.json new file mode 100644 index 0000000000000..626f1f787f421 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/visualization/sample_visualization.json @@ -0,0 +1,11 @@ +{ + "attributes": { + "description": "sample visualization 0.2.0", + "title": "sample vis title", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"aggs\":[{\"enabled\":true,\"id\":\"1\",\"params\":{},\"schema\":\"metric\",\"type\":\"count\"},{\"enabled\":true,\"id\":\"2\",\"params\":{\"extended_bounds\":{},\"field\":\"@timestamp\",\"interval\":\"auto\",\"min_doc_count\":1},\"schema\":\"segment\",\"type\":\"date_histogram\"},{\"enabled\":true,\"id\":\"3\",\"params\":{\"customLabel\":\"Log Level\",\"field\":\"log.level\",\"order\":\"desc\",\"orderBy\":\"1\",\"size\":5},\"schema\":\"group\",\"type\":\"terms\"}],\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"labels\":{\"show\":true,\"truncate\":100},\"position\":\"bottom\",\"scale\":{\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{\"text\":\"@timestamp per day\"},\"type\":\"category\"}],\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"legendPosition\":\"right\",\"seriesParams\":[{\"data\":{\"id\":\"1\",\"label\":\"Count\"},\"drawLinesBetweenPoints\":true,\"mode\":\"stacked\",\"show\":\"true\",\"showCircles\":true,\"type\":\"histogram\",\"valueAxis\":\"ValueAxis-1\"}],\"times\":[],\"type\":\"histogram\",\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"labels\":{\"filter\":false,\"rotate\":0,\"show\":true,\"truncate\":100},\"name\":\"LeftAxis-1\",\"position\":\"left\",\"scale\":{\"mode\":\"normal\",\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{\"text\":\"Count\"},\"type\":\"value\"}]},\"title\":\"Log levels over time [Logs Kafka] ECS\",\"type\":\"histogram\"}" + }, + "id": "sample_visualization", + "type": "visualization" +} \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/manifest.yml new file mode 100644 index 0000000000000..70da51a14bce8 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/manifest.yml @@ -0,0 +1,20 @@ +format_version: 1.0.0 +name: all_assets +title: All Assets Updated +description: tests that all assets are updated +version: 0.2.0 +categories: [] +release: beta +type: integration +license: basic + +requirement: + elasticsearch: + versions: '>7.7.0' + kibana: + versions: '>7.7.0' + +icons: + - src: '/img/logo_overrides_64_color.svg' + size: '16x16' + type: 'image/svg+xml' diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json new file mode 100644 index 0000000000000..7cf62e890f865 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json @@ -0,0 +1,15 @@ +{ + "policy": { + "phases": { + "hot": { + "min_age": "0ms", + "actions": { + "rollover": { + "max_size": "50gb", + "max_age": "30d" + } + } + } + } + } +} \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml new file mode 100644 index 0000000000000..580db049d0d5d --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml @@ -0,0 +1,7 @@ +--- +description: Pipeline for parsing test logs + plugins. +processors: +- set: + field: error.message + value: '{{ _ingest.on_failure_message }}' \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/fields/ecs.yml new file mode 100644 index 0000000000000..3d88fe5dfefb6 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/fields/ecs.yml @@ -0,0 +1,3 @@ +- name: logs_test_name + title: logs_test_title + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/manifest.yml new file mode 100644 index 0000000000000..8cd522e2845bb --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_logs/manifest.yml @@ -0,0 +1,9 @@ +title: Test Dataset + +type: logs + +elasticsearch: + index_template.mappings: + dynamic: false + index_template.settings: + index.lifecycle.name: reference \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/fields/ecs.yml new file mode 100644 index 0000000000000..a30e3c7a87856 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/fields/ecs.yml @@ -0,0 +1,3 @@ +- name: metrics_test_name + title: metrics_test_title + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/manifest.yml new file mode 100644 index 0000000000000..6bc20442bd432 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/dataset/test_metrics/manifest.yml @@ -0,0 +1,3 @@ +title: Test Dataset + +type: metrics \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/docs/README.md b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/docs/README.md new file mode 100644 index 0000000000000..34b1f08a55cbe --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/docs/README.md @@ -0,0 +1,3 @@ +# Test package + +For testing that datastream rolls over when mappings are not compatible diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/manifest.yml new file mode 100644 index 0000000000000..0ab43760b7ee8 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.1.0/manifest.yml @@ -0,0 +1,20 @@ +format_version: 1.0.0 +name: datastreams +title: datastream test +description: This is a test package for testing that datastreams rollover when mappings are incompatible +version: 0.1.0 +categories: [] +release: beta +type: integration +license: basic + +requirement: + elasticsearch: + versions: '>7.7.0' + kibana: + versions: '>7.7.0' + +icons: + - src: '/img/logo_overrides_64_color.svg' + size: '16x16' + type: 'image/svg+xml' diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json new file mode 100644 index 0000000000000..d8bab8a75f680 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/elasticsearch/ilm_policy/all_assets.json @@ -0,0 +1,15 @@ +{ + "policy": { + "phases": { + "hot": { + "min_age": "1ms", + "actions": { + "rollover": { + "max_size": "50gb", + "max_age": "31d" + } + } + } + } + } +} \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml new file mode 100644 index 0000000000000..580db049d0d5d --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/elasticsearch/ingest_pipeline/default.yml @@ -0,0 +1,7 @@ +--- +description: Pipeline for parsing test logs + plugins. +processors: +- set: + field: error.message + value: '{{ _ingest.on_failure_message }}' \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/fields/ecs.yml new file mode 100644 index 0000000000000..7df52cc11fd20 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/fields/ecs.yml @@ -0,0 +1,6 @@ +- name: logs_test_name + title: logs_test_title + type: text +- name: new_field_name + title: new_field_title + type: keyword diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/manifest.yml new file mode 100644 index 0000000000000..8a53f9e26e827 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_logs/manifest.yml @@ -0,0 +1,9 @@ +title: Test Dataset + +type: logs + +elasticsearch: + index_template.mappings: + dynamic: true + index_template.settings: + index.lifecycle.name: reference2 \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/fields/ecs.yml new file mode 100644 index 0000000000000..8fb3ccd3de8fd --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/fields/ecs.yml @@ -0,0 +1,6 @@ +- name: metrics_test_name + title: metrics_test_title + type: keyword +- name: metrics_test_name2 + title: metrics_test_title2 + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/manifest.yml new file mode 100644 index 0000000000000..6bc20442bd432 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/dataset/test_metrics/manifest.yml @@ -0,0 +1,3 @@ +title: Test Dataset + +type: metrics \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/docs/README.md b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/docs/README.md new file mode 100644 index 0000000000000..34b1f08a55cbe --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/docs/README.md @@ -0,0 +1,3 @@ +# Test package + +For testing that datastream rolls over when mappings are not compatible diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/manifest.yml new file mode 100644 index 0000000000000..1aa1410bd0aef --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/datastreams/0.2.0/manifest.yml @@ -0,0 +1,20 @@ +format_version: 1.0.0 +name: datastreams +title: datastream test +description: This is a test package for testing that datastreams rollover when mappings are incompatible +version: 0.2.0 +categories: [] +release: beta +type: integration +license: basic + +requirement: + elasticsearch: + versions: '>7.7.0' + kibana: + versions: '>7.7.0' + +icons: + - src: '/img/logo_overrides_64_color.svg' + size: '16x16' + type: 'image/svg+xml' From 7dc33f9ba8f93873dcd15509da125587c1730bb4 Mon Sep 17 00:00:00 2001 From: Robert Austin Date: Fri, 7 Aug 2020 09:15:35 -0400 Subject: [PATCH 057/106] [Resolver] UI tests for the panel and bug fix (#74421) * Change the way the resolver simulator works * refactor resolver tree and data access layer mocks * Fix bug where timestamp and pid sometimes don't show in the node detail view * add a few tests for the panel (not done, but worth committing.) --- .../common/endpoint/types.ts | 9 + ...ildren.ts => no_ancestors_two_children.ts} | 48 ++--- ..._children_with_related_events_on_origin.ts | 94 +++++++++ .../{store => }/mocks/endpoint_event.ts | 21 +- .../{store => }/mocks/resolver_tree.ts | 48 +++-- .../resolver/store/data/selectors.test.ts | 2 +- .../resolver/store/mocks/related_event.ts | 36 ---- .../public/resolver/store/selectors.test.ts | 2 +- .../test_utilities/simulator/index.tsx | 194 ++++++++---------- .../resolver/view/clickthrough.test.tsx | 81 ++++---- .../public/resolver/view/panel.test.tsx | 59 ++++++ .../resolver/view/panels/process_details.tsx | 26 ++- .../view/panels/process_list_with_counts.tsx | 7 +- 13 files changed, 390 insertions(+), 237 deletions(-) rename x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/{one_ancestor_two_children.ts => no_ancestors_two_children.ts} (62%) create mode 100644 x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_with_related_events_on_origin.ts rename x-pack/plugins/security_solution/public/resolver/{store => }/mocks/endpoint_event.ts (66%) rename x-pack/plugins/security_solution/public/resolver/{store => }/mocks/resolver_tree.ts (89%) delete mode 100644 x-pack/plugins/security_solution/public/resolver/store/mocks/related_event.ts create mode 100644 x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx diff --git a/x-pack/plugins/security_solution/common/endpoint/types.ts b/x-pack/plugins/security_solution/common/endpoint/types.ts index 61ce672405fd5..ffde47825b501 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types.ts @@ -182,6 +182,15 @@ export interface ResolverRelatedEvents { nextEvent: string | null; } +/** + * Safe version of `ResolverRelatedEvents` + */ +export interface SafeResolverRelatedEvents { + entityID: string; + events: SafeResolverEvent[]; + nextEvent: string | null; +} + /** * Response structure for the alerts route. */ diff --git a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/one_ancestor_two_children.ts b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children.ts similarity index 62% rename from x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/one_ancestor_two_children.ts rename to x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children.ts index 94c176d343d17..b0407fa5d7c1d 100644 --- a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/one_ancestor_two_children.ts +++ b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children.ts @@ -9,11 +9,8 @@ import { ResolverTree, ResolverEntityIndex, } from '../../../../common/endpoint/types'; -import { mockEndpointEvent } from '../../store/mocks/endpoint_event'; -import { - mockTreeWithNoAncestorsAnd2Children, - withRelatedEventsOnOrigin, -} from '../../store/mocks/resolver_tree'; +import { mockEndpointEvent } from '../../mocks/endpoint_event'; +import { mockTreeWithNoAncestorsAnd2Children } from '../../mocks/resolver_tree'; import { DataAccessLayer } from '../../types'; interface Metadata { @@ -43,24 +40,11 @@ interface Metadata { /** * A simple mock dataAccessLayer possible that returns a tree with 0 ancestors and 2 direct children. 1 related event is returned. The parameter to `entities` is ignored. */ -export function oneAncestorTwoChildren( - { withRelatedEvents }: { withRelatedEvents: Iterable<[string, string]> | null } = { - withRelatedEvents: null, - } -): { dataAccessLayer: DataAccessLayer; metadata: Metadata } { +export function noAncestorsTwoChildren(): { dataAccessLayer: DataAccessLayer; metadata: Metadata } { const metadata: Metadata = { databaseDocumentID: '_id', entityIDs: { origin: 'origin', firstChild: 'firstChild', secondChild: 'secondChild' }, }; - const baseTree = mockTreeWithNoAncestorsAnd2Children({ - originID: metadata.entityIDs.origin, - firstChildID: metadata.entityIDs.firstChild, - secondChildID: metadata.entityIDs.secondChild, - }); - const composedTree = withRelatedEvents - ? withRelatedEventsOnOrigin(baseTree, withRelatedEvents) - : baseTree; - return { metadata, dataAccessLayer: { @@ -70,17 +54,13 @@ export function oneAncestorTwoChildren( relatedEvents(entityID: string): Promise { return Promise.resolve({ entityID, - events: - /* Respond with the mocked related events when the origin's related events are fetched*/ withRelatedEvents && - entityID === metadata.entityIDs.origin - ? composedTree.relatedEvents.events - : [ - mockEndpointEvent({ - entityID, - name: 'event', - timestamp: 0, - }), - ], + events: [ + mockEndpointEvent({ + entityID, + name: 'event', + timestamp: 0, + }), + ], nextEvent: null, }); }, @@ -89,7 +69,13 @@ export function oneAncestorTwoChildren( * Fetch a ResolverTree for a entityID */ resolverTree(): Promise { - return Promise.resolve(composedTree); + return Promise.resolve( + mockTreeWithNoAncestorsAnd2Children({ + originID: metadata.entityIDs.origin, + firstChildID: metadata.entityIDs.firstChild, + secondChildID: metadata.entityIDs.secondChild, + }) + ); }, /** diff --git a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_with_related_events_on_origin.ts b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_with_related_events_on_origin.ts new file mode 100644 index 0000000000000..01e75e3eefdbf --- /dev/null +++ b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_with_related_events_on_origin.ts @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DataAccessLayer } from '../../types'; +import { mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin } from '../../mocks/resolver_tree'; +import { + ResolverRelatedEvents, + ResolverTree, + ResolverEntityIndex, +} from '../../../../common/endpoint/types'; + +interface Metadata { + /** + * The `_id` of the document being analyzed. + */ + databaseDocumentID: string; + /** + * A record of entityIDs to be used in tests assertions. + */ + entityIDs: { + /** + * The entityID of the node related to the document being analyzed. + */ + origin: 'origin'; + /** + * The entityID of the first child of the origin. + */ + firstChild: 'firstChild'; + /** + * The entityID of the second child of the origin. + */ + secondChild: 'secondChild'; + }; +} + +export function noAncestorsTwoChildrenWithRelatedEventsOnOrigin(): { + dataAccessLayer: DataAccessLayer; + metadata: Metadata; +} { + const metadata: Metadata = { + databaseDocumentID: '_id', + entityIDs: { origin: 'origin', firstChild: 'firstChild', secondChild: 'secondChild' }, + }; + const tree = mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin({ + originID: metadata.entityIDs.origin, + firstChildID: metadata.entityIDs.firstChild, + secondChildID: metadata.entityIDs.secondChild, + }); + + return { + metadata, + dataAccessLayer: { + /** + * Fetch related events for an entity ID + */ + relatedEvents(entityID: string): Promise { + /** + * Respond with the mocked related events when the origin's related events are fetched. + **/ + const events = entityID === metadata.entityIDs.origin ? tree.relatedEvents.events : []; + + return Promise.resolve({ + entityID, + events, + nextEvent: null, + } as ResolverRelatedEvents); + }, + + /** + * Fetch a ResolverTree for a entityID + */ + resolverTree(): Promise { + return Promise.resolve(tree); + }, + + /** + * Get an array of index patterns that contain events. + */ + indexPatterns(): string[] { + return ['index pattern']; + }, + + /** + * Get entities matching a document. + */ + entities(): Promise { + return Promise.resolve([{ entity_id: metadata.entityIDs.origin }]); + }, + }, + }; +} diff --git a/x-pack/plugins/security_solution/public/resolver/store/mocks/endpoint_event.ts b/x-pack/plugins/security_solution/public/resolver/mocks/endpoint_event.ts similarity index 66% rename from x-pack/plugins/security_solution/public/resolver/store/mocks/endpoint_event.ts rename to x-pack/plugins/security_solution/public/resolver/mocks/endpoint_event.ts index 709f2faf13b00..c822fdf647c16 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/mocks/endpoint_event.ts +++ b/x-pack/plugins/security_solution/public/resolver/mocks/endpoint_event.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EndpointEvent } from '../../../../common/endpoint/types'; +import { EndpointEvent } from '../../../common/endpoint/types'; /** * Simple mock endpoint event that works for tree layouts. @@ -28,10 +28,29 @@ export function mockEndpointEvent({ type: lifecycleType ? lifecycleType : 'start', category: 'process', }, + agent: { + id: 'agent.id', + version: 'agent.version', + type: 'agent.type', + }, + ecs: { + version: 'ecs.version', + }, + user: { + name: 'user.name', + domain: 'user.domain', + }, process: { entity_id: entityID, + executable: 'executable', + args: 'args', name, + pid: 0, + hash: { + md5: 'hash.md5', + }, parent: { + pid: 0, entity_id: parentEntityId, }, }, diff --git a/x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts b/x-pack/plugins/security_solution/public/resolver/mocks/resolver_tree.ts similarity index 89% rename from x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts rename to x-pack/plugins/security_solution/public/resolver/mocks/resolver_tree.ts index 21d0309501aa8..5d2cbb2eab0dc 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts +++ b/x-pack/plugins/security_solution/public/resolver/mocks/resolver_tree.ts @@ -5,8 +5,7 @@ */ import { mockEndpointEvent } from './endpoint_event'; -import { mockRelatedEvent } from './related_event'; -import { ResolverTree, ResolverEvent } from '../../../../common/endpoint/types'; +import { ResolverTree, ResolverEvent, SafeResolverEvent } from '../../../common/endpoint/types'; export function mockTreeWith2AncestorsAndNoChildren({ originID, @@ -125,11 +124,11 @@ type RelatedEventType = string; * @param treeToAddRelatedEventsTo the ResolverTree to modify * @param relatedEventsToAddByCategoryAndType Iterable of `[category, type]` pairs describing related events. e.g. [['dns','info'],['registry','access']] */ -export function withRelatedEventsOnOrigin( +function withRelatedEventsOnOrigin( treeToAddRelatedEventsTo: ResolverTree, relatedEventsToAddByCategoryAndType: Iterable<[RelatedEventCategory, RelatedEventType]> ): ResolverTree { - const events = []; + const events: SafeResolverEvent[] = []; const byCategory: Record = {}; const stats = { totalAlerts: 0, @@ -139,14 +138,18 @@ export function withRelatedEventsOnOrigin( }, }; for (const [category, type] of relatedEventsToAddByCategoryAndType) { - events.push( - mockRelatedEvent({ - entityID: treeToAddRelatedEventsTo.entityID, - timestamp: 1, - category, + events.push({ + '@timestamp': 1, + event: { + kind: 'event', type, - }) - ); + category, + id: 'xyz', + }, + process: { + entity_id: treeToAddRelatedEventsTo.entityID, + }, + }); stats.events.total++; stats.events.byCategory[category] = stats.events.byCategory[category] ? stats.events.byCategory[category] + 1 @@ -156,7 +159,7 @@ export function withRelatedEventsOnOrigin( ...treeToAddRelatedEventsTo, stats, relatedEvents: { - events, + events: events as ResolverEvent[], nextEvent: null, }, }; @@ -309,3 +312,24 @@ export function mockTreeWithNoProcessEvents(): ResolverTree { }, }; } + +export function mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin({ + originID, + firstChildID, + secondChildID, +}: { + originID: string; + firstChildID: string; + secondChildID: string; +}) { + const baseTree = mockTreeWithNoAncestorsAnd2Children({ + originID, + firstChildID, + secondChildID, + }); + const withRelatedEvents: Array<[string, string]> = [ + ['registry', 'access'], + ['registry', 'access'], + ]; + return withRelatedEventsOnOrigin(baseTree, withRelatedEvents); +} diff --git a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.test.ts b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.test.ts index 6786a93f1d9ca..15a981d460730 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.test.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.test.ts @@ -15,7 +15,7 @@ import { mockTreeWith1AncestorAnd2ChildrenAndAllNodesHave2GraphableEvents, mockTreeWithAllProcessesTerminated, mockTreeWithNoProcessEvents, -} from '../mocks/resolver_tree'; +} from '../../mocks/resolver_tree'; import { uniquePidForProcess } from '../../models/process_event'; import { EndpointEvent } from '../../../../common/endpoint/types'; diff --git a/x-pack/plugins/security_solution/public/resolver/store/mocks/related_event.ts b/x-pack/plugins/security_solution/public/resolver/store/mocks/related_event.ts deleted file mode 100644 index 1e0c460a3a711..0000000000000 --- a/x-pack/plugins/security_solution/public/resolver/store/mocks/related_event.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { EndpointEvent } from '../../../../common/endpoint/types'; - -/** - * Simple mock related event. - */ -export function mockRelatedEvent({ - entityID, - timestamp, - category, - type, - id, -}: { - entityID: string; - timestamp: number; - category: string; - type: string; - id?: string; -}): EndpointEvent { - return { - '@timestamp': timestamp, - event: { - kind: 'event', - type, - category, - id: id ?? 'xyz', - }, - process: { - entity_id: entityID, - }, - } as EndpointEvent; -} diff --git a/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts b/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts index dfbc6bd290686..f113e861d3ce9 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts @@ -12,7 +12,7 @@ import * as selectors from './selectors'; import { mockTreeWith2AncestorsAndNoChildren, mockTreeWithNoAncestorsAnd2Children, -} from './mocks/resolver_tree'; +} from '../mocks/resolver_tree'; import { SafeResolverEvent } from '../../../common/endpoint/types'; describe('resolver selectors', () => { diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index ed30643ed871e..6f44c5aee7cac 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -113,83 +113,21 @@ export class Simulator { } /** - * Return a promise that resolves after the `store`'s next state transition. - * Used by `mapStateTransitions` + * Yield the result of `mapper` over and over, once per event-loop cycle. + * After 10 times, quit. + * Use this to continually check a value. See `toYieldEqualTo`. */ - private stateTransitioned(): Promise { - // keep track of the resolve function of the promise that has been returned. - let resolveState: (() => void) | null = null; - - const promise: Promise = new Promise((resolve) => { - // Immediately expose the resolve function in the outer scope. It will be resolved when the next state transition occurs. - resolveState = resolve; - }); - - // Subscribe to the store - const unsubscribe = this.store.subscribe(() => { - // Once a state transition occurs, unsubscribe. - unsubscribe(); - // Resolve the promise. The null assertion is safe here as Promise initializers run immediately (according to spec and node/browser implementations.) - // NB: the state is not resolved here. Code using the simulator should not rely on state or selectors of state. - resolveState!(); - }); - - // Return the promise that will be resolved on the next state transition, allowing code to `await` for the next state transition. - return promise; - } - - /** - * This will yield the return value of `mapper` after each state transition. If no state transition occurs for 10 event loops in a row, this will give up. - */ - public async *mapStateTransitions(mapper: () => R): AsyncIterable { - // Yield the value before any state transitions have occurred. - yield mapper(); - - /** Increment this each time an event loop completes without a state transition. - * If this value hits `10`, end the loop. - * - * Code will test assertions after each state transition. If the assertion hasn't passed and no further state transitions occur, - * then the jest timeout will happen. The timeout doesn't give a useful message about the assertion. - * By short-circuiting this function, code that uses it can short circuit the test timeout and print a useful error message. - * - * NB: the logic to short-circuit the loop is here because knowledge of state is a concern of the simulator, not tests. - */ + public async *map(mapper: () => R): AsyncIterable { let timeoutCount = 0; - while (true) { - /** - * `await` a race between the next state transition and a timeout that happens after `0`ms. - * If the timeout wins, no `dispatch` call caused a state transition in the last loop. - * If this keeps happening, assume that Resolver isn't going to do anything else. - * - * If Resolver adds intentional delay logic (e.g. waiting before making a request), this code might have to change. - * In that case, Resolver should use the side effect context to schedule future work. This code could then subscribe to some event published by the side effect context. That way, this code will be aware of Resolver's intention to do work. - */ - const timedOut: boolean = await Promise.race([ - (async (): Promise => { - await this.stateTransitioned(); - // If a state transition occurs, return false for `timedOut` - return false; - })(), - new Promise((resolve) => { - setTimeout(() => { - // If a timeout occurs, resolve `timedOut` as true - return resolve(true); - }, 0); - }), - ]); - - if (timedOut) { - // If a timout occurred, note it. - timeoutCount++; - if (timeoutCount === 10) { - // if 10 timeouts happen in a row, end the loop early - return; - } - } else { - // If a state transition occurs, reset the timeout count and yield the value - timeoutCount = 0; - yield mapper(); - } + while (timeoutCount < 10) { + timeoutCount++; + yield mapper(); + await new Promise((resolve) => { + setTimeout(() => { + this.wrapper.update(); + resolve(); + }, 0); + }); } } @@ -198,25 +136,22 @@ export class Simulator { * returns a `ReactWrapper` even if nothing is found, as that is how `enzyme` does things. */ public processNodeElements(options: ProcessNodeElementSelectorOptions = {}): ReactWrapper { - return this.findInDOM(processNodeElementSelector(options)); + return this.domNodes(processNodeElementSelector(options)); } /** - * true if a process node element is found for the entityID and if it has an [aria-selected] attribute. + * Return the node element with the given `entityID`. */ - public processNodeElementLooksSelected(entityID: string): boolean { - return this.processNodeElements({ entityID, selected: true }).length === 1; + public selectedProcessNode(entityID: string): ReactWrapper { + return this.processNodeElements({ entityID, selected: true }); } /** - * true if a process node element is found for the entityID and if it *does not have* an [aria-selected] attribute. + * Return the node element with the given `entityID`. It will only be returned if it is not selected. */ - public processNodeElementLooksUnselected(entityID: string): boolean { - // find the process node, then exclude it if its selected. - return ( - this.processNodeElements({ entityID }).not( - processNodeElementSelector({ entityID, selected: true }) - ).length === 1 + public unselectedProcessNode(entityID: string): ReactWrapper { + return this.processNodeElements({ entityID }).not( + processNodeElementSelector({ entityID, selected: true }) ); } @@ -234,11 +169,8 @@ export class Simulator { * @param entityID The entity ID of the proocess node to select in */ public processNodeRelatedEventButton(entityID: string): ReactWrapper { - return this.processNodeElements({ entityID }).findWhere( - (wrapper) => - // Filter out React components - typeof wrapper.type() === 'string' && - wrapper.prop('data-test-subj') === 'resolver:submenu:button' + return this.domNodes( + `${processNodeElementSelector({ entityID })} [data-test-subj="resolver:submenu:button"]` ); } @@ -256,42 +188,98 @@ export class Simulator { * The element that shows when Resolver is waiting for the graph data. */ public graphLoadingElement(): ReactWrapper { - return this.findInDOM('[data-test-subj="resolver:graph:loading"]'); + return this.domNodes('[data-test-subj="resolver:graph:loading"]'); } /** * The element that shows if Resolver couldn't draw the graph. */ public graphErrorElement(): ReactWrapper { - return this.findInDOM('[data-test-subj="resolver:graph:error"]'); + return this.domNodes('[data-test-subj="resolver:graph:error"]'); } /** * The element where nodes get drawn. */ public graphElement(): ReactWrapper { - return this.findInDOM('[data-test-subj="resolver:graph"]'); + return this.domNodes('[data-test-subj="resolver:graph"]'); + } + + /** + * An element with a list of all nodes. + */ + public nodeListElement(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:node-list"]'); + } + + /** + * Return the items in the node list (the default panel view.) + */ + public nodeListItems(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:node-list:item"]'); + } + + /** + * The element containing the details for the selected node. + */ + public nodeDetailElement(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:node-detail"]'); + } + + /** + * The details of the selected node are shown in a description list. This returns the title elements of the description list. + */ + private nodeDetailEntryTitle(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:node-detail:entry-title"]'); } /** - * The outer panel container. + * The details of the selected node are shown in a description list. This returns the description elements of the description list. */ - public panelElement(): ReactWrapper { - return this.findInDOM('[data-test-subj="resolver:panel"]'); + private nodeDetailEntryDescription(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:node-detail:entry-description"]'); } /** - * The panel content element (which may include tables, lists, other data depending on the view). + * Return DOM nodes that match `enzymeSelector`. */ - public panelContentElement(): ReactWrapper { - return this.findInDOM('[data-test-subj^="resolver:panel:"]'); + private domNodes(enzymeSelector: string): ReactWrapper { + return this.wrapper + .find(enzymeSelector) + .filterWhere((wrapper) => typeof wrapper.type() === 'string'); } /** - * Like `this.wrapper.find` but only returns DOM nodes. + * The titles and descriptions (as text) from the node detail panel. */ - private findInDOM(selector: string): ReactWrapper { - return this.wrapper.find(selector).filterWhere((wrapper) => typeof wrapper.type() === 'string'); + public nodeDetailDescriptionListEntries(): Array<[string, string]> { + const titles = this.nodeDetailEntryTitle(); + const descriptions = this.nodeDetailEntryDescription(); + const entries: Array<[string, string]> = []; + for (let index = 0; index < Math.min(titles.length, descriptions.length); index++) { + const title = titles.at(index).text(); + const description = descriptions.at(index).text(); + + // Exclude timestamp since we can't currently calculate the expected description for it from tests + if (title !== '@timestamp') { + entries.push([title, description]); + } + } + return entries; + } + + /** + * Resolve the wrapper returned by `wrapperFactory` only once it has at least 1 element in it. + */ + public async resolveWrapper( + wrapperFactory: () => ReactWrapper, + predicate: (wrapper: ReactWrapper) => boolean = (wrapper) => wrapper.length > 0 + ): Promise { + for await (const wrapper of this.map(wrapperFactory)) { + if (predicate(wrapper)) { + return wrapper; + } + } } } diff --git a/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx index c819491dd28f0..98ea235d3524f 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx @@ -4,10 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { oneAncestorTwoChildren } from '../data_access_layer/mocks/one_ancestor_two_children'; +import { noAncestorsTwoChildren } from '../data_access_layer/mocks/no_ancestors_two_children'; import { Simulator } from '../test_utilities/simulator'; // Extend jest with a custom matcher import '../test_utilities/extend_jest'; +import { noAncestorsTwoChildrenWithRelatedEventsOnOrigin } from '../data_access_layer/mocks/no_ancestors_two_children_with_related_events_on_origin'; let simulator: Simulator; let databaseDocumentID: string; @@ -16,10 +17,10 @@ let entityIDs: { origin: string; firstChild: string; secondChild: string }; // the resolver component instance ID, used by the react code to distinguish piece of global state from those used by other resolver instances const resolverComponentInstanceID = 'resolverComponentInstanceID'; -describe('Resolver, when analyzing a tree that has 1 ancestor and 2 children', () => { +describe('Resolver, when analyzing a tree that has no ancestors and 2 children', () => { beforeEach(async () => { // create a mock data access layer - const { metadata: dataAccessLayerMetadata, dataAccessLayer } = oneAncestorTwoChildren(); + const { metadata: dataAccessLayerMetadata, dataAccessLayer } = noAncestorsTwoChildren(); // save a reference to the entity IDs exposed by the mock data layer entityIDs = dataAccessLayerMetadata.entityIDs; @@ -40,7 +41,7 @@ describe('Resolver, when analyzing a tree that has 1 ancestor and 2 children', ( * * For example, there might be no loading element at one point, and 1 graph element at one point, but never a single time when there is both 1 graph element and 0 loading elements. */ - simulator.mapStateTransitions(() => ({ + simulator.map(() => ({ graphElements: simulator.graphElement().length, graphLoadingElements: simulator.graphLoadingElement().length, graphErrorElements: simulator.graphErrorElement().length, @@ -55,22 +56,23 @@ describe('Resolver, when analyzing a tree that has 1 ancestor and 2 children', ( // Combining assertions here for performance. Unfortunately, Enzyme + jsdom + React is slow. it(`should have 3 nodes, with the entityID's 'origin', 'firstChild', and 'secondChild'. 'origin' should be selected.`, async () => { - expect(simulator.processNodeElementLooksSelected(entityIDs.origin)).toBe(true); - - expect(simulator.processNodeElementLooksUnselected(entityIDs.firstChild)).toBe(true); - expect(simulator.processNodeElementLooksUnselected(entityIDs.secondChild)).toBe(true); - - expect(simulator.processNodeElements().length).toBe(3); + await expect( + simulator.map(() => ({ + selectedOriginCount: simulator.selectedProcessNode(entityIDs.origin).length, + unselectedFirstChildCount: simulator.unselectedProcessNode(entityIDs.firstChild).length, + unselectedSecondChildCount: simulator.unselectedProcessNode(entityIDs.secondChild).length, + processNodeCount: simulator.processNodeElements().length, + })) + ).toYieldEqualTo({ + selectedOriginCount: 1, + unselectedFirstChildCount: 1, + unselectedSecondChildCount: 1, + processNodeCount: 3, + }); }); - it(`should have the default "process list" panel present`, async () => { - expect(simulator.panelElement().length).toBe(1); - expect(simulator.panelContentElement().length).toBe(1); - const testSubjectName = simulator - .panelContentElement() - .getDOMNode() - .getAttribute('data-test-subj'); - expect(testSubjectName).toMatch(/process-list/g); + it(`should show the node list`, async () => { + await expect(simulator.map(() => simulator.nodeListElement().length)).toYieldEqualTo(1); }); describe("when the second child node's first button has been clicked", () => { @@ -82,42 +84,37 @@ describe('Resolver, when analyzing a tree that has 1 ancestor and 2 children', ( .first() .simulate('click'); }); - it('should render the second child node as selected, and the first child not as not selected, and the query string should indicate that the second child is selected', async () => { + it('should render the second child node as selected, and the origin as not selected, and the query string should indicate that the second child is selected', async () => { await expect( - simulator.mapStateTransitions(function value() { - return { - // the query string has a key showing that the second child is selected - queryStringSelectedNode: simulator.queryStringValues().selectedNode, - // the second child is rendered in the DOM, and shows up as selected - secondChildLooksSelected: simulator.processNodeElementLooksSelected( - entityIDs.secondChild - ), - // the origin is in the DOM, but shows up as unselected - originLooksUnselected: simulator.processNodeElementLooksUnselected(entityIDs.origin), - }; - }) + simulator.map(() => ({ + // the query string has a key showing that the second child is selected + queryStringSelectedNode: simulator.queryStringValues().selectedNode, + // the second child is rendered in the DOM, and shows up as selected + selectedSecondChildNodeCount: simulator.selectedProcessNode(entityIDs.secondChild) + .length, + // the origin is in the DOM, but shows up as unselected + unselectedOriginNodeCount: simulator.unselectedProcessNode(entityIDs.origin).length, + })) ).toYieldEqualTo({ // Just the second child should be marked as selected in the query string queryStringSelectedNode: [entityIDs.secondChild], // The second child is rendered and has `[aria-selected]` - secondChildLooksSelected: true, + selectedSecondChildNodeCount: 1, // The origin child is rendered and doesn't have `[aria-selected]` - originLooksUnselected: true, + unselectedOriginNodeCount: 1, }); }); }); }); }); -describe('Resolver, when analyzing a tree that has some related events', () => { +describe('Resolver, when analyzing a tree that has two related events for the origin', () => { beforeEach(async () => { // create a mock data access layer with related events - const { metadata: dataAccessLayerMetadata, dataAccessLayer } = oneAncestorTwoChildren({ - withRelatedEvents: [ - ['registry', 'access'], - ['registry', 'access'], - ], - }); + const { + metadata: dataAccessLayerMetadata, + dataAccessLayer, + } = noAncestorsTwoChildrenWithRelatedEventsOnOrigin(); // save a reference to the entity IDs exposed by the mock data layer entityIDs = dataAccessLayerMetadata.entityIDs; @@ -132,7 +129,7 @@ describe('Resolver, when analyzing a tree that has some related events', () => { describe('when it has loaded', () => { beforeEach(async () => { await expect( - simulator.mapStateTransitions(() => ({ + simulator.map(() => ({ graphElements: simulator.graphElement().length, graphLoadingElements: simulator.graphLoadingElement().length, graphErrorElements: simulator.graphErrorElement().length, @@ -148,7 +145,7 @@ describe('Resolver, when analyzing a tree that has some related events', () => { it('should render a related events button', async () => { await expect( - simulator.mapStateTransitions(() => ({ + simulator.map(() => ({ relatedEventButtons: simulator.processNodeRelatedEventButton(entityIDs.origin).length, })) ).toYieldEqualTo({ diff --git a/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx new file mode 100644 index 0000000000000..78e5fd79bea13 --- /dev/null +++ b/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { noAncestorsTwoChildren } from '../data_access_layer/mocks/no_ancestors_two_children'; +import { Simulator } from '../test_utilities/simulator'; +// Extend jest with a custom matcher +import '../test_utilities/extend_jest'; + +describe('Resolver: when analyzing a tree with no ancestors and two children', () => { + let simulator: Simulator; + let databaseDocumentID: string; + + // the resolver component instance ID, used by the react code to distinguish piece of global state from those used by other resolver instances + const resolverComponentInstanceID = 'resolverComponentInstanceID'; + + beforeEach(async () => { + // create a mock data access layer + const { metadata: dataAccessLayerMetadata, dataAccessLayer } = noAncestorsTwoChildren(); + + // save a reference to the `_id` supported by the mock data layer + databaseDocumentID = dataAccessLayerMetadata.databaseDocumentID; + + // create a resolver simulator, using the data access layer and an arbitrary component instance ID + simulator = new Simulator({ databaseDocumentID, dataAccessLayer, resolverComponentInstanceID }); + }); + + it('should show the node list', async () => { + await expect(simulator.map(() => simulator.nodeListElement().length)).toYieldEqualTo(1); + }); + + it('should have 3 nodes in the node list', async () => { + await expect(simulator.map(() => simulator.nodeListItems().length)).toYieldEqualTo(3); + }); + describe('when there is an item in the node list and it has been clicked', () => { + beforeEach(async () => { + const nodeListItems = await simulator.resolveWrapper(() => simulator.nodeListItems()); + expect(nodeListItems && nodeListItems.length).toBeTruthy(); + if (nodeListItems) { + nodeListItems.first().find('button').simulate('click'); + } + }); + it('should show the details for the first node', async () => { + await expect( + simulator.map(() => simulator.nodeDetailDescriptionListEntries()) + ).toYieldEqualTo([ + ['process.executable', 'executable'], + ['process.pid', '0'], + ['user.name', 'user.name'], + ['user.domain', 'user.domain'], + ['process.parent.pid', '0'], + ['process.hash.md5', 'hash.md5'], + ['process.args', 'args'], + ]); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/resolver/view/panels/process_details.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/process_details.tsx index 03d9e4c2d5a2b..112a3400c4947 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panels/process_details.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/process_details.tsx @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { memo, useMemo } from 'react'; +import React, { memo, useMemo, HTMLAttributes } from 'react'; import { useSelector } from 'react-redux'; import { i18n } from '@kbn/i18n'; import { @@ -16,6 +16,7 @@ import { } from '@elastic/eui'; import styled from 'styled-components'; import { FormattedMessage } from 'react-intl'; +import { EuiDescriptionListProps } from '@elastic/eui/src/components/description_list/description_list'; import * as selectors from '../../store/selectors'; import * as event from '../../../../common/endpoint/models/event'; import { CrumbInfo, formatDate, StyledBreadcrumbs } from './panel_content_utilities'; @@ -51,9 +52,9 @@ export const ProcessDetails = memo(function ProcessDetails({ const processName = event.eventName(processEvent); const entityId = event.entityId(processEvent); const isProcessTerminated = useSelector(selectors.isProcessTerminated)(entityId); - const processInfoEntry = useMemo(() => { + const processInfoEntry: EuiDescriptionListProps['listItems'] = useMemo(() => { const eventTime = event.eventTimestamp(processEvent); - const dateTime = eventTime ? formatDate(eventTime) : ''; + const dateTime = eventTime === undefined ? null : formatDate(eventTime); const createdEntry = { title: '@timestamp', @@ -95,7 +96,7 @@ export const ProcessDetails = memo(function ProcessDetails({ description: argsForProcess(processEvent), }; - // This is the data in {title, description} form for the EUIDescriptionList to display + // This is the data in {title, description} form for the EuiDescriptionList to display const processDescriptionListData = [ createdEntry, pathEntry, @@ -107,7 +108,7 @@ export const ProcessDetails = memo(function ProcessDetails({ commandLineEntry, ] .filter((entry) => { - return entry.description; + return entry.description !== undefined; }) .map((entry) => { return { @@ -172,13 +173,24 @@ export const ProcessDetails = memo(function ProcessDetails({ + } + descriptionProps={ + { 'data-test-subj': 'resolver:node-detail:entry-description' } as HTMLAttributes< + HTMLElement + > + } compressed listItems={processInfoEntry} /> ); }); -ProcessDetails.displayName = 'ProcessDetails'; diff --git a/x-pack/plugins/security_solution/public/resolver/view/panels/process_list_with_counts.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/process_list_with_counts.tsx index 046c840470262..11f005f8acbcd 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panels/process_list_with_counts.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/process_list_with_counts.tsx @@ -150,7 +150,7 @@ export const ProcessListWithCounts = memo(function ProcessListWithCounts({ const processTableView: ProcessTableView[] = useMemo( () => [...processNodePositions.keys()].map((processEvent) => { - let dateTime; + let dateTime: Date | undefined; const eventTime = event.timestampSafeVersion(processEvent); const name = event.processNameSafeVersion(processEvent); if (eventTime) { @@ -186,13 +186,15 @@ export const ProcessListWithCounts = memo(function ProcessListWithCounts({ const children = useSelector(selectors.hasMoreChildren); const ancestors = useSelector(selectors.hasMoreAncestors); const showWarning = children === true || ancestors === true; + const rowProps = useMemo(() => ({ 'data-test-subj': 'resolver:node-list:item' }), []); return ( <> {showWarning && } - data-test-subj="resolver:panel:process-list" + rowProps={rowProps} + data-test-subj="resolver:node-list" items={processTableView} columns={columns} sorting @@ -200,4 +202,3 @@ export const ProcessListWithCounts = memo(function ProcessListWithCounts({ ); }); -ProcessListWithCounts.displayName = 'ProcessListWithCounts'; From c6c300e8f82d138f28a080a7a34a78ebc27d9776 Mon Sep 17 00:00:00 2001 From: Clint Andrew Hall Date: Fri, 7 Aug 2020 11:21:44 -0400 Subject: [PATCH 058/106] [Canvas][tech-debt] Add Typescript to apps directory (#73766) Co-authored-by: Elastic Machine --- .../export/__tests__/export_app.test.tsx | 8 +- .../export/export/export_app.component.tsx | 63 ++++++++++++++ .../public/apps/export/export/export_app.js | 59 ------------- .../public/apps/export/export/export_app.ts | 21 +++++ .../canvas/public/apps/export/export/index.js | 30 ------- .../export/index.ts} | 5 +- .../public/apps/export/{index.js => index.ts} | 0 .../apps/export/{routes.js => routes.ts} | 13 ++- .../{home_app.js => home_app.component.tsx} | 10 ++- .../home/home_app/{index.js => home_app.ts} | 8 +- .../home_app/index.ts} | 5 +- .../public/apps/home/{index.js => index.ts} | 0 .../public/apps/home/{routes.js => routes.ts} | 0 .../canvas/public/apps/{index.js => index.ts} | 1 + .../apps/workpad/{index.js => index.ts} | 0 .../apps/workpad/{routes.js => routes.ts} | 24 ++++-- .../public/apps/workpad/workpad_app/index.js | 41 --------- .../public/apps/workpad/workpad_app/index.ts | 8 ++ .../workpad_app/workpad_app.component.tsx | 83 +++++++++++++++++++ .../apps/workpad/workpad_app/workpad_app.js | 81 ------------------ .../apps/workpad/workpad_app/workpad_app.ts | 32 +++++++ .../workpad_header.component.tsx | 12 ++- .../workpad_header/workpad_header.tsx | 29 +------ x-pack/plugins/canvas/types/canvas.ts | 4 + 24 files changed, 274 insertions(+), 263 deletions(-) create mode 100644 x-pack/plugins/canvas/public/apps/export/export/export_app.component.tsx delete mode 100644 x-pack/plugins/canvas/public/apps/export/export/export_app.js create mode 100644 x-pack/plugins/canvas/public/apps/export/export/export_app.ts delete mode 100644 x-pack/plugins/canvas/public/apps/export/export/index.js rename x-pack/plugins/canvas/public/apps/{workpad/workpad_app/load_workpad.js => export/export/index.ts} (67%) rename x-pack/plugins/canvas/public/apps/export/{index.js => index.ts} (100%) rename x-pack/plugins/canvas/public/apps/export/{routes.js => routes.ts} (79%) rename x-pack/plugins/canvas/public/apps/home/home_app/{home_app.js => home_app.component.tsx} (79%) rename x-pack/plugins/canvas/public/apps/home/home_app/{index.js => home_app.ts} (69%) rename x-pack/plugins/canvas/public/apps/{export/export/load_workpad.js => home/home_app/index.ts} (69%) rename x-pack/plugins/canvas/public/apps/home/{index.js => index.ts} (100%) rename x-pack/plugins/canvas/public/apps/home/{routes.js => routes.ts} (100%) rename x-pack/plugins/canvas/public/apps/{index.js => index.ts} (88%) rename x-pack/plugins/canvas/public/apps/workpad/{index.js => index.ts} (100%) rename x-pack/plugins/canvas/public/apps/workpad/{routes.js => routes.ts} (82%) delete mode 100644 x-pack/plugins/canvas/public/apps/workpad/workpad_app/index.js create mode 100644 x-pack/plugins/canvas/public/apps/workpad/workpad_app/index.ts create mode 100644 x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.component.tsx delete mode 100644 x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.js create mode 100644 x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.ts diff --git a/x-pack/plugins/canvas/public/apps/export/export/__tests__/export_app.test.tsx b/x-pack/plugins/canvas/public/apps/export/export/__tests__/export_app.test.tsx index b0a8d1e990e75..1bb58919b7fa6 100644 --- a/x-pack/plugins/canvas/public/apps/export/export/__tests__/export_app.test.tsx +++ b/x-pack/plugins/canvas/public/apps/export/export/__tests__/export_app.test.tsx @@ -6,8 +6,8 @@ import React from 'react'; import { mount } from 'enzyme'; -// @ts-expect-error untyped local -import { ExportApp } from '../export_app'; +import { ExportApp } from '../export_app.component'; +import { CanvasWorkpad } from '../../../../../types'; jest.mock('style-it', () => ({ it: (css: string, Component: any) => Component, @@ -23,7 +23,7 @@ jest.mock('../../../../components/link', () => ({ describe('', () => { test('renders as expected', () => { - const sampleWorkpad = { + const sampleWorkpad = ({ id: 'my-workpad-abcd', css: '', pages: [ @@ -34,7 +34,7 @@ describe('', () => { elements: [3, 4, 5, 6], }, ], - }; + } as any) as CanvasWorkpad; const page1 = mount( {}} /> diff --git a/x-pack/plugins/canvas/public/apps/export/export/export_app.component.tsx b/x-pack/plugins/canvas/public/apps/export/export/export_app.component.tsx new file mode 100644 index 0000000000000..03121e749d0dc --- /dev/null +++ b/x-pack/plugins/canvas/public/apps/export/export/export_app.component.tsx @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, useEffect } from 'react'; +import PropTypes from 'prop-types'; +// @ts-expect-error untyped library +import Style from 'style-it'; +// @ts-expect-error untyped local +import { WorkpadPage } from '../../../components/workpad_page'; +import { Link } from '../../../components/link'; +import { CanvasWorkpad } from '../../../../types'; + +interface Props { + workpad: CanvasWorkpad; + selectedPageIndex: number; + initializeWorkpad: () => void; +} + +export const ExportApp: FC = ({ workpad, selectedPageIndex, initializeWorkpad }) => { + const { id, pages, height, width } = workpad; + const activePage = pages[selectedPageIndex]; + const pageElementCount = activePage.elements.length; + + useEffect(() => initializeWorkpad()); + + return ( +
    +
    +
    + + Edit Workpad + +
    + {Style.it( + workpad.css, +
    + {}} + unregisterLayout={() => {}} + /> +
    + )} +
    +
    + ); +}; + +ExportApp.propTypes = { + workpad: PropTypes.shape({ + id: PropTypes.string.isRequired, + pages: PropTypes.array.isRequired, + }).isRequired, + selectedPageIndex: PropTypes.number.isRequired, + initializeWorkpad: PropTypes.func.isRequired, +}; diff --git a/x-pack/plugins/canvas/public/apps/export/export/export_app.js b/x-pack/plugins/canvas/public/apps/export/export/export_app.js deleted file mode 100644 index 1d02d85cae0b3..0000000000000 --- a/x-pack/plugins/canvas/public/apps/export/export/export_app.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import PropTypes from 'prop-types'; -import Style from 'style-it'; -import { WorkpadPage } from '../../../components/workpad_page'; -import { Link } from '../../../components/link'; - -export class ExportApp extends React.PureComponent { - static propTypes = { - workpad: PropTypes.shape({ - id: PropTypes.string.isRequired, - pages: PropTypes.array.isRequired, - }).isRequired, - selectedPageIndex: PropTypes.number.isRequired, - initializeWorkpad: PropTypes.func.isRequired, - }; - - componentDidMount() { - this.props.initializeWorkpad(); - } - - render() { - const { workpad, selectedPageIndex } = this.props; - const { pages, height, width } = workpad; - const activePage = pages[selectedPageIndex]; - const pageElementCount = activePage.elements.length; - - return ( -
    -
    -
    - - Edit Workpad - -
    - {Style.it( - workpad.css, -
    - {}} - unregisterLayout={() => {}} - /> -
    - )} -
    -
    - ); - } -} diff --git a/x-pack/plugins/canvas/public/apps/export/export/export_app.ts b/x-pack/plugins/canvas/public/apps/export/export/export_app.ts new file mode 100644 index 0000000000000..b47d1950ec2b7 --- /dev/null +++ b/x-pack/plugins/canvas/public/apps/export/export/export_app.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { connect } from 'react-redux'; +import { initializeWorkpad } from '../../../state/actions/workpad'; +import { getWorkpad, getSelectedPageIndex } from '../../../state/selectors/workpad'; +import { ExportApp as Component } from './export_app.component'; +import { State } from '../../../../types'; + +export const ExportApp = connect( + (state: State) => ({ + workpad: getWorkpad(state), + selectedPageIndex: getSelectedPageIndex(state), + }), + (dispatch) => ({ + initializeWorkpad: () => dispatch(initializeWorkpad()), + }) +)(Component); diff --git a/x-pack/plugins/canvas/public/apps/export/export/index.js b/x-pack/plugins/canvas/public/apps/export/export/index.js deleted file mode 100644 index 95c46d9e1c8ae..0000000000000 --- a/x-pack/plugins/canvas/public/apps/export/export/index.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { connect } from 'react-redux'; -import { compose, branch, renderComponent } from 'recompose'; -import { initializeWorkpad } from '../../../state/actions/workpad'; -import { getWorkpad, getSelectedPageIndex } from '../../../state/selectors/workpad'; -import { LoadWorkpad } from './load_workpad'; -import { ExportApp as Component } from './export_app'; - -const mapStateToProps = (state) => ({ - workpad: getWorkpad(state), - selectedPageIndex: getSelectedPageIndex(state), -}); - -const mapDispatchToProps = (dispatch) => ({ - initializeWorkpad() { - dispatch(initializeWorkpad()); - }, -}); - -const branches = [branch(({ workpad }) => workpad == null, renderComponent(LoadWorkpad))]; - -export const ExportApp = compose( - connect(mapStateToProps, mapDispatchToProps), - ...branches -)(Component); diff --git a/x-pack/plugins/canvas/public/apps/workpad/workpad_app/load_workpad.js b/x-pack/plugins/canvas/public/apps/export/export/index.ts similarity index 67% rename from x-pack/plugins/canvas/public/apps/workpad/workpad_app/load_workpad.js rename to x-pack/plugins/canvas/public/apps/export/export/index.ts index 388bf00723f82..81939d550a7ab 100644 --- a/x-pack/plugins/canvas/public/apps/workpad/workpad_app/load_workpad.js +++ b/x-pack/plugins/canvas/public/apps/export/export/index.ts @@ -4,6 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; - -export const LoadWorkpad = () =>
    Load a workpad...
    ; +export { ExportApp } from './export_app'; +export { ExportApp as ExportAppComponent } from './export_app.component'; diff --git a/x-pack/plugins/canvas/public/apps/export/index.js b/x-pack/plugins/canvas/public/apps/export/index.ts similarity index 100% rename from x-pack/plugins/canvas/public/apps/export/index.js rename to x-pack/plugins/canvas/public/apps/export/index.ts diff --git a/x-pack/plugins/canvas/public/apps/export/routes.js b/x-pack/plugins/canvas/public/apps/export/routes.ts similarity index 79% rename from x-pack/plugins/canvas/public/apps/export/routes.js rename to x-pack/plugins/canvas/public/apps/export/routes.ts index 33e375115aa19..0b4f74149fb4f 100644 --- a/x-pack/plugins/canvas/public/apps/export/routes.js +++ b/x-pack/plugins/canvas/public/apps/export/routes.ts @@ -4,10 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Dispatch } from 'redux'; +// @ts-expect-error Untyped local import * as workpadService from '../../lib/workpad_service'; import { setWorkpad } from '../../state/actions/workpad'; +// @ts-expect-error Untyped local import { fetchAllRenderables } from '../../state/actions/elements'; +// @ts-expect-error Untyped local import { setPage } from '../../state/actions/pages'; +// @ts-expect-error Untyped local import { setAssets } from '../../state/actions/assets'; import { ExportApp } from './export'; @@ -18,7 +23,13 @@ export const routes = [ { name: 'exportWorkpad', path: '/pdf/:id/page/:page', - action: (dispatch) => async ({ params, router }) => { + action: (dispatch: Dispatch) => async ({ + params, + // @ts-expect-error Fix when Router is typed. + router, + }: { + params: { id: string; page: string }; + }) => { // load workpad if given a new id via url param const fetchedWorkpad = await workpadService.get(params.id); const pageNumber = parseInt(params.page, 10); diff --git a/x-pack/plugins/canvas/public/apps/home/home_app/home_app.js b/x-pack/plugins/canvas/public/apps/home/home_app/home_app.component.tsx similarity index 79% rename from x-pack/plugins/canvas/public/apps/home/home_app/home_app.js rename to x-pack/plugins/canvas/public/apps/home/home_app/home_app.component.tsx index bfa4abbf7c56d..3c2e989cc8e51 100644 --- a/x-pack/plugins/canvas/public/apps/home/home_app/home_app.js +++ b/x-pack/plugins/canvas/public/apps/home/home_app/home_app.component.tsx @@ -4,12 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { FC } from 'react'; import { EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui'; +// @ts-expect-error untyped local import { WorkpadManager } from '../../../components/workpad_manager'; +// @ts-expect-error untyped local import { setDocTitle } from '../../../lib/doc_title'; -export const HomeApp = ({ onLoad = () => {} }) => { +interface Props { + onLoad: () => void; +} + +export const HomeApp: FC = ({ onLoad = () => {} }) => { onLoad(); setDocTitle('Canvas'); return ( diff --git a/x-pack/plugins/canvas/public/apps/home/home_app/index.js b/x-pack/plugins/canvas/public/apps/home/home_app/home_app.ts similarity index 69% rename from x-pack/plugins/canvas/public/apps/home/home_app/index.js rename to x-pack/plugins/canvas/public/apps/home/home_app/home_app.ts index f78ee1f8a18af..ff9d1c1cc63ac 100644 --- a/x-pack/plugins/canvas/public/apps/home/home_app/index.js +++ b/x-pack/plugins/canvas/public/apps/home/home_app/home_app.ts @@ -6,12 +6,10 @@ import { connect } from 'react-redux'; import { resetWorkpad } from '../../../state/actions/workpad'; -import { HomeApp as Component } from './home_app'; +import { HomeApp as Component } from './home_app.component'; -const mapDispatchToProps = (dispatch) => ({ +export const HomeApp = connect(null, (dispatch) => ({ onLoad() { dispatch(resetWorkpad()); }, -}); - -export const HomeApp = connect(null, mapDispatchToProps)(Component); +}))(Component); diff --git a/x-pack/plugins/canvas/public/apps/export/export/load_workpad.js b/x-pack/plugins/canvas/public/apps/home/home_app/index.ts similarity index 69% rename from x-pack/plugins/canvas/public/apps/export/export/load_workpad.js rename to x-pack/plugins/canvas/public/apps/home/home_app/index.ts index 388bf00723f82..8ea92312e3e50 100644 --- a/x-pack/plugins/canvas/public/apps/export/export/load_workpad.js +++ b/x-pack/plugins/canvas/public/apps/home/home_app/index.ts @@ -4,6 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; - -export const LoadWorkpad = () =>
    Load a workpad...
    ; +export { HomeApp } from './home_app'; +export { HomeApp as HomeAppComponent } from './home_app.component'; diff --git a/x-pack/plugins/canvas/public/apps/home/index.js b/x-pack/plugins/canvas/public/apps/home/index.ts similarity index 100% rename from x-pack/plugins/canvas/public/apps/home/index.js rename to x-pack/plugins/canvas/public/apps/home/index.ts diff --git a/x-pack/plugins/canvas/public/apps/home/routes.js b/x-pack/plugins/canvas/public/apps/home/routes.ts similarity index 100% rename from x-pack/plugins/canvas/public/apps/home/routes.js rename to x-pack/plugins/canvas/public/apps/home/routes.ts diff --git a/x-pack/plugins/canvas/public/apps/index.js b/x-pack/plugins/canvas/public/apps/index.ts similarity index 88% rename from x-pack/plugins/canvas/public/apps/index.js rename to x-pack/plugins/canvas/public/apps/index.ts index c014349ca18da..8b3d378e23f80 100644 --- a/x-pack/plugins/canvas/public/apps/index.js +++ b/x-pack/plugins/canvas/public/apps/index.ts @@ -8,6 +8,7 @@ import * as home from './home'; import * as workpad from './workpad'; import * as exp from './export'; +// @ts-expect-error Router and routes are not yet strongly typed export const routes = [].concat(workpad.routes, home.routes, exp.routes); export const apps = [workpad.WorkpadApp, home.HomeApp, exp.ExportApp]; diff --git a/x-pack/plugins/canvas/public/apps/workpad/index.js b/x-pack/plugins/canvas/public/apps/workpad/index.ts similarity index 100% rename from x-pack/plugins/canvas/public/apps/workpad/index.js rename to x-pack/plugins/canvas/public/apps/workpad/index.ts diff --git a/x-pack/plugins/canvas/public/apps/workpad/routes.js b/x-pack/plugins/canvas/public/apps/workpad/routes.ts similarity index 82% rename from x-pack/plugins/canvas/public/apps/workpad/routes.js rename to x-pack/plugins/canvas/public/apps/workpad/routes.ts index a330020b741ac..d83f85f717305 100644 --- a/x-pack/plugins/canvas/public/apps/workpad/routes.js +++ b/x-pack/plugins/canvas/public/apps/workpad/routes.ts @@ -4,17 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ErrorStrings } from '../../../i18n'; +import { Dispatch } from 'redux'; +// @ts-expect-error import * as workpadService from '../../lib/workpad_service'; import { notifyService } from '../../services'; import { getBaseBreadcrumb, getWorkpadBreadcrumb, setBreadcrumb } from '../../lib/breadcrumbs'; +// @ts-expect-error import { getDefaultWorkpad } from '../../state/defaults'; import { setWorkpad } from '../../state/actions/workpad'; +// @ts-expect-error import { setAssets, resetAssets } from '../../state/actions/assets'; +// @ts-expect-error import { setPage } from '../../state/actions/pages'; import { getWorkpad } from '../../state/selectors/workpad'; +// @ts-expect-error import { setZoomScale } from '../../state/actions/transient'; +import { ErrorStrings } from '../../../i18n'; import { WorkpadApp } from './workpad_app'; +import { State } from '../../../types'; const { workpadRoutes: strings } = ErrorStrings; @@ -25,7 +32,8 @@ export const routes = [ { name: 'createWorkpad', path: '/create', - action: (dispatch) => async ({ router }) => { + // @ts-expect-error Fix when Router is typed. + action: (dispatch: Dispatch) => async ({ router }) => { const newWorkpad = getDefaultWorkpad(); try { await workpadService.create(newWorkpad); @@ -46,7 +54,13 @@ export const routes = [ { name: 'loadWorkpad', path: '/:id(/page/:page)', - action: (dispatch, getState) => async ({ params, router }) => { + action: (dispatch: Dispatch, getState: () => State) => async ({ + params, + // @ts-expect-error Fix when Router is typed. + router, + }: { + params: { id: string; page?: string }; + }) => { // load workpad if given a new id via url param const state = getState(); const currentWorkpad = getWorkpad(state); @@ -70,10 +84,10 @@ export const routes = [ // fetch the workpad again, to get changes const workpad = getWorkpad(getState()); - const pageNumber = parseInt(params.page, 10); + const pageNumber = params.page ? parseInt(params.page, 10) : null; // no page provided, append current page to url - if (isNaN(pageNumber)) { + if (!pageNumber || isNaN(pageNumber)) { return router.redirectTo('loadWorkpad', { id: workpad.id, page: workpad.page + 1 }); } diff --git a/x-pack/plugins/canvas/public/apps/workpad/workpad_app/index.js b/x-pack/plugins/canvas/public/apps/workpad/workpad_app/index.js deleted file mode 100644 index ac50cd3fb99b6..0000000000000 --- a/x-pack/plugins/canvas/public/apps/workpad/workpad_app/index.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { connect } from 'react-redux'; -import { compose, branch, renderComponent } from 'recompose'; -import { selectToplevelNodes } from '../../../state/actions/transient'; -import { canUserWrite, getAppReady } from '../../../state/selectors/app'; -import { getWorkpad, isWriteable } from '../../../state/selectors/workpad'; -import { LoadWorkpad } from './load_workpad'; -import { WorkpadApp as Component } from './workpad_app'; -import { withElementsLoadedTelemetry } from './workpad_telemetry'; - -export { WORKPAD_CONTAINER_ID } from './workpad_app'; - -const mapStateToProps = (state) => { - const appReady = getAppReady(state); - - return { - isWriteable: isWriteable(state) && canUserWrite(state), - appReady: typeof appReady === 'object' ? appReady : { ready: appReady }, - workpad: getWorkpad(state), - }; -}; - -const mapDispatchToProps = (dispatch) => ({ - deselectElement(ev) { - ev && ev.stopPropagation(); - dispatch(selectToplevelNodes([])); - }, -}); - -const branches = [branch(({ workpad }) => workpad == null, renderComponent(LoadWorkpad))]; - -export const WorkpadApp = compose( - connect(mapStateToProps, mapDispatchToProps), - ...branches, - withElementsLoadedTelemetry -)(Component); diff --git a/x-pack/plugins/canvas/public/apps/workpad/workpad_app/index.ts b/x-pack/plugins/canvas/public/apps/workpad/workpad_app/index.ts new file mode 100644 index 0000000000000..a00bf855ba376 --- /dev/null +++ b/x-pack/plugins/canvas/public/apps/workpad/workpad_app/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { WorkpadApp } from './workpad_app'; +export { WorkpadApp as WorkpadAppComponent } from './workpad_app.component'; diff --git a/x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.component.tsx b/x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.component.tsx new file mode 100644 index 0000000000000..791f40f0219cd --- /dev/null +++ b/x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.component.tsx @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, MouseEventHandler, useRef } from 'react'; +import PropTypes from 'prop-types'; +import { Sidebar } from '../../../components/sidebar'; +import { Toolbar } from '../../../components/toolbar'; +// @ts-expect-error Untyped local +import { Workpad } from '../../../components/workpad'; +import { WorkpadHeader } from '../../../components/workpad_header'; +import { CANVAS_LAYOUT_STAGE_CONTENT_SELECTOR } from '../../../../common/lib/constants'; +import { CommitFn } from '../../../../types'; + +export const WORKPAD_CONTAINER_ID = 'canvasWorkpadContainer'; + +interface Props { + deselectElement?: MouseEventHandler; + isWriteable: boolean; +} + +export const WorkpadApp: FC = ({ deselectElement, isWriteable }) => { + const interactivePageLayout = useRef(null); // future versions may enable editing on multiple pages => use array then + + const registerLayout = (newLayout: CommitFn) => { + if (interactivePageLayout.current !== newLayout) { + interactivePageLayout.current = newLayout; + } + }; + + const unregisterLayout = (oldLayout: CommitFn) => { + if (interactivePageLayout.current === oldLayout) { + interactivePageLayout.current = null; + } + }; + + const commit = interactivePageLayout.current || (() => {}); + + return ( +
    +
    +
    +
    +
    + +
    + +
    + {/* NOTE: canvasWorkpadContainer is used for exporting */} +
    + +
    +
    +
    + + {isWriteable && ( +
    + +
    + )} +
    + +
    + +
    +
    +
    + ); +}; + +WorkpadApp.propTypes = { + isWriteable: PropTypes.bool.isRequired, + deselectElement: PropTypes.func, +}; diff --git a/x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.js b/x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.js deleted file mode 100644 index fc3ac9922355a..0000000000000 --- a/x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.js +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import PropTypes from 'prop-types'; -import { Sidebar } from '../../../components/sidebar'; -import { Toolbar } from '../../../components/toolbar'; -import { Workpad } from '../../../components/workpad'; -import { WorkpadHeader } from '../../../components/workpad_header'; -import { CANVAS_LAYOUT_STAGE_CONTENT_SELECTOR } from '../../../../common/lib/constants'; - -export const WORKPAD_CONTAINER_ID = 'canvasWorkpadContainer'; - -export class WorkpadApp extends React.PureComponent { - static propTypes = { - isWriteable: PropTypes.bool.isRequired, - deselectElement: PropTypes.func, - }; - - interactivePageLayout = null; // future versions may enable editing on multiple pages => use array then - - registerLayout(newLayout) { - if (this.interactivePageLayout !== newLayout) { - this.interactivePageLayout = newLayout; - } - } - - unregisterLayout(oldLayout) { - if (this.interactivePageLayout === oldLayout) { - this.interactivePageLayout = null; - } - } - - render() { - const { isWriteable, deselectElement } = this.props; - - return ( -
    -
    -
    -
    -
    - {})} /> -
    - -
    - {/* NOTE: canvasWorkpadContainer is used for exporting */} -
    - -
    -
    -
    - - {isWriteable && ( -
    - -
    - )} -
    - -
    - -
    -
    -
    - ); - } -} diff --git a/x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.ts b/x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.ts new file mode 100644 index 0000000000000..46f2efaf5e7d2 --- /dev/null +++ b/x-pack/plugins/canvas/public/apps/workpad/workpad_app/workpad_app.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { MouseEventHandler } from 'react'; +import { Dispatch } from 'redux'; +import { connect } from 'react-redux'; +// @ts-expect-error untyped local +import { selectToplevelNodes } from '../../../state/actions/transient'; +import { canUserWrite } from '../../../state/selectors/app'; +import { getWorkpad, isWriteable } from '../../../state/selectors/workpad'; +import { WorkpadApp as Component } from './workpad_app.component'; +import { withElementsLoadedTelemetry } from './workpad_telemetry'; +import { State } from '../../../../types'; + +export { WORKPAD_CONTAINER_ID } from './workpad_app.component'; + +const mapDispatchToProps = (dispatch: Dispatch): { deselectElement: MouseEventHandler } => ({ + deselectElement: (ev) => { + ev.stopPropagation(); + dispatch(selectToplevelNodes([])); + }, +}); + +export const WorkpadApp = connect( + (state: State) => ({ + isWriteable: isWriteable(state) && canUserWrite(state), + workpad: getWorkpad(state), + }), + mapDispatchToProps +)(withElementsLoadedTelemetry(Component)); diff --git a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx index eb4b451896b46..b1e87ca67f5e5 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx @@ -18,22 +18,25 @@ import { EditMenu } from './edit_menu'; import { ElementMenu } from './element_menu'; import { ShareMenu } from './share_menu'; import { ViewMenu } from './view_menu'; +import { CommitFn } from '../../../types'; const { WorkpadHeader: strings } = ComponentStrings; export interface Props { isWriteable: boolean; - toggleWriteable: () => void; canUserWrite: boolean; - commit: (type: string, payload: any) => any; + commit: CommitFn; + onSetWriteable?: (writeable: boolean) => void; } export const WorkpadHeader: FunctionComponent = ({ isWriteable, canUserWrite, - toggleWriteable, commit, + onSetWriteable = () => {}, }) => { + const toggleWriteable = () => onSetWriteable(!isWriteable); + const keyHandler = (action: string) => { if (action === 'EDITING') { toggleWriteable(); @@ -145,6 +148,7 @@ export const WorkpadHeader: FunctionComponent = ({ WorkpadHeader.propTypes = { isWriteable: PropTypes.bool, - toggleWriteable: PropTypes.func, + commit: PropTypes.func.isRequired, + onSetWriteable: PropTypes.func, canUserWrite: PropTypes.bool, }; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.tsx b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.tsx index 1f630040b0c36..0661aa4be4313 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.tsx @@ -10,37 +10,16 @@ import { canUserWrite } from '../../state/selectors/app'; import { getSelectedPage, isWriteable } from '../../state/selectors/workpad'; import { setWriteable } from '../../state/actions/workpad'; import { State } from '../../../types'; -import { WorkpadHeader as Component, Props as ComponentProps } from './workpad_header.component'; +import { WorkpadHeader as Component } from './workpad_header.component'; -interface StateProps { - isWriteable: boolean; - canUserWrite: boolean; - selectedPage: string; -} - -interface DispatchProps { - setWriteable: (isWorkpadWriteable: boolean) => void; -} - -const mapStateToProps = (state: State): StateProps => ({ +const mapStateToProps = (state: State) => ({ isWriteable: isWriteable(state) && canUserWrite(state), canUserWrite: canUserWrite(state), selectedPage: getSelectedPage(state), }); const mapDispatchToProps = (dispatch: Dispatch) => ({ - setWriteable: (isWorkpadWriteable: boolean) => dispatch(setWriteable(isWorkpadWriteable)), -}); - -const mergeProps = ( - stateProps: StateProps, - dispatchProps: DispatchProps, - ownProps: ComponentProps -): ComponentProps => ({ - ...stateProps, - ...dispatchProps, - ...ownProps, - toggleWriteable: () => dispatchProps.setWriteable(!stateProps.isWriteable), + onSetWriteable: (isWorkpadWriteable: boolean) => dispatch(setWriteable(isWorkpadWriteable)), }); -export const WorkpadHeader = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Component); +export const WorkpadHeader = connect(mapStateToProps, mapDispatchToProps)(Component); diff --git a/x-pack/plugins/canvas/types/canvas.ts b/x-pack/plugins/canvas/types/canvas.ts index cc07f498f1eec..6b3f9ad3e8043 100644 --- a/x-pack/plugins/canvas/types/canvas.ts +++ b/x-pack/plugins/canvas/types/canvas.ts @@ -76,3 +76,7 @@ export interface CanvasWorkpadBoundingBox { top: number; bottom: number; } + +export type LayoutState = any; + +export type CommitFn = (type: string, payload: any) => LayoutState; From 37ce10158ad8911bbbd951a5b5e329858beec091 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Mon, 10 Aug 2020 09:08:36 +0200 Subject: [PATCH 059/106] RFC: encryption key rotation support for the `encryptedSavedObjects` plugin (#72828) --- rfcs/text/0012_encryption_key_rotation.md | 119 ++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 rfcs/text/0012_encryption_key_rotation.md diff --git a/rfcs/text/0012_encryption_key_rotation.md b/rfcs/text/0012_encryption_key_rotation.md new file mode 100644 index 0000000000000..d984d1157a0a1 --- /dev/null +++ b/rfcs/text/0012_encryption_key_rotation.md @@ -0,0 +1,119 @@ +- Start Date: 2020-07-22 +- RFC PR: [#72828](https://github.com/elastic/kibana/pull/72828) +- Kibana Issue: (leave this empty) + +# Summary + +This RFC proposes a way of the encryption key (`xpack.encryptedSavedObjects.encryptionKey`) rotation that would allow administrators to seamlessly change existing encryption key without any data loss and manual intervention. + +# Basic example + +When administrators decide to rotate encryption key they will have to generate a new one and move the old key(s) to the `keyRotation` section in the `kibana.yml`: + +```yaml +xpack.encryptedSavedObjects: + encryptionKey: "NEW-encryption-key" + keyRotation: + decryptionOnlyKeys: ["OLD-encryption-key-1", "OLD-encryption-key-2"] +``` + +Before old decryption-only key is disposed administrators may want to call a dedicated and _protected_ API endpoint that will go through all registered Saved Objects with encrypted attributes and try to re-encrypt them with the primary encryption key: + +```http request +POST https://localhost:5601/api/encrypted_saved_objects/rotate_key?conflicts=abort +Content-Type: application/json +Kbn-Xsrf: true +``` + +# Motivation + +Today when encryption key changes we can no longer decrypt Saved Objects attributes that were previously encrypted with the `EncryptedSavedObjects` plugin. We handle this case in two different ways depending on whether consumers explicitly requested decryption or not: + +* If consumers explicitly request decryption via `getDecryptedAsInternalUser()` we abort operation and throw exception. +* If consumers fetch Saved Objects with encrypted attributes that should be automatically decrypted (the ones with `dangerouslyExposeValue: true` marker) via standard Saved Objects APIs we don't abort operation, but rather strip all encrypted attributes from the response and record decryption error in the `error` Saved Object field. +* If Kibana tries to migrate encrypted Saved Objects at the start up time we abort operation and throw exception. + +In both of these cases we throw or record error with the specific type to allow consumers to gracefully handle this scenario and either drop Saved Objects with unrecoverable encrypted attributes or facilitate the process of re-entering and re-encryption of the new values. + +This approach works reasonably well in some scenarios, but it may become very troublesome if we have to deal with lots of Saved Objects. Moreover, we'd like to recommend our users to periodically rotate encryption keys even if they aren't compromised. Hence, we need to provide a way of seamless migration of the existing encrypted Saved Objects to a new encryption key. + +There are two main scenarios we'd like to cover in this RFC: + +## Encryption key is not available + +Administrators may lose existing encryption key or explicitly decide to not use it if it was compromised and users can no longer trust encrypted content that may have been tampered with. In this scenario encrypted portion of the existing Saved Objects is considered lost, and the only way to recover from this state is a manual intervention described previously. That means `EncryptedSavedObjects` plugin consumers __should__ continue supporting this scenario even after we implement a proper encryption key rotation mechanism described in this RFC. + +## Encryption key is available, but needs to be rotated + +In this scenario a new encryption key (primary encryption key) will be generated, and we will use it to encrypt new or updated Saved Objects. We will still need to know the old encryption key to decrypt existing attributes, but we will no longer use this key to encrypt any of the new or existing Saved Objects. It's also should be possible to have multiple old decryption-only keys. + +The old old decryption-only keys should be eventually disposed and users should have a way to make sure all existing Saved Objects are re-encrypted with the new primary encryption key. + +__NOTE:__ users can get into a state when different Saved Objects are encrypted with different encryption keys even if they didn't intend to rotate the encryption key. We anticipate that it can happen during initial Elastic Stack HA setup, when by mistake or intentionally different Kibana instances were using different encryption keys. Key rotation mechanism can help to fix this issue without a data loss. + +# Detailed design + +The core idea is that when the encryption key needs to be rotated then a new key is generated and becomes a primary one, and the old one moves to the `keyRotation` section: + +```yaml +xpack.encryptedSavedObjects: + encryptionKey: "NEW-encryption-key" + keyRotation: + decryptionOnlyKeys: ["OLD-encryption-key"] +``` + +As the name implies, the key from the `decryptionOnlyKeys` is only used to decrypt content that we cannot decrypt with the primary encryption key. It's allowed to have multiple decryption-only keys at the same time. When user creates a new Saved Object or updates the existing one then its content is always encrypted with the primary encryption key. Config schema won't allow having the same key in `encryptionKey` and `decryptionOnlyKeys`. + +Having multiple decryption keys at the same time brings one problem though: we need to figure out which key to use to decrypt specific Saved Object. If our encryption keys could have a unique ID that we would store together with the encrypted data (we cannot use encryption key hash for that for obvious reasons) we could know for sure which key to use, but we don't have such functionality right now and it may not be the easiest one to manage through `yml` configuration anyway. + +Instead, this RFC proposes to try available existing decryption keys one by one to decrypt Saved Object and always start from the primary one. This way we won't incur any penalty while decrypting Saved Objects that are already encrypted with the primary encryption key, but there will still be some cost when we have to perform multiple decryption attempts. See the [`Drawbacks`](#drawbacks) section for the details. + +Technically just having `decryptionOnlyKeys` would be enough to cover the majority of the use cases, but the old decryption-only keys should be eventually disposed. At this point administrators would like to make sure _all_ Saved Objects are encrypted with the new primary encryption key. Another reason to re-encrypt all existing Saved Objects with the new key at once is to preventively reduce the performance impact of the multiple decryption attempts. + +We'd like to make this process as simple as possible while meeting the following requirements: + +* It should not be required to restart Kibana to perform this type of migration since Saved Objects encrypted with the another encryption key can theoretically appear at any point in time. +* It should be possible to integrate this operation into other operational flows our users may have and any user-friendly key management UIs we may introduce in this future. +* Any possible failures that may happen during this operation shouldn't make Kibana nonfunctional. +* Ordinary users should not be able to trigger this migration since it may consume a considerable amount of computing resources. + +We think that the best option we have right now is a dedicated API endpoint that would trigger this migration: + +```http request +POST https://localhost:5601/api/encrypted_saved_objects/rotate_key?conflicts=abort +Content-Type: application/json +Kbn-Xsrf: true +``` + +This will be a protected endpoint and only user with enough privileges will be able to use it. + +Under the hood we'll scroll over all Saved Objects that are registered with `EncryptedSavedObjects` plugin and re-encrypt attributes only for those of them that can only be decrypted with any of the old decryption-only keys. Saved Objects that can be decrypted with the primary encryption key will be ignored. We'll also ignore the ones that cannot be decrypted with any of the available decryption keys at all, and presumably return their IDs in the response. + +As for any other encryption or decryption operation we'll record relevant bits in the audit logs. + +# Benefits + +* The concept of decryption-only keys is easy to grasp and allows Kibana to function even if it has a mix of Saved Objects encrypted with different encryption keys. +* Support of the key rotation out of the box decreases the chances of the data loss and makes `EncryptedSavedObjects` story more secure and approachable overall. + +# Drawbacks + +* Multiple decryption attempts affect performance. See [the performance test results](https://github.com/elastic/kibana/pull/72420#issue-453400211) for more details, but making two decryption attempts is basically twice as slow as with a single attempt. Although it's only relevant for the encrypted Saved Objects migration performed at the start up time and batch operations that trigger automatic decryption (only for the Saved Objects registered with `dangerouslyExposeValue: true` marker that nobody is using in Kibana right now), we may have more use cases in the future. +* Historically we supported Kibana features with either configuration or dedicated UI, but in this case we want to introduce an API endpoint that _should be_ used directly. We may have a key management UI in the future though. + +# Alternatives + +We cannot think of any better alternative for `decryptionOnlyKeys` at the moment, but instead of API endpoint for the batch re-encryption we could potentially use another `kibana.yml` config option. For example `keyRotation.mode: onWrite | onStart | both`, but it feels a bit hacky and cannot be really integrated with anything else. + +# Adoption strategy + +Adoption strategy is pretty straightforward since the feature is an enhancement and doesn't bring any BWC concerns. + +# How we teach this + +Key rotation is a well-known paradigm. We'll update `README.md` of the `EncryptedSavedObjects` plugin and create a dedicated section in the public Kibana documentation. + +# Unresolved questions + +* Is it reasonable to have this feature in Basic? +* Are there any other use-cases that are not covered by the proposal? From 0a65e172a1563c9b0e39d06c5a4c0a3a4af480ec Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 10 Aug 2020 09:30:51 +0200 Subject: [PATCH 060/106] [ES UI Shared] Added README (#72034) * Added readme to es-ui-shared * implement PR feedback; clarify terms and tighten grammar * added note about intended users of es ui shared modules --- src/plugins/es_ui_shared/README.md | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/plugins/es_ui_shared/README.md diff --git a/src/plugins/es_ui_shared/README.md b/src/plugins/es_ui_shared/README.md new file mode 100644 index 0000000000000..5a9091e2dd1eb --- /dev/null +++ b/src/plugins/es_ui_shared/README.md @@ -0,0 +1,32 @@ +## ES UI shared modules + +This plugin contains reusable code in the form of self-contained modules (or libraries). Each of these modules exports a set of functionality relevant to the domain of the module. + +**Please note**: Modules in ES UI shared are intended for use by the ES UI Management Team (elastic/es-ui@) only. Please reach out to us if there is something you would like to contribute or use in these modules. + +## Files and folders overview + +- `./public` | `./server`. Folders for grouping server or public code according to the Kibana plugin pattern. +- `./__packages_do_not_import__` is where actual functionality is kept. This enables modules more control over what functionality is directly exported and prevents parts of modules to be depended on externally in unintended ways. +- `./public/index.ts` | `./server/index.ts` These files export modules (simple JavaScript objects). For example, `Monaco` is the name of a module. In this way, modules namespace all of their exports and do not have to be concerned about name collisions from other modules. + +## Conventions for adding code + +When adding new functionality, look at the folders in `./__packages_do_not_import__` and consider whether your functionality falls into any of those modules. + +If it does not, you should create a module and expose it to public or server code (or both) following the conventions described above. + +### Example + +If I wanted to add functionality for calculating a Fibonacci sequence browser-side one would do the following: + +1. Create a folder `./__packages_do_not_import__/math`. The name of the folder should be a snake_case version of the module name. In this case `Math` -> `math`. Another case, `IndexManagement` -> `index_management`. +2. Write your function in `./__packages_do_not_import__/math/calculate_fibonacci.ts`, adding any relevant tests in the same folder. +3. Export functionality intended _for consumers_ from `./__packages_do_not_import__/math/index.ts`. +4. Create a folder `./public/math`. +5. Export all functionality from `./__packages_do_not_import__/math` in `./public/math/index.ts`. +6. In `./public/index.ts` import `./public/math` using `import * as Math from './public/math;`. The name (`Math`) given here is really important and will be what consumers depend on. +7. Add the `Math` module to the list of exported modules in `./public/index.ts`, e.g. `export { <...other modules>, Math }` +8. Use `Math` in your public side code elsewhere! + +This example assumes no other appropriate home for such a function exists. From ce025732a17bb1a1488e6d01abf73545d9a393ba Mon Sep 17 00:00:00 2001 From: Dmitry Lemeshko Date: Mon, 10 Aug 2020 10:09:30 +0200 Subject: [PATCH 061/106] add retry for checking Add button (#74551) Co-authored-by: Elastic Machine --- .../test/functional/apps/dashboard/_async_dashboard.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/test/functional/apps/dashboard/_async_dashboard.ts b/x-pack/test/functional/apps/dashboard/_async_dashboard.ts index cc30a7a7e640f..8851c83dea1ff 100644 --- a/x-pack/test/functional/apps/dashboard/_async_dashboard.ts +++ b/x-pack/test/functional/apps/dashboard/_async_dashboard.ts @@ -27,8 +27,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'timePicker', ]); - // Flakky: https://github.com/elastic/kibana/issues/65949 - describe.skip('sample data dashboard', function describeIndexTests() { + describe('sample data dashboard', function describeIndexTests() { before(async () => { await PageObjects.common.sleep(5000); await PageObjects.common.navigateToUrl('home', '/tutorial_directory/sampleData', { @@ -36,8 +35,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.home.addSampleDataSet('flights'); - const isInstalled = await PageObjects.home.isSampleDataSetInstalled('flights'); - expect(isInstalled).to.be(true); + await retry.tryForTime(10000, async () => { + const isInstalled = await PageObjects.home.isSampleDataSetInstalled('flights'); + expect(isInstalled).to.be(true); + }); + // add the range of the sample data so we can pick it in the quick pick list const SAMPLE_DATA_RANGE = `[ { From ad8502c8d9cbf35822ed187aae9ea31e5eca21ab Mon Sep 17 00:00:00 2001 From: spalger Date: Mon, 10 Aug 2020 01:25:29 -0700 Subject: [PATCH 062/106] update code-exploration docs --- docs/developer/architecture/code-exploration.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/developer/architecture/code-exploration.asciidoc b/docs/developer/architecture/code-exploration.asciidoc index bb7222020180c..d9502e4cb47ee 100644 --- a/docs/developer/architecture/code-exploration.asciidoc +++ b/docs/developer/architecture/code-exploration.asciidoc @@ -86,9 +86,9 @@ Contains the Discover application and the saved search embeddable. Embeddables are re-usable widgets that can be rendered in any environment or plugin. Developers can embed them directly in their plugin. End users can dynamically add them to any embeddable containers. -- {kib-repo}blob/{branch}/src/plugins/es_ui_shared[esUiShared] +- {kib-repo}blob/{branch}/src/plugins/es_ui_shared/README.md[esUiShared] -WARNING: Missing README. +This plugin contains reusable code in the form of self-contained modules (or libraries). Each of these modules exports a set of functionality relevant to the domain of the module. - {kib-repo}blob/{branch}/src/plugins/expressions/README.md[expressions] From f7f2988aa2d6a557ee2aa6aa184ea774bb57f345 Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Mon, 10 Aug 2020 13:04:57 +0200 Subject: [PATCH 063/106] [ML] Functional tests - stabilize DFA job type check (#74631) This PR stabilizes the data frame analytics job type assertion by adding a retry. --- .../ml/data_frame_analytics_creation.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts b/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts index a49febfe68f61..d8df2fb869ed7 100644 --- a/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts +++ b/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts @@ -46,14 +46,16 @@ export function MachineLearningDataFrameAnalyticsCreationProvider( }, async assertJobTypeSelection(expectedSelection: string) { - const actualSelection = await testSubjects.getAttribute( - 'mlAnalyticsCreateJobWizardJobTypeSelect', - 'value' - ); - expect(actualSelection).to.eql( - expectedSelection, - `Job type selection should be '${expectedSelection}' (got '${actualSelection}')` - ); + await retry.tryForTime(5000, async () => { + const actualSelection = await testSubjects.getAttribute( + 'mlAnalyticsCreateJobWizardJobTypeSelect', + 'value' + ); + expect(actualSelection).to.eql( + expectedSelection, + `Job type selection should be '${expectedSelection}' (got '${actualSelection}')` + ); + }); }, async selectJobType(jobType: string) { From cccf15a3f42943aa81393fe532bfb4ce48ea6994 Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Mon, 10 Aug 2020 07:35:12 -0500 Subject: [PATCH 064/106] Index pattern field class refactor (#73180) - Better distinction and relationship between IndexPatternField and its spec - IndexPatternField class is no longer defined via object mutation - Reduction of dependencies - UI code moved into Index Pattern class (will be removed in next ticket) - IndexPattern field list was previously composed of IndexPatternFields or specs, now only IndexPatternFields - IndexPattern field list was previously redefined when loading fields, now only its contents are replaced. --- ...ins-data-public.fieldlist._constructor_.md | 23 +++ ...lugin-plugins-data-public.fieldlist.add.md | 11 + ...plugins-data-public.fieldlist.getbyname.md | 11 + ...plugins-data-public.fieldlist.getbytype.md | 11 + ...na-plugin-plugins-data-public.fieldlist.md | 31 +++ ...in-plugins-data-public.fieldlist.remove.md | 11 + ...plugins-data-public.fieldlist.removeall.md | 11 + ...lugins-data-public.fieldlist.replaceall.md | 11 + ...in-plugins-data-public.fieldlist.tospec.md | 25 +++ ...in-plugins-data-public.fieldlist.update.md | 11 + ...-public.getindexpatternfieldlistcreator.md | 11 - ...public.iindexpatternfieldlist.getbyname.md | 6 +- ...public.iindexpatternfieldlist.getbytype.md | 6 +- ...gins-data-public.iindexpatternfieldlist.md | 4 +- ...public.iindexpatternfieldlist.removeall.md | 15 ++ ...ublic.iindexpatternfieldlist.replaceall.md | 22 ++ ...data-public.indexpattern.getfieldbyname.md | 4 +- ...ublic.indexpattern.getformatterforfield.md | 22 ++ ...ublic.indexpattern.getnonscriptedfields.md | 4 +- ...a-public.indexpattern.getscriptedfields.md | 4 +- ...s-data-public.indexpattern.gettimefield.md | 4 +- ...plugin-plugins-data-public.indexpattern.md | 3 +- ...public.indexpattern.removescriptedfield.md | 4 +- ...-public.indexpatternfield._constructor_.md | 12 +- ...a-public.indexpatternfield.aggregatable.md | 2 +- ....indexpatternfield.conflictdescriptions.md | 4 +- ...ins-data-public.indexpatternfield.count.md | 4 +- ...ta-public.indexpatternfield.displayname.md | 2 +- ...s-data-public.indexpatternfield.estypes.md | 2 +- ...ata-public.indexpatternfield.filterable.md | 2 +- ...ns-data-public.indexpatternfield.format.md | 2 +- ...a-public.indexpatternfield.indexpattern.md | 2 +- ...gins-data-public.indexpatternfield.lang.md | 4 +- ...n-plugins-data-public.indexpatternfield.md | 28 ++- ...gins-data-public.indexpatternfield.name.md | 2 +- ...lic.indexpatternfield.readfromdocvalues.md | 2 +- ...ns-data-public.indexpatternfield.script.md | 4 +- ...-data-public.indexpatternfield.scripted.md | 2 +- ...ata-public.indexpatternfield.searchable.md | 2 +- ...-data-public.indexpatternfield.sortable.md | 2 +- ...ins-data-public.indexpatternfield.spec.md} | 6 +- ...s-data-public.indexpatternfield.subtype.md | 2 +- ...ns-data-public.indexpatternfield.tojson.md | 41 ++++ ...ns-data-public.indexpatternfield.tospec.md | 36 +++- ...gins-data-public.indexpatternfield.type.md | 2 +- ...a-public.indexpatternfield.visualizable.md | 2 +- .../kibana-plugin-plugins-data-public.md | 2 +- ....snap => index_pattern_field.test.ts.snap} | 0 .../common/index_patterns/fields/field.ts | 176 ---------------- .../index_patterns/fields/field_list.ts | 159 ++++++++------- .../common/index_patterns/fields/index.ts | 2 +- ...ld.test.ts => index_pattern_field.test.ts} | 105 ++-------- .../fields/index_pattern_field.ts | 188 ++++++++++++++++++ .../index_patterns/fields/obj_define.js | 158 --------------- .../index_patterns/fields/obj_define.test.js | 149 -------------- .../index_patterns/index_pattern.test.ts | 22 +- .../index_patterns/index_pattern.ts | 119 ++++++----- .../index_patterns/index_patterns.ts | 28 +-- .../data/common/index_patterns/types.ts | 15 +- .../kbn_field_types/kbn_field_types.test.ts | 4 +- .../common/kbn_field_types/kbn_field_types.ts | 6 +- .../kbn_field_types_factory.ts | 8 +- src/plugins/data/public/index.ts | 5 +- .../data/public/index_patterns/index.ts | 6 +- src/plugins/data/public/public.api.md | 169 +++++++++++----- .../public/search/aggs/agg_configs.test.ts | 2 +- .../public/search/aggs/param_types/field.ts | 2 +- .../doc_table/components/row_headers.test.js | 43 ++-- .../sidebar/discover_field.test.tsx | 30 +-- .../components/sidebar/discover_sidebar.tsx | 11 +- .../lib/get_index_pattern_field_list.ts | 12 +- .../components/sidebar/lib/group_fields.tsx | 4 +- .../create_edit_field/create_edit_field.tsx | 31 ++- .../indexed_fields_table.test.tsx.snap | 20 +- .../indexed_fields_table.test.tsx | 21 +- .../indexed_fields_table.tsx | 2 +- .../__snapshots__/field_editor.test.tsx.snap | 5 + .../editors/string/string.tsx | 2 +- .../field_editor/field_editor.test.tsx | 23 ++- .../components/field_editor/field_editor.tsx | 166 ++++++++-------- .../public/components/test_utils.tsx | 4 +- src/test_utils/public/stub_index_pattern.js | 22 +- .../management/_index_pattern_popularity.js | 2 +- .../apps/management/_scripted_fields.js | 3 +- .../management/_scripted_fields_filter.js | 4 +- 85 files changed, 1086 insertions(+), 1076 deletions(-) create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist._constructor_.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.add.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getbyname.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getbytype.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.remove.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.removeall.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.replaceall.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.tospec.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.update.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getindexpatternfieldlistcreator.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getformatterforfield.md rename docs/development/plugins/data/public/{kibana-plugin-plugins-data-public.indexpatternfield.__spec.md => kibana-plugin-plugins-data-public.indexpatternfield.spec.md} (56%) create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tojson.md rename src/plugins/data/common/index_patterns/fields/__snapshots__/{field.test.ts.snap => index_pattern_field.test.ts.snap} (100%) delete mode 100644 src/plugins/data/common/index_patterns/fields/field.ts rename src/plugins/data/common/index_patterns/fields/{field.test.ts => index_pattern_field.test.ts} (64%) create mode 100644 src/plugins/data/common/index_patterns/fields/index_pattern_field.ts delete mode 100644 src/plugins/data/common/index_patterns/fields/obj_define.js delete mode 100644 src/plugins/data/common/index_patterns/fields/obj_define.test.js diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist._constructor_.md new file mode 100644 index 0000000000000..3b60ac0f48edd --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist._constructor_.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) > [(constructor)](./kibana-plugin-plugins-data-public.fieldlist._constructor_.md) + +## FieldList.(constructor) + +Constructs a new instance of the `FieldList` class + +Signature: + +```typescript +constructor(indexPattern: IndexPattern, specs?: FieldSpec[], shortDotsEnable?: boolean, onNotification?: () => void); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| indexPattern | IndexPattern | | +| specs | FieldSpec[] | | +| shortDotsEnable | boolean | | +| onNotification | () => void | | + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.add.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.add.md new file mode 100644 index 0000000000000..ae3d82f0cc3ea --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.add.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) > [add](./kibana-plugin-plugins-data-public.fieldlist.add.md) + +## FieldList.add property + +Signature: + +```typescript +readonly add: (field: FieldSpec) => void; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getbyname.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getbyname.md new file mode 100644 index 0000000000000..af368d003423a --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getbyname.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) > [getByName](./kibana-plugin-plugins-data-public.fieldlist.getbyname.md) + +## FieldList.getByName property + +Signature: + +```typescript +readonly getByName: (name: IndexPatternField['name']) => IndexPatternField | undefined; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getbytype.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getbytype.md new file mode 100644 index 0000000000000..16bae3ee7c555 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getbytype.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) > [getByType](./kibana-plugin-plugins-data-public.fieldlist.getbytype.md) + +## FieldList.getByType property + +Signature: + +```typescript +readonly getByType: (type: IndexPatternField['type']) => any[]; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.md new file mode 100644 index 0000000000000..ef740575dff4e --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.md @@ -0,0 +1,31 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) + +## FieldList class + +Signature: + +```typescript +export declare class FieldList extends Array implements IIndexPatternFieldList +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(indexPattern, specs, shortDotsEnable, onNotification)](./kibana-plugin-plugins-data-public.fieldlist._constructor_.md) | | Constructs a new instance of the FieldList class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [add](./kibana-plugin-plugins-data-public.fieldlist.add.md) | | (field: FieldSpec) => void | | +| [getByName](./kibana-plugin-plugins-data-public.fieldlist.getbyname.md) | | (name: IndexPatternField['name']) => IndexPatternField | undefined | | +| [getByType](./kibana-plugin-plugins-data-public.fieldlist.getbytype.md) | | (type: IndexPatternField['type']) => any[] | | +| [remove](./kibana-plugin-plugins-data-public.fieldlist.remove.md) | | (field: IFieldType) => void | | +| [removeAll](./kibana-plugin-plugins-data-public.fieldlist.removeall.md) | | () => void | | +| [replaceAll](./kibana-plugin-plugins-data-public.fieldlist.replaceall.md) | | (specs: FieldSpec[]) => void | | +| [toSpec](./kibana-plugin-plugins-data-public.fieldlist.tospec.md) | | () => {
    count: number;
    script: string | undefined;
    lang: string | undefined;
    conflictDescriptions: Record<string, string[]> | undefined;
    name: string;
    type: string;
    esTypes: string[] | undefined;
    scripted: boolean;
    searchable: boolean;
    aggregatable: boolean;
    readFromDocValues: boolean;
    subType: import("../types").IFieldSubType | undefined;
    format: any;
    }[] | | +| [update](./kibana-plugin-plugins-data-public.fieldlist.update.md) | | (field: FieldSpec) => void | | + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.remove.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.remove.md new file mode 100644 index 0000000000000..149410adb3550 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.remove.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) > [remove](./kibana-plugin-plugins-data-public.fieldlist.remove.md) + +## FieldList.remove property + +Signature: + +```typescript +readonly remove: (field: IFieldType) => void; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.removeall.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.removeall.md new file mode 100644 index 0000000000000..92a45349ad005 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.removeall.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) > [removeAll](./kibana-plugin-plugins-data-public.fieldlist.removeall.md) + +## FieldList.removeAll property + +Signature: + +```typescript +readonly removeAll: () => void; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.replaceall.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.replaceall.md new file mode 100644 index 0000000000000..5330440e6b96a --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.replaceall.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) > [replaceAll](./kibana-plugin-plugins-data-public.fieldlist.replaceall.md) + +## FieldList.replaceAll property + +Signature: + +```typescript +readonly replaceAll: (specs: FieldSpec[]) => void; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.tospec.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.tospec.md new file mode 100644 index 0000000000000..e646339feb495 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.tospec.md @@ -0,0 +1,25 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) > [toSpec](./kibana-plugin-plugins-data-public.fieldlist.tospec.md) + +## FieldList.toSpec property + +Signature: + +```typescript +readonly toSpec: () => { + count: number; + script: string | undefined; + lang: string | undefined; + conflictDescriptions: Record | undefined; + name: string; + type: string; + esTypes: string[] | undefined; + scripted: boolean; + searchable: boolean; + aggregatable: boolean; + readFromDocValues: boolean; + subType: import("../types").IFieldSubType | undefined; + format: any; + }[]; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.update.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.update.md new file mode 100644 index 0000000000000..c718e47b31b50 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.update.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) > [update](./kibana-plugin-plugins-data-public.fieldlist.update.md) + +## FieldList.update property + +Signature: + +```typescript +readonly update: (field: FieldSpec) => void; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getindexpatternfieldlistcreator.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getindexpatternfieldlistcreator.md deleted file mode 100644 index 880acdc8956d4..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getindexpatternfieldlistcreator.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [getIndexPatternFieldListCreator](./kibana-plugin-plugins-data-public.getindexpatternfieldlistcreator.md) - -## getIndexPatternFieldListCreator variable - -Signature: - -```typescript -getIndexPatternFieldListCreator: ({ fieldFormats, onNotification, }: FieldListDependencies) => CreateIndexPatternFieldList -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md index 14b5aa7137dc2..e277df87fe908 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md @@ -7,16 +7,16 @@ Signature: ```typescript -getByName(name: Field['name']): Field | undefined; +getByName(name: IndexPatternField['name']): IndexPatternField | undefined; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| name | Field['name'] | | +| name | IndexPatternField['name'] | | Returns: -`Field | undefined` +`IndexPatternField | undefined` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md index 3c65b78e5291d..9a7b3ab36b0c1 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md @@ -7,16 +7,16 @@ Signature: ```typescript -getByType(type: Field['type']): Field[]; +getByType(type: IndexPatternField['type']): IndexPatternField[]; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| type | Field['type'] | | +| type | IndexPatternField['type'] | | Returns: -`Field[]` +`IndexPatternField[]` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md index 47d7c7491aa86..4ab012a2601d2 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md @@ -7,7 +7,7 @@ Signature: ```typescript -export interface IIndexPatternFieldList extends Array +export interface IIndexPatternFieldList extends Array ``` ## Methods @@ -18,5 +18,7 @@ export interface IIndexPatternFieldList extends Array | [getByName(name)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md) | | | [getByType(type)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md) | | | [remove(field)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.remove.md) | | +| [removeAll()](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md) | | +| [replaceAll(specs)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md) | | | [update(field)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.update.md) | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md new file mode 100644 index 0000000000000..55e7ca98e2637 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [removeAll](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md) + +## IIndexPatternFieldList.removeAll() method + +Signature: + +```typescript +removeAll(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md new file mode 100644 index 0000000000000..c7e8cdd578bfe --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [replaceAll](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md) + +## IIndexPatternFieldList.replaceAll() method + +Signature: + +```typescript +replaceAll(specs: FieldSpec[]): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| specs | FieldSpec[] | | + +Returns: + +`void` + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getfieldbyname.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getfieldbyname.md index e6a23c5c70aab..75cdfd0a2e22e 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getfieldbyname.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getfieldbyname.md @@ -7,7 +7,7 @@ Signature: ```typescript -getFieldByName(name: string): Field | void; +getFieldByName(name: string): IndexPatternField | undefined; ``` ## Parameters @@ -18,5 +18,5 @@ getFieldByName(name: string): Field | void; Returns: -`Field | void` +`IndexPatternField | undefined` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getformatterforfield.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getformatterforfield.md new file mode 100644 index 0000000000000..7984f7aff1d2d --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getformatterforfield.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [getFormatterForField](./kibana-plugin-plugins-data-public.indexpattern.getformatterforfield.md) + +## IndexPattern.getFormatterForField() method + +Signature: + +```typescript +getFormatterForField(field: IndexPatternField | IndexPatternField['spec']): FieldFormat; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| field | IndexPatternField | IndexPatternField['spec'] | | + +Returns: + +`FieldFormat` + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getnonscriptedfields.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getnonscriptedfields.md index 4e49304484815..77ce6f6f23a67 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getnonscriptedfields.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getnonscriptedfields.md @@ -7,9 +7,9 @@ Signature: ```typescript -getNonScriptedFields(): Field[]; +getNonScriptedFields(): IndexPatternField[]; ``` Returns: -`Field[]` +`IndexPatternField[]` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getscriptedfields.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getscriptedfields.md index 9ab4f9a9aaed5..055f07367c96e 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getscriptedfields.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getscriptedfields.md @@ -7,9 +7,9 @@ Signature: ```typescript -getScriptedFields(): Field[]; +getScriptedFields(): IndexPatternField[]; ``` Returns: -`Field[]` +`IndexPatternField[]` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.gettimefield.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.gettimefield.md index 8e68e8c35aff7..24de0be3794bb 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.gettimefield.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.gettimefield.md @@ -7,9 +7,9 @@ Signature: ```typescript -getTimeField(): Field | undefined; +getTimeField(): IndexPatternField | undefined; ``` Returns: -`Field | undefined` +`IndexPatternField | undefined` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md index a37f115358922..d340aaeeef25e 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md @@ -42,6 +42,7 @@ export declare class IndexPattern implements IIndexPattern | [getAggregationRestrictions()](./kibana-plugin-plugins-data-public.indexpattern.getaggregationrestrictions.md) | | | | [getComputedFields()](./kibana-plugin-plugins-data-public.indexpattern.getcomputedfields.md) | | | | [getFieldByName(name)](./kibana-plugin-plugins-data-public.indexpattern.getfieldbyname.md) | | | +| [getFormatterForField(field)](./kibana-plugin-plugins-data-public.indexpattern.getformatterforfield.md) | | | | [getNonScriptedFields()](./kibana-plugin-plugins-data-public.indexpattern.getnonscriptedfields.md) | | | | [getScriptedFields()](./kibana-plugin-plugins-data-public.indexpattern.getscriptedfields.md) | | | | [getSourceFiltering()](./kibana-plugin-plugins-data-public.indexpattern.getsourcefiltering.md) | | | @@ -55,7 +56,7 @@ export declare class IndexPattern implements IIndexPattern | [popularizeField(fieldName, unit)](./kibana-plugin-plugins-data-public.indexpattern.popularizefield.md) | | | | [prepBody()](./kibana-plugin-plugins-data-public.indexpattern.prepbody.md) | | | | [refreshFields()](./kibana-plugin-plugins-data-public.indexpattern.refreshfields.md) | | | -| [removeScriptedField(field)](./kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md) | | | +| [removeScriptedField(fieldName)](./kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md) | | | | [save(saveAttempts)](./kibana-plugin-plugins-data-public.indexpattern.save.md) | | | | [toJSON()](./kibana-plugin-plugins-data-public.indexpattern.tojson.md) | | | | [toSpec()](./kibana-plugin-plugins-data-public.indexpattern.tospec.md) | | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md index 2a6811f501152..42c6dd72b8c4e 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md @@ -7,14 +7,14 @@ Signature: ```typescript -removeScriptedField(field: IFieldType): Promise; +removeScriptedField(fieldName: string): Promise; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| field | IFieldType | | +| fieldName | string | | Returns: diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield._constructor_.md index 7a195702b6f13..10b65bdccdf87 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield._constructor_.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield._constructor_.md @@ -4,20 +4,20 @@ ## IndexPatternField.(constructor) -Constructs a new instance of the `Field` class +Constructs a new instance of the `IndexPatternField` class Signature: ```typescript -constructor(indexPattern: IIndexPattern, spec: FieldSpecExportFmt | FieldSpec | Field, shortDotsEnable: boolean, { fieldFormats, onNotification }: FieldDependencies); +constructor(indexPattern: IndexPattern, spec: FieldSpec, displayName: string, onNotification: OnNotification); ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| indexPattern | IIndexPattern | | -| spec | FieldSpecExportFmt | FieldSpec | Field | | -| shortDotsEnable | boolean | | -| { fieldFormats, onNotification } | FieldDependencies | | +| indexPattern | IndexPattern | | +| spec | FieldSpec | | +| displayName | string | | +| onNotification | OnNotification | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.aggregatable.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.aggregatable.md index 267c8f786b5dd..6ef87d08600a3 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.aggregatable.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.aggregatable.md @@ -7,5 +7,5 @@ Signature: ```typescript -aggregatable?: boolean; +get aggregatable(): boolean; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.conflictdescriptions.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.conflictdescriptions.md index ec19a4854bf0e..6d62053726197 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.conflictdescriptions.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.conflictdescriptions.md @@ -7,5 +7,7 @@ Signature: ```typescript -conflictDescriptions?: FieldSpecConflictDescriptions; +get conflictDescriptions(): Record | undefined; + +set conflictDescriptions(conflictDescriptions: Record | undefined); ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.count.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.count.md index 8e848276f21c4..84c0a75fd206d 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.count.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.count.md @@ -7,5 +7,7 @@ Signature: ```typescript -count?: number; +get count(): number; + +set count(count: number); ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.displayname.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.displayname.md index ed9630f92fc97..c0ce2fff419bf 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.displayname.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.displayname.md @@ -7,5 +7,5 @@ Signature: ```typescript -displayName?: string; +readonly displayName: string; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.estypes.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.estypes.md index dec74df099d43..ac088cb69a3d6 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.estypes.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.estypes.md @@ -7,5 +7,5 @@ Signature: ```typescript -esTypes?: string[]; +get esTypes(): string[] | undefined; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.filterable.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.filterable.md index 4290c4a2f86b3..1149047c0eccd 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.filterable.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.filterable.md @@ -7,5 +7,5 @@ Signature: ```typescript -filterable?: boolean; +get filterable(): boolean; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.format.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.format.md index d5df8ed628cb0..f28d5b1bca7e5 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.format.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.format.md @@ -7,5 +7,5 @@ Signature: ```typescript -format: any; +get format(): FieldFormat; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.indexpattern.md index 4acaaa8c0dc2c..3d145cce9d07d 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.indexpattern.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.indexpattern.md @@ -7,5 +7,5 @@ Signature: ```typescript -indexPattern?: IIndexPattern; +readonly indexPattern: IndexPattern; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.lang.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.lang.md index f731be8f613cf..0a8446d40e5ec 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.lang.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.lang.md @@ -7,5 +7,7 @@ Signature: ```typescript -lang?: string; +get lang(): string | undefined; + +set lang(lang: string | undefined); ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.md index d82999e7a96af..713b29ea3a3d3 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.md @@ -7,37 +7,43 @@ Signature: ```typescript -export declare class Field implements IFieldType +export declare class IndexPatternField implements IFieldType ``` ## Constructors | Constructor | Modifiers | Description | | --- | --- | --- | -| [(constructor)(indexPattern, spec, shortDotsEnable, { fieldFormats, onNotification })](./kibana-plugin-plugins-data-public.indexpatternfield._constructor_.md) | | Constructs a new instance of the Field class | +| [(constructor)(indexPattern, spec, displayName, onNotification)](./kibana-plugin-plugins-data-public.indexpatternfield._constructor_.md) | | Constructs a new instance of the IndexPatternField class | ## Properties | Property | Modifiers | Type | Description | | --- | --- | --- | --- | -| [$$spec](./kibana-plugin-plugins-data-public.indexpatternfield.__spec.md) | | FieldSpec | | | [aggregatable](./kibana-plugin-plugins-data-public.indexpatternfield.aggregatable.md) | | boolean | | -| [conflictDescriptions](./kibana-plugin-plugins-data-public.indexpatternfield.conflictdescriptions.md) | | FieldSpecConflictDescriptions | | +| [conflictDescriptions](./kibana-plugin-plugins-data-public.indexpatternfield.conflictdescriptions.md) | | Record<string, string[]> | undefined | | | [count](./kibana-plugin-plugins-data-public.indexpatternfield.count.md) | | number | | | [displayName](./kibana-plugin-plugins-data-public.indexpatternfield.displayname.md) | | string | | -| [esTypes](./kibana-plugin-plugins-data-public.indexpatternfield.estypes.md) | | string[] | | +| [esTypes](./kibana-plugin-plugins-data-public.indexpatternfield.estypes.md) | | string[] | undefined | | | [filterable](./kibana-plugin-plugins-data-public.indexpatternfield.filterable.md) | | boolean | | -| [format](./kibana-plugin-plugins-data-public.indexpatternfield.format.md) | | any | | -| [indexPattern](./kibana-plugin-plugins-data-public.indexpatternfield.indexpattern.md) | | IIndexPattern | | -| [lang](./kibana-plugin-plugins-data-public.indexpatternfield.lang.md) | | string | | +| [format](./kibana-plugin-plugins-data-public.indexpatternfield.format.md) | | FieldFormat | | +| [indexPattern](./kibana-plugin-plugins-data-public.indexpatternfield.indexpattern.md) | | IndexPattern | | +| [lang](./kibana-plugin-plugins-data-public.indexpatternfield.lang.md) | | string | undefined | | | [name](./kibana-plugin-plugins-data-public.indexpatternfield.name.md) | | string | | | [readFromDocValues](./kibana-plugin-plugins-data-public.indexpatternfield.readfromdocvalues.md) | | boolean | | -| [script](./kibana-plugin-plugins-data-public.indexpatternfield.script.md) | | string | | +| [script](./kibana-plugin-plugins-data-public.indexpatternfield.script.md) | | string | undefined | | | [scripted](./kibana-plugin-plugins-data-public.indexpatternfield.scripted.md) | | boolean | | | [searchable](./kibana-plugin-plugins-data-public.indexpatternfield.searchable.md) | | boolean | | | [sortable](./kibana-plugin-plugins-data-public.indexpatternfield.sortable.md) | | boolean | | -| [subType](./kibana-plugin-plugins-data-public.indexpatternfield.subtype.md) | | IFieldSubType | | -| [toSpec](./kibana-plugin-plugins-data-public.indexpatternfield.tospec.md) | | () => FieldSpecExportFmt | | +| [spec](./kibana-plugin-plugins-data-public.indexpatternfield.spec.md) | | FieldSpec | | +| [subType](./kibana-plugin-plugins-data-public.indexpatternfield.subtype.md) | | import("../types").IFieldSubType | undefined | | | [type](./kibana-plugin-plugins-data-public.indexpatternfield.type.md) | | string | | | [visualizable](./kibana-plugin-plugins-data-public.indexpatternfield.visualizable.md) | | boolean | | +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [toJSON()](./kibana-plugin-plugins-data-public.indexpatternfield.tojson.md) | | | +| [toSpec()](./kibana-plugin-plugins-data-public.indexpatternfield.tospec.md) | | | + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.name.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.name.md index cb24621e73209..c690edeafea6e 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.name.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.name.md @@ -7,5 +7,5 @@ Signature: ```typescript -name: string; +get name(): string; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.readfromdocvalues.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.readfromdocvalues.md index 4b012c26a8620..22f727e3c00e8 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.readfromdocvalues.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.readfromdocvalues.md @@ -7,5 +7,5 @@ Signature: ```typescript -readFromDocValues?: boolean; +get readFromDocValues(): boolean; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.script.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.script.md index 132ba25a47637..27f9c797c92f2 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.script.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.script.md @@ -7,5 +7,7 @@ Signature: ```typescript -script?: string; +get script(): string | undefined; + +set script(script: string | undefined); ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.scripted.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.scripted.md index 1dd6bc865a75d..f3810b9698a11 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.scripted.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.scripted.md @@ -7,5 +7,5 @@ Signature: ```typescript -scripted?: boolean; +get scripted(): boolean; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.searchable.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.searchable.md index 42f984d851435..431907b154dc0 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.searchable.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.searchable.md @@ -7,5 +7,5 @@ Signature: ```typescript -searchable?: boolean; +get searchable(): boolean; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.sortable.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.sortable.md index 72d225185140b..871320c9586d3 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.sortable.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.sortable.md @@ -7,5 +7,5 @@ Signature: ```typescript -sortable?: boolean; +get sortable(): boolean; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.__spec.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.spec.md similarity index 56% rename from docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.__spec.md rename to docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.spec.md index f52a3324af36f..9884faaa6c7bb 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.__spec.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.spec.md @@ -1,11 +1,11 @@ -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternField](./kibana-plugin-plugins-data-public.indexpatternfield.md) > [$$spec](./kibana-plugin-plugins-data-public.indexpatternfield.__spec.md) +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternField](./kibana-plugin-plugins-data-public.indexpatternfield.md) > [spec](./kibana-plugin-plugins-data-public.indexpatternfield.spec.md) -## IndexPatternField.$$spec property +## IndexPatternField.spec property Signature: ```typescript -$$spec: FieldSpec; +readonly spec: FieldSpec; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.subtype.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.subtype.md index 2d807f8a5739c..5c3c4d54ad099 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.subtype.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.subtype.md @@ -7,5 +7,5 @@ Signature: ```typescript -subType?: IFieldSubType; +get subType(): import("../types").IFieldSubType | undefined; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tojson.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tojson.md new file mode 100644 index 0000000000000..a6a3a5a093c8e --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tojson.md @@ -0,0 +1,41 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternField](./kibana-plugin-plugins-data-public.indexpatternfield.md) > [toJSON](./kibana-plugin-plugins-data-public.indexpatternfield.tojson.md) + +## IndexPatternField.toJSON() method + +Signature: + +```typescript +toJSON(): { + count: number; + script: string | undefined; + lang: string | undefined; + conflictDescriptions: Record | undefined; + name: string; + type: string; + esTypes: string[] | undefined; + scripted: boolean; + searchable: boolean; + aggregatable: boolean; + readFromDocValues: boolean; + subType: import("../types").IFieldSubType | undefined; + }; +``` +Returns: + +`{ + count: number; + script: string | undefined; + lang: string | undefined; + conflictDescriptions: Record | undefined; + name: string; + type: string; + esTypes: string[] | undefined; + scripted: boolean; + searchable: boolean; + aggregatable: boolean; + readFromDocValues: boolean; + subType: import("../types").IFieldSubType | undefined; + }` + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tospec.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tospec.md index 35714faa03bc9..5037cb0049e82 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tospec.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tospec.md @@ -2,10 +2,42 @@ [Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternField](./kibana-plugin-plugins-data-public.indexpatternfield.md) > [toSpec](./kibana-plugin-plugins-data-public.indexpatternfield.tospec.md) -## IndexPatternField.toSpec property +## IndexPatternField.toSpec() method Signature: ```typescript -toSpec: () => FieldSpecExportFmt; +toSpec(): { + count: number; + script: string | undefined; + lang: string | undefined; + conflictDescriptions: Record | undefined; + name: string; + type: string; + esTypes: string[] | undefined; + scripted: boolean; + searchable: boolean; + aggregatable: boolean; + readFromDocValues: boolean; + subType: import("../types").IFieldSubType | undefined; + format: any; + }; ``` +Returns: + +`{ + count: number; + script: string | undefined; + lang: string | undefined; + conflictDescriptions: Record | undefined; + name: string; + type: string; + esTypes: string[] | undefined; + scripted: boolean; + searchable: boolean; + aggregatable: boolean; + readFromDocValues: boolean; + subType: import("../types").IFieldSubType | undefined; + format: any; + }` + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.type.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.type.md index c8483c9b83c9a..45085b9e74bcc 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.type.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.type.md @@ -7,5 +7,5 @@ Signature: ```typescript -type: string; +get type(): string; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.visualizable.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.visualizable.md index dd661ae779c11..9ed689752503a 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.visualizable.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.visualizable.md @@ -7,5 +7,5 @@ Signature: ```typescript -visualizable?: boolean; +get visualizable(): boolean; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index db41936f35cca..c8d45804a3729 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -10,6 +10,7 @@ | --- | --- | | [AggParamType](./kibana-plugin-plugins-data-public.aggparamtype.md) | | | [FieldFormat](./kibana-plugin-plugins-data-public.fieldformat.md) | | +| [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) | | | [FilterManager](./kibana-plugin-plugins-data-public.filtermanager.md) | | | [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) | | | [IndexPatternField](./kibana-plugin-plugins-data-public.indexpatternfield.md) | | @@ -103,7 +104,6 @@ | [extractSearchSourceReferences](./kibana-plugin-plugins-data-public.extractsearchsourcereferences.md) | | | [fieldFormats](./kibana-plugin-plugins-data-public.fieldformats.md) | | | [FilterBar](./kibana-plugin-plugins-data-public.filterbar.md) | | -| [getIndexPatternFieldListCreator](./kibana-plugin-plugins-data-public.getindexpatternfieldlistcreator.md) | | | [getKbnTypeNames](./kibana-plugin-plugins-data-public.getkbntypenames.md) | Get the esTypes known by all kbnFieldTypes {Array} | | [indexPatterns](./kibana-plugin-plugins-data-public.indexpatterns.md) | | | [injectSearchSourceReferences](./kibana-plugin-plugins-data-public.injectsearchsourcereferences.md) | | diff --git a/src/plugins/data/common/index_patterns/fields/__snapshots__/field.test.ts.snap b/src/plugins/data/common/index_patterns/fields/__snapshots__/index_pattern_field.test.ts.snap similarity index 100% rename from src/plugins/data/common/index_patterns/fields/__snapshots__/field.test.ts.snap rename to src/plugins/data/common/index_patterns/fields/__snapshots__/index_pattern_field.test.ts.snap diff --git a/src/plugins/data/common/index_patterns/fields/field.ts b/src/plugins/data/common/index_patterns/fields/field.ts deleted file mode 100644 index 81c7aff8a0faa..0000000000000 --- a/src/plugins/data/common/index_patterns/fields/field.ts +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { i18n } from '@kbn/i18n'; -// @ts-ignore -import { ObjDefine } from './obj_define'; -import { IIndexPattern } from '../../types'; -import { - IFieldType, - getKbnFieldType, - IFieldSubType, - FieldFormat, - shortenDottedString, -} from '../../../common'; -import { - OnNotification, - FieldSpec, - FieldSpecConflictDescriptions, - FieldSpecExportFmt, -} from '../types'; -import { FieldFormatsStartCommon } from '../../field_formats'; - -interface FieldDependencies { - fieldFormats: FieldFormatsStartCommon; - onNotification: OnNotification; -} - -export class Field implements IFieldType { - name: string; - type: string; - script?: string; - lang?: string; - count?: number; - // esTypes might be undefined on old index patterns that have not been refreshed since we added - // this prop. It is also undefined on scripted fields. - esTypes?: string[]; - aggregatable?: boolean; - filterable?: boolean; - searchable?: boolean; - sortable?: boolean; - visualizable?: boolean; - scripted?: boolean; - subType?: IFieldSubType; - displayName?: string; - indexPattern?: IIndexPattern; - readFromDocValues?: boolean; - format: any; - $$spec: FieldSpec; - conflictDescriptions?: FieldSpecConflictDescriptions; - - constructor( - indexPattern: IIndexPattern, - spec: FieldSpecExportFmt | FieldSpec | Field, - shortDotsEnable: boolean, - { fieldFormats, onNotification }: FieldDependencies - ) { - // unwrap old instances of Field - if (spec instanceof Field) spec = spec.$$spec; - - // construct this object using ObjDefine class, which - // extends the Field.prototype but gets it's properties - // defined using the logic below - const obj = new ObjDefine(spec, Field.prototype); - - if (spec.name === '_source') { - spec.type = '_source'; - } - - // find the type for this field, fallback to unknown type - let type = getKbnFieldType(spec.type); - if (spec.type && !type) { - const title = i18n.translate('data.indexPatterns.unknownFieldHeader', { - values: { type: spec.type }, - defaultMessage: 'Unknown field type {type}', - }); - const text = i18n.translate('data.indexPatterns.unknownFieldErrorMessage', { - values: { name: spec.name, title: indexPattern.title }, - defaultMessage: 'Field {name} in indexPattern {title} is using an unknown field type.', - }); - onNotification({ title, text, color: 'danger', iconType: 'alert' }); - } - - if (!type) type = getKbnFieldType('unknown'); - - let format: any = spec.format; - - if (!FieldFormat.isInstanceOfFieldFormat(format)) { - format = - (indexPattern.fieldFormatMap && indexPattern.fieldFormatMap[spec.name]) || - fieldFormats.getDefaultInstance(spec.type, spec.esTypes); - } - - const indexed = !!spec.indexed; - const scripted = !!spec.scripted; - const searchable = !!spec.searchable || scripted; - const aggregatable = !!spec.aggregatable || scripted; - const readFromDocValues = !!spec.readFromDocValues && !scripted; - const sortable = spec.name === '_score' || ((indexed || aggregatable) && type && type.sortable); - const filterable = - spec.name === '_id' || scripted || ((indexed || searchable) && type && type.filterable); - const visualizable = aggregatable; - - this.name = ''; - obj.fact('name'); - this.type = ''; - obj.fact('type'); - obj.fact('esTypes'); - obj.writ('count', spec.count || 0); - - // scripted objs - obj.fact('scripted', scripted); - obj.writ('script', scripted ? spec.script : null); - obj.writ('lang', scripted ? spec.lang || 'painless' : null); - - // stats - obj.fact('searchable', searchable); - obj.fact('aggregatable', aggregatable); - obj.fact('readFromDocValues', readFromDocValues); - - // usage flags, read-only and won't be saved - obj.comp('format', format); - obj.comp('sortable', sortable); - obj.comp('filterable', filterable); - obj.comp('visualizable', visualizable); - - // computed values - obj.comp('indexPattern', indexPattern); - obj.comp('displayName', shortDotsEnable ? shortenDottedString(spec.name) : spec.name); - this.$$spec = spec; - obj.comp('$$spec', spec); - - // conflict info - obj.writ('conflictDescriptions'); - - // multi info - obj.fact('subType'); - - const newObj = obj.create(); - newObj.toSpec = function () { - return { - count: this.count, - script: this.script, - lang: this.lang, - conflictDescriptions: this.conflictDescriptions, - name: this.name, - type: this.type, - esTypes: this.esTypes, - scripted: this.scripted, - searchable: this.searchable, - aggregatable: this.aggregatable, - readFromDocValues: this.readFromDocValues, - subType: this.subType, - format: this.indexPattern?.fieldFormatMap[this.name]?.toJSON() || undefined, - }; - }; - return newObj; - } - // only providing type info as constructor returns new object instead of `this` - toSpec = () => (({} as unknown) as FieldSpecExportFmt); -} diff --git a/src/plugins/data/common/index_patterns/fields/field_list.ts b/src/plugins/data/common/index_patterns/fields/field_list.ts index c1ca5341328ce..207002f42bbce 100644 --- a/src/plugins/data/common/index_patterns/fields/field_list.ts +++ b/src/plugins/data/common/index_patterns/fields/field_list.ts @@ -18,95 +18,110 @@ */ import { findIndex } from 'lodash'; -import { IIndexPattern } from '../../types'; -import { IFieldType } from '../../../common'; -import { Field } from './field'; +import { IFieldType, shortenDottedString } from '../../../common'; +import { IndexPatternField } from './index_pattern_field'; import { OnNotification, FieldSpec } from '../types'; -import { FieldFormatsStartCommon } from '../../field_formats'; +import { IndexPattern } from '../index_patterns'; -type FieldMap = Map; +type FieldMap = Map; -interface FieldListDependencies { - fieldFormats: FieldFormatsStartCommon; - onNotification: OnNotification; -} - -export interface IIndexPatternFieldList extends Array { - getByName(name: Field['name']): Field | undefined; - getByType(type: Field['type']): Field[]; +export interface IIndexPatternFieldList extends Array { add(field: FieldSpec): void; + getByName(name: IndexPatternField['name']): IndexPatternField | undefined; + getByType(type: IndexPatternField['type']): IndexPatternField[]; remove(field: IFieldType): void; + removeAll(): void; + replaceAll(specs: FieldSpec[]): void; update(field: FieldSpec): void; } export type CreateIndexPatternFieldList = ( - indexPattern: IIndexPattern, + indexPattern: IndexPattern, specs?: FieldSpec[], - shortDotsEnable?: boolean + shortDotsEnable?: boolean, + onNotification?: OnNotification ) => IIndexPatternFieldList; -export const getIndexPatternFieldListCreator = ({ - fieldFormats, - onNotification, -}: FieldListDependencies): CreateIndexPatternFieldList => (...fieldListParams) => { - class FieldList extends Array implements IIndexPatternFieldList { - private byName: FieldMap = new Map(); - private groups: Map = new Map(); - private indexPattern: IIndexPattern; - private shortDotsEnable: boolean; - private setByName = (field: Field) => this.byName.set(field.name, field); - private setByGroup = (field: Field) => { - if (typeof this.groups.get(field.type) === 'undefined') { - this.groups.set(field.type, new Map()); - } - this.groups.get(field.type)!.set(field.name, field); - }; - private removeByGroup = (field: IFieldType) => this.groups.get(field.type)!.delete(field.name); +export class FieldList extends Array implements IIndexPatternFieldList { + private byName: FieldMap = new Map(); + private groups: Map = new Map(); + private indexPattern: IndexPattern; + private shortDotsEnable: boolean; + private onNotification: OnNotification; + private setByName = (field: IndexPatternField) => this.byName.set(field.name, field); + private setByGroup = (field: IndexPatternField) => { + if (typeof this.groups.get(field.type) === 'undefined') { + this.groups.set(field.type, new Map()); + } + this.groups.get(field.type)!.set(field.name, field); + }; + private removeByGroup = (field: IFieldType) => this.groups.get(field.type)!.delete(field.name); + private calcDisplayName = (name: string) => + this.shortDotsEnable ? shortenDottedString(name) : name; + constructor( + indexPattern: IndexPattern, + specs: FieldSpec[] = [], + shortDotsEnable = false, + onNotification = () => {} + ) { + super(); + this.indexPattern = indexPattern; + this.shortDotsEnable = shortDotsEnable; + this.onNotification = onNotification; - constructor(indexPattern: IIndexPattern, specs: FieldSpec[] = [], shortDotsEnable = false) { - super(); - this.indexPattern = indexPattern; - this.shortDotsEnable = shortDotsEnable; + specs.map((field) => this.add(field)); + } - specs.map((field) => this.add(field)); - } + public readonly getByName = (name: IndexPatternField['name']) => this.byName.get(name); + public readonly getByType = (type: IndexPatternField['type']) => [ + ...(this.groups.get(type) || new Map()).values(), + ]; + public readonly add = (field: FieldSpec) => { + const newField = new IndexPatternField( + this.indexPattern, + field, + this.calcDisplayName(field.name), + this.onNotification + ); + this.push(newField); + this.setByName(newField); + this.setByGroup(newField); + }; - getByName = (name: Field['name']) => this.byName.get(name); - getByType = (type: Field['type']) => [...(this.groups.get(type) || new Map()).values()]; - add = (field: FieldSpec) => { - const newField = new Field(this.indexPattern, field, this.shortDotsEnable, { - fieldFormats, - onNotification, - }); - this.push(newField); - this.setByName(newField); - this.setByGroup(newField); - }; + public readonly remove = (field: IFieldType) => { + this.removeByGroup(field); + this.byName.delete(field.name); - remove = (field: IFieldType) => { - this.removeByGroup(field); - this.byName.delete(field.name); + const fieldIndex = findIndex(this, { name: field.name }); + this.splice(fieldIndex, 1); + }; - const fieldIndex = findIndex(this, { name: field.name }); - this.splice(fieldIndex, 1); - }; + public readonly update = (field: FieldSpec) => { + const newField = new IndexPatternField( + this.indexPattern, + field, + this.calcDisplayName(field.name), + this.onNotification + ); + const index = this.findIndex((f) => f.name === newField.name); + this.splice(index, 1, newField); + this.setByName(newField); + this.removeByGroup(newField); + this.setByGroup(newField); + }; - update = (field: FieldSpec) => { - const newField = new Field(this.indexPattern, field, this.shortDotsEnable, { - fieldFormats, - onNotification, - }); - const index = this.findIndex((f) => f.name === newField.name); - this.splice(index, 1, newField); - this.setByName(newField); - this.removeByGroup(newField); - this.setByGroup(newField); - }; + public readonly removeAll = () => { + this.length = 0; + this.byName.clear(); + this.groups.clear(); + }; - toSpec = () => { - return [...this.map((field) => field.toSpec())]; - }; - } + public readonly replaceAll = (specs: FieldSpec[]) => { + this.removeAll(); + specs.forEach(this.add); + }; - return new FieldList(...fieldListParams); -}; + public readonly toSpec = () => { + return [...this.map((field) => field.toSpec())]; + }; +} diff --git a/src/plugins/data/common/index_patterns/fields/index.ts b/src/plugins/data/common/index_patterns/fields/index.ts index 1b7c87d556f59..0c3b43181c5b4 100644 --- a/src/plugins/data/common/index_patterns/fields/index.ts +++ b/src/plugins/data/common/index_patterns/fields/index.ts @@ -20,4 +20,4 @@ export * from './types'; export { isFilterable, isNestedField } from './utils'; export * from './field_list'; -export * from './field'; +export * from './index_pattern_field'; diff --git a/src/plugins/data/common/index_patterns/fields/field.test.ts b/src/plugins/data/common/index_patterns/fields/index_pattern_field.test.ts similarity index 64% rename from src/plugins/data/common/index_patterns/fields/field.test.ts rename to src/plugins/data/common/index_patterns/fields/index_pattern_field.test.ts index 910f22088f43a..0cd0fe8324809 100644 --- a/src/plugins/data/common/index_patterns/fields/field.test.ts +++ b/src/plugins/data/common/index_patterns/fields/index_pattern_field.test.ts @@ -17,10 +17,10 @@ * under the License. */ -import { Field } from './field'; +import { IndexPatternField } from './index_pattern_field'; import { IndexPattern } from '../index_patterns'; -import { FieldFormatsStartCommon } from '../..'; -import { KBN_FIELD_TYPES, FieldSpec, FieldSpecExportFmt } from '../../../common'; +import { KBN_FIELD_TYPES } from '../../../common'; +import { FieldSpec } from '../types'; describe('Field', function () { function flatten(obj: Record) { @@ -28,14 +28,11 @@ describe('Field', function () { } function getField(values = {}) { - return new Field( + return new IndexPatternField( fieldValues.indexPattern as IndexPattern, { ...fieldValues, ...values }, - false, - { - fieldFormats: {} as FieldFormatsStartCommon, - onNotification: () => {}, - } + 'displayName', + () => {} ); } @@ -50,6 +47,7 @@ describe('Field', function () { filterable: true, searchable: true, sortable: true, + indexed: true, readFromDocValues: false, visualizable: true, scripted: true, @@ -58,11 +56,9 @@ describe('Field', function () { indexPattern: ({ fieldFormatMap: { name: {}, _source: {}, _score: {}, _id: {} }, } as unknown) as IndexPattern, - format: { name: 'formatName' }, $$spec: ({} as unknown) as FieldSpec, conflictDescriptions: { a: ['b', 'c'], d: ['e'] }, - toSpec: () => (({} as unknown) as FieldSpecExportFmt), - } as Field; + }; it('the correct properties are writable', () => { const field = getField(); @@ -84,72 +80,6 @@ describe('Field', function () { expect(field.conflictDescriptions).toEqual({}); }); - it('the correct properties are not writable', () => { - const field = getField(); - - expect(field.name).toEqual(fieldValues.name); - field.name = 'newName'; - expect(field.name).toEqual(fieldValues.name); - - expect(field.type).toEqual(fieldValues.type); - field.type = 'newType'; - expect(field.type).toEqual(fieldValues.type); - - expect(field.esTypes).toEqual(fieldValues.esTypes); - field.esTypes = ['newType']; - expect(field.esTypes).toEqual(fieldValues.esTypes); - - expect(field.scripted).toEqual(fieldValues.scripted); - field.scripted = false; - expect(field.scripted).toEqual(fieldValues.scripted); - - expect(field.searchable).toEqual(fieldValues.searchable); - field.searchable = false; - expect(field.searchable).toEqual(fieldValues.searchable); - - expect(field.aggregatable).toEqual(fieldValues.aggregatable); - field.aggregatable = false; - expect(field.aggregatable).toEqual(fieldValues.aggregatable); - - expect(field.readFromDocValues).toEqual(fieldValues.readFromDocValues); - field.readFromDocValues = true; - expect(field.readFromDocValues).toEqual(fieldValues.readFromDocValues); - - expect(field.subType).toEqual(fieldValues.subType); - field.subType = {}; - expect(field.subType).toEqual(fieldValues.subType); - - // not writable, not serialized - expect(() => { - field.indexPattern = {} as IndexPattern; - }).toThrow(); - - // computed fields - expect(() => { - field.format = { name: 'newFormatName' }; - }).toThrow(); - - expect(() => { - field.sortable = false; - }).toThrow(); - - expect(() => { - field.filterable = false; - }).toThrow(); - - expect(() => { - field.visualizable = false; - }).toThrow(); - - expect(() => { - field.displayName = 'newDisplayName'; - }).toThrow(); - - expect(() => { - field.$$spec = ({ a: 'b' } as unknown) as FieldSpec; - }).toThrow(); - }); - it('sets type field when _source field', () => { const field = getField({ name: '_source' }); expect(field.type).toEqual('_source'); @@ -214,26 +144,25 @@ describe('Field', function () { }); it('exports the property to JSON', () => { - const field = new Field({ fieldFormatMap: { name: {} } } as IndexPattern, fieldValues, false, { - fieldFormats: {} as FieldFormatsStartCommon, - onNotification: () => {}, - }); + const field = new IndexPatternField( + { fieldFormatMap: { name: {} } } as IndexPattern, + fieldValues, + 'displayName', + () => {} + ); expect(flatten(field)).toMatchSnapshot(); }); it('spec snapshot', () => { - const field = new Field( + const field = new IndexPatternField( { fieldFormatMap: { name: { toJSON: () => ({ id: 'number', params: { pattern: '$0,0.[00]' } }) }, }, } as IndexPattern, fieldValues, - false, - { - fieldFormats: {} as FieldFormatsStartCommon, - onNotification: () => {}, - } + 'displayName', + () => {} ); expect(field.toSpec()).toMatchSnapshot(); }); diff --git a/src/plugins/data/common/index_patterns/fields/index_pattern_field.ts b/src/plugins/data/common/index_patterns/fields/index_pattern_field.ts new file mode 100644 index 0000000000000..4e22332bef141 --- /dev/null +++ b/src/plugins/data/common/index_patterns/fields/index_pattern_field.ts @@ -0,0 +1,188 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { + IFieldType, + KbnFieldType, + getKbnFieldType, + KBN_FIELD_TYPES, + FieldFormat, +} from '../../../common'; +import { OnNotification, FieldSpec } from '../types'; + +import { IndexPattern } from '../index_patterns'; + +export class IndexPatternField implements IFieldType { + readonly spec: FieldSpec; + // not writable or serialized + readonly indexPattern: IndexPattern; + readonly displayName: string; + private readonly kbnFieldType: KbnFieldType; + + constructor( + indexPattern: IndexPattern, + spec: FieldSpec, + displayName: string, + onNotification: OnNotification + ) { + this.indexPattern = indexPattern; + this.spec = { ...spec, type: spec.name === '_source' ? '_source' : spec.type }; + this.displayName = displayName; + + this.kbnFieldType = getKbnFieldType(spec.type); + if (spec.type && this.kbnFieldType?.name === KBN_FIELD_TYPES.UNKNOWN) { + const title = i18n.translate('data.indexPatterns.unknownFieldHeader', { + values: { type: spec.type }, + defaultMessage: 'Unknown field type {type}', + }); + const text = i18n.translate('data.indexPatterns.unknownFieldErrorMessage', { + values: { name: spec.name, title: indexPattern.title }, + defaultMessage: 'Field {name} in indexPattern {title} is using an unknown field type.', + }); + onNotification({ title, text, color: 'danger', iconType: 'alert' }); + } + } + + // writable attrs + public get count() { + return this.spec.count; + } + + public set count(count) { + this.spec.count = count; + } + + public get script() { + return this.spec.script; + } + + public set script(script) { + this.spec.script = script; + } + + public get lang() { + return this.spec.lang; + } + + public set lang(lang) { + this.spec.lang = lang; + } + + public get conflictDescriptions() { + return this.spec.conflictDescriptions; + } + + public set conflictDescriptions(conflictDescriptions) { + this.spec.conflictDescriptions = conflictDescriptions; + } + + // read only attrs + public get name() { + return this.spec.name; + } + + public get type() { + return this.spec.type; + } + + public get esTypes() { + return this.spec.esTypes; + } + + public get scripted() { + return this.spec.scripted; + } + + public get searchable() { + return !!(this.spec.searchable || this.scripted); + } + + public get aggregatable() { + return !!(this.spec.aggregatable || this.scripted); + } + + public get readFromDocValues() { + return !!(this.spec.readFromDocValues && !this.scripted); + } + + public get subType() { + return this.spec.subType; + } + + // not writable, not serialized + public get sortable() { + return ( + this.name === '_score' || + ((this.spec.indexed || this.aggregatable) && this.kbnFieldType.sortable) + ); + } + + public get filterable() { + return ( + this.name === '_id' || + this.scripted || + ((this.spec.indexed || this.searchable) && this.kbnFieldType.filterable) + ); + } + + public get visualizable() { + return this.aggregatable; + } + + public get format(): FieldFormat { + return this.indexPattern.getFormatterForField(this); + } + + public toJSON() { + return { + count: this.count, + script: this.script, + lang: this.lang, + conflictDescriptions: this.conflictDescriptions, + + name: this.name, + type: this.type, + esTypes: this.esTypes, + scripted: this.scripted, + searchable: this.searchable, + aggregatable: this.aggregatable, + readFromDocValues: this.readFromDocValues, + subType: this.subType, + }; + } + + public toSpec() { + return { + count: this.count, + script: this.script, + lang: this.lang, + conflictDescriptions: this.conflictDescriptions, + name: this.name, + type: this.type, + esTypes: this.esTypes, + scripted: this.scripted, + searchable: this.searchable, + aggregatable: this.aggregatable, + readFromDocValues: this.readFromDocValues, + subType: this.subType, + format: this.indexPattern?.fieldFormatMap[this.name]?.toJSON() || undefined, + }; + } +} diff --git a/src/plugins/data/common/index_patterns/fields/obj_define.js b/src/plugins/data/common/index_patterns/fields/obj_define.js deleted file mode 100644 index 9c9e5c8f3d55f..0000000000000 --- a/src/plugins/data/common/index_patterns/fields/obj_define.js +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import _ from 'lodash'; - -export function ObjDefine(defaults, prototype) { - this.obj; // created by this.create() - - this.descs = {}; - this.defaults = defaults || {}; - this.prototype = prototype || Object.prototype; -} - -ObjDefine.REDEFINE_SUPPORTED = (function () { - const a = Object.create(Object.prototype, { - prop: { - configurable: true, - value: 1, - }, - }); - - Object.defineProperty(a, 'prop', { - configurable: true, - value: 2, - }); - - return a.prop === 2; -})(); - -/** - * normal value, writable and exported in JSON - * - * @param {any} v - value - * @return {object} - property descriptor - */ -ObjDefine.prototype.writ = function (name, val) { - this._define(name, val, true, true); -}; - -/** - * known value, exported in JSON, not changeable - * - * @param {any} v - value - * @return {object} - property descriptor - */ -ObjDefine.prototype.fact = function (name, val) { - this._define(name, val, true); -}; - -/** - * computed fact, not exported or changeable - * - * @param {any} v - value - * @return {object} - property descriptor - */ -ObjDefine.prototype.comp = function (name, val) { - this._define(name, val); -}; - -/** - * Creates an object, decorated by the property descriptors - * created by other ObjDefine methods and inheriting form the - * prototype - * - * # note: - * If a value is writable, but the value is undefined, the property will - * be created by not exported to JSON unless the property is written to - * - * @return {object} - created object - */ -ObjDefine.prototype.create = function () { - const self = this; - self.obj = Object.create(this.prototype, self.descs); - - if (!ObjDefine.REDEFINE_SUPPORTED && !self.prototype.toJSON) { - // since we can't redefine properties as enumerable we will - // clone the object on serialization and choose which properties - // to include or trim manually. This is currently only in use in PhantomJS - // due to https://github.com/ariya/phantomjs/issues/11856 - // TODO: remove this: https://github.com/elastic/kibana/issues/27136 - self.obj.toJSON = function () { - return _.transform( - self.obj, - function (json, val, key) { - const desc = self.descs[key]; - if (desc && desc.enumerable && val == null) return; - json[key] = val; - }, - {} - ); - }; - } - - return self.obj; -}; - -/** - * Private APIS - */ - -ObjDefine.prototype._define = function (name, val, exported, changeable) { - val = val != null ? val : this.defaults[name]; - this.descs[name] = this._describe(name, val, !!exported, !!changeable); -}; - -ObjDefine.prototype._describe = function (name, val, exported, changeable) { - const self = this; - const exists = val != null; - - if (exported && ObjDefine.REDEFINE_SUPPORTED) { - return { - enumerable: exists, - configurable: true, - get: _.constant(val), - set: function (update) { - if (!changeable) return false; - - // change the descriptor, since the value now exists. - self.descs[name] = self._describe(name, update, exported, changeable); - - // apply the updated descriptor - Object.defineProperty(self.obj, name, self.descs[name]); - }, - }; - } - - if (exported && !ObjDefine.REDEFINE_SUPPORTED) { - return { - enumerable: true, - configurable: true, - writable: changeable, - value: val, - }; - } - - return { - enumerable: false, - writable: changeable, - configurable: true, - value: val, - }; -}; diff --git a/src/plugins/data/common/index_patterns/fields/obj_define.test.js b/src/plugins/data/common/index_patterns/fields/obj_define.test.js deleted file mode 100644 index ec9a022253621..0000000000000 --- a/src/plugins/data/common/index_patterns/fields/obj_define.test.js +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import { ObjDefine } from './obj_define'; - -describe('ObjDefine Utility', function () { - function flatten(obj) { - return JSON.parse(JSON.stringify(obj)); - } - - describe('#writ', function () { - it('creates writeable properties', function () { - const def = new ObjDefine(); - def.writ('name', 'foo'); - - const obj = def.create(); - expect(obj).to.have.property('name', 'foo'); - - obj.name = 'bar'; - expect(obj).to.have.property('name', 'bar'); - }); - - it('exports the property to JSON', function () { - const def = new ObjDefine(); - def.writ('name', 'foo'); - expect(flatten(def.create())).to.have.property('name', 'foo'); - }); - - it("does not export property to JSON it it's undefined or null", function () { - const def = new ObjDefine(); - def.writ('name'); - expect(flatten(def.create())).to.not.have.property('name'); - - def.writ('name', null); - expect(flatten(def.create())).to.not.have.property('name'); - }); - - it('switched to exporting if a value is written', function () { - const def = new ObjDefine(); - def.writ('name'); - - const obj = def.create(); - expect(flatten(obj)).to.not.have.property('name'); - - obj.name = null; - expect(flatten(obj)).to.not.have.property('name'); - - obj.name = 'foo'; - expect(flatten(obj)).to.have.property('name', 'foo'); - }); - - it('setting a writ value to null prevents it from exporting', function () { - const def = new ObjDefine(); - def.writ('name', 'foo'); - - const obj = def.create(); - expect(flatten(obj)).to.have.property('name', 'foo'); - - obj.name = null; - expect(flatten(obj)).to.not.have.property('name'); - }); - }); - - describe('#fact', function () { - it('creates an immutable field', function () { - const def = new ObjDefine(); - const val = 'foo'; - const notval = 'bar'; - def.fact('name', val); - const obj = def.create(); - - obj.name = notval; // UPDATE SHOULD BE IGNORED - expect(obj).to.have.property('name', val); - }); - - it('exports the fact to JSON', function () { - const def = new ObjDefine(); - def.fact('name', 'foo'); - expect(flatten(def.create())).to.have.property('name', 'foo'); - }); - }); - - describe('#comp', function () { - it('creates an immutable field', function () { - const def = new ObjDefine(); - const val = 'foo'; - const notval = 'bar'; - def.comp('name', val); - const obj = def.create(); - - expect(function () { - 'use strict'; // eslint-disable-line strict - - obj.name = notval; - }).to.throwException(); - }); - - it('does not export the computed value to JSON', function () { - const def = new ObjDefine(); - def.comp('name', 'foo'); - expect(flatten(def.create())).to.not.have.property('name'); - }); - }); - - describe('#create', function () { - it('creates object that inherits from the prototype', function () { - function SomeClass() {} - - const def = new ObjDefine(null, SomeClass.prototype); - const obj = def.create(); - - expect(obj).to.be.a(SomeClass); - }); - - it('uses the defaults for property values', function () { - const def = new ObjDefine({ name: 'bar' }); - def.fact('name'); - - const obj = def.create(); - - expect(obj).to.have.property('name', 'bar'); - }); - - it('ignores default values that are not defined properties', function () { - const def = new ObjDefine({ name: 'foo', name2: 'bar' }); - const obj = def.create(); - - expect(obj).to.not.have.property('name'); - expect(obj).to.not.have.property('name2'); - }); - }); -}); diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts index ebf873b14c379..e4f297b29c372 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts @@ -26,7 +26,7 @@ import { DuplicateField } from '../../../../kibana_utils/common'; import mockLogStashFields from '../../../../../fixtures/logstash_fields'; // @ts-ignore import { stubbedSavedObjectIndexPattern } from '../../../../../fixtures/stubbed_saved_object_index_pattern'; -import { Field } from '../fields'; +import { IndexPatternField } from '../fields'; import { fieldFormatsMock } from '../../field_formats/mocks'; @@ -170,8 +170,8 @@ describe('IndexPattern', () => { describe('getScriptedFields', () => { test('should return all scripted fields', () => { const scriptedNames = mockLogStashFields() - .filter((item: Field) => item.scripted === true) - .map((item: Field) => item.name); + .filter((item: IndexPatternField) => item.scripted === true) + .map((item: IndexPatternField) => item.name); const respNames = map(indexPattern.getScriptedFields(), 'name'); expect(respNames).toEqual(scriptedNames); @@ -214,8 +214,8 @@ describe('IndexPattern', () => { describe('getNonScriptedFields', () => { test('should return all non-scripted fields', () => { const notScriptedNames = mockLogStashFields() - .filter((item: Field) => item.scripted === false) - .map((item: Field) => item.name); + .filter((item: IndexPatternField) => item.scripted === false) + .map((item: IndexPatternField) => item.name); const respNames = map(indexPattern.getNonScriptedFields(), 'name'); expect(respNames).toEqual(notScriptedNames); @@ -235,7 +235,7 @@ describe('IndexPattern', () => { const newFields = indexPattern.getNonScriptedFields(); expect(newFields).toHaveLength(2); - expect(newFields.map((f) => f.name)).toEqual(['foo', 'bar']); + expect([...newFields.map((f) => f.name)]).toEqual(['foo', 'bar']); }); test('should preserve the scripted fields', async () => { @@ -249,8 +249,8 @@ describe('IndexPattern', () => { // sinon.assert.calledOnce(indexPattern.getScriptedFields); expect(indexPattern.getScriptedFields().map((f) => f.name)).toEqual( mockLogStashFields() - .filter((f: Field) => f.scripted) - .map((f: Field) => f.name) + .filter((f: IndexPatternField) => f.scripted) + .map((f: IndexPatternField) => f.name) ); }); }); @@ -278,7 +278,7 @@ describe('IndexPattern', () => { const scriptedFields = indexPattern.getScriptedFields(); // expect(saveSpy.callCount).to.equal(1); expect(scriptedFields).toHaveLength(oldCount + 1); - expect((indexPattern.fields.getByName(scriptedField.name) as Field).name).toEqual( + expect((indexPattern.fields.getByName(scriptedField.name) as IndexPatternField).name).toEqual( scriptedField.name ); }); @@ -287,9 +287,9 @@ describe('IndexPattern', () => { // const saveSpy = sinon.spy(indexPattern, 'save'); const scriptedFields = indexPattern.getScriptedFields(); const oldCount = scriptedFields.length; - const scriptedField = last(scriptedFields) as any; + const scriptedField = last(scriptedFields)!; - await indexPattern.removeScriptedField(scriptedField); + await indexPattern.removeScriptedField(scriptedField.name); // expect(saveSpy.callCount).to.equal(1); expect(indexPattern.getScriptedFields().length).toEqual(oldCount - 1); diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts index 2acb9d5f767ad..211919e8e6b53 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts @@ -22,10 +22,10 @@ import { i18n } from '@kbn/i18n'; import { SavedObjectsClientCommon } from '../..'; import { DuplicateField, SavedObjectNotFound } from '../../../../kibana_utils/common'; -import { ES_FIELD_TYPES, KBN_FIELD_TYPES, IIndexPattern, IFieldType } from '../../../common'; +import { ES_FIELD_TYPES, KBN_FIELD_TYPES, IIndexPattern } from '../../../common'; import { findByTitle } from '../utils'; import { IndexPatternMissingIndices } from '../lib'; -import { Field, IIndexPatternFieldList, getIndexPatternFieldListCreator } from '../fields'; +import { IndexPatternField, IIndexPatternFieldList, FieldList } from '../fields'; import { createFieldsFetcher } from './_fields_fetcher'; import { formatHitProvider } from './format_hit'; import { flattenHitWrapper } from './flatten_hit'; @@ -36,7 +36,7 @@ import { IIndexPatternsApiClient, IndexPatternAttributes, } from '../types'; -import { FieldFormatsStartCommon } from '../../field_formats'; +import { FieldFormatsStartCommon, FieldFormat } from '../../field_formats'; import { PatternCache } from './_pattern_cache'; import { expandShorthand, FieldMappingSpec, MappingObject } from '../../field_mapping'; import { IndexPatternSpec, TypeMeta, FieldSpec, SourceFilter } from '../types'; @@ -138,12 +138,8 @@ export class IndexPattern implements IIndexPattern { this.shortDotsEnable = uiSettingsValues.shortDotsEnable; this.metaFields = uiSettingsValues.metaFields; - this.createFieldList = getIndexPatternFieldListCreator({ - fieldFormats, - onNotification, - }); + this.fields = new FieldList(this, [], this.shortDotsEnable, this.onUnknownType); - this.fields = this.createFieldList(this, [], this.shortDotsEnable); this.apiClient = apiClient; this.fieldsFetcher = createFieldsFetcher(this, apiClient, uiSettingsValues.metaFields); this.flattenHit = flattenHitWrapper(this, uiSettingsValues.metaFields); @@ -161,49 +157,45 @@ export class IndexPattern implements IIndexPattern { } private deserializeFieldFormatMap(mapping: any) { - const FieldFormat = this.fieldFormats.getType(mapping.id); + const FieldFormatter = this.fieldFormats.getType(mapping.id); return ( - FieldFormat && - new FieldFormat( + FieldFormatter && + new FieldFormatter( mapping.params, (key: string) => this.uiSettingsValues[key]?.userValue || this.uiSettingsValues[key]?.value ) ); } - private initFields(input?: any) { - const newValue = input || this.fields; - - this.fields = this.createFieldList(this, newValue, this.shortDotsEnable); - } - - private isFieldRefreshRequired(): boolean { - if (!this.fields) { + private isFieldRefreshRequired(specs?: FieldSpec[]): boolean { + if (!specs) { return true; } - return this.fields.every((field) => { + return specs.every((spec) => { // See https://github.com/elastic/kibana/pull/8421 - const hasFieldCaps = 'aggregatable' in field && 'searchable' in field; + const hasFieldCaps = 'aggregatable' in spec && 'searchable' in spec; // See https://github.com/elastic/kibana/pull/11969 - const hasDocValuesFlag = 'readFromDocValues' in field; + const hasDocValuesFlag = 'readFromDocValues' in spec; return !hasFieldCaps || !hasDocValuesFlag; }); } - private async indexFields(forceFieldRefresh: boolean = false) { + private async indexFields(forceFieldRefresh: boolean = false, specs?: FieldSpec[]) { if (!this.id) { return; } - if (forceFieldRefresh || this.isFieldRefreshRequired()) { + if (forceFieldRefresh || this.isFieldRefreshRequired(specs)) { await this.refreshFields(); + } else { + if (specs) { + this.fields.replaceAll(specs); + } } - - this.initFields(); } public initFromSpec(spec: IndexPatternSpec) { @@ -223,15 +215,13 @@ export class IndexPattern implements IIndexPattern { this.timeFieldName = spec.timeFieldName; this.sourceFilters = spec.sourceFilters; - // ignoring this because the same thing happens elsewhere but via _.assign - // @ts-expect-error - this.fields = spec.fields || []; + this.fields.replaceAll(spec.fields || []); this.typeMeta = spec.typeMeta; + this.fieldFormatMap = _.mapValues(fieldFormatMap, (mapping) => { return this.deserializeFieldFormatMap(mapping); }); - this.initFields(); return this; } @@ -249,14 +239,16 @@ export class IndexPattern implements IIndexPattern { }); // give index pattern all of the values + const fieldList = this.fields; _.assign(this, response); + this.fields = fieldList; if (!this.title && this.id) { this.title = this.id; } this.version = response.version; - return this.indexFields(forceFieldRefresh); + return this.indexFields(forceFieldRefresh, response.fields); } getComputedFields() { @@ -359,32 +351,26 @@ export class IndexPattern implements IIndexPattern { throw new DuplicateField(name); } - this.fields.add( - new Field( - this, - { - name, - script, - fieldType, - scripted: true, - lang, - aggregatable: true, - filterable: true, - searchable: true, - }, - false, - { - fieldFormats: this.fieldFormats, - onNotification: this.onNotification, - } - ) - ); + this.fields.add({ + name, + script, + type: fieldType, + scripted: true, + lang, + aggregatable: true, + searchable: true, + count: 0, + readFromDocValues: false, + }); await this.save(); } - removeScriptedField(field: IFieldType) { - this.fields.remove(field); + removeScriptedField(fieldName: string) { + const field = this.fields.getByName(fieldName); + if (field) { + this.fields.remove(field); + } return this.save(); } @@ -417,11 +403,11 @@ export class IndexPattern implements IIndexPattern { } getNonScriptedFields() { - return _.filter(this.fields, { scripted: false }); + return [...this.fields.filter((field) => !field.scripted)]; } getScriptedFields() { - return _.filter(this.fields, { scripted: true }); + return [...this.fields.filter((field) => field.scripted)]; } isTimeBased(): boolean { @@ -438,12 +424,12 @@ export class IndexPattern implements IIndexPattern { } getTimeField() { - if (!this.timeFieldName || !this.fields || !this.fields.getByName) return; - return this.fields.getByName(this.timeFieldName); + if (!this.timeFieldName || !this.fields || !this.fields.getByName) return undefined; + return this.fields.getByName(this.timeFieldName) || undefined; } - getFieldByName(name: string): Field | void { - if (!this.fields || !this.fields.getByName) return; + getFieldByName(name: string): IndexPatternField | undefined { + if (!this.fields || !this.fields.getByName) return undefined; return this.fields.getByName(name); } @@ -470,6 +456,16 @@ export class IndexPattern implements IIndexPattern { return body; } + getFormatterForField(field: IndexPatternField | IndexPatternField['spec']): FieldFormat { + return ( + this.fieldFormatMap[field.name] || + this.fieldFormats.getDefaultInstance( + field.type as KBN_FIELD_TYPES, + field.esTypes as ES_FIELD_TYPES[] + ) + ); + } + async create(allowOverride: boolean = false) { const _create = async (duplicateId?: string) => { if (duplicateId) { @@ -581,9 +577,8 @@ export class IndexPattern implements IIndexPattern { async _fetchFields() { const fields = await this.fieldsFetcher.fetch(this); - const scripted = this.getScriptedFields(); - const all = fields.concat(scripted); - await this.initFields(all); + const scripted = this.getScriptedFields().map((field) => field.spec); + this.fields.replaceAll([...fields, ...scripted]); } refreshFields() { diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts index a07ffaf92aea5..8874ce5f04b7c 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts @@ -25,14 +25,13 @@ import { createEnsureDefaultIndexPattern, EnsureDefaultIndexPattern, } from './ensure_default_index_pattern'; -import { getIndexPatternFieldListCreator, CreateIndexPatternFieldList, Field } from '../fields'; +import { IndexPatternField } from '../fields'; import { OnNotification, OnError, UiSettingsCommon, IIndexPatternsApiClient, GetFieldsOptions, - FieldSpec, IndexPatternSpec, } from '../types'; import { FieldFormatsStartCommon } from '../../field_formats'; @@ -65,12 +64,6 @@ export class IndexPatternsService { private onNotification: OnNotification; private onError: OnError; ensureDefaultIndexPattern: EnsureDefaultIndexPattern; - createFieldList: CreateIndexPatternFieldList; - createField: ( - indexPattern: IndexPattern, - spec: FieldSpec | Field, - shortDotsEnable: boolean - ) => Field; constructor({ uiSettings, @@ -91,16 +84,15 @@ export class IndexPatternsService { uiSettings, onRedirectNoIndexPattern ); - this.createFieldList = getIndexPatternFieldListCreator({ - fieldFormats, - onNotification, - }); - this.createField = (indexPattern, spec, shortDotsEnable) => { - return new Field(indexPattern, spec, shortDotsEnable, { - fieldFormats, - onNotification, - }); - }; + } + + public createField( + indexPattern: IndexPattern, + spec: IndexPatternField['spec'], + displayName: string, + onNotification: OnNotification + ) { + return new IndexPatternField(indexPattern, spec, displayName, onNotification); } private async refreshSavedObjectsCache() { diff --git a/src/plugins/data/common/index_patterns/types.ts b/src/plugins/data/common/index_patterns/types.ts index 4241df5718243..3a7cf54843dfc 100644 --- a/src/plugins/data/common/index_patterns/types.ts +++ b/src/plugins/data/common/index_patterns/types.ts @@ -149,8 +149,21 @@ export interface FieldSpecExportFmt { } export interface FieldSpec { - [key: string]: any; + count: number; + script?: string; + lang?: string; + conflictDescriptions?: Record; format?: SerializedFieldFormat; + + name: string; + type: string; + esTypes?: string[]; + scripted: boolean; + searchable: boolean; + aggregatable: boolean; + readFromDocValues?: boolean; + subType?: IFieldSubType; + indexed?: boolean; } export interface IndexPatternSpec { diff --git a/src/plugins/data/common/kbn_field_types/kbn_field_types.test.ts b/src/plugins/data/common/kbn_field_types/kbn_field_types.test.ts index a3fe19fa9b2fc..6a2d6edd04692 100644 --- a/src/plugins/data/common/kbn_field_types/kbn_field_types.test.ts +++ b/src/plugins/data/common/kbn_field_types/kbn_field_types.test.ts @@ -55,10 +55,10 @@ describe('utils/kbn_field_types', () => { expect(kbnFieldType).toHaveProperty('name', ES_FIELD_TYPES.STRING); }); - test('returns undefined for invalid name', () => { + test('returns unknown for invalid name', () => { const kbnFieldType = getKbnFieldType('wrongType'); - expect(kbnFieldType).toBeUndefined(); + expect(kbnFieldType).toHaveProperty('name', KBN_FIELD_TYPES.UNKNOWN); }); }); diff --git a/src/plugins/data/common/kbn_field_types/kbn_field_types.ts b/src/plugins/data/common/kbn_field_types/kbn_field_types.ts index ce05dc796bbab..ffeb9c517daf5 100644 --- a/src/plugins/data/common/kbn_field_types/kbn_field_types.ts +++ b/src/plugins/data/common/kbn_field_types/kbn_field_types.ts @@ -17,7 +17,7 @@ * under the License. */ -import { createKbnFieldTypes } from './kbn_field_types_factory'; +import { createKbnFieldTypes, kbnFieldTypeUnknown } from './kbn_field_types_factory'; import { KbnFieldType } from './kbn_field_type'; import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from './types'; @@ -30,8 +30,8 @@ const registeredKbnTypes = createKbnFieldTypes(); * @param {string} typeName * @return {KbnFieldType} */ -export const getKbnFieldType = (typeName: string): KbnFieldType | undefined => - registeredKbnTypes.find((t) => t.name === typeName); +export const getKbnFieldType = (typeName: string): KbnFieldType => + registeredKbnTypes.find((t) => t.name === typeName) || kbnFieldTypeUnknown; /** * Get the esTypes known by all kbnFieldTypes diff --git a/src/plugins/data/common/kbn_field_types/kbn_field_types_factory.ts b/src/plugins/data/common/kbn_field_types/kbn_field_types_factory.ts index cb9357eb9865e..b93ebcbbca9c8 100644 --- a/src/plugins/data/common/kbn_field_types/kbn_field_types_factory.ts +++ b/src/plugins/data/common/kbn_field_types/kbn_field_types_factory.ts @@ -20,6 +20,10 @@ import { KbnFieldType } from './kbn_field_type'; import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from './types'; +export const kbnFieldTypeUnknown = new KbnFieldType({ + name: KBN_FIELD_TYPES.UNKNOWN, +}); + export const createKbnFieldTypes = (): KbnFieldType[] => [ new KbnFieldType({ name: KBN_FIELD_TYPES.STRING, @@ -103,7 +107,5 @@ export const createKbnFieldTypes = (): KbnFieldType[] => [ new KbnFieldType({ name: KBN_FIELD_TYPES.CONFLICT, }), - new KbnFieldType({ - name: KBN_FIELD_TYPES.UNKNOWN, - }), + kbnFieldTypeUnknown, ]; diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index e95150e8f6f73..5a9930d2b6b56 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -249,9 +249,7 @@ export { IndexPatternsContract, IndexPattern, IIndexPatternFieldList, - Field as IndexPatternField, - // TODO: exported only in stub_index_pattern test. Move into data plugin and remove export. - getIndexPatternFieldListCreator, + IndexPatternField, } from './index_patterns'; export { @@ -264,6 +262,7 @@ export { UI_SETTINGS, TypeMeta as IndexPatternTypeMeta, AggregationRestrictions as IndexPatternAggRestrictions, + FieldList, } from '../common'; /* diff --git a/src/plugins/data/public/index_patterns/index.ts b/src/plugins/data/public/index_patterns/index.ts index a6ee71c624f5a..9cd5e5a4736f1 100644 --- a/src/plugins/data/public/index_patterns/index.ts +++ b/src/plugins/data/public/index_patterns/index.ts @@ -28,11 +28,7 @@ export { } from '../../common/index_patterns/lib'; export { flattenHitWrapper, formatHitProvider, onRedirectNoIndexPattern } from './index_patterns'; -export { - getIndexPatternFieldListCreator, - Field, - IIndexPatternFieldList, -} from '../../common/index_patterns'; +export { IndexPatternField, IIndexPatternFieldList } from '../../common/index_patterns'; export { IndexPatternsService, diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 2cfdab80123ed..76f88df4dd6fc 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -576,6 +576,44 @@ export type FieldFormatsContentType = 'html' | 'text'; // @public (undocumented) export type FieldFormatsGetConfigFn = (key: string, defaultOverride?: T) => T; +// Warning: (ae-missing-release-tag) "FieldList" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class FieldList extends Array implements IIndexPatternFieldList { + // Warning: (ae-forgotten-export) The symbol "FieldSpec" needs to be exported by the entry point index.d.ts + constructor(indexPattern: IndexPattern, specs?: FieldSpec[], shortDotsEnable?: boolean, onNotification?: () => void); + // (undocumented) + readonly add: (field: FieldSpec) => void; + // (undocumented) + readonly getByName: (name: IndexPatternField['name']) => IndexPatternField | undefined; + // (undocumented) + readonly getByType: (type: IndexPatternField['type']) => any[]; + // (undocumented) + readonly remove: (field: IFieldType) => void; + // (undocumented) + readonly removeAll: () => void; + // (undocumented) + readonly replaceAll: (specs: FieldSpec[]) => void; + // (undocumented) + readonly toSpec: () => { + count: number; + script: string | undefined; + lang: string | undefined; + conflictDescriptions: Record | undefined; + name: string; + type: string; + esTypes: string[] | undefined; + scripted: boolean; + searchable: boolean; + aggregatable: boolean; + readFromDocValues: boolean; + subType: import("../types").IFieldSubType | undefined; + format: any; + }[]; + // (undocumented) + readonly update: (field: FieldSpec) => void; +} + // @public (undocumented) export interface FieldMappingSpec { // (undocumented) @@ -658,13 +696,6 @@ export function getDefaultQuery(language?: QueryLanguage): { // @public (undocumented) export function getEsPreference(uiSettings: IUiSettingsClient_2, sessionId?: string): any; -// Warning: (ae-forgotten-export) The symbol "FieldListDependencies" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "CreateIndexPatternFieldList" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "getIndexPatternFieldListCreator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const getIndexPatternFieldListCreator: ({ fieldFormats, onNotification, }: FieldListDependencies) => CreateIndexPatternFieldList; - // Warning: (ae-missing-release-tag) "getKbnTypeNames" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @@ -808,8 +839,6 @@ export interface IFieldType { sortable?: boolean; // (undocumented) subType?: IFieldSubType; - // Warning: (ae-forgotten-export) The symbol "FieldSpec" needs to be exported by the entry point index.d.ts - // // (undocumented) toSpec?: () => FieldSpec; // (undocumented) @@ -856,6 +885,10 @@ export interface IIndexPatternFieldList extends Array { // (undocumented) remove(field: IFieldType): void; // (undocumented) + removeAll(): void; + // (undocumented) + replaceAll(specs: FieldSpec[]): void; + // (undocumented) update(field: FieldSpec): void; } @@ -929,7 +962,9 @@ export class IndexPattern implements IIndexPattern { }[]; }; // (undocumented) - getFieldByName(name: string): IndexPatternField | void; + getFieldByName(name: string): IndexPatternField | undefined; + // (undocumented) + getFormatterForField(field: IndexPatternField | IndexPatternField['spec']): FieldFormat; // (undocumented) getNonScriptedFields(): IndexPatternField[]; // (undocumented) @@ -967,7 +1002,7 @@ export class IndexPattern implements IIndexPattern { // (undocumented) refreshFields(): Promise; // (undocumented) - removeScriptedField(field: IFieldType): Promise; + removeScriptedField(fieldName: string): Promise; // (undocumented) save(saveAttempts?: number): Promise; // (undocumented) @@ -1018,55 +1053,85 @@ export interface IndexPatternAttributes { typeMeta: string; } -// Warning: (ae-missing-release-tag) "Field" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "IndexPatternField" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export class IndexPatternField implements IFieldType { + // Warning: (ae-forgotten-export) The symbol "OnNotification" needs to be exported by the entry point index.d.ts + constructor(indexPattern: IndexPattern, spec: FieldSpec, displayName: string, onNotification: OnNotification); // (undocumented) - $$spec: FieldSpec; - // Warning: (ae-forgotten-export) The symbol "FieldSpecExportFmt" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "FieldDependencies" needs to be exported by the entry point index.d.ts - constructor(indexPattern: IIndexPattern, spec: FieldSpecExportFmt | FieldSpec | IndexPatternField, shortDotsEnable: boolean, { fieldFormats, onNotification }: FieldDependencies); + get aggregatable(): boolean; // (undocumented) - aggregatable?: boolean; - // Warning: (ae-forgotten-export) The symbol "FieldSpecConflictDescriptions" needs to be exported by the entry point index.d.ts - // + get conflictDescriptions(): Record | undefined; + set conflictDescriptions(conflictDescriptions: Record | undefined); // (undocumented) - conflictDescriptions?: FieldSpecConflictDescriptions; + get count(): number; + set count(count: number); // (undocumented) - count?: number; + readonly displayName: string; // (undocumented) - displayName?: string; + get esTypes(): string[] | undefined; // (undocumented) - esTypes?: string[]; + get filterable(): boolean; // (undocumented) - filterable?: boolean; + get format(): FieldFormat; // (undocumented) - format: any; + readonly indexPattern: IndexPattern; // (undocumented) - indexPattern?: IIndexPattern; + get lang(): string | undefined; + set lang(lang: string | undefined); // (undocumented) - lang?: string; + get name(): string; // (undocumented) - name: string; + get readFromDocValues(): boolean; // (undocumented) - readFromDocValues?: boolean; + get script(): string | undefined; + set script(script: string | undefined); // (undocumented) - script?: string; + get scripted(): boolean; // (undocumented) - scripted?: boolean; + get searchable(): boolean; // (undocumented) - searchable?: boolean; + get sortable(): boolean; // (undocumented) - sortable?: boolean; + readonly spec: FieldSpec; // (undocumented) - subType?: IFieldSubType; + get subType(): import("../types").IFieldSubType | undefined; + // (undocumented) + toJSON(): { + count: number; + script: string | undefined; + lang: string | undefined; + conflictDescriptions: Record | undefined; + name: string; + type: string; + esTypes: string[] | undefined; + scripted: boolean; + searchable: boolean; + aggregatable: boolean; + readFromDocValues: boolean; + subType: import("../types").IFieldSubType | undefined; + }; // (undocumented) - toSpec: () => FieldSpecExportFmt; + toSpec(): { + count: number; + script: string | undefined; + lang: string | undefined; + conflictDescriptions: Record | undefined; + name: string; + type: string; + esTypes: string[] | undefined; + scripted: boolean; + searchable: boolean; + aggregatable: boolean; + readFromDocValues: boolean; + subType: import("../types").IFieldSubType | undefined; + format: any; + }; // (undocumented) - type: string; + get type(): string; // (undocumented) - visualizable?: boolean; + get visualizable(): boolean; } // Warning: (ae-missing-release-tag) "indexPatterns" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1899,21 +1964,21 @@ export const UI_SETTINGS: { // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "getFromSavedObject" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:371:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:371:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:371:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:371:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:373:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:374:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:383:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:384:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:385:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:386:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:391:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:394:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:395:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:398:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:370:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:370:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:370:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:370:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:372:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:373:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:382:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:383:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:384:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:385:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:393:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:394:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:397:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:45:5 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts // src/plugins/data/public/types.ts:54:5 - (ae-forgotten-export) The symbol "createFiltersFromValueClickAction" needs to be exported by the entry point index.d.ts // src/plugins/data/public/types.ts:55:5 - (ae-forgotten-export) The symbol "createFiltersFromRangeSelectAction" needs to be exported by the entry point index.d.ts diff --git a/src/plugins/data/public/search/aggs/agg_configs.test.ts b/src/plugins/data/public/search/aggs/agg_configs.test.ts index df4a5420ae0db..ff0cc3341929e 100644 --- a/src/plugins/data/public/search/aggs/agg_configs.test.ts +++ b/src/plugins/data/public/search/aggs/agg_configs.test.ts @@ -22,7 +22,7 @@ import { AggConfig } from './agg_config'; import { AggConfigs } from './agg_configs'; import { AggTypesRegistryStart } from './agg_types_registry'; import { mockAggTypesRegistry } from './test_helpers'; -import { Field as IndexPatternField, IndexPattern } from '../../index_patterns'; +import { IndexPatternField, IndexPattern } from '../../index_patterns'; import { stubIndexPattern, stubIndexPatternWithFields } from '../../../public/stubs'; describe('AggConfigs', () => { diff --git a/src/plugins/data/public/search/aggs/param_types/field.ts b/src/plugins/data/public/search/aggs/param_types/field.ts index cb3617b02e882..7c00bc668a39f 100644 --- a/src/plugins/data/public/search/aggs/param_types/field.ts +++ b/src/plugins/data/public/search/aggs/param_types/field.ts @@ -23,7 +23,7 @@ import { SavedObjectNotFound } from '../../../../../../plugins/kibana_utils/comm import { BaseParamType } from './base'; import { propFilter } from '../utils'; import { isNestedField, KBN_FIELD_TYPES } from '../../../../common'; -import { Field as IndexPatternField } from '../../../index_patterns'; +import { IndexPatternField } from '../../../index_patterns'; const filterByType = propFilter('type'); diff --git a/src/plugins/discover/public/application/angular/doc_table/components/row_headers.test.js b/src/plugins/discover/public/application/angular/doc_table/components/row_headers.test.js index b30b13b1f0b6e..d85ca6a072890 100644 --- a/src/plugins/discover/public/application/angular/doc_table/components/row_headers.test.js +++ b/src/plugins/discover/public/application/angular/doc_table/components/row_headers.test.js @@ -23,7 +23,7 @@ import 'angular-sanitize'; import 'angular-route'; import _ from 'lodash'; import sinon from 'sinon'; -import { getFakeRow, getFakeRowVals } from 'fixtures/fake_row'; +import { getFakeRow } from 'fixtures/fake_row'; import $ from 'jquery'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import { setScopedHistory, setServices, setDocViewsRegistry } from '../../../../kibana_services'; @@ -33,6 +33,13 @@ import { navigationPluginMock } from '../../../../../../navigation/public/mocks' import { getInnerAngularModule } from '../../../../get_inner_angular'; import { createBrowserHistory } from 'history'; +const fakeRowVals = { + time: 'time_formatted', + bytes: 'bytes_formatted', + '@timestamp': '@timestamp_formatted', + request_body: 'request_body_formatted', +}; + describe('Doc Table', () => { const core = coreMock.createStart(); const dataMock = dataPluginMock.createStartContract(); @@ -45,8 +52,6 @@ describe('Doc Table', () => { // Stub out a minimal mapping of 4 fields let mapping; - let fakeRowVals; - let stubFieldFormatConverter; beforeAll(() => setScopedHistory(createBrowserHistory())); beforeEach(() => { angular.element.prototype.slice = jest.fn(function (index) { @@ -97,21 +102,15 @@ describe('Doc Table', () => { mapping = $parentScope.indexPattern.fields; // Stub `getConverterFor` for a field in the indexPattern to return mock data. - // Returns `val` if provided, otherwise generates fake data for the field. - fakeRowVals = getFakeRowVals('formatted', 0, mapping); - stubFieldFormatConverter = function ($root, field, val) { - const convertFn = (value, type, options) => { - if (val) { - return val; - } - const fieldName = _.get(options, 'field.name', null); - - return fakeRowVals[fieldName] || ''; - }; - - $root.indexPattern.fields.getByName(field).format.convert = convertFn; - $root.indexPattern.fields.getByName(field).format.getConverterFor = () => convertFn; + + const convertFn = (value, type, options) => { + const fieldName = _.get(options, 'field.name', null); + return fakeRowVals[fieldName] || ''; }; + $parentScope.indexPattern.getFormatterForField = () => ({ + convert: convertFn, + getConverterFor: () => convertFn, + }); }) ); @@ -148,9 +147,6 @@ describe('Doc Table', () => { test('should be able to add and remove columns', () => { let childElems; - stubFieldFormatConverter($parentScope, 'bytes'); - stubFieldFormatConverter($parentScope, 'request_body'); - // Should include a column for toggling and the time column by default $parentScope.columns = ['bytes']; $elementScope.$digest(); @@ -302,9 +298,6 @@ describe('Doc Table', () => { $root.mapping = mapping; $root.indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider); - // Stub field format converters for every field in the indexPattern - $root.indexPattern.fields.forEach((f) => stubFieldFormatConverter($root, f.name)); - $row = $('').attr({ 'kbn-table-row': 'row', columns: 'columns', @@ -417,7 +410,8 @@ describe('Doc Table', () => { }); test('handles two columns with the same content', () => { - stubFieldFormatConverter($root, 'request_body', fakeRowVals.bytes); + const tempVal = fakeRowVals.request_body; + fakeRowVals.request_body = 'bytes_formatted'; $root.columns.length = 0; $root.columns.push('bytes'); @@ -428,6 +422,7 @@ describe('Doc Table', () => { expect($after).toHaveLength(4); expect($after.eq(2).text().trim()).toMatch(/^bytes_formatted/); expect($after.eq(3).text().trim()).toMatch(/^bytes_formatted/); + fakeRowVals.request_body = tempVal; }); test('handles two columns swapping position', () => { diff --git a/src/plugins/discover/public/application/components/sidebar/discover_field.test.tsx b/src/plugins/discover/public/application/components/sidebar/discover_field.test.tsx index 099ec2e5b1ffc..3f12a8c0fa769 100644 --- a/src/plugins/discover/public/application/components/sidebar/discover_field.test.tsx +++ b/src/plugins/discover/public/application/components/sidebar/discover_field.test.tsx @@ -28,7 +28,6 @@ import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { DiscoverField } from './discover_field'; import { coreMock } from '../../../../../../core/public/mocks'; import { IndexPatternField } from '../../../../../data/public'; -import { FieldSpecExportFmt } from '../../../../../data/common'; jest.mock('../../../kibana_services', () => ({ getServices: () => ({ @@ -63,20 +62,21 @@ function getComponent(selected = false, showDetails = false, useShortDots = fals coreMock.createStart() ); - const field = { - name: 'bytes', - type: 'number', - esTypes: ['long'], - count: 10, - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - format: null, - routes: {}, - $$spec: {}, - toSpec: () => (({} as unknown) as FieldSpecExportFmt), - } as IndexPatternField; + const field = new IndexPatternField( + indexPattern, + { + name: 'bytes', + type: 'number', + esTypes: ['long'], + count: 10, + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + 'bytes', + () => {} + ); const props = { indexPattern, diff --git a/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx b/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx index e8ed8b80da3bb..58b468762c501 100644 --- a/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx +++ b/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx @@ -29,12 +29,7 @@ import { IndexPatternAttributes } from '../../../../../data/common'; import { SavedObject } from '../../../../../../core/types'; import { FIELDS_LIMIT_SETTING } from '../../../../common'; import { groupFields } from './lib/group_fields'; -import { - IIndexPatternFieldList, - IndexPatternField, - IndexPattern, - UI_SETTINGS, -} from '../../../../../data/public'; +import { IndexPatternField, IndexPattern, UI_SETTINGS } from '../../../../../data/public'; import { AppState } from '../../angular/discover_state'; import { getDetails } from './lib/get_details'; import { getDefaultFieldFilter, setFieldFilterProp } from './lib/field_filter'; @@ -99,12 +94,12 @@ export function DiscoverSidebar({ }: DiscoverSidebarProps) { const [openFieldMap, setOpenFieldMap] = useState(new Map()); const [showFields, setShowFields] = useState(false); - const [fields, setFields] = useState(null); + const [fields, setFields] = useState(null); const [fieldFilterState, setFieldFilterState] = useState(getDefaultFieldFilter()); const services = useMemo(() => getServices(), []); useEffect(() => { - const newFields = getIndexPatternFieldList(selectedIndexPattern, fieldCounts, services); + const newFields = getIndexPatternFieldList(selectedIndexPattern, fieldCounts); setFields(newFields); }, [selectedIndexPattern, fieldCounts, hits, services]); diff --git a/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts b/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts index 0fcbe925e0798..751a59d982153 100644 --- a/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts +++ b/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts @@ -18,25 +18,23 @@ */ import { difference, map } from 'lodash'; import { IndexPattern, IndexPatternField } from 'src/plugins/data/public'; -import { DiscoverServices } from '../../../../build_services'; export function getIndexPatternFieldList( indexPattern: IndexPattern, - fieldCounts: Record, - { data }: DiscoverServices + fieldCounts: Record ) { - if (!indexPattern || !fieldCounts) return data.indexPatterns.createFieldList(indexPattern); + if (!indexPattern || !fieldCounts) return []; - const fieldSpecs = indexPattern.fields.slice(0); const fieldNamesInDocs = Object.keys(fieldCounts); const fieldNamesInIndexPattern = map(indexPattern.fields, 'name'); + const unknownTypes: IndexPatternField[] = []; difference(fieldNamesInDocs, fieldNamesInIndexPattern).forEach((unknownFieldName) => { - fieldSpecs.push({ + unknownTypes.push({ name: String(unknownFieldName), type: 'unknown', } as IndexPatternField); }); - return data.indexPatterns.createFieldList(indexPattern, fieldSpecs); + return [...indexPattern.fields, ...unknownTypes]; } diff --git a/src/plugins/discover/public/application/components/sidebar/lib/group_fields.tsx b/src/plugins/discover/public/application/components/sidebar/lib/group_fields.tsx index fab4637d87ca7..c6a06618900fd 100644 --- a/src/plugins/discover/public/application/components/sidebar/lib/group_fields.tsx +++ b/src/plugins/discover/public/application/components/sidebar/lib/group_fields.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { IIndexPatternFieldList, IndexPatternField } from 'src/plugins/data/public'; +import { IndexPatternField } from 'src/plugins/data/public'; import { FieldFilterState, isFieldFiltered } from './field_filter'; interface GroupedFields { @@ -29,7 +29,7 @@ interface GroupedFields { * group the fields into selected, popular and unpopular, filter by fieldFilterState */ export function groupFields( - fields: IIndexPatternFieldList | null, + fields: IndexPatternField[] | null, columns: string[], popularLimit: number, fieldCounts: Record, diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field.tsx index f7b982ef1659e..22bc78ee0538e 100644 --- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field.tsx @@ -21,7 +21,7 @@ import { withRouter, RouteComponentProps } from 'react-router-dom'; import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { IndexPattern } from '../../../../../../plugins/data/public'; +import { IndexPattern, IndexPatternField } from '../../../../../../plugins/data/public'; import { useKibana } from '../../../../../../plugins/kibana_react/public'; import { IndexPatternManagmentContext } from '../../../types'; import { IndexHeader } from '../index_header'; @@ -44,24 +44,21 @@ const newFieldPlaceholder = i18n.translate( export const CreateEditField = withRouter( ({ indexPattern, mode, fieldName, history }: CreateEditFieldProps) => { - const { data, uiSettings, chrome, notifications } = useKibana< + const { uiSettings, chrome, notifications } = useKibana< IndexPatternManagmentContext >().services; - const field = + const spec = mode === 'edit' && fieldName - ? indexPattern.fields.getByName(fieldName) - : data.indexPatterns.createField( - indexPattern, - { - scripted: true, - type: 'number', - }, - false - ); + ? indexPattern.fields.getByName(fieldName)?.spec + : (({ + scripted: true, + type: 'number', + name: undefined, + } as unknown) as IndexPatternField); const url = `/patterns/${indexPattern.id}`; - if (mode === 'edit' && !field) { + if (mode === 'edit' && !spec) { const message = i18n.translate( 'indexPatternManagement.editIndexPattern.scripted.noFieldLabel', { @@ -74,17 +71,17 @@ export const CreateEditField = withRouter( history.push(url); } - const docFieldName = field?.name || newFieldPlaceholder; + const docFieldName = spec?.name || newFieldPlaceholder; chrome.docTitle.change([docFieldName, indexPattern.title]); const redirectAway = () => { history.push( - `${url}#/?_a=(tab:${field?.scripted ? TAB_SCRIPTED_FIELDS : TAB_INDEXED_FIELDS})` + `${url}#/?_a=(tab:${spec?.scripted ? TAB_SCRIPTED_FIELDS : TAB_INDEXED_FIELDS})` ); }; - if (field) { + if (spec) { return ( @@ -97,7 +94,7 @@ export const CreateEditField = withRouter( ({ @@ -41,6 +41,19 @@ const helpers = { getFieldInfo: () => [], }; +const indexPattern = ({ + getNonScriptedFields: () => fields, +} as unknown) as IIndexPattern; + +const mockFieldToIndexPatternField = (spec: Record) => { + return new IndexPatternField( + indexPattern as IndexPattern, + (spec as unknown) as IndexPatternField['spec'], + spec.displayName as string, + () => {} + ); +}; + const fields = [ { name: 'Elastic', @@ -50,11 +63,7 @@ const fields = [ }, { name: 'timestamp', displayName: 'timestamp', type: 'date' }, { name: 'conflictingField', displayName: 'conflictingField', type: 'conflict' }, -] as IndexPatternField[]; - -const indexPattern = ({ - getNonScriptedFields: () => fields, -} as unknown) as IIndexPattern; +].map(mockFieldToIndexPatternField); describe('IndexedFieldsTable', () => { test('should render normally', async () => { diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx index 3344c46c35ac6..90f81a88b3da0 100644 --- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/indexed_fields_table/indexed_fields_table.tsx @@ -75,7 +75,7 @@ export class IndexedFieldsTable extends Component< (fields && fields.map((field) => { return { - ...field, + ...field.spec, displayName: field.displayName, indexPattern: field.indexPattern, format: getFieldFormat(indexPattern, field.name), diff --git a/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap index 7a7545580d82a..c22160bc4036d 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap @@ -30,6 +30,7 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = ` "name": "foobar", }, ], + "getFormatterForField": [Function], } } isVisible={false} @@ -273,6 +274,7 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = ` "type": "number", }, ], + "getFormatterForField": [Function], } } isVisible={false} @@ -523,6 +525,7 @@ exports[`FieldEditor should show conflict field warning 1`] = ` "type": "number", }, ], + "getFormatterForField": [Function], } } isVisible={false} @@ -802,6 +805,7 @@ exports[`FieldEditor should show deprecated lang warning 1`] = ` "type": "number", }, ], + "getFormatterForField": [Function], } } isVisible={false} @@ -1133,6 +1137,7 @@ exports[`FieldEditor should show multiple type field warning with a table contai "type": "number", }, ], + "getFormatterForField": [Function], } } isVisible={false} diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/string/string.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/string/string.tsx index 7a3bb6f5cd398..cdc29e129c457 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/string/string.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/string/string.tsx @@ -68,7 +68,7 @@ export class StringFormatEditor extends DefaultFormatEditor { + options={(format.type.transformOptions || []).map((option: TransformOptions) => { return { value: option.kind, text: option.text, diff --git a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx index e0e053d8b606b..ba1f2ff4b665d 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx @@ -26,7 +26,7 @@ import { jest.mock('brace/mode/groovy', () => ({})); -import { FieldEditor } from './field_editor'; +import { FieldEditor, FieldEdiorProps } from './field_editor'; import { mockManagementPlugin } from '../../mocks'; import { createComponentWithContext } from '../test_utils'; @@ -113,15 +113,16 @@ describe('FieldEditor', () => { beforeEach(() => { indexPattern = ({ fields: fields as IIndexPatternFieldList, + getFormatterForField: () => ({ params: () => ({}) }), } as unknown) as IndexPattern; }); it('should render create new scripted field correctly', async () => { - const component = createComponentWithContext( + const component = createComponentWithContext( FieldEditor, { indexPattern, - field: (field as unknown) as IndexPatternField, + spec: (field as unknown) as IndexPatternField, services: { redirectAway: () => {} }, }, mockContext @@ -146,11 +147,11 @@ describe('FieldEditor', () => { return flds[name] as IndexPatternField; }; - const component = createComponentWithContext( + const component = createComponentWithContext( FieldEditor, { indexPattern, - field: (testField as unknown) as IndexPatternField, + spec: (testField as unknown) as IndexPatternField, services: { redirectAway: () => {} }, }, mockContext @@ -176,11 +177,11 @@ describe('FieldEditor', () => { return flds[name] as IndexPatternField; }; - const component = createComponentWithContext( + const component = createComponentWithContext( FieldEditor, { indexPattern, - field: (testField as unknown) as IndexPatternField, + spec: (testField as unknown) as IndexPatternField, services: { redirectAway: () => {} }, }, mockContext @@ -193,11 +194,11 @@ describe('FieldEditor', () => { it('should show conflict field warning', async () => { const testField = { ...field }; - const component = createComponentWithContext( + const component = createComponentWithContext( FieldEditor, { indexPattern, - field: (testField as unknown) as IndexPatternField, + spec: (testField as unknown) as IndexPatternField, services: { redirectAway: () => {} }, }, mockContext @@ -218,11 +219,11 @@ describe('FieldEditor', () => { text: ['index_name_3'], }, }; - const component = createComponentWithContext( + const component = createComponentWithContext( FieldEditor, { indexPattern, - field: (testField as unknown) as IndexPatternField, + spec: (testField as unknown) as IndexPatternField, services: { redirectAway: () => {} }, }, mockContext diff --git a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx index 99ef83604239a..d78e1e1014581 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx @@ -76,7 +76,7 @@ import { executeScript, isScriptValid } from './lib'; import 'brace/mode/groovy'; const getFieldTypeFormatsList = ( - field: IFieldType, + field: IndexPatternField['spec'], defaultFieldFormat: FieldFormatInstanceType, fieldFormats: DataPublicPluginStart['fieldFormats'] ) => { @@ -108,10 +108,6 @@ interface InitialFieldTypeFormat extends FieldTypeFormat { defaultFieldFormat: FieldFormatInstanceType; } -interface FieldClone extends IndexPatternField { - format: any; -} - export interface FieldEditorState { isReady: boolean; isCreating: boolean; @@ -120,7 +116,6 @@ export interface FieldEditorState { fieldTypes: string[]; fieldTypeFormats: FieldTypeFormat[]; existingFieldNames: string[]; - field: FieldClone; fieldFormatId?: string; fieldFormatParams: { [key: string]: unknown }; showScriptingHelp: boolean; @@ -129,11 +124,13 @@ export interface FieldEditorState { hasScriptError: boolean; isSaving: boolean; errors?: string[]; + format: any; + spec: IndexPatternField['spec']; } export interface FieldEdiorProps { indexPattern: IndexPattern; - field: IndexPatternField; + spec: IndexPatternField['spec']; services: { redirectAway: () => void; }; @@ -149,7 +146,7 @@ export class FieldEditor extends PureComponent f.name), - field: { ...field, format: field.format }, fieldFormatId: undefined, fieldFormatParams: {}, showScriptingHelp: false, @@ -167,6 +163,8 @@ export class FieldEditor extends PureComponent f.name === field.name), - isDeprecatedLang: this.deprecatedLangs.includes(field.lang || ''), + isCreating: !indexPattern.fields.find((f) => f.name === spec.name), + isDeprecatedLang: this.deprecatedLangs.includes(spec.lang || ''), errors: [], scriptingLangs, fieldTypes, fieldTypeFormats: getFieldTypeFormatsList( - field, + spec, DefaultFieldFormat as FieldFormatInstanceType, data.fieldFormats ), - fieldFormatId: get(indexPattern, ['fieldFormatMap', field.name, 'type', 'id']), - fieldFormatParams: field.format.params(), + fieldFormatId: get(indexPattern, ['fieldFormatMap', spec.name, 'type', 'id']), + fieldFormatParams: format.params(), }); } onFieldChange = (fieldName: string, value: string | number) => { - const { field } = this.state; - (field as any)[fieldName] = value; + const { spec } = this.state; + (spec as any)[fieldName] = value; this.forceUpdate(); }; onTypeChange = (type: KBN_FIELD_TYPES) => { const { uiSettings, data } = this.context.services; - const { field } = this.state; + const { spec, format } = this.state; const DefaultFieldFormat = data.fieldFormats.getDefaultType(type) as FieldFormatInstanceType; - field.type = type; + spec.type = type; - field.format = new DefaultFieldFormat(null, (key) => uiSettings.get(key)); + spec.format = new DefaultFieldFormat(null, (key) => uiSettings.get(key)); this.setState({ - fieldTypeFormats: getFieldTypeFormatsList(field, DefaultFieldFormat, data.fieldFormats), + fieldTypeFormats: getFieldTypeFormatsList(spec, DefaultFieldFormat, data.fieldFormats), fieldFormatId: DefaultFieldFormat.id, - fieldFormatParams: field.format.params(), + fieldFormatParams: format.params(), }); }; onLangChange = (lang: string) => { - const { field } = this.state; + const { spec } = this.state; const fieldTypes = get(FIELD_TYPES_BY_LANG, lang, DEFAULT_FIELD_TYPES); - field.lang = lang; - field.type = fieldTypes.includes(field.type) ? field.type : fieldTypes[0]; + spec.lang = lang; + spec.type = fieldTypes.includes(spec.type) ? spec.type : fieldTypes[0]; this.setState({ fieldTypes, @@ -244,18 +246,20 @@ export class FieldEditor extends PureComponent { - const { field, fieldTypeFormats } = this.state; + const { spec, fieldTypeFormats } = this.state; const { uiSettings, data } = this.context.services; const FieldFormat = data.fieldFormats.getType( formatId || (fieldTypeFormats[0] as InitialFieldTypeFormat).defaultFieldFormat.id ) as FieldFormatInstanceType; - field.format = new FieldFormat(params, (key) => uiSettings.get(key)); + const newFormat = new FieldFormat(params, (key) => uiSettings.get(key)); + spec.format = newFormat; this.setState({ fieldFormatId: FieldFormat.id, - fieldFormatParams: field.format.params(), + fieldFormatParams: newFormat.params(), + format: newFormat, }); }; @@ -271,13 +275,13 @@ export class FieldEditor extends PureComponent ), - fieldName: {field.name}, + fieldName: {spec.name}, }} /> @@ -316,7 +320,7 @@ export class FieldEditor extends PureComponent {field.lang}, + language: {spec.lang}, painlessLink: ( { return { value: lang, text: lang }; })} @@ -388,15 +392,15 @@ export class FieldEditor extends PureComponent { return { value: type, text: type }; })} @@ -414,8 +418,8 @@ export class FieldEditor extends PureComponent ({ + const items = Object.entries(spec.conflictDescriptions).map(([type, indices]) => ({ type, indices: Array.isArray(indices) ? indices.join(', ') : 'Index names unavailable', })); @@ -466,7 +470,7 @@ export class FieldEditor extends PureComponent { - return { value: format.id || '', text: format.title }; + options={fieldTypeFormats.map((fmt) => { + return { value: fmt.id || '', text: fmt.title }; })} data-test-subj="editorSelectedFormatId" onChange={(e) => { @@ -507,8 +511,8 @@ export class FieldEditor extends PureComponent {fieldFormatId ? ( { this.onFieldChange('count', e.target.value ? Number(e.target.value) : ''); @@ -550,8 +554,8 @@ export class FieldEditor extends PureComponent ); - return field.scripted ? ( + return spec.scripted ? ( { - const { field } = this.state; + const { spec } = this.state; return this.state.showDeleteModal ? ( { @@ -674,7 +678,7 @@ export class FieldEditor extends PureComponent - {!isCreating && field.scripted ? ( + {!isCreating && spec.scripted ? ( @@ -729,9 +733,9 @@ export class FieldEditor extends PureComponent { - const { scriptingLangs, field, showScriptingHelp } = this.state; + const { scriptingLangs, spec, showScriptingHelp } = this.state; - if (!field.scripted) { + if (!spec.scripted) { return; } @@ -743,9 +747,9 @@ export class FieldEditor extends PureComponent @@ -755,14 +759,14 @@ export class FieldEditor extends PureComponent { const { redirectAway } = this.props.services; const { indexPattern } = this.props; - const { field } = this.state; - const remove = indexPattern.removeScriptedField(field); + const { spec } = this.state; + const remove = indexPattern.removeScriptedField(spec.name); if (remove) { remove.then(() => { const message = i18n.translate('indexPatternManagement.deleteField.deletedHeader', { defaultMessage: "Deleted '{fieldName}'", - values: { fieldName: field.name }, + values: { fieldName: spec.name }, }); this.context.services.notifications.toasts.addSuccess(message); redirectAway(); @@ -773,7 +777,7 @@ export class FieldEditor extends PureComponent { - const field = this.state.field; + const field = this.state.spec; const { indexPattern } = this.props; const { fieldFormatId } = this.state; @@ -802,10 +806,10 @@ export class FieldEditor extends PureComponent f.name === field.name); - let oldField: IFieldType | undefined; + let oldField: IndexPatternField['spec']; if (index > -1) { - oldField = indexPattern.fields.getByName(field.name); + oldField = indexPattern.fields.getByName(field.name)!.spec; indexPattern.fields.update(field); } else { indexPattern.fields.add(field); @@ -837,14 +841,14 @@ export class FieldEditor extends PureComponent @@ -868,7 +872,7 @@ export class FieldEditor extends PureComponent )}

    diff --git a/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap index fabe94763e07d..cc3417e09987e 100644 --- a/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap @@ -8,6 +8,7 @@ exports[`Manage ML Job renders without errors 1`] = ` class="euiPopover__anchor" >
    diff --git a/x-pack/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx index 7a2899558891d..f4382b37b3d30 100644 --- a/x-pack/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx @@ -54,6 +54,10 @@ export const ManageMLJobComponent = ({ hasMLJob, onEnableJob, onJobDelete }: Pro const deleteAnomalyAlert = () => dispatch(deleteAlertAction.get({ alertId: anomalyAlert?.id as string })); + const showLoading = isMLJobCreating || isMLJobLoading; + + const btnText = hasMLJob ? labels.ANOMALY_DETECTION : labels.ENABLE_ANOMALY_DETECTION; + const button = ( - {hasMLJob ? labels.ANOMALY_DETECTION : labels.ENABLE_ANOMALY_DETECTION} + {showLoading ? '' : btnText} ); @@ -79,7 +84,6 @@ export const ManageMLJobComponent = ({ hasMLJob, onEnableJob, onJobDelete }: Pro monitorId, dateRange: { from: dateRangeStart, to: dateRangeEnd }, }), - target: '_blank', }, { name: anomalyAlert ? labels.DISABLE_ANOMALY_ALERT : labels.ENABLE_ANOMALY_ALERT, diff --git a/x-pack/plugins/uptime/public/components/monitor/ml/translations.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/translations.tsx index 90ebdf10a73f5..dfc912e6be9ee 100644 --- a/x-pack/plugins/uptime/public/components/monitor/ml/translations.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/ml/translations.tsx @@ -162,3 +162,11 @@ export const START_TRAIL_DESC = i18n.translate( 'In order to access duration anomaly detection, you have to be subscribed to an Elastic Platinum license.', } ); + +export const ENABLE_MANAGE_JOB = i18n.translate( + 'xpack.uptime.ml.enableAnomalyDetectionPanel.enable_or_manage_job', + { + defaultMessage: + 'You can enable anomaly detection job or if job is already there you can manage the job or alert.', + } +); diff --git a/x-pack/plugins/uptime/public/lib/__mocks__/index.ts b/x-pack/plugins/uptime/public/lib/__mocks__/index.ts new file mode 100644 index 0000000000000..45ef5787927e1 --- /dev/null +++ b/x-pack/plugins/uptime/public/lib/__mocks__/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { mockHistory } from './react_router_history.mock'; diff --git a/x-pack/plugins/uptime/public/lib/__mocks__/react_router_history.mock.ts b/x-pack/plugins/uptime/public/lib/__mocks__/react_router_history.mock.ts new file mode 100644 index 0000000000000..fd422465d87f1 --- /dev/null +++ b/x-pack/plugins/uptime/public/lib/__mocks__/react_router_history.mock.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/** + * NOTE: This variable name MUST start with 'mock*' in order for + * Jest to accept its use within a jest.mock() + */ +export const mockHistory = { + createHref: jest.fn(({ pathname }) => `/enterprise_search${pathname}`), + push: jest.fn(), + location: { + pathname: '/current-path', + }, +}; + +jest.mock('react-router-dom', () => ({ + useHistory: jest.fn(() => mockHistory), +})); + +/** + * For example usage, @see public/applications/shared/react_router_helpers/eui_link.test.tsx + */ diff --git a/x-pack/plugins/uptime/public/pages/certificates.tsx b/x-pack/plugins/uptime/public/pages/certificates.tsx index e46d228c6d21f..a524ce6ba9b71 100644 --- a/x-pack/plugins/uptime/public/pages/certificates.tsx +++ b/x-pack/plugins/uptime/public/pages/certificates.tsx @@ -29,6 +29,7 @@ import { certificatesSelector, getCertificatesAction } from '../state/certificat import { CertificateList, CertificateSearch, CertSort } from '../components/certificates'; import { ToggleAlertFlyoutButton } from '../components/overview/alerts/alerts_containers'; import { CLIENT_ALERT_TYPES } from '../../common/constants/alerts'; +import { ReactRouterEuiButtonEmpty } from '../components/common/react_router_helpers'; const DEFAULT_PAGE_SIZE = 10; const LOCAL_STORAGE_KEY = 'xpack.uptime.certList.pageSize'; @@ -79,15 +80,16 @@ export const CertificatesPage: React.FC = () => { <> - {labels.RETURN_TO_OVERVIEW} - + diff --git a/x-pack/plugins/uptime/public/pages/page_header.tsx b/x-pack/plugins/uptime/public/pages/page_header.tsx index 16279a63b5f40..325d82696d47c 100644 --- a/x-pack/plugins/uptime/public/pages/page_header.tsx +++ b/x-pack/plugins/uptime/public/pages/page_header.tsx @@ -7,12 +7,12 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiSpacer, EuiButtonEmpty } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useHistory } from 'react-router-dom'; import styled from 'styled-components'; import { UptimeDatePicker } from '../components/common/uptime_date_picker'; import { SETTINGS_ROUTE } from '../../common/constants'; import { ToggleAlertFlyoutButton } from '../components/overview/alerts/alerts_containers'; import { useKibana } from '../../../../../src/plugins/kibana_react/public'; +import { ReactRouterEuiButtonEmpty } from '../components/common/react_router_helpers'; interface PageHeaderProps { headingText: string | JSX.Element; @@ -58,7 +58,6 @@ export const PageHeader = React.memo( ) : null; const kibana = useKibana(); - const history = useHistory(); const extraLinkComponents = !extraLinks ? null : ( @@ -66,13 +65,13 @@ export const PageHeader = React.memo( - {SETTINGS_LINK_TEXT} - + { ); - const history = useHistory(); - return ( <> - {Translations.settings.returnToOverviewLinkLabel} - + diff --git a/x-pack/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts b/x-pack/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts index bddca1b863ce4..09b857f37e1df 100644 --- a/x-pack/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts +++ b/x-pack/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts @@ -10,11 +10,11 @@ import { assertCloseTo } from '../assert_close_to'; describe('getHistogramInterval', () => { it('specifies the interval necessary to divide a given timespan into equal buckets, rounded to the nearest integer, expressed in ms', () => { const interval = getHistogramInterval('now-15m', 'now', 10); - assertCloseTo(interval, 90000, 10); + assertCloseTo(interval, 90000, 20); }); it('will supply a default constant value for bucketCount when none is provided', () => { const interval = getHistogramInterval('now-15m', 'now'); - assertCloseTo(interval, 36000, 10); + assertCloseTo(interval, 36000, 20); }); }); From c1b55d57399ded6dbca4415db9077dda7cfccbc9 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Mon, 10 Aug 2020 15:06:58 +0200 Subject: [PATCH 066/106] [Lens] Clear out all attribute properties before updating (#74483) --- .../persistence/saved_object_store.test.ts | 47 +++++++++++++------ .../public/persistence/saved_object_store.ts | 44 +++++++++-------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/x-pack/plugins/lens/public/persistence/saved_object_store.test.ts b/x-pack/plugins/lens/public/persistence/saved_object_store.test.ts index f7caac6549389..f8f8d889233a7 100644 --- a/x-pack/plugins/lens/public/persistence/saved_object_store.test.ts +++ b/x-pack/plugins/lens/public/persistence/saved_object_store.test.ts @@ -4,19 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ +import { SavedObjectsClientContract, SavedObjectsBulkUpdateObject } from 'kibana/public'; import { SavedObjectIndexStore } from './saved_object_store'; describe('LensStore', () => { function testStore(testId?: string) { const client = { create: jest.fn(() => Promise.resolve({ id: testId || 'testid' })), - update: jest.fn((_type: string, id: string) => Promise.resolve({ id })), + bulkUpdate: jest.fn(([{ id }]: SavedObjectsBulkUpdateObject[]) => + Promise.resolve({ savedObjects: [{ id }, { id }] }) + ), get: jest.fn(), }; return { client, - store: new SavedObjectIndexStore(client), + store: new SavedObjectIndexStore((client as unknown) as SavedObjectsClientContract), }; } @@ -108,19 +111,35 @@ describe('LensStore', () => { }, }); - expect(client.update).toHaveBeenCalledTimes(1); - expect(client.update).toHaveBeenCalledWith('lens', 'Gandalf', { - title: 'Even the very wise cannot see all ends.', - visualizationType: 'line', - expression: '', - state: { - datasourceMetaData: { filterableIndexPatterns: [] }, - datasourceStates: { indexpattern: { type: 'index_pattern', indexPattern: 'lotr' } }, - visualization: { gear: ['staff', 'pointy hat'] }, - query: { query: '', language: 'lucene' }, - filters: [], + expect(client.bulkUpdate).toHaveBeenCalledTimes(1); + expect(client.bulkUpdate).toHaveBeenCalledWith([ + { + type: 'lens', + id: 'Gandalf', + attributes: { + title: null, + visualizationType: null, + expression: null, + state: null, + }, }, - }); + { + type: 'lens', + id: 'Gandalf', + attributes: { + title: 'Even the very wise cannot see all ends.', + visualizationType: 'line', + expression: '', + state: { + datasourceMetaData: { filterableIndexPatterns: [] }, + datasourceStates: { indexpattern: { type: 'index_pattern', indexPattern: 'lotr' } }, + visualization: { gear: ['staff', 'pointy hat'] }, + query: { query: '', language: 'lucene' }, + filters: [], + }, + }, + }, + ]); }); }); diff --git a/x-pack/plugins/lens/public/persistence/saved_object_store.ts b/x-pack/plugins/lens/public/persistence/saved_object_store.ts index af90634874fb1..59ead53956a8d 100644 --- a/x-pack/plugins/lens/public/persistence/saved_object_store.ts +++ b/x-pack/plugins/lens/public/persistence/saved_object_store.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SavedObjectAttributes } from 'kibana/server'; +import { SavedObjectAttributes, SavedObjectsClientContract } from 'kibana/public'; import { Query, Filter } from '../../../../../src/plugins/data/public'; export interface Document { @@ -27,20 +27,6 @@ export interface Document { export const DOC_TYPE = 'lens'; -interface SavedObjectClient { - create: (type: string, object: SavedObjectAttributes) => Promise<{ id: string }>; - update: (type: string, id: string, object: SavedObjectAttributes) => Promise<{ id: string }>; - get: ( - type: string, - id: string - ) => Promise<{ - id: string; - type: string; - attributes: SavedObjectAttributes; - error?: { statusCode: number; message: string }; - }>; -} - export interface DocumentSaver { save: (vis: Document) => Promise<{ id: string }>; } @@ -52,9 +38,9 @@ export interface DocumentLoader { export type SavedObjectStore = DocumentLoader & DocumentSaver; export class SavedObjectIndexStore implements SavedObjectStore { - private client: SavedObjectClient; + private client: SavedObjectsClientContract; - constructor(client: SavedObjectClient) { + constructor(client: SavedObjectsClientContract) { this.client = client; } @@ -63,13 +49,33 @@ export class SavedObjectIndexStore implements SavedObjectStore { // TODO: SavedObjectAttributes should support this kind of object, // remove this workaround when SavedObjectAttributes is updated. const attributes = (rest as unknown) as SavedObjectAttributes; + const result = await (id - ? this.client.update(DOC_TYPE, id, attributes) + ? this.safeUpdate(id, attributes) : this.client.create(DOC_TYPE, attributes)); return { ...vis, id: result.id }; } + // As Lens is using an object to store its attributes, using the update API + // will merge the new attribute object with the old one, not overwriting deleted + // keys. As Lens is using objects as maps in various places, this is a problem because + // deleted subtrees make it back into the object after a load. + // This function fixes this by doing two updates - one to empty out the document setting + // every key to null, and a second one to load the new content. + private async safeUpdate(id: string, attributes: SavedObjectAttributes) { + const resetAttributes: SavedObjectAttributes = {}; + Object.keys(attributes).forEach((key) => { + resetAttributes[key] = null; + }); + return ( + await this.client.bulkUpdate([ + { type: DOC_TYPE, id, attributes: resetAttributes }, + { type: DOC_TYPE, id, attributes }, + ]) + ).savedObjects[1]; + } + async load(id: string): Promise { const { type, attributes, error } = await this.client.get(DOC_TYPE, id); @@ -78,7 +84,7 @@ export class SavedObjectIndexStore implements SavedObjectStore { } return { - ...attributes, + ...(attributes as SavedObjectAttributes), id, type, } as Document; From 23adb256bb4799f61e8ae9914e2ee8231e7b7598 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Mon, 10 Aug 2020 16:29:29 +0300 Subject: [PATCH 067/106] [i18n] revert reverted changes (#74633) Co-authored-by: Elastic Machine --- src/dev/i18n/integrate_locale_files.test.ts | 3 ++- src/dev/i18n/integrate_locale_files.ts | 21 +++++++++++++++++++- src/dev/i18n/tasks/check_compatibility.ts | 4 +++- src/dev/i18n/utils.js | 22 +++++++++++++++++++++ src/dev/run_i18n_check.ts | 5 ++++- src/dev/run_i18n_integrate.ts | 7 ++++--- 6 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/dev/i18n/integrate_locale_files.test.ts b/src/dev/i18n/integrate_locale_files.test.ts index 7ff1d87f1bc55..3bd3dc61c044f 100644 --- a/src/dev/i18n/integrate_locale_files.test.ts +++ b/src/dev/i18n/integrate_locale_files.test.ts @@ -21,7 +21,7 @@ import { mockMakeDirAsync, mockWriteFileAsync } from './integrate_locale_files.t import path from 'path'; import { integrateLocaleFiles, verifyMessages } from './integrate_locale_files'; -// @ts-ignore +// @ts-expect-error import { normalizePath } from './utils'; const localePath = path.resolve(__dirname, '__fixtures__', 'integrate_locale_files', 'fr.json'); @@ -36,6 +36,7 @@ const defaultIntegrateOptions = { sourceFileName: localePath, dryRun: false, ignoreIncompatible: false, + ignoreMalformed: false, ignoreMissing: false, ignoreUnused: false, config: { diff --git a/src/dev/i18n/integrate_locale_files.ts b/src/dev/i18n/integrate_locale_files.ts index d8ccccca15559..f9cd6dd1971c7 100644 --- a/src/dev/i18n/integrate_locale_files.ts +++ b/src/dev/i18n/integrate_locale_files.ts @@ -31,7 +31,8 @@ import { normalizePath, readFileAsync, writeFileAsync, - // @ts-ignore + verifyICUMessage, + // @ts-expect-error } from './utils'; import { I18nConfig } from './config'; @@ -41,6 +42,7 @@ export interface IntegrateOptions { sourceFileName: string; targetFileName?: string; dryRun: boolean; + ignoreMalformed: boolean; ignoreIncompatible: boolean; ignoreUnused: boolean; ignoreMissing: boolean; @@ -105,6 +107,23 @@ export function verifyMessages( } } + for (const messageId of localizedMessagesIds) { + const defaultMessage = defaultMessagesMap.get(messageId); + if (defaultMessage) { + try { + const message = localizedMessagesMap.get(messageId)!; + verifyICUMessage(message); + } catch (err) { + if (options.ignoreMalformed) { + localizedMessagesMap.delete(messageId); + options.log.warning(`Malformed translation ignored (${messageId}): ${err}`); + } else { + errorMessage += `\nMalformed translation (${messageId}): ${err}\n`; + } + } + } + } + if (errorMessage) { throw createFailError(errorMessage); } diff --git a/src/dev/i18n/tasks/check_compatibility.ts b/src/dev/i18n/tasks/check_compatibility.ts index 5900bf5aff252..afaf3cd875a8a 100644 --- a/src/dev/i18n/tasks/check_compatibility.ts +++ b/src/dev/i18n/tasks/check_compatibility.ts @@ -22,13 +22,14 @@ import { integrateLocaleFiles, I18nConfig } from '..'; export interface I18nFlags { fix: boolean; + ignoreMalformed: boolean; ignoreIncompatible: boolean; ignoreUnused: boolean; ignoreMissing: boolean; } export function checkCompatibility(config: I18nConfig, flags: I18nFlags, log: ToolingLog) { - const { fix, ignoreIncompatible, ignoreUnused, ignoreMissing } = flags; + const { fix, ignoreIncompatible, ignoreUnused, ignoreMalformed, ignoreMissing } = flags; return config.translations.map((translationsPath) => ({ task: async ({ messages }: { messages: Map }) => { // If `fix` is set we should try apply all possible fixes and override translations file. @@ -37,6 +38,7 @@ export function checkCompatibility(config: I18nConfig, flags: I18nFlags, log: To ignoreIncompatible: fix || ignoreIncompatible, ignoreUnused: fix || ignoreUnused, ignoreMissing: fix || ignoreMissing, + ignoreMalformed: fix || ignoreMalformed, sourceFileName: translationsPath, targetFileName: fix ? translationsPath : undefined, config, diff --git a/src/dev/i18n/utils.js b/src/dev/i18n/utils.js index 1d1c3118e0852..11a002fdbf4a8 100644 --- a/src/dev/i18n/utils.js +++ b/src/dev/i18n/utils.js @@ -208,6 +208,28 @@ export function checkValuesProperty(prefixedValuesKeys, defaultMessage, messageI } } +/** + * Verifies valid ICU message. + * @param message ICU message. + * @param messageId ICU message id + * @returns {undefined} + */ +export function verifyICUMessage(message) { + try { + parser.parse(message); + } catch (error) { + if (error.name === 'SyntaxError') { + const errorWithContext = createParserErrorMessage(message, { + loc: { + line: error.location.start.line, + column: error.location.start.column - 1, + }, + message: error.message, + }); + throw errorWithContext; + } + } +} /** * Extracts value references from the ICU message. * @param message ICU message. diff --git a/src/dev/run_i18n_check.ts b/src/dev/run_i18n_check.ts index 97ea988b1de3a..70eeedac2b8b6 100644 --- a/src/dev/run_i18n_check.ts +++ b/src/dev/run_i18n_check.ts @@ -36,6 +36,7 @@ run( async ({ flags: { 'ignore-incompatible': ignoreIncompatible, + 'ignore-malformed': ignoreMalformed, 'ignore-missing': ignoreMissing, 'ignore-unused': ignoreUnused, 'include-config': includeConfig, @@ -48,12 +49,13 @@ run( fix && (ignoreIncompatible !== undefined || ignoreUnused !== undefined || + ignoreMalformed !== undefined || ignoreMissing !== undefined) ) { throw createFailError( `${chalk.white.bgRed( ' I18N ERROR ' - )} none of the --ignore-incompatible, --ignore-unused or --ignore-missing is allowed when --fix is set.` + )} none of the --ignore-incompatible, --ignore-malformed, --ignore-unused or --ignore-missing is allowed when --fix is set.` ); } @@ -99,6 +101,7 @@ run( checkCompatibility( config, { + ignoreMalformed: !!ignoreMalformed, ignoreIncompatible: !!ignoreIncompatible, ignoreUnused: !!ignoreUnused, ignoreMissing: !!ignoreMissing, diff --git a/src/dev/run_i18n_integrate.ts b/src/dev/run_i18n_integrate.ts index ac1e957adfc99..25c3ea32783aa 100644 --- a/src/dev/run_i18n_integrate.ts +++ b/src/dev/run_i18n_integrate.ts @@ -31,6 +31,7 @@ run( 'ignore-incompatible': ignoreIncompatible = false, 'ignore-missing': ignoreMissing = false, 'ignore-unused': ignoreUnused = false, + 'ignore-malformed': ignoreMalformed = false, 'include-config': includeConfig, path, source, @@ -66,12 +67,13 @@ run( typeof ignoreIncompatible !== 'boolean' || typeof ignoreUnused !== 'boolean' || typeof ignoreMissing !== 'boolean' || + typeof ignoreMalformed !== 'boolean' || typeof dryRun !== 'boolean' ) { throw createFailError( `${chalk.white.bgRed( ' I18N ERROR ' - )} --ignore-incompatible, --ignore-unused, --ignore-missing, and --dry-run can't have values` + )} --ignore-incompatible, --ignore-unused, --ignore-malformed, --ignore-missing, and --dry-run can't have values` ); } @@ -97,6 +99,7 @@ run( ignoreIncompatible, ignoreUnused, ignoreMissing, + ignoreMalformed, config, log, }); @@ -108,7 +111,6 @@ run( const reporter = new ErrorReporter(); const messages: Map = new Map(); await list.run({ messages, reporter }); - process.exitCode = 0; } catch (error) { process.exitCode = 1; if (error instanceof ErrorReporter) { @@ -118,7 +120,6 @@ run( log.error(error); } } - process.exit(); }, { flags: { From 708ba4ce4c5862f7be474cd61abc878caa3ef2ab Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Mon, 10 Aug 2020 08:17:04 -0600 Subject: [PATCH 068/106] [App Arch]: remove legacy karma tests (#74599) --- .../public/storage/__tests__/storage.js | 124 ------------------ .../public/storage/storage.test.ts | 109 +++++++++++++++ ...gauge_objs.js => vis_update_state.stub.js} | 0 .../public/legacy/vis_update_state.test.js | 2 +- 4 files changed, 110 insertions(+), 125 deletions(-) delete mode 100644 src/plugins/kibana_utils/public/storage/__tests__/storage.js create mode 100644 src/plugins/kibana_utils/public/storage/storage.test.ts rename src/plugins/visualizations/public/legacy/{__tests__/vis_update_objs/gauge_objs.js => vis_update_state.stub.js} (100%) diff --git a/src/plugins/kibana_utils/public/storage/__tests__/storage.js b/src/plugins/kibana_utils/public/storage/__tests__/storage.js deleted file mode 100644 index 073ed275b9aac..0000000000000 --- a/src/plugins/kibana_utils/public/storage/__tests__/storage.js +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import sinon from 'sinon'; -import expect from '@kbn/expect'; -import ngMock from 'ng_mock'; -import '..'; - -let storage; -let $window; -const payload = { first: 'john', last: 'smith' }; - -function init() { - ngMock.module('kibana/storage', function ($provide) { - // mock $window.localStorage for storage - $provide.value('$window', { - localStorage: { - getItem: sinon.stub(), - setItem: sinon.spy(), - removeItem: sinon.spy(), - clear: sinon.spy(), - }, - }); - }); - - ngMock.inject(function ($injector) { - storage = $injector.get('localStorage'); - $window = $injector.get('$window'); - }); -} - -describe('StorageService', function () { - beforeEach(function () { - init(); - }); - - describe('expected API', function () { - it('should have expected methods', function () { - expect(storage.get).to.be.a('function'); - expect(storage.set).to.be.a('function'); - expect(storage.remove).to.be.a('function'); - expect(storage.clear).to.be.a('function'); - }); - }); - - describe('call behavior', function () { - it('should call getItem on the store', function () { - storage.get('name'); - - expect($window.localStorage.getItem.callCount).to.equal(1); - }); - - it('should call setItem on the store', function () { - storage.set('name', 'john smith'); - - expect($window.localStorage.setItem.callCount).to.equal(1); - }); - - it('should call removeItem on the store', function () { - storage.remove('name'); - - expect($window.localStorage.removeItem.callCount).to.equal(1); - }); - - it('should call clear on the store', function () { - storage.clear(); - - expect($window.localStorage.clear.callCount).to.equal(1); - }); - }); - - describe('json data', function () { - it('should parse JSON when reading from the store', function () { - const getItem = $window.localStorage.getItem; - getItem.returns(JSON.stringify(payload)); - - const data = storage.get('name'); - expect(data).to.eql(payload); - }); - - it('should write JSON string to the store', function () { - const setItem = $window.localStorage.setItem; - const key = 'name'; - const value = payload; - - storage.set(key, value); - - const call = setItem.getCall(0); - expect(call.args[0]).to.equal(key); - expect(call.args[1]).to.equal(JSON.stringify(value)); - }); - }); - - describe('expected responses', function () { - it('should return null when not exists', function () { - const data = storage.get('notexists'); - expect(data).to.equal(null); - }); - - it('should return null when invalid JSON', function () { - const getItem = $window.localStorage.getItem; - getItem.returns('not: json'); - - const data = storage.get('name'); - expect(data).to.equal(null); - }); - }); -}); diff --git a/src/plugins/kibana_utils/public/storage/storage.test.ts b/src/plugins/kibana_utils/public/storage/storage.test.ts new file mode 100644 index 0000000000000..8c5d3d11a21fe --- /dev/null +++ b/src/plugins/kibana_utils/public/storage/storage.test.ts @@ -0,0 +1,109 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Storage } from './storage'; +import { IStorage, IStorageWrapper } from './types'; + +const payload = { first: 'john', last: 'smith' }; +const createMockStore = (): MockedKeys => { + let store: Record = {}; + return { + getItem: jest.fn().mockImplementation((key) => store[key]), + setItem: jest.fn().mockImplementation((key, value) => (store[key] = value)), + removeItem: jest.fn().mockImplementation((key: string) => delete store[key]), + clear: jest.fn().mockImplementation(() => (store = {})), + }; +}; + +describe('StorageService', () => { + let storage: IStorageWrapper; + let mockStore: MockedKeys; + + beforeEach(() => { + jest.resetAllMocks(); + mockStore = createMockStore(); + storage = new Storage(mockStore); + }); + + describe('expected API', () => { + test('should have expected methods', () => { + expect(typeof storage.get).toBe('function'); + expect(typeof storage.set).toBe('function'); + expect(typeof storage.remove).toBe('function'); + expect(typeof storage.clear).toBe('function'); + }); + }); + + describe('call behavior', () => { + test('should call getItem on the store', () => { + storage.get('name'); + + expect(mockStore.getItem).toHaveBeenCalledTimes(1); + }); + + test('should call setItem on the store', () => { + storage.set('name', 'john smith'); + + expect(mockStore.setItem).toHaveBeenCalledTimes(1); + }); + + test('should call removeItem on the store', () => { + storage.remove('name'); + + expect(mockStore.removeItem).toHaveBeenCalledTimes(1); + }); + + test('should call clear on the store', () => { + storage.clear(); + + expect(mockStore.clear).toHaveBeenCalledTimes(1); + }); + }); + + describe('json data', () => { + test('should parse JSON when reading from the store', () => { + mockStore.getItem = jest.fn().mockImplementationOnce(() => JSON.stringify(payload)); + + const data = storage.get('name'); + expect(data).toEqual(payload); + }); + + test('should write JSON string to the store', () => { + const key = 'name'; + const value = payload; + + storage.set(key, value); + expect(mockStore.setItem).toHaveBeenCalledWith(key, JSON.stringify(value)); + }); + }); + + describe('expected responses', () => { + test('should return null when not exists', () => { + const data = storage.get('notexists'); + expect(data).toBe(null); + }); + + test('should return null when invalid JSON', () => { + mockStore.getItem = jest.fn().mockImplementationOnce(() => 'not: json'); + + const data = storage.get('name'); + expect(data).toBe(null); + }); + }); +}); diff --git a/src/plugins/visualizations/public/legacy/__tests__/vis_update_objs/gauge_objs.js b/src/plugins/visualizations/public/legacy/vis_update_state.stub.js similarity index 100% rename from src/plugins/visualizations/public/legacy/__tests__/vis_update_objs/gauge_objs.js rename to src/plugins/visualizations/public/legacy/vis_update_state.stub.js diff --git a/src/plugins/visualizations/public/legacy/vis_update_state.test.js b/src/plugins/visualizations/public/legacy/vis_update_state.test.js index 7ddf0cc6e33e1..d0a735fbacdc2 100644 --- a/src/plugins/visualizations/public/legacy/vis_update_state.test.js +++ b/src/plugins/visualizations/public/legacy/vis_update_state.test.js @@ -21,7 +21,7 @@ import _ from 'lodash'; import { updateOldState } from './vis_update_state'; // eslint-disable-next-line camelcase -import { pre_6_1, since_6_1 } from './__tests__/vis_update_objs/gauge_objs'; +import { pre_6_1, since_6_1 } from './vis_update_state.stub'; function watchForChanges(obj) { const originalObject = _.cloneDeep(obj); From b4b6428c1ca095f8e1388bcec29d8d508ec08a22 Mon Sep 17 00:00:00 2001 From: Jonathan Buttner <56361221+jonathan-buttner@users.noreply.github.com> Date: Mon, 10 Aug 2020 11:18:30 -0400 Subject: [PATCH 069/106] [Ingest Manager] Allow prerelease in package version (#74452) * Allow prerelease in version * Adding integration test for prerelease version of a package * Tests for invalid package key * Removing inter-test dependency --- src/dev/precommit_hook/casing_check_config.js | 2 + .../server/routes/epm/handlers.ts | 5 ++- .../server/services/epm/packages/install.ts | 2 +- .../server/services/epm/packages/remove.ts | 3 +- .../services/epm/registry/index.test.ts | 34 ++++++++++++++- .../server/services/epm/registry/index.ts | 21 ++++++++++ .../apis/epm/get.ts | 33 +++++++++++++++ .../apis/epm/index.js | 2 + .../apis/epm/install_overrides.ts | 6 +-- .../apis/epm/install_prerelease.ts | 41 +++++++++++++++++++ .../dataset/test/fields/fields.yml | 16 ++++++++ .../0.1.0-dev.0+abc/dataset/test/manifest.yml | 3 ++ .../prerelease/0.1.0-dev.0+abc/docs/README.md | 3 ++ .../img/logo_prerelease_64_color.svg | 7 ++++ .../prerelease/0.1.0-dev.0+abc/manifest.yml | 20 +++++++++ 15 files changed, 190 insertions(+), 8 deletions(-) create mode 100644 x-pack/test/ingest_manager_api_integration/apis/epm/get.ts create mode 100644 x-pack/test/ingest_manager_api_integration/apis/epm/install_prerelease.ts create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/dataset/test/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/dataset/test/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/docs/README.md create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/img/logo_prerelease_64_color.svg create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/manifest.yml diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index 36d0ff8f51d88..bdbd600e9aa74 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -71,6 +71,8 @@ export const IGNORE_FILE_GLOBS = [ 'x-pack/plugins/apm/e2e/**/*', 'x-pack/plugins/maps/server/fonts/**/*', + // packages for the ingest manager's api integration tests could be valid semver which has dashes + 'x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/**/*', ]; /** diff --git a/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts index f8f39f6294260..bbd91b97a86c9 100644 --- a/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts +++ b/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts @@ -33,6 +33,7 @@ import { getInstallationObject, } from '../../services/epm/packages'; import { IngestManagerError, getHTTPResponseCode } from '../../errors'; +import { splitPkgKey } from '../../services/epm/registry'; export const getCategoriesHandler: RequestHandler< undefined, @@ -131,7 +132,7 @@ export const getInfoHandler: RequestHandler { // TODO: change epm API to /packageName/version so we don't need to do this - const [pkgName, pkgVersion] = pkgkey.split('-'); + const { pkgName, pkgVersion } = Registry.splitPkgKey(pkgkey); // TODO: calls to getInstallationObject, Registry.fetchInfo, and Registry.fetchFindLatestPackge // and be replaced by getPackageInfo after adjusting for it to not group/use archive assets const latestPackage = await Registry.fetchFindLatestPackage(pkgName); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts index 1acf2131dcb01..1e50c67d63c42 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts @@ -13,6 +13,7 @@ import { getInstallation, savedObjectTypes } from './index'; import { deletePipeline } from '../elasticsearch/ingest_pipeline/'; import { installIndexPatterns } from '../kibana/index_pattern/install'; import { packageConfigService, appContextService } from '../..'; +import { splitPkgKey } from '../registry'; export async function removeInstallation(options: { savedObjectsClient: SavedObjectsClientContract; @@ -21,7 +22,7 @@ export async function removeInstallation(options: { }): Promise { const { savedObjectsClient, pkgkey, callCluster } = options; // TODO: the epm api should change to /name/version so we don't need to do this - const [pkgName] = pkgkey.split('-'); + const { pkgName } = splitPkgKey(pkgkey); const installation = await getInstallation({ savedObjectsClient, pkgName }); if (!installation) throw Boom.badRequest(`${pkgName} is not installed`); if (installation.removable === false) diff --git a/x-pack/plugins/ingest_manager/server/services/epm/registry/index.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/registry/index.test.ts index eae84275a49b9..085dc990fa376 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/registry/index.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/registry/index.test.ts @@ -5,7 +5,7 @@ */ import { AssetParts } from '../../../types'; -import { pathParts } from './index'; +import { pathParts, splitPkgKey } from './index'; const testPaths = [ { @@ -48,3 +48,35 @@ test('testPathParts', () => { expect(pathParts(value.path)).toStrictEqual(value.assetParts as AssetParts); } }); + +describe('splitPkgKey tests', () => { + it('throws an error if the delimiter is not found', () => { + expect(() => { + splitPkgKey('awesome_package'); + }).toThrow(); + }); + + it('throws an error if there is nothing before the delimiter', () => { + expect(() => { + splitPkgKey('-0.0.1-dev1'); + }).toThrow(); + }); + + it('throws an error if the version is not a semver', () => { + expect(() => { + splitPkgKey('awesome-laskdfj'); + }).toThrow(); + }); + + it('returns the name and version if the delimiter is found once', () => { + const { pkgName, pkgVersion } = splitPkgKey('awesome-0.1.0'); + expect(pkgName).toBe('awesome'); + expect(pkgVersion).toBe('0.1.0'); + }); + + it('returns the name and version if the delimiter is found multiple times', () => { + const { pkgName, pkgVersion } = splitPkgKey('endpoint-0.13.0-alpha.1+abcd'); + expect(pkgName).toBe('endpoint'); + expect(pkgVersion).toBe('0.13.0-alpha.1+abcd'); + }); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/registry/index.ts b/x-pack/plugins/ingest_manager/server/services/epm/registry/index.ts index c701762e50b50..b635378960468 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/registry/index.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/registry/index.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import semver from 'semver'; import { Response } from 'node-fetch'; import { URL } from 'url'; import { @@ -35,6 +36,26 @@ export interface CategoriesParams { experimental?: boolean; } +/** + * Extract the package name and package version from a string. + * + * @param pkgkey a string containing the package name delimited by the package version + */ +export function splitPkgKey(pkgkey: string): { pkgName: string; pkgVersion: string } { + // this will return an empty string if `indexOf` returns -1 + const pkgName = pkgkey.substr(0, pkgkey.indexOf('-')); + if (pkgName === '') { + throw new Error('Package key parsing failed: package name was empty'); + } + + // this will return the entire string if `indexOf` return -1 + const pkgVersion = pkgkey.substr(pkgkey.indexOf('-') + 1); + if (!semver.valid(pkgVersion)) { + throw new Error('Package key parsing failed: package version was not a valid semver'); + } + return { pkgName, pkgVersion }; +} + export const pkgToPkgKey = ({ name, version }: { name: string; version: string }) => `${name}-${version}`; diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/get.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/get.ts new file mode 100644 index 0000000000000..382bd6beb2e2f --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/get.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { warnAndSkipTest } from '../../helpers'; + +export default function ({ getService }: FtrProviderContext) { + const log = getService('log'); + const supertest = getService('supertest'); + const dockerServers = getService('dockerServers'); + const server = dockerServers.get('registry'); + + describe('EPM - get', () => { + it('returns a 500 for a package key without a proper name', async function () { + if (server.enabled) { + await supertest.get('/api/ingest_manager/epm/packages/-0.1.0').expect(500); + } else { + warnAndSkipTest(this, log); + } + }); + + it('returns a 500 for a package key without a proper semver version', async function () { + if (server.enabled) { + await supertest.get('/api/ingest_manager/epm/packages/endpoint-0.1.0.1.2.3').expect(500); + } else { + warnAndSkipTest(this, log); + } + }); + }); +} diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/index.js b/x-pack/test/ingest_manager_api_integration/apis/epm/index.js index 0f32d2b4ae703..0a259cb96bf59 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/epm/index.js +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/index.js @@ -7,10 +7,12 @@ export default function loadTests({ loadTestFile }) { describe('EPM Endpoints', () => { loadTestFile(require.resolve('./list')); + loadTestFile(require.resolve('./get')); loadTestFile(require.resolve('./file')); //loadTestFile(require.resolve('./template')); loadTestFile(require.resolve('./ilm')); loadTestFile(require.resolve('./install_overrides')); + loadTestFile(require.resolve('./install_prerelease')); loadTestFile(require.resolve('./install_remove_assets')); loadTestFile(require.resolve('./install_update')); loadTestFile(require.resolve('./update_assets')); diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/install_overrides.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/install_overrides.ts index f73ba56c172c4..c75c51f6a5000 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/epm/install_overrides.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/install_overrides.ts @@ -14,13 +14,13 @@ export default function ({ getService }: FtrProviderContext) { const dockerServers = getService('dockerServers'); const log = getService('log'); + const mappingsPackage = 'overrides-0.1.0'; + const server = dockerServers.get('registry'); + const deletePackage = async (pkgkey: string) => { await supertest.delete(`/api/ingest_manager/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); }; - const mappingsPackage = 'overrides-0.1.0'; - const server = dockerServers.get('registry'); - describe('installs packages that include settings and mappings overrides', async () => { after(async () => { if (server.enabled) { diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/install_prerelease.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/install_prerelease.ts new file mode 100644 index 0000000000000..a641a105c66e0 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/install_prerelease.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { warnAndSkipTest } from '../../helpers'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const dockerServers = getService('dockerServers'); + const log = getService('log'); + + const testPackage = 'prerelease-0.1.0-dev.0+abc'; + const server = dockerServers.get('registry'); + + const deletePackage = async (pkgkey: string) => { + await supertest.delete(`/api/ingest_manager/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); + }; + + describe('installs package that has a prerelease version', async () => { + after(async () => { + if (server.enabled) { + // remove the package just in case it being installed will affect other tests + await deletePackage(testPackage); + } + }); + + it('should install the package correctly', async function () { + if (server.enabled) { + await supertest + .post(`/api/ingest_manager/epm/packages/${testPackage}`) + .set('kbn-xsrf', 'xxxx') + .expect(200); + } else { + warnAndSkipTest(this, log); + } + }); + }); +} diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/dataset/test/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/dataset/test/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/dataset/test/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/dataset/test/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/dataset/test/manifest.yml new file mode 100644 index 0000000000000..17c33c745ce74 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/dataset/test/manifest.yml @@ -0,0 +1,3 @@ +title: Test Dataset + +type: logs diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/docs/README.md b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/docs/README.md new file mode 100644 index 0000000000000..0002afd9cdfc0 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/docs/README.md @@ -0,0 +1,3 @@ +# Test package + +For testing a prerelease package diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/img/logo_prerelease_64_color.svg b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/img/logo_prerelease_64_color.svg new file mode 100644 index 0000000000000..b03007a76ffcc --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/img/logo_prerelease_64_color.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/manifest.yml new file mode 100644 index 0000000000000..a0adb184cfc59 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/prerelease/0.1.0-dev.0+abc/manifest.yml @@ -0,0 +1,20 @@ +format_version: 1.0.0 +name: prerelease +title: Prerelease package +description: This is a test package for testing that parsing a prerelease version works +version: 0.1.0-dev.0+abc +categories: ['security'] +release: beta +type: integration +license: basic + +requirement: + elasticsearch: + versions: '>7.7.0' + kibana: + versions: '>7.7.0' + +icons: + - src: '/img/logo_prerelease_64_color.svg' + size: '16x16' + type: 'image/svg+xml' From a6615c61411728f3485a52d8160073c675b9a9db Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Mon, 10 Aug 2020 11:50:18 -0400 Subject: [PATCH 070/106] add memoryStatus to df analytics page and analytics table in management (#74570) --- .../components/analytics_list/common.ts | 6 ++++++ .../components/analytics_list/use_columns.tsx | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts index cc52138d7c7b7..39489836773b3 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts @@ -35,6 +35,11 @@ interface ProgressSection { export interface DataFrameAnalyticsStats { assignment_explanation?: string; id: DataFrameAnalyticsId; + memory_usage?: { + timestamp?: string; + peak_usage_bytes: number; + status: string; + }; node?: { attributes: Record; ephemeral_id: string; @@ -121,6 +126,7 @@ export enum DataFrameAnalyticsListColumn { configCreateTime = 'config.create_time', description = 'config.description', id = 'id', + memoryStatus = 'stats.memory_usage.status', } export type ItemIdToExpandedRowMap = Record; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_columns.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_columns.tsx index 1b115496c2091..9ed87ff9f8312 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_columns.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_columns.tsx @@ -213,6 +213,14 @@ export const useColumns = ( truncateText: true, 'data-test-subj': 'mlAnalyticsTableColumnJobDescription', }, + { + field: DataFrameAnalyticsListColumn.memoryStatus, + name: i18n.translate('xpack.ml.dataframe.analyticsList.memoryStatus', { + defaultMessage: 'Memory status', + }), + truncateText: true, + 'data-test-subj': 'mlAnalyticsTableColumnJobMemoryStatus', + }, { field: DataFrameAnalyticsListColumn.configSourceIndex, name: i18n.translate('xpack.ml.dataframe.analyticsList.sourceIndex', { From 7fd2c2bed224c634b25933f009fa2eb094475561 Mon Sep 17 00:00:00 2001 From: Jonathan Buttner <56361221+jonathan-buttner@users.noreply.github.com> Date: Mon, 10 Aug 2020 11:54:22 -0400 Subject: [PATCH 071/106] [Security Solution] Resolver children pagination (#74603) * Handle info and change events for children * Adding sequence * Fixing children pagination * Fixing tests * Adding docs --- .../common/endpoint/generate_data.test.ts | 7 + .../common/endpoint/generate_data.ts | 3 + .../common/endpoint/models/event.ts | 14 ++ .../common/endpoint/types.ts | 3 + .../routes/resolver/queries/children.test.ts | 10 +- .../routes/resolver/queries/children.ts | 9 +- .../routes/resolver/utils/children_helper.ts | 4 +- .../resolver/utils/children_pagination.ts | 129 ++++++++++++++++++ .../utils/children_start_query_handler.ts | 11 +- .../routes/resolver/utils/pagination.ts | 92 +++++++++---- .../apis/resolver/children.ts | 83 ++++++++++- .../apis/resolver/tree.ts | 26 ++-- 12 files changed, 337 insertions(+), 54 deletions(-) create mode 100644 x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_pagination.ts diff --git a/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts b/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts index debe4a3da6a6f..46fc002e76e7f 100644 --- a/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts +++ b/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts @@ -26,6 +26,13 @@ describe('data generator', () => { generator = new EndpointDocGenerator('seed'); }); + it('creates events with a numerically increasing sequence value', () => { + const event1 = generator.generateEvent(); + const event2 = generator.generateEvent(); + + expect(event2.event.sequence).toBe(event1.event.sequence + 1); + }); + it('creates the same documents with same random seed', () => { const generator1 = new EndpointDocGenerator('seed'); const generator2 = new EndpointDocGenerator('seed'); diff --git a/x-pack/plugins/security_solution/common/endpoint/generate_data.ts b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts index aa3f0bf287fca..09f25fc074eff 100644 --- a/x-pack/plugins/security_solution/common/endpoint/generate_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts @@ -333,6 +333,7 @@ export function getTreeOptionsWithDef(options?: TreeOptions): TreeOptionDefaults export class EndpointDocGenerator { commonInfo: HostInfo; random: seedrandom.prng; + sequence: number = 0; constructor(seed: string | seedrandom.prng = Math.random().toString()) { if (typeof seed === 'string') { this.random = seedrandom(seed); @@ -440,6 +441,7 @@ export class EndpointDocGenerator { dataset: 'endpoint', module: 'endpoint', type: 'creation', + sequence: this.sequence++, }, file: { owner: 'SYSTEM', @@ -586,6 +588,7 @@ export class EndpointDocGenerator { kind: 'event', type: options.eventType ? options.eventType : ['start'], id: this.seededUUIDv4(), + sequence: this.sequence++, }, host: this.commonInfo.host, process: { diff --git a/x-pack/plugins/security_solution/common/endpoint/models/event.ts b/x-pack/plugins/security_solution/common/endpoint/models/event.ts index b1a8524a9f9e7..30e11819c0272 100644 --- a/x-pack/plugins/security_solution/common/endpoint/models/event.ts +++ b/x-pack/plugins/security_solution/common/endpoint/models/event.ts @@ -86,6 +86,20 @@ export function eventId(event: ResolverEvent): number | undefined | string { return event.event.id; } +export function eventSequence(event: ResolverEvent): number | undefined { + if (isLegacyEvent(event)) { + return firstNonNullValue(event.endgame.serial_event_id); + } + return firstNonNullValue(event.event?.sequence); +} + +export function eventSequenceSafeVersion(event: SafeResolverEvent): number | undefined { + if (isLegacyEventSafeVersion(event)) { + return firstNonNullValue(event.endgame.serial_event_id); + } + return firstNonNullValue(event.event?.sequence); +} + export function eventIDSafeVersion(event: SafeResolverEvent): number | undefined | string { return firstNonNullValue( isLegacyEventSafeVersion(event) ? event.endgame?.serial_event_id : event.event?.id diff --git a/x-pack/plugins/security_solution/common/endpoint/types.ts b/x-pack/plugins/security_solution/common/endpoint/types.ts index ffde47825b501..2a1c95caff3a3 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types.ts @@ -320,6 +320,7 @@ export interface AlertEvent { dataset: string; module: string; type: string; + sequence: number; }; Endpoint: { policy: { @@ -524,6 +525,7 @@ export interface EndpointEvent { type: string | string[]; id: string; kind: string; + sequence: number; }; host: Host; network?: { @@ -600,6 +602,7 @@ export type SafeEndpointEvent = Partial<{ type: ECSField; id: ECSField; kind: ECSField; + sequence: ECSField; }>; host: Partial<{ id: ECSField; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.test.ts index 8175764b3a0a2..4e210e0237fcd 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.test.ts @@ -4,12 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ import { ChildrenQuery } from './children'; -import { PaginationBuilder } from '../utils/pagination'; +import { ChildrenPaginationBuilder } from '../utils/children_pagination'; import { legacyEventIndexPattern } from './legacy_event_index_pattern'; describe('Children query', () => { it('constructs a legacy multi search query', () => { - const query = new ChildrenQuery(new PaginationBuilder(1), 'index-pattern', 'endpointID'); + const query = new ChildrenQuery( + new ChildrenPaginationBuilder(1), + 'index-pattern', + 'endpointID' + ); // using any here because otherwise ts complains that it doesn't know what bool and filter are // eslint-disable-next-line @typescript-eslint/no-explicit-any const msearch: any = query.buildMSearch('1234'); @@ -20,7 +24,7 @@ describe('Children query', () => { }); it('constructs a non-legacy multi search query', () => { - const query = new ChildrenQuery(new PaginationBuilder(1), 'index-pattern'); + const query = new ChildrenQuery(new ChildrenPaginationBuilder(1), 'index-pattern'); // using any here because otherwise ts complains that it doesn't know what bool and filter are // eslint-disable-next-line @typescript-eslint/no-explicit-any const msearch: any = query.buildMSearch(['1234', '5678']); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.ts index 902d287a09e42..6fb38a32f9581 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.ts @@ -6,7 +6,7 @@ import { SearchResponse } from 'elasticsearch'; import { ResolverEvent } from '../../../../../common/endpoint/types'; import { ResolverQuery } from './base'; -import { PaginationBuilder } from '../utils/pagination'; +import { ChildrenPaginationBuilder } from '../utils/children_pagination'; import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/common'; /** @@ -14,7 +14,7 @@ import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/com */ export class ChildrenQuery extends ResolverQuery { constructor( - private readonly pagination: PaginationBuilder, + private readonly pagination: ChildrenPaginationBuilder, indexPattern: string | string[], endpointID?: string ) { @@ -32,6 +32,7 @@ export class ChildrenQuery extends ResolverQuery { query: { bool: { filter: [ + ...paginationFields.filters, { terms: { 'endgame.unique_ppid': uniquePIDs }, }, @@ -63,7 +64,7 @@ export class ChildrenQuery extends ResolverQuery { } protected query(entityIDs: string[]): JsonObject { - const paginationFields = this.pagination.buildQueryFieldsAsInterface('event.id'); + const paginationFields = this.pagination.buildQueryFields('event.id'); return { /** * Using collapse here will only return a single event per occurrence of a process.entity_id. The events are sorted @@ -80,12 +81,12 @@ export class ChildrenQuery extends ResolverQuery { collapse: { field: 'process.entity_id', }, - // do not set the search_after field because collapse does not work with it size: paginationFields.size, sort: paginationFields.sort, query: { bool: { filter: [ + ...paginationFields.filters, { bool: { should: [ diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.ts index ef487897e3b4e..b82b972b887b5 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.ts @@ -16,7 +16,7 @@ import { ResolverChildren, } from '../../../../../common/endpoint/types'; import { createChild } from './node'; -import { PaginationBuilder } from './pagination'; +import { ChildrenPaginationBuilder } from './children_pagination'; /** * This class helps construct the children structure when building a resolver tree. @@ -162,7 +162,7 @@ export class ChildrenNodesHelper { for (const nodeEntityID of nodes.values()) { const cachedNode = this.entityToNodeCache.get(nodeEntityID); if (cachedNode) { - cachedNode.nextChild = PaginationBuilder.buildCursor(startEvents); + cachedNode.nextChild = ChildrenPaginationBuilder.buildCursor(startEvents); } } } diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_pagination.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_pagination.ts new file mode 100644 index 0000000000000..1e154caf70c48 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_pagination.ts @@ -0,0 +1,129 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ResolverEvent } from '../../../../../common/endpoint/types'; +import { eventSequence } from '../../../../../common/endpoint/models/event'; +import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/common'; +import { urlEncodeCursor, SortFields, urlDecodeCursor } from './pagination'; + +/** + * Pagination information for the children class. + */ +export interface ChildrenPaginationCursor { + timestamp: number; + sequence: number; +} + +/** + * Interface for defining the returned pagination information. + */ +export interface ChildrenPaginationFields { + sort: SortFields; + size: number; + filters: JsonObject[]; +} + +/** + * This class handles constructing pagination cursors that resolver can use to return additional events in subsequent + * queries. + */ +export class ChildrenPaginationBuilder { + constructor( + /** + * upper limit of how many results should be returned by the parent query. + */ + private readonly size: number, + /** + * timestamp that will be used in the search_after section + */ + private readonly timestamp?: number, + /** + * unique sequence number for the event + */ + private readonly sequence?: number + ) {} + + /** + * This function validates that the parsed cursor is a ChildrenPaginationCursor. + * + * @param parsed an object parsed from an encoded cursor. + */ + static decode( + parsed: ChildrenPaginationCursor | undefined + ): ChildrenPaginationCursor | undefined { + if (parsed && parsed.timestamp && parsed.sequence) { + const { timestamp, sequence } = parsed; + return { timestamp, sequence }; + } + } + + /** + * Construct a cursor to use in subsequent queries. + * + * @param results the events that were returned by the ES query + */ + static buildCursor(results: ResolverEvent[]): string | null { + const lastResult = results[results.length - 1]; + const sequence = eventSequence(lastResult); + const cursor = { + timestamp: lastResult['@timestamp'], + sequence: sequence === undefined ? 0 : sequence, + }; + return urlEncodeCursor(cursor); + } + + /** + * Creates a PaginationBuilder with an upper bound limit of results and a specific cursor to use to retrieve the next + * set of results. + * + * @param limit upper bound for the number of results to return within this query + * @param after a cursor to retrieve the next set of results + */ + static createBuilder(limit: number, after?: string): ChildrenPaginationBuilder { + if (after) { + try { + const cursor = urlDecodeCursor(after, ChildrenPaginationBuilder.decode); + if (cursor && cursor.timestamp && cursor.sequence) { + return new ChildrenPaginationBuilder(limit, cursor.timestamp, cursor.sequence); + } + } catch (err) { + /* tslint:disable:no-empty */ + } // ignore invalid cursor values + } + return new ChildrenPaginationBuilder(limit); + } + + /** + * Helper for creates an object for adding the pagination fields to a query + * + * @param tiebreaker a unique field to use as the tiebreaker for the search_after + * @returns an object containing the pagination information + */ + buildQueryFields(tiebreaker: string): ChildrenPaginationFields { + const sort: SortFields = [{ '@timestamp': 'asc' }, { [tiebreaker]: 'asc' }]; + const filters: JsonObject[] = []; + if (this.timestamp && this.sequence) { + filters.push( + { + range: { + '@timestamp': { + gte: this.timestamp, + }, + }, + }, + { + range: { + 'event.sequence': { + gt: this.sequence, + }, + }, + } + ); + } + + return { sort, size: this.size, filters }; + } +} diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_start_query_handler.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_start_query_handler.ts index 1c74184720793..30d46d12afbe5 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_start_query_handler.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_start_query_handler.ts @@ -11,7 +11,7 @@ import { ChildrenQuery } from '../queries/children'; import { QueryInfo } from '../queries/multi_searcher'; import { QueryHandler } from './fetch'; import { ChildrenNodesHelper } from './children_helper'; -import { PaginationBuilder } from './pagination'; +import { ChildrenPaginationBuilder } from './children_pagination'; /** * Retrieve the start lifecycle events for the children of a resolver tree. @@ -32,7 +32,7 @@ export class ChildrenStartQueryHandler implements QueryHandler = (parsed: T | undefined) => T | undefined; + /** * Interface for defining the returned pagination information. */ @@ -31,10 +41,42 @@ export interface PaginationFields { searchAfter?: SearchAfterFields; } +/** + * A function to encode a cursor from a pagination object. + * + * @param data Transforms a pagination cursor into a base64 encoded string + */ +export function urlEncodeCursor(data: PaginationCursor | ChildrenPaginationCursor): string { + const value = JSON.stringify(data); + return Buffer.from(value, 'utf8') + .toString('base64') + .replace(/\+/g, '-') + .replace(/\//g, '_') + .replace(/=+$/g, ''); +} + +/** + * A function to decode a cursor. + * + * @param cursor a cursor encoded by the `urlEncodeCursor` function + * @param decode a function to transform the parsed data into an actual type + */ +export function urlDecodeCursor(cursor: string, decode: Decoder): T | undefined { + const fixedCursor = cursor.replace(/\-/g, '+').replace(/_/g, '/'); + const data = Buffer.from(fixedCursor, 'base64').toString('utf8'); + let parsed: T; + try { + parsed = JSON.parse(data); + } catch (e) { + return; + } + + return decode(parsed); +} + /** * This class handles constructing pagination cursors that resolver can use to return additional events in subsequent - * queries. It also constructs an aggregation query to determine the totals for other queries. This class should be used - * with a query to build cursors for paginated results. + * queries. */ export class PaginationBuilder { constructor( @@ -52,22 +94,16 @@ export class PaginationBuilder { private readonly eventID?: string ) {} - private static urlEncodeCursor(data: PaginationCursor): string { - const value = JSON.stringify(data); - return Buffer.from(value, 'utf8') - .toString('base64') - .replace(/\+/g, '-') - .replace(/\//g, '_') - .replace(/=+$/g, ''); - } - - private static urlDecodeCursor(cursor: string): PaginationCursor { - const fixedCursor = cursor.replace(/\-/g, '+').replace(/_/g, '/'); - const data = Buffer.from(fixedCursor, 'base64').toString('utf8'); - const { timestamp, eventID } = JSON.parse(data); - // take some extra care to only grab the things we want - // convert the timestamp string to date object - return { timestamp, eventID }; + /** + * Validates that the parsed object is actually a PaginationCursor. + * + * @param parsed an object parsed from an encoded cursor. + */ + static decode(parsed: PaginationCursor | undefined): PaginationCursor | undefined { + if (parsed && parsed.timestamp && parsed.eventID) { + const { timestamp, eventID } = parsed; + return { timestamp, eventID }; + } } /** @@ -81,7 +117,7 @@ export class PaginationBuilder { timestamp: lastResult['@timestamp'], eventID: eventId(lastResult) === undefined ? '' : String(eventId(lastResult)), }; - return PaginationBuilder.urlEncodeCursor(cursor); + return urlEncodeCursor(cursor); } /** @@ -107,8 +143,8 @@ export class PaginationBuilder { static createBuilder(limit: number, after?: string): PaginationBuilder { if (after) { try { - const cursor = PaginationBuilder.urlDecodeCursor(after); - if (cursor.timestamp && cursor.eventID) { + const cursor = urlDecodeCursor(after, PaginationBuilder.decode); + if (cursor && cursor.timestamp && cursor.eventID) { return new PaginationBuilder(limit, cursor.timestamp, cursor.eventID); } } catch (err) { diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/resolver/children.ts b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/children.ts index cde1a3616b620..2dec3c755a93b 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/resolver/children.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/children.ts @@ -7,11 +7,12 @@ import expect from '@kbn/expect'; import { SearchResponse } from 'elasticsearch'; import { entityId } from '../../../../plugins/security_solution/common/endpoint/models/event'; import { eventsIndexPattern } from '../../../../plugins/security_solution/common/endpoint/constants'; -import { PaginationBuilder } from '../../../../plugins/security_solution/server/endpoint/routes/resolver/utils/pagination'; +import { ChildrenPaginationBuilder } from '../../../../plugins/security_solution/server/endpoint/routes/resolver/utils/children_pagination'; import { ChildrenQuery } from '../../../../plugins/security_solution/server/endpoint/routes/resolver/queries/children'; import { ResolverTree, ResolverEvent, + ResolverChildren, } from '../../../../plugins/security_solution/common/endpoint/types'; import { FtrProviderContext } from '../../ftr_provider_context'; import { @@ -112,7 +113,7 @@ export default function resolverAPIIntegrationTests({ getService }: FtrProviderC it('only retrieves the start event for the child node', async () => { const childrenQuery = new ChildrenQuery( - PaginationBuilder.createBuilder(100), + ChildrenPaginationBuilder.createBuilder(100), eventsIndexPattern ); // [1] here gets the body portion of the array @@ -125,5 +126,83 @@ export default function resolverAPIIntegrationTests({ getService }: FtrProviderC expect(event.event?.type).to.eql(['start']); }); }); + + describe('children api returns same node multiple times', () => { + let origin: Event; + let startEvent: Event; + let infoEvent: Event; + let execEvent: Event; + let genData: InsertedEvents; + + before(async () => { + // Construct the following tree: + // Origin -> (infoEvent, startEvent, execEvent are all for the same node) + origin = generator.generateEvent(); + startEvent = generator.generateEvent({ + parentEntityID: origin.process.entity_id, + ancestry: [origin.process.entity_id], + eventType: ['start'], + }); + + infoEvent = generator.generateEvent({ + timestamp: startEvent['@timestamp'] + 100, + parentEntityID: origin.process.entity_id, + ancestry: [origin.process.entity_id], + entityID: startEvent.process.entity_id, + eventType: ['info'], + }); + + execEvent = generator.generateEvent({ + timestamp: infoEvent['@timestamp'] + 100, + parentEntityID: origin.process.entity_id, + ancestry: [origin.process.entity_id], + eventType: ['change'], + entityID: startEvent.process.entity_id, + }); + genData = await resolver.insertEvents([origin, infoEvent, startEvent, execEvent]); + }); + + after(async () => { + await resolver.deleteData(genData); + }); + + it('retrieves the same node three times', async () => { + let { body }: { body: ResolverChildren } = await supertest + .get(`/api/endpoint/resolver/${origin.process.entity_id}/children?children=1`) + .expect(200); + expect(body.childNodes.length).to.be(1); + expect(body.nextChild).to.not.be(null); + expect(body.childNodes[0].entityID).to.be(startEvent.process.entity_id); + expect(body.childNodes[0].lifecycle[0].event?.type).to.eql(startEvent.event.type); + + ({ body } = await supertest + .get( + `/api/endpoint/resolver/${origin.process.entity_id}/children?children=1&afterChild=${body.nextChild}` + ) + .expect(200)); + expect(body.childNodes.length).to.be(1); + expect(body.nextChild).to.not.be(null); + expect(body.childNodes[0].entityID).to.be(infoEvent.process.entity_id); + expect(body.childNodes[0].lifecycle[1].event?.type).to.eql(infoEvent.event.type); + + ({ body } = await supertest + .get( + `/api/endpoint/resolver/${origin.process.entity_id}/children?children=1&afterChild=${body.nextChild}` + ) + .expect(200)); + expect(body.childNodes.length).to.be(1); + expect(body.nextChild).to.not.be(null); + expect(body.childNodes[0].entityID).to.be(infoEvent.process.entity_id); + expect(body.childNodes[0].lifecycle[2].event?.type).to.eql(execEvent.event.type); + + ({ body } = await supertest + .get( + `/api/endpoint/resolver/${origin.process.entity_id}/children?children=1&afterChild=${body.nextChild}` + ) + .expect(200)); + expect(body.childNodes.length).to.be(0); + expect(body.nextChild).to.be(null); + }); + }); }); } diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/resolver/tree.ts b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/tree.ts index 7b511c3be74b5..f4836379ca273 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/resolver/tree.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/tree.ts @@ -537,7 +537,6 @@ export default function ({ getService }: FtrProviderContext) { describe('legacy events', () => { const endpointID = '5a0c957f-b8e7-4538-965e-57e8bb86ad3a'; const entityID = '94041'; - const cursor = 'eyJ0aW1lc3RhbXAiOjE1ODE0NTYyNTUwMDAsImV2ZW50SUQiOiI5NDA0MiJ9'; it('returns child process lifecycle events', async () => { const { body }: { body: ResolverChildren } = await supertest @@ -566,20 +565,25 @@ export default function ({ getService }: FtrProviderContext) { ).to.eql(93932); }); - // The children api does not support pagination currently - it.skip('returns no values when there is no more data', async () => { - const { body } = await supertest - // after is set to the document id of the last event so there shouldn't be any more after it + it('returns no values when there is no more data', async () => { + let { body }: { body: ResolverChildren } = await supertest .get( - `/api/endpoint/resolver/${entityID}/children?legacyEndpointID=${endpointID}&afterChild=${cursor}` + // there should only be a single child for this node + `/api/endpoint/resolver/94041/children?legacyEndpointID=${endpointID}&children=1` ) .expect(200); + expect(body.nextChild).to.not.be(null); + + ({ body } = await supertest + .get( + `/api/endpoint/resolver/94041/children?legacyEndpointID=${endpointID}&afterChild=${body.nextChild}` + ) + .expect(200)); expect(body.childNodes).be.empty(); expect(body.nextChild).to.eql(null); }); - // The children api does not support pagination currently - it.skip('returns the first page of information when the cursor is invalid', async () => { + it('returns the first page of information when the cursor is invalid', async () => { const { body }: { body: ResolverChildren } = await supertest .get( `/api/endpoint/resolver/${entityID}/children?legacyEndpointID=${endpointID}&afterChild=blah` @@ -641,8 +645,7 @@ export default function ({ getService }: FtrProviderContext) { expect(body.nextChild).to.not.eql(null); }); - // children api does not support pagination currently - it.skip('paginates the children', async () => { + it('paginates the children', async () => { // this gets a node should have 3 children which were created in succession so that the timestamps // are ordered correctly to be retrieved in a single call const distantChildEntityID = Array.from(tree.childrenLevels[0].values())[0].id; @@ -671,8 +674,7 @@ export default function ({ getService }: FtrProviderContext) { expect(body.nextChild).to.be(null); }); - // children api does not support pagination currently - it.skip('gets all children in two queries', async () => { + it('gets all children in two queries', async () => { // should get all the children of the origin let { body }: { body: ResolverChildren } = await supertest .get(`/api/endpoint/resolver/${tree.origin.id}/children?children=3`) From 415a32c86f8274bd0329319fa527a50427af4ccb Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Mon, 10 Aug 2020 18:06:20 +0200 Subject: [PATCH 072/106] fix: update apm agents to catch abort requests (#74658) --- package.json | 4 ++-- x-pack/package.json | 2 +- yarn.lock | 46 ++++++++++++++++++++++----------------------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index fc3af14ecae09..1f51e8b3c6e26 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "@babel/core": "^7.11.1", "@babel/plugin-transform-modules-commonjs": "^7.10.4", "@babel/register": "^7.10.5", - "@elastic/apm-rum": "^5.2.0", + "@elastic/apm-rum": "^5.4.0", "@elastic/charts": "19.8.1", "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "7.9.0-rc.2", @@ -173,7 +173,7 @@ "deep-freeze-strict": "^1.1.1", "deepmerge": "^4.2.2", "del": "^5.1.0", - "elastic-apm-node": "^3.6.0", + "elastic-apm-node": "^3.7.0", "elasticsearch": "^16.7.0", "elasticsearch-browser": "^16.7.0", "execa": "^4.0.2", diff --git a/x-pack/package.json b/x-pack/package.json index 8fbb94c97c143..83eb0910add11 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -202,7 +202,7 @@ "@babel/core": "^7.11.1", "@babel/register": "^7.10.5", "@babel/runtime": "^7.11.2", - "@elastic/apm-rum-react": "^1.1.2", + "@elastic/apm-rum-react": "^1.2.2", "@elastic/datemath": "5.0.3", "@elastic/ems-client": "7.9.3", "@elastic/eui": "26.3.1", diff --git a/yarn.lock b/yarn.lock index 33083667a3c5e..49345184eb3dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1976,29 +1976,29 @@ enabled "2.0.x" kuler "^2.0.0" -"@elastic/apm-rum-core@^5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum-core/-/apm-rum-core-5.3.0.tgz#3ae5e84eba5b5287b92458a49755f6e39e7bba5b" - integrity sha512-b/qAnPqi3km808BhSYo+ROpTINm3eVBQ6hNcxOELwKitS3O/HikkwRn5aPkVIhQXOVrbPSufMl1A991nrE3daA== +"@elastic/apm-rum-core@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@elastic/apm-rum-core/-/apm-rum-core-5.5.0.tgz#e05ffd87b95420c788ed3be7cfbbbce1ff54bcf5" + integrity sha512-fPx65oZD495WdHQ3YA8TnzqmjqlvSxoXm0tZqXQKzKVv7CMsNkolnEPSAXFl0W5pmAVRvw6T+vMmxcVIGsCD4Q== dependencies: error-stack-parser "^1.3.5" opentracing "^0.14.3" promise-polyfill "^8.1.3" -"@elastic/apm-rum-react@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum-react/-/apm-rum-react-1.1.2.tgz#274cc414074d05e33e8f0afcad25ef9a30d99452" - integrity sha512-2/wEaPF4EQaVzU8Qj5aYucDc+VFr7438AieON31fx8wsbvnxh9iG+iV7xky2YtT/mf53BbFgZm35L5y/pxCKwA== +"@elastic/apm-rum-react@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@elastic/apm-rum-react/-/apm-rum-react-1.2.2.tgz#b92f1491bae62de0b4296264afe73171f17af022" + integrity sha512-KXM2qxG4p1GeDoud9jpmUA19uuQxW4M+CgtrNIXuNwITMIw46qRLyl5zOIvy9dqHodvLIvZ7RWsFtSZH4kZnAQ== dependencies: - "@elastic/apm-rum" "^5.2.0" + "@elastic/apm-rum" "^5.4.0" hoist-non-react-statics "^3.3.0" -"@elastic/apm-rum@^5.2.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum/-/apm-rum-5.2.0.tgz#b0cfd6e5771b1e765fda2715a38c87746f49f1aa" - integrity sha512-l8/Ji1GMuahMCN5DsALIf+fioKi1QeY4pU0izfVI37se2/fxsMNEDpw52WxJknHdfBE0Imh3FPg4T56J5MO+IQ== +"@elastic/apm-rum@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@elastic/apm-rum/-/apm-rum-5.4.0.tgz#2d87d5ca19f7f4a021c03f075d9d767894e88b3c" + integrity sha512-X4uaJlM28pyDOsD06serggspbTyz7Za0zFr+OWUntI6tQKu++Tn8yGsr6L2WuXhKNGhyJmrAfh13pmy9ZGyFcg== dependencies: - "@elastic/apm-rum-core" "^5.3.0" + "@elastic/apm-rum-core" "^5.5.0" "@elastic/charts@19.8.1": version "19.8.1" @@ -12395,10 +12395,10 @@ ejs@^3.0.1: resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.0.2.tgz#745b01cdcfe38c1c6a2da3bbb2d9957060a31226" integrity sha512-IncmUpn1yN84hy2shb0POJ80FWrfGNY0cxO9f4v+/sG7qcBvAtVWUA1IdzY/8EYUmOVhoKJVdJjNd3AZcnxOjA== -elastic-apm-http-client@^9.3.0: - version "9.3.0" - resolved "https://registry.yarnpkg.com/elastic-apm-http-client/-/elastic-apm-http-client-9.3.0.tgz#fcbb3b4f2af209dc304ac496438d381ef19b9b44" - integrity sha512-vxySk7S1oPN7uPcjv0+GLs3Y1cmN7WDVTEHBJixEDg+L6DJMysgxIGst+32Nc0ZmeU5NIjV/Ds9b+6S/yXRdIQ== +elastic-apm-http-client@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/elastic-apm-http-client/-/elastic-apm-http-client-9.4.0.tgz#1c985923369f0c511b94d5c20f6d13aef588cb55" + integrity sha512-/jOZDyfzLNwHrNkPAI+AspLg0TXYXODWT+I1eoAWRCB7gP1vKvzUQAsP5iChodVqCbAj1eUNXB0KrvM6b07Thw== dependencies: breadth-filter "^2.0.0" container-info "^1.0.1" @@ -12410,10 +12410,10 @@ elastic-apm-http-client@^9.3.0: stream-chopper "^3.0.1" unicode-byte-truncate "^1.0.0" -elastic-apm-node@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-3.6.0.tgz#675980951fbf2fc5606d5a95a8d0b097609ac6eb" - integrity sha512-T1BlWlQ3kYPIjcGaGIszaVYbsiP9aMr8V5gFxzkI7LjY9XelahOnC3u8Mmd6TWLh/QyakDcdt8J6VL3bMuR3WA== +elastic-apm-node@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-3.7.0.tgz#168f0cfce8d93b5ebc82f387b158fa0924de9d7a" + integrity sha512-ZH3Xru6eLbUyfuNe+EnTOcKlm0B+MKduu1lCXXwEM8CDfDceW1Ks9FtmTaTeZHZW4nMacieGZMpxETrceoVk/A== dependencies: after-all-results "^2.0.0" async-value-promise "^1.1.1" @@ -12421,7 +12421,7 @@ elastic-apm-node@^3.6.0: console-log-level "^1.4.1" cookie "^0.4.0" core-util-is "^1.0.2" - elastic-apm-http-client "^9.3.0" + elastic-apm-http-client "^9.4.0" end-of-stream "^1.4.4" error-stack-parser "^2.0.6" fast-safe-stringify "^2.0.7" From 8819644f138b16d1271e4c00d774b05330747d5a Mon Sep 17 00:00:00 2001 From: Dmitry Lemeshko Date: Mon, 10 Aug 2020 18:15:28 +0200 Subject: [PATCH 073/106] bump geckodriver binary to 0.27 (#74638) --- package.json | 2 +- yarn.lock | 84 +++++++++++++++++++++------------------------------- 2 files changed, 34 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index 1f51e8b3c6e26..0b5a6822e6afa 100644 --- a/package.json +++ b/package.json @@ -438,7 +438,7 @@ "exit-hook": "^2.2.0", "faker": "1.1.0", "fetch-mock": "^7.3.9", - "geckodriver": "^1.19.0", + "geckodriver": "^1.20.0", "getopts": "^2.2.4", "grunt": "1.0.4", "grunt-available-tasks": "^0.6.3", diff --git a/yarn.lock b/yarn.lock index 49345184eb3dd..7c397c33ad8a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6284,10 +6284,10 @@ adjust-sourcemap-loader@2.0.0: object-path "0.11.4" regex-parser "2.2.10" -adm-zip@0.4.11: - version "0.4.11" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.11.tgz#2aa54c84c4b01a9d0fb89bb11982a51f13e3d62a" - integrity sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA== +adm-zip@0.4.16: + version "0.4.16" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" + integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== after-all-results@^2.0.0: version "2.0.0" @@ -8295,11 +8295,6 @@ bluebird-retry@^0.11.0: resolved "https://registry.yarnpkg.com/bluebird-retry/-/bluebird-retry-0.11.0.tgz#1289ab22cbbc3a02587baad35595351dd0c1c047" integrity sha1-EomrIsu8OgJYe6rTVZU1HdDBwEc= -bluebird@3.4.6: - version "3.4.6" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" - integrity sha1-AdqNgh2HgT0ViWfnQ9X+bGLPjA8= - bluebird@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" @@ -14900,16 +14895,16 @@ gaze@^1.0.0, gaze@^1.1.0: dependencies: globule "^1.0.0" -geckodriver@^1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-1.19.0.tgz#b2b07e343c2e409ce645e65fe88132bd34fa400a" - integrity sha512-Zq98rXKjvB+NCfzKlJGkQkFAO8zvmUSNqYEIxUwlF1qxmv4taRwwBbEfDa6Dj7Auf7C0p+ZZZmIA8KmlL1cfsw== +geckodriver@^1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-1.20.0.tgz#cd16edb177b88e31affcb54b18a238cae88950a7" + integrity sha512-5nVF4ixR+ZGhVsc4udnVihA9RmSlO6guPV1d2HqxYsgAOUNh0HfzxbzG7E49w4ilXq/CSu87x9yWvrsOstrADQ== dependencies: - adm-zip "0.4.11" - bluebird "3.4.6" + adm-zip "0.4.16" + bluebird "3.7.2" got "5.6.0" - https-proxy-agent "2.2.1" - tar "4.4.2" + https-proxy-agent "5.0.0" + tar "6.0.2" generate-function@^2.0.0: version "2.3.1" @@ -16816,7 +16811,15 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -https-proxy-agent@2.2.1, https-proxy-agent@^2.2.1: +https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +https-proxy-agent@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== @@ -16840,14 +16843,6 @@ https-proxy-agent@^4.0.0: agent-base "5" debug "4" -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -21315,7 +21310,7 @@ minipass-pipeline@^1.2.2: dependencies: minipass "^3.0.0" -minipass@^2.2.1, minipass@^2.2.4, minipass@^2.8.6, minipass@^2.9.0: +minipass@^2.2.1, minipass@^2.8.6, minipass@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== @@ -21330,7 +21325,7 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" -minizlib@^1.1.0, minizlib@^1.2.1: +minizlib@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== @@ -29180,29 +29175,7 @@ tar@4.4.13, tar@^4: safe-buffer "^5.1.2" yallist "^3.0.3" -tar@4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.2.tgz#60685211ba46b38847b1ae7ee1a24d744a2cd462" - integrity sha512-BfkE9CciGGgDsATqkikUHrQrraBCO+ke/1f6SFAEMnxyyfN9lxC+nW1NFWMpqH865DhHIy9vQi682gk1X7friw== - dependencies: - chownr "^1.0.1" - fs-minipass "^1.2.5" - minipass "^2.2.4" - minizlib "^1.1.0" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.2" - -tar@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" - integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== - dependencies: - block-stream "*" - fstream "^1.0.12" - inherits "2" - -tar@^6.0.1, tar@^6.0.2: +tar@6.0.2, tar@^6.0.1, tar@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.2.tgz#5df17813468a6264ff14f766886c622b84ae2f39" integrity sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg== @@ -29214,6 +29187,15 @@ tar@^6.0.1, tar@^6.0.2: mkdirp "^1.0.3" yallist "^4.0.0" +tar@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + tcomb-validation@^3.3.0: version "3.4.1" resolved "https://registry.yarnpkg.com/tcomb-validation/-/tcomb-validation-3.4.1.tgz#a7696ec176ce56a081d9e019f8b732a5a8894b65" From ed34d6fe30c4692f98f8a68ab3144ff512e047e5 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 10 Aug 2020 10:46:11 -0600 Subject: [PATCH 074/106] [maps] convert vector style properties to TS (#74553) * [maps] convert vector style properties to TS * more conversionts * tslint cleanup * final tslint fixes * update snapshots for bug fix * review feedback Co-authored-by: Elastic Machine --- .../public/classes/styles/color_palettes.ts | 2 +- .../components/legend/breaked_legend.tsx | 4 +- .../vector/components/legend/category.tsx | 4 +- ...p => dynamic_color_property.test.tsx.snap} | 34 +++++- .../vector/properties/__tests__/test_util.ts | 15 --- ...est.js => dynamic_color_property.test.tsx} | 107 ++++++++++++++---- ...property.js => dynamic_color_property.tsx} | 67 ++++++----- .../properties/dynamic_size_property.test.tsx | 58 +++++++--- ..._property.js => dynamic_size_property.tsx} | 56 ++++++--- .../properties/dynamic_style_property.tsx | 2 +- ...t_property.js => dynamic_text_property.ts} | 6 +- ...perty.js => label_border_size_property.ts} | 22 +++- ...r_property.js => static_color_property.ts} | 20 ++-- ...on_property.js => static_icon_property.ts} | 7 +- ...erty.js => static_orientation_property.ts} | 9 +- ...ze_property.js => static_size_property.ts} | 20 ++-- ...e_property.js => static_style_property.ts} | 2 +- ...xt_property.js => static_text_property.ts} | 6 +- ...s_property.js => symbolize_as_property.ts} | 7 +- 19 files changed, 302 insertions(+), 146 deletions(-) rename x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/{dynamic_color_property.test.js.snap => dynamic_color_property.test.tsx.snap} (93%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{dynamic_color_property.test.js => dynamic_color_property.test.tsx} (82%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{dynamic_color_property.js => dynamic_color_property.tsx} (79%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{dynamic_size_property.js => dynamic_size_property.tsx} (72%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{dynamic_text_property.js => dynamic_text_property.ts} (80%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{label_border_size_property.js => label_border_size_property.ts} (68%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{static_color_property.js => static_color_property.ts} (63%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{static_icon_property.js => static_icon_property.ts} (67%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{static_orientation_property.js => static_orientation_property.ts} (62%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{static_size_property.js => static_size_property.ts} (65%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{static_style_property.js => static_style_property.ts} (84%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{static_text_property.js => static_text_property.ts} (69%) rename x-pack/plugins/maps/public/classes/styles/vector/properties/{symbolize_as_property.js => symbolize_as_property.ts} (74%) diff --git a/x-pack/plugins/maps/public/classes/styles/color_palettes.ts b/x-pack/plugins/maps/public/classes/styles/color_palettes.ts index e7574b4e7b3e4..51aadd98c1177 100644 --- a/x-pack/plugins/maps/public/classes/styles/color_palettes.ts +++ b/x-pack/plugins/maps/public/classes/styles/color_palettes.ts @@ -129,7 +129,7 @@ export function getColorRampCenterColor(colorPaletteId: string): string | null { // Returns an array of color stops // [ stop_input_1: number, stop_output_1: color, stop_input_n: number, stop_output_n: color ] export function getOrdinalMbColorRampStops( - colorPaletteId: string, + colorPaletteId: string | null, min: number, max: number ): Array | null { diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/breaked_legend.tsx b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/breaked_legend.tsx index 9d5bf85005ae1..8eca89e31cf7a 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/breaked_legend.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/breaked_legend.tsx @@ -14,8 +14,8 @@ const EMPTY_VALUE = ''; interface Break { color: string; - label: ReactElement | string; - symbolId: string; + label: ReactElement | string | number; + symbolId?: string; } interface Props { diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/category.tsx b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/category.tsx index 02ca4645dd8cd..4a71eb982d4d7 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/category.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/category.tsx @@ -11,11 +11,11 @@ import { VectorIcon } from './vector_icon'; interface Props { styleName: VECTOR_STYLES; - label: ReactElement | string; + label: ReactElement | string | number; color: string; isLinesOnly: boolean; isPointsOnly: boolean; - symbolId: string; + symbolId?: string; } export function Category({ styleName, label, color, isLinesOnly, isPointsOnly, symbolId }: Props) { diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_color_property.test.js.snap b/x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_color_property.test.tsx.snap similarity index 93% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_color_property.test.js.snap rename to x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_color_property.test.tsx.snap index 402eab355406b..c722e86512e52 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_color_property.test.js.snap +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_color_property.test.tsx.snap @@ -121,6 +121,17 @@ exports[`ordinal Should render custom ordinal legend with breaks 1`] = ` > + + + + + + ({ import React from 'react'; import { shallow } from 'enzyme'; +import { Feature, Point } from 'geojson'; import { DynamicColorProperty } from './dynamic_color_property'; import { COLOR_MAP_TYPE, VECTOR_STYLES } from '../../../../../common/constants'; import { mockField, MockLayer, MockStyle } from './__tests__/test_util'; +import { ColorDynamicOptions } from '../../../../../common/descriptor_types'; +import { IVectorLayer } from '../../../layers/vector_layer/vector_layer'; +import { IField } from '../../../fields/field'; -const makeProperty = (options, mockStyle, field = mockField) => { +const makeProperty = (options: ColorDynamicOptions, style?: MockStyle, field?: IField) => { return new DynamicColorProperty( options, VECTOR_STYLES.LINE_COLOR, - field, - new MockLayer(mockStyle), + field ? field : mockField, + (new MockLayer(style ? style : new MockStyle()) as unknown) as IVectorLayer, () => { - return (x) => x + '_format'; + return (value: string | number | undefined) => value + '_format'; } ); }; @@ -35,11 +39,14 @@ const defaultLegendParams = { isLinesOnly: false, }; +const fieldMetaOptions = { isEnabled: true }; + describe('ordinal', () => { test('Should render ordinal legend as bands', async () => { const colorStyle = makeProperty({ color: 'Blues', type: undefined, + fieldMetaOptions, }); const legendRow = colorStyle.renderLegendDetailRow(defaultLegendParams); @@ -59,6 +66,7 @@ describe('ordinal', () => { { color: 'Blues', type: undefined, + fieldMetaOptions, }, new MockStyle({ min: 100, max: 100 }) ); @@ -89,6 +97,7 @@ describe('ordinal', () => { color: '#00FF00', }, ], + fieldMetaOptions, }); const legendRow = colorStyle.renderLegendDetailRow(defaultLegendParams); @@ -110,6 +119,7 @@ describe('categorical', () => { type: COLOR_MAP_TYPE.CATEGORICAL, useCustomColorPalette: false, colorCategory: 'palette_0', + fieldMetaOptions, }); const legendRow = colorStyle.renderLegendDetailRow(defaultLegendParams); @@ -130,7 +140,7 @@ describe('categorical', () => { useCustomColorPalette: true, customColorPalette: [ { - stop: null, //should include the default stop + stop: null, // should include the default stop color: '#FFFF00', }, { @@ -142,6 +152,7 @@ describe('categorical', () => { color: '#00FF00', }, ], + fieldMetaOptions, }); const legendRow = colorStyle.renderLegendDetailRow(defaultLegendParams); @@ -152,14 +163,18 @@ describe('categorical', () => { }); }); -function makeFeatures(foobarPropValues) { - return foobarPropValues.map((value) => { +function makeFeatures(foobarPropValues: string[]) { + return foobarPropValues.map((value: string) => { return { type: 'Feature', + geometry: { + type: 'Point', + coordinates: [-10, 0], + } as Point, properties: { foobar: value, }, - }; + } as Feature; }); } @@ -167,6 +182,7 @@ test('Should pluck the categorical style-meta', async () => { const colorStyle = makeProperty({ type: COLOR_MAP_TYPE.CATEGORICAL, colorCategory: 'palette_0', + fieldMetaOptions, }); const features = makeFeatures(['CN', 'CN', 'US', 'CN', 'US', 'IN']); @@ -185,6 +201,7 @@ test('Should pluck the categorical style-meta from fieldmeta', async () => { const colorStyle = makeProperty({ type: COLOR_MAP_TYPE.CATEGORICAL, colorCategory: 'palette_0', + fieldMetaOptions, }); const meta = colorStyle._pluckCategoricalStyleMetaFromFieldMetaData({ @@ -210,25 +227,27 @@ test('Should pluck the categorical style-meta from fieldmeta', async () => { }); describe('supportsFieldMeta', () => { - test('should support it when field does for ordinals', () => { + test('should support fieldMeta when ordinal field supports fieldMeta', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.ORDINAL, + fieldMetaOptions, }; const styleProp = makeProperty(dynamicStyleOptions); expect(styleProp.supportsFieldMeta()).toEqual(true); }); - test('should support it when field does for categories', () => { + test('should support fieldMeta when categorical field supports fieldMeta', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.CATEGORICAL, + fieldMetaOptions, }; const styleProp = makeProperty(dynamicStyleOptions); expect(styleProp.supportsFieldMeta()).toEqual(true); }); - test('should not support it when field does not', () => { + test('should not support fieldMeta when field does not support fieldMeta', () => { const field = Object.create(mockField); field.supportsFieldMeta = function () { return false; @@ -236,37 +255,50 @@ describe('supportsFieldMeta', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.ORDINAL, + fieldMetaOptions, }; const styleProp = makeProperty(dynamicStyleOptions, undefined, field); expect(styleProp.supportsFieldMeta()).toEqual(false); }); - test('should not support it when field config not complete', () => { + test('should not support fieldMeta when field is not provided', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.ORDINAL, + fieldMetaOptions, }; - const styleProp = makeProperty(dynamicStyleOptions, undefined, null); + + const styleProp = new DynamicColorProperty( + dynamicStyleOptions, + VECTOR_STYLES.LINE_COLOR, + null, + (new MockLayer(new MockStyle()) as unknown) as IVectorLayer, + () => { + return (value: string | number | undefined) => value + '_format'; + } + ); expect(styleProp.supportsFieldMeta()).toEqual(false); }); - test('should not support it when using custom ramp for ordinals', () => { + test('should not support fieldMeta when using custom ramp for ordinal field', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.ORDINAL, useCustomColorRamp: true, customColorRamp: [], + fieldMetaOptions, }; const styleProp = makeProperty(dynamicStyleOptions); expect(styleProp.supportsFieldMeta()).toEqual(false); }); - test('should not support it when using custom palette for categories', () => { + test('should not support fieldMeta when using custom palette for categorical field', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.CATEGORICAL, useCustomColorPalette: true, customColorPalette: [], + fieldMetaOptions, }; const styleProp = makeProperty(dynamicStyleOptions); @@ -279,6 +311,7 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { test('should return null when field is not provided', async () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.ORDINAL, + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toBeNull(); @@ -288,7 +321,9 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.ORDINAL, field: {}, + fieldMetaOptions, }; + // @ts-expect-error - test is verifing behavior when field is invalid. const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toBeNull(); }); @@ -297,6 +332,7 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { test('should return null when color ramp is not provided', async () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.ORDINAL, + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toBeNull(); @@ -305,6 +341,7 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.ORDINAL, color: 'Blues', + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toEqual([ @@ -343,19 +380,11 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { }); describe('custom color ramp', () => { - const dynamicStyleOptions = { - type: COLOR_MAP_TYPE.ORDINAL, - useCustomColorRamp: true, - customColorRamp: [ - { stop: 10, color: '#f7faff' }, - { stop: 100, color: '#072f6b' }, - ], - }; - test('should return null when customColorRamp is not provided', async () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.ORDINAL, useCustomColorRamp: true, + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toBeNull(); @@ -366,12 +395,22 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { type: COLOR_MAP_TYPE.ORDINAL, useCustomColorRamp: true, customColorRamp: [], + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toBeNull(); }); test('should use `feature-state` by default', async () => { + const dynamicStyleOptions = { + type: COLOR_MAP_TYPE.ORDINAL, + useCustomColorRamp: true, + customColorRamp: [ + { stop: 10, color: '#f7faff' }, + { stop: 100, color: '#072f6b' }, + ], + fieldMetaOptions, + }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toEqual([ 'step', @@ -389,6 +428,15 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { field.canReadFromGeoJson = function () { return false; }; + const dynamicStyleOptions = { + type: COLOR_MAP_TYPE.ORDINAL, + useCustomColorRamp: true, + customColorRamp: [ + { stop: 10, color: '#f7faff' }, + { stop: 100, color: '#072f6b' }, + ], + fieldMetaOptions, + }; const colorProperty = makeProperty(dynamicStyleOptions, undefined, field); expect(colorProperty._getMbColor()).toEqual([ 'step', @@ -407,6 +455,7 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { test('should return null when field is not provided', async () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.CATEGORICAL, + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toBeNull(); @@ -416,7 +465,9 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.CATEGORICAL, field: {}, + fieldMetaOptions, }; + // @ts-expect-error - test is verifing behavior when field is invalid. const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toBeNull(); }); @@ -425,6 +476,7 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { test('should return null when color palette is not provided', async () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.CATEGORICAL, + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toBeNull(); @@ -434,6 +486,7 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.CATEGORICAL, colorCategory: 'palette_0', + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toEqual([ @@ -453,6 +506,7 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { const dynamicStyleOptions = { type: COLOR_MAP_TYPE.CATEGORICAL, useCustomColorPalette: true, + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toBeNull(); @@ -463,6 +517,7 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { type: COLOR_MAP_TYPE.CATEGORICAL, useCustomColorPalette: true, customColorPalette: [], + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toBeNull(); @@ -476,6 +531,7 @@ describe('get mapbox color expression (via internal _getMbColor)', () => { { stop: null, color: '#f7faff' }, { stop: 'MX', color: '#072f6b' }, ], + fieldMetaOptions, }; const colorProperty = makeProperty(dynamicStyleOptions); expect(colorProperty._getMbColor()).toEqual([ @@ -494,6 +550,7 @@ test('isCategorical should return true when type is categorical', async () => { const categoricalColorStyle = makeProperty({ type: COLOR_MAP_TYPE.CATEGORICAL, colorCategory: 'palette_0', + fieldMetaOptions, }); expect(categoricalColorStyle.isOrdinal()).toEqual(false); @@ -504,6 +561,7 @@ test('isOrdinal should return true when type is ordinal', async () => { const ordinalColorStyle = makeProperty({ type: undefined, color: 'Blues', + fieldMetaOptions, }); expect(ordinalColorStyle.isOrdinal()).toEqual(true); @@ -514,6 +572,7 @@ test('Should read out ordinal type correctly', async () => { const ordinalColorStyle2 = makeProperty({ type: COLOR_MAP_TYPE.ORDINAL, colorCategory: 'palette_0', + fieldMetaOptions, }); expect(ordinalColorStyle2.isOrdinal()).toEqual(true); diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.tsx similarity index 79% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.tsx index e643abcaf8d54..faecf51d4ced5 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.tsx @@ -4,69 +4,73 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Map as MbMap } from 'mapbox-gl'; +import React from 'react'; +import { EuiTextColor } from '@elastic/eui'; import { DynamicStyleProperty } from './dynamic_style_property'; import { makeMbClampedNumberExpression, dynamicRound } from '../style_util'; import { getOrdinalMbColorRampStops, getColorPalette } from '../../color_palettes'; -import React from 'react'; import { COLOR_MAP_TYPE } from '../../../../../common/constants'; import { isCategoricalStopsInvalid, getOtherCategoryLabel, + // @ts-expect-error } from '../components/color/color_stops_utils'; import { BreakedLegend } from '../components/legend/breaked_legend'; -import { EuiTextColor } from '@elastic/eui'; +import { ColorDynamicOptions, OrdinalColorStop } from '../../../../../common/descriptor_types'; +import { LegendProps } from './style_property'; const EMPTY_STOPS = { stops: [], defaultColor: null }; const RGBA_0000 = 'rgba(0,0,0,0)'; -export class DynamicColorProperty extends DynamicStyleProperty { - syncCircleColorWithMb(mbLayerId, mbMap, alpha) { +export class DynamicColorProperty extends DynamicStyleProperty { + syncCircleColorWithMb(mbLayerId: string, mbMap: MbMap, alpha: number) { const color = this._getMbColor(); mbMap.setPaintProperty(mbLayerId, 'circle-color', color); mbMap.setPaintProperty(mbLayerId, 'circle-opacity', alpha); } - syncIconColorWithMb(mbLayerId, mbMap) { + syncIconColorWithMb(mbLayerId: string, mbMap: MbMap) { const color = this._getMbColor(); mbMap.setPaintProperty(mbLayerId, 'icon-color', color); } - syncHaloBorderColorWithMb(mbLayerId, mbMap) { + syncHaloBorderColorWithMb(mbLayerId: string, mbMap: MbMap) { const color = this._getMbColor(); mbMap.setPaintProperty(mbLayerId, 'icon-halo-color', color); } - syncCircleStrokeWithMb(pointLayerId, mbMap, alpha) { + syncCircleStrokeWithMb(pointLayerId: string, mbMap: MbMap, alpha: number) { const color = this._getMbColor(); mbMap.setPaintProperty(pointLayerId, 'circle-stroke-color', color); mbMap.setPaintProperty(pointLayerId, 'circle-stroke-opacity', alpha); } - syncFillColorWithMb(mbLayerId, mbMap, alpha) { + syncFillColorWithMb(mbLayerId: string, mbMap: MbMap, alpha: number) { const color = this._getMbColor(); mbMap.setPaintProperty(mbLayerId, 'fill-color', color); mbMap.setPaintProperty(mbLayerId, 'fill-opacity', alpha); } - syncLineColorWithMb(mbLayerId, mbMap, alpha) { + syncLineColorWithMb(mbLayerId: string, mbMap: MbMap, alpha: number) { const color = this._getMbColor(); mbMap.setPaintProperty(mbLayerId, 'line-color', color); mbMap.setPaintProperty(mbLayerId, 'line-opacity', alpha); } - syncLabelColorWithMb(mbLayerId, mbMap, alpha) { + syncLabelColorWithMb(mbLayerId: string, mbMap: MbMap, alpha: number) { const color = this._getMbColor(); mbMap.setPaintProperty(mbLayerId, 'text-color', color); mbMap.setPaintProperty(mbLayerId, 'text-opacity', alpha); } - syncLabelBorderColorWithMb(mbLayerId, mbMap) { + syncLabelBorderColorWithMb(mbLayerId: string, mbMap: MbMap) { const color = this._getMbColor(); mbMap.setPaintProperty(mbLayerId, 'text-halo-color', color); } supportsFieldMeta() { - if (!this.isComplete() || !this._field.supportsFieldMeta()) { + if (!this.isComplete() || !this._field || !this._field.supportsFieldMeta()) { return false; } @@ -87,12 +91,16 @@ export class DynamicColorProperty extends DynamicStyleProperty { } getNumberOfCategories() { + if (!this._options.colorCategory) { + return 0; + } + const colors = getColorPalette(this._options.colorCategory); return colors ? colors.length : 0; } _getMbColor() { - if (!this._field || !this._field.getName()) { + if (!this.getFieldName()) { return null; } @@ -102,17 +110,20 @@ export class DynamicColorProperty extends DynamicStyleProperty { } _getOrdinalColorMbExpression() { - const targetName = this._field.getName(); + const targetName = this.getFieldName(); if (this._options.useCustomColorRamp) { if (!this._options.customColorRamp || !this._options.customColorRamp.length) { // custom color ramp config is not complete return null; } - const colorStops = this._options.customColorRamp.reduce((accumulatedStops, nextStop) => { - return [...accumulatedStops, nextStop.stop, nextStop.color]; - }, []); - const firstStopValue = colorStops[0]; + const colorStops: Array = this._options.customColorRamp.reduce( + (accumulatedStops: Array, nextStop: OrdinalColorStop) => { + return [...accumulatedStops, nextStop.stop, nextStop.color]; + }, + [] + ); + const firstStopValue = colorStops[0] as number; const lessThanFirstStopValue = firstStopValue - 1; return [ 'step', @@ -127,7 +138,7 @@ export class DynamicColorProperty extends DynamicStyleProperty { } const colorStops = getOrdinalMbColorRampStops( - this._options.color, + this._options.color ? this._options.color : null, rangeFieldMeta.min, rangeFieldMeta.max ); @@ -179,7 +190,9 @@ export class DynamicColorProperty extends DynamicStyleProperty { return EMPTY_STOPS; } - const colors = getColorPalette(this._options.colorCategory); + const colors = this._options.colorCategory + ? getColorPalette(this._options.colorCategory) + : null; if (!colors) { return EMPTY_STOPS; } @@ -209,7 +222,7 @@ export class DynamicColorProperty extends DynamicStyleProperty { const { stops, defaultColor } = this._getColorPaletteStops(); if (stops.length < 1) { - //occurs when no data + // occurs when no data return null; } @@ -225,8 +238,8 @@ export class DynamicColorProperty extends DynamicStyleProperty { mbStops.push(stop.color); } - mbStops.push(defaultColor); //last color is default color - return ['match', ['to-string', ['get', this._field.getName()]], ...mbStops]; + mbStops.push(defaultColor); // last color is default color + return ['match', ['to-string', ['get', this.getFieldName()]], ...mbStops]; } _getColorRampStops() { @@ -246,7 +259,7 @@ export class DynamicColorProperty extends DynamicStyleProperty { const colors = getColorPalette(this._options.color); if (rangeFieldMeta.delta === 0) { - //map to last color. + // map to last color. return [ { color: colors[colors.length - 1], @@ -277,11 +290,11 @@ export class DynamicColorProperty extends DynamicStyleProperty { } } - renderLegendDetailRow({ isPointsOnly, isLinesOnly, symbolId }) { + renderLegendDetailRow({ isPointsOnly, isLinesOnly, symbolId }: LegendProps) { const { stops, defaultColor } = this._getColorStops(); const breaks = []; - stops.forEach(({ stop, color }) => { - if (stop) { + stops.forEach(({ stop, color }: { stop: string | number | null; color: string }) => { + if (stop !== null) { breaks.push({ color, symbolId, diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.test.tsx b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.test.tsx index c60547f3606c5..db44ae0da562d 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.test.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.test.tsx @@ -18,31 +18,52 @@ import { shallow } from 'enzyme'; import { DynamicSizeProperty } from './dynamic_size_property'; import { VECTOR_STYLES } from '../../../../../common/constants'; import { IField } from '../../../fields/field'; -import { MockMbMap } from './__tests__/test_util'; - +import { Map as MbMap } from 'mapbox-gl'; +import { SizeDynamicOptions } from '../../../../../common/descriptor_types'; import { mockField, MockLayer, MockStyle } from './__tests__/test_util'; +import { IVectorLayer } from '../../../layers/vector_layer/vector_layer'; + +export class MockMbMap { + _paintPropertyCalls: unknown[]; + + constructor() { + this._paintPropertyCalls = []; + } + setPaintProperty(...args: unknown[]) { + this._paintPropertyCalls.push([...args]); + } -const makeProperty = (options: object, mockStyle: MockStyle, field: IField = mockField) => { + getPaintPropertyCalls(): unknown[] { + return this._paintPropertyCalls; + } +} + +const makeProperty = ( + options: SizeDynamicOptions, + mockStyle: MockStyle, + field: IField = mockField +) => { return new DynamicSizeProperty( options, VECTOR_STYLES.ICON_SIZE, field, - new MockLayer(mockStyle), + (new MockLayer(mockStyle) as unknown) as IVectorLayer, () => { - return (x: string) => x + '_format'; - } + return (value: string | number | undefined) => value + '_format'; + }, + false ); }; -const defaultLegendParams = { - isPointsOnly: true, - isLinesOnly: false, -}; +const fieldMetaOptions = { isEnabled: true }; describe('renderLegendDetailRow', () => { test('Should render as range', async () => { - const sizeProp = makeProperty({}, new MockStyle({ min: 0, max: 100 })); - const legendRow = sizeProp.renderLegendDetailRow(defaultLegendParams); + const sizeProp = makeProperty( + { minSize: 0, maxSize: 10, fieldMetaOptions }, + new MockStyle({ min: 0, max: 100 }) + ); + const legendRow = sizeProp.renderLegendDetailRow(); const component = shallow(legendRow); // Ensure all promises resolve @@ -55,11 +76,15 @@ describe('renderLegendDetailRow', () => { describe('syncSize', () => { test('Should sync with circle-radius prop', async () => { - const sizeProp = makeProperty({ minSize: 8, maxSize: 32 }, new MockStyle({ min: 0, max: 100 })); - const mockMbMap = new MockMbMap(); + const sizeProp = makeProperty( + { minSize: 8, maxSize: 32, fieldMetaOptions }, + new MockStyle({ min: 0, max: 100 }) + ); + const mockMbMap = (new MockMbMap() as unknown) as MbMap; sizeProp.syncCircleRadiusWithMb('foobar', mockMbMap); + // @ts-expect-error expect(mockMbMap.getPaintPropertyCalls()).toEqual([ [ 'foobar', @@ -88,13 +113,14 @@ describe('syncSize', () => { test('Should truncate interpolate expression to max when no delta', async () => { const sizeProp = makeProperty( - { minSize: 8, maxSize: 32 }, + { minSize: 8, maxSize: 32, fieldMetaOptions }, new MockStyle({ min: 100, max: 100 }) ); - const mockMbMap = new MockMbMap(); + const mockMbMap = (new MockMbMap() as unknown) as MbMap; sizeProp.syncCircleRadiusWithMb('foobar', mockMbMap); + // @ts-expect-error expect(mockMbMap.getPaintPropertyCalls()).toEqual([ [ 'foobar', diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.tsx similarity index 72% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.tsx index 83bd4b70ba5c3..35c830f3cb5e3 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.tsx @@ -4,20 +4,34 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DynamicStyleProperty } from './dynamic_style_property'; +import _ from 'lodash'; +import React from 'react'; +import { Map as MbMap } from 'mapbox-gl'; +import { DynamicStyleProperty, FieldFormatter } from './dynamic_style_property'; import { OrdinalLegend } from '../components/legend/ordinal_legend'; import { makeMbClampedNumberExpression } from '../style_util'; import { HALF_LARGE_MAKI_ICON_SIZE, LARGE_MAKI_ICON_SIZE, SMALL_MAKI_ICON_SIZE, + // @ts-expect-error } from '../symbol_utils'; import { MB_LOOKUP_FUNCTION, VECTOR_STYLES } from '../../../../../common/constants'; -import _ from 'lodash'; -import React from 'react'; - -export class DynamicSizeProperty extends DynamicStyleProperty { - constructor(options, styleName, field, vectorLayer, getFieldFormatter, isSymbolizedAsIcon) { +import { SizeDynamicOptions } from '../../../../../common/descriptor_types'; +import { IField } from '../../../fields/field'; +import { IVectorLayer } from '../../../layers/vector_layer/vector_layer'; + +export class DynamicSizeProperty extends DynamicStyleProperty { + private readonly _isSymbolizedAsIcon: boolean; + + constructor( + options: SizeDynamicOptions, + styleName: VECTOR_STYLES, + field: IField | null, + vectorLayer: IVectorLayer, + getFieldFormatter: (fieldName: string) => null | FieldFormatter, + isSymbolizedAsIcon: boolean + ) { super(options, styleName, field, vectorLayer, getFieldFormatter); this._isSymbolizedAsIcon = isSymbolizedAsIcon; } @@ -36,7 +50,7 @@ export class DynamicSizeProperty extends DynamicStyleProperty { return super.supportsMbFeatureState(); } - syncHaloWidthWithMb(mbLayerId, mbMap) { + syncHaloWidthWithMb(mbLayerId: string, mbMap: MbMap) { const haloWidth = this.getMbSizeExpression(); mbMap.setPaintProperty(mbLayerId, 'icon-halo-width', haloWidth); } @@ -47,9 +61,9 @@ export class DynamicSizeProperty extends DynamicStyleProperty { : SMALL_MAKI_ICON_SIZE; } - syncIconSizeWithMb(symbolLayerId, mbMap) { + syncIconSizeWithMb(symbolLayerId: string, mbMap: MbMap) { const rangeFieldMeta = this.getRangeFieldMeta(); - if (this._isSizeDynamicConfigComplete(this._options) && rangeFieldMeta) { + if (this._isSizeDynamicConfigComplete() && rangeFieldMeta) { const halfIconPixels = this.getIconPixelSize() / 2; const targetName = this.getFieldName(); // Using property state instead of feature-state because layout properties do not support feature-state @@ -73,29 +87,29 @@ export class DynamicSizeProperty extends DynamicStyleProperty { } } - syncCircleStrokeWidthWithMb(mbLayerId, mbMap) { + syncCircleStrokeWidthWithMb(mbLayerId: string, mbMap: MbMap) { const lineWidth = this.getMbSizeExpression(); mbMap.setPaintProperty(mbLayerId, 'circle-stroke-width', lineWidth); } - syncCircleRadiusWithMb(mbLayerId, mbMap) { + syncCircleRadiusWithMb(mbLayerId: string, mbMap: MbMap) { const circleRadius = this.getMbSizeExpression(); mbMap.setPaintProperty(mbLayerId, 'circle-radius', circleRadius); } - syncLineWidthWithMb(mbLayerId, mbMap) { + syncLineWidthWithMb(mbLayerId: string, mbMap: MbMap) { const lineWidth = this.getMbSizeExpression(); mbMap.setPaintProperty(mbLayerId, 'line-width', lineWidth); } - syncLabelSizeWithMb(mbLayerId, mbMap) { + syncLabelSizeWithMb(mbLayerId: string, mbMap: MbMap) { const lineWidth = this.getMbSizeExpression(); mbMap.setLayoutProperty(mbLayerId, 'text-size', lineWidth); } getMbSizeExpression() { const rangeFieldMeta = this.getRangeFieldMeta(); - if (!this._isSizeDynamicConfigComplete(this._options) || !rangeFieldMeta) { + if (!this._isSizeDynamicConfigComplete() || !rangeFieldMeta) { return null; } @@ -108,7 +122,19 @@ export class DynamicSizeProperty extends DynamicStyleProperty { }); } - _getMbDataDrivenSize({ targetName, minSize, maxSize, minValue, maxValue }) { + _getMbDataDrivenSize({ + targetName, + minSize, + maxSize, + minValue, + maxValue, + }: { + targetName: string; + minSize: number; + maxSize: number; + minValue: number; + maxValue: number; + }) { const stops = minValue === maxValue ? [maxValue, maxSize] : [minValue, minSize, maxValue, maxSize]; return [ diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx index 39ceb580e92b9..47659e055936e 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx @@ -47,7 +47,7 @@ export interface IDynamicStyleProperty extends IStyleProperty { getValueSuggestions(query: string): Promise; } -type FieldFormatter = (value: string | number | undefined) => string | number; +export type FieldFormatter = (value: string | number | undefined) => string | number; export class DynamicStyleProperty extends AbstractStyleProperty implements IDynamicStyleProperty { diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.ts similarity index 80% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.ts index a7a3130875a95..d55a6e1cfb444 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.ts @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Map as MbMap } from 'mapbox-gl'; import { DynamicStyleProperty } from './dynamic_style_property'; import { getComputedFieldName } from '../style_util'; +import { LabelDynamicOptions } from '../../../../../common/descriptor_types'; -export class DynamicTextProperty extends DynamicStyleProperty { - syncTextFieldWithMb(mbLayerId, mbMap) { +export class DynamicTextProperty extends DynamicStyleProperty { + syncTextFieldWithMb(mbLayerId: string, mbMap: MbMap) { if (this._field && this._field.isValid()) { // Fields that support auto-domain are normalized with a field-formatter and stored into a computed-field // Otherwise, the raw value is just carried over and no computed field is created. diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/label_border_size_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/label_border_size_property.ts similarity index 68% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/label_border_size_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/label_border_size_property.ts index 3016b15d0a05c..bda7a4584370f 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/label_border_size_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/label_border_size_property.ts @@ -5,15 +5,20 @@ */ import _ from 'lodash'; +import { Map as MbMap } from 'mapbox-gl'; import { AbstractStyleProperty } from './style_property'; import { DEFAULT_LABEL_SIZE } from '../vector_style_defaults'; import { LABEL_BORDER_SIZES } from '../../../../../common/constants'; +import { LabelBorderSizeOptions } from '../../../../../common/descriptor_types'; +import { VECTOR_STYLES } from '../../../../../common/constants'; +import { StaticSizeProperty } from './static_size_property'; +import { DynamicSizeProperty } from './dynamic_size_property'; const SMALL_SIZE = 1 / 16; const MEDIUM_SIZE = 1 / 8; const LARGE_SIZE = 1 / 5; // halo of 1/4 is just a square. Use smaller ratio to preserve contour on letters -function getWidthRatio(size) { +function getWidthRatio(size: LABEL_BORDER_SIZES) { switch (size) { case LABEL_BORDER_SIZES.LARGE: return LARGE_SIZE; @@ -24,13 +29,19 @@ function getWidthRatio(size) { } } -export class LabelBorderSizeProperty extends AbstractStyleProperty { - constructor(options, styleName, labelSizeProperty) { +export class LabelBorderSizeProperty extends AbstractStyleProperty { + private readonly _labelSizeProperty: StaticSizeProperty | DynamicSizeProperty; + + constructor( + options: LabelBorderSizeOptions, + styleName: VECTOR_STYLES, + labelSizeProperty: StaticSizeProperty | DynamicSizeProperty + ) { super(options, styleName); this._labelSizeProperty = labelSizeProperty; } - syncLabelBorderSizeWithMb(mbLayerId, mbMap) { + syncLabelBorderSizeWithMb(mbLayerId: string, mbMap: MbMap) { if (this.getOptions().size === LABEL_BORDER_SIZES.NONE) { mbMap.setPaintProperty(mbLayerId, 'text-halo-width', 0); return; @@ -39,7 +50,8 @@ export class LabelBorderSizeProperty extends AbstractStyleProperty { const widthRatio = getWidthRatio(this.getOptions().size); if (this._labelSizeProperty.isDynamic() && this._labelSizeProperty.isComplete()) { - const labelSizeExpression = this._labelSizeProperty.getMbSizeExpression(); + const labelSizeExpression = (this + ._labelSizeProperty as DynamicSizeProperty).getMbSizeExpression(); if (labelSizeExpression) { mbMap.setPaintProperty(mbLayerId, 'text-halo-width', [ 'max', diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_color_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_color_property.ts similarity index 63% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/static_color_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/static_color_property.ts index ebe2a322711fc..45d25565b6f23 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_color_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_color_property.ts @@ -4,43 +4,45 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Map as MbMap } from 'mapbox-gl'; import { StaticStyleProperty } from './static_style_property'; +import { ColorStaticOptions } from '../../../../../common/descriptor_types'; -export class StaticColorProperty extends StaticStyleProperty { - syncCircleColorWithMb(mbLayerId, mbMap, alpha) { +export class StaticColorProperty extends StaticStyleProperty { + syncCircleColorWithMb(mbLayerId: string, mbMap: MbMap, alpha: number) { mbMap.setPaintProperty(mbLayerId, 'circle-color', this._options.color); mbMap.setPaintProperty(mbLayerId, 'circle-opacity', alpha); } - syncFillColorWithMb(mbLayerId, mbMap, alpha) { + syncFillColorWithMb(mbLayerId: string, mbMap: MbMap, alpha: number) { mbMap.setPaintProperty(mbLayerId, 'fill-color', this._options.color); mbMap.setPaintProperty(mbLayerId, 'fill-opacity', alpha); } - syncIconColorWithMb(mbLayerId, mbMap) { + syncIconColorWithMb(mbLayerId: string, mbMap: MbMap) { mbMap.setPaintProperty(mbLayerId, 'icon-color', this._options.color); } - syncHaloBorderColorWithMb(mbLayerId, mbMap) { + syncHaloBorderColorWithMb(mbLayerId: string, mbMap: MbMap) { mbMap.setPaintProperty(mbLayerId, 'icon-halo-color', this._options.color); } - syncLineColorWithMb(mbLayerId, mbMap, alpha) { + syncLineColorWithMb(mbLayerId: string, mbMap: MbMap, alpha: number) { mbMap.setPaintProperty(mbLayerId, 'line-color', this._options.color); mbMap.setPaintProperty(mbLayerId, 'line-opacity', alpha); } - syncCircleStrokeWithMb(mbLayerId, mbMap, alpha) { + syncCircleStrokeWithMb(mbLayerId: string, mbMap: MbMap, alpha: number) { mbMap.setPaintProperty(mbLayerId, 'circle-stroke-color', this._options.color); mbMap.setPaintProperty(mbLayerId, 'circle-stroke-opacity', alpha); } - syncLabelColorWithMb(mbLayerId, mbMap, alpha) { + syncLabelColorWithMb(mbLayerId: string, mbMap: MbMap, alpha: number) { mbMap.setPaintProperty(mbLayerId, 'text-color', this._options.color); mbMap.setPaintProperty(mbLayerId, 'text-opacity', alpha); } - syncLabelBorderColorWithMb(mbLayerId, mbMap) { + syncLabelBorderColorWithMb(mbLayerId: string, mbMap: MbMap) { mbMap.setPaintProperty(mbLayerId, 'text-halo-color', this._options.color); } } diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_icon_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_icon_property.ts similarity index 67% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/static_icon_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/static_icon_property.ts index 3b5be083dd3c9..58c569e8132d6 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_icon_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_icon_property.ts @@ -4,11 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Map as MbMap } from 'mapbox-gl'; import { StaticStyleProperty } from './static_style_property'; +// @ts-expect-error import { getMakiSymbolAnchor, getMakiIconId } from '../symbol_utils'; +import { IconStaticOptions } from '../../../../../common/descriptor_types'; -export class StaticIconProperty extends StaticStyleProperty { - syncIconWithMb(symbolLayerId, mbMap, iconPixelSize) { +export class StaticIconProperty extends StaticStyleProperty { + syncIconWithMb(symbolLayerId: string, mbMap: MbMap, iconPixelSize: number) { const symbolId = this._options.value; mbMap.setLayoutProperty(symbolLayerId, 'icon-anchor', getMakiSymbolAnchor(symbolId)); mbMap.setLayoutProperty(symbolLayerId, 'icon-image', getMakiIconId(symbolId, iconPixelSize)); diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_orientation_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_orientation_property.ts similarity index 62% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/static_orientation_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/static_orientation_property.ts index 0c8cae10d6189..388cfbd645468 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_orientation_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_orientation_property.ts @@ -4,10 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Map as MbMap } from 'mapbox-gl'; import { StaticStyleProperty } from './static_style_property'; +import { VECTOR_STYLES } from '../../../../../common/constants'; +import { OrientationStaticOptions } from '../../../../../common/descriptor_types'; -export class StaticOrientationProperty extends StaticStyleProperty { - constructor(options, styleName) { +export class StaticOrientationProperty extends StaticStyleProperty { + constructor(options: OrientationStaticOptions, styleName: VECTOR_STYLES) { if (typeof options.orientation !== 'number') { super({ orientation: 0 }, styleName); } else { @@ -15,7 +18,7 @@ export class StaticOrientationProperty extends StaticStyleProperty { } } - syncIconRotationWithMb(symbolLayerId, mbMap) { + syncIconRotationWithMb(symbolLayerId: string, mbMap: MbMap) { mbMap.setLayoutProperty(symbolLayerId, 'icon-rotate', this._options.orientation); } } diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_size_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_size_property.ts similarity index 65% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/static_size_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/static_size_property.ts index d86556c6218cf..c9ee64ca56647 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_size_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_size_property.ts @@ -4,15 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Map as MbMap } from 'mapbox-gl'; import { StaticStyleProperty } from './static_style_property'; +import { VECTOR_STYLES } from '../../../../../common/constants'; import { HALF_LARGE_MAKI_ICON_SIZE, LARGE_MAKI_ICON_SIZE, SMALL_MAKI_ICON_SIZE, + // @ts-expect-error } from '../symbol_utils'; +import { SizeStaticOptions } from '../../../../../common/descriptor_types'; -export class StaticSizeProperty extends StaticStyleProperty { - constructor(options, styleName) { +export class StaticSizeProperty extends StaticStyleProperty { + constructor(options: SizeStaticOptions, styleName: VECTOR_STYLES) { if (typeof options.size !== 'number') { super({ size: 1 }, styleName); } else { @@ -20,7 +24,7 @@ export class StaticSizeProperty extends StaticStyleProperty { } } - syncHaloWidthWithMb(mbLayerId, mbMap) { + syncHaloWidthWithMb(mbLayerId: string, mbMap: MbMap) { mbMap.setPaintProperty(mbLayerId, 'icon-halo-width', this._options.size); } @@ -30,12 +34,12 @@ export class StaticSizeProperty extends StaticStyleProperty { : SMALL_MAKI_ICON_SIZE; } - syncIconSizeWithMb(symbolLayerId, mbMap) { + syncIconSizeWithMb(symbolLayerId: string, mbMap: MbMap) { const halfIconPixels = this.getIconPixelSize() / 2; mbMap.setLayoutProperty(symbolLayerId, 'icon-size', this._options.size / halfIconPixels); } - syncCircleStrokeWidthWithMb(mbLayerId, mbMap, hasNoRadius) { + syncCircleStrokeWidthWithMb(mbLayerId: string, mbMap: MbMap, hasNoRadius: boolean) { if (hasNoRadius) { mbMap.setPaintProperty(mbLayerId, 'circle-stroke-width', 0); } else { @@ -43,15 +47,15 @@ export class StaticSizeProperty extends StaticStyleProperty { } } - syncCircleRadiusWithMb(mbLayerId, mbMap) { + syncCircleRadiusWithMb(mbLayerId: string, mbMap: MbMap) { mbMap.setPaintProperty(mbLayerId, 'circle-radius', this._options.size); } - syncLineWidthWithMb(mbLayerId, mbMap) { + syncLineWidthWithMb(mbLayerId: string, mbMap: MbMap) { mbMap.setPaintProperty(mbLayerId, 'line-width', this._options.size); } - syncLabelSizeWithMb(mbLayerId, mbMap) { + syncLabelSizeWithMb(mbLayerId: string, mbMap: MbMap) { mbMap.setLayoutProperty(mbLayerId, 'text-size', this._options.size); } } diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_style_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_style_property.ts similarity index 84% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/static_style_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/static_style_property.ts index a02aa15e28b28..ea39f4fa06a78 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_style_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_style_property.ts @@ -7,6 +7,6 @@ import { AbstractStyleProperty } from './style_property'; import { STYLE_TYPE } from '../../../../../common/constants'; -export class StaticStyleProperty extends AbstractStyleProperty { +export class StaticStyleProperty extends AbstractStyleProperty { static type = STYLE_TYPE.STATIC; } diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.ts similarity index 69% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.ts index 7a4a4672152c0..e24e7553d0b38 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.ts @@ -4,14 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Map as MbMap } from 'mapbox-gl'; import { StaticStyleProperty } from './static_style_property'; +import { LabelStaticOptions } from '../../../../../common/descriptor_types'; -export class StaticTextProperty extends StaticStyleProperty { +export class StaticTextProperty extends StaticStyleProperty { isComplete() { return this.getOptions().value.length > 0; } - syncTextFieldWithMb(mbLayerId, mbMap) { + syncTextFieldWithMb(mbLayerId: string, mbMap: MbMap) { if (this.getOptions().value.length) { mbMap.setLayoutProperty(mbLayerId, 'text-field', this.getOptions().value); } else { diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/symbolize_as_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/symbolize_as_property.ts similarity index 74% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/symbolize_as_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/symbolize_as_property.ts index 9ae1ef5054e30..8bfc06a1c7fa9 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/symbolize_as_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/symbolize_as_property.ts @@ -6,12 +6,9 @@ import { AbstractStyleProperty } from './style_property'; import { SYMBOLIZE_AS_TYPES } from '../../../../../common/constants'; +import { SymbolizeAsOptions } from '../../../../../common/descriptor_types'; -export class SymbolizeAsProperty extends AbstractStyleProperty { - constructor(options, styleName) { - super(options, styleName); - } - +export class SymbolizeAsProperty extends AbstractStyleProperty { isSymbolizedAsIcon = () => { return this.getOptions().value === SYMBOLIZE_AS_TYPES.ICON; }; From 7e55da56deee6ee4339b13ff8eda060f0802a2ef Mon Sep 17 00:00:00 2001 From: Fabien Baligand Date: Mon, 10 Aug 2020 19:24:28 +0200 Subject: [PATCH 075/106] [visualizations] Add i18n translation for 'No results found' (#74619) --- src/plugins/vis_type_vislib/public/vislib/errors.ts | 7 ++++++- .../public/components/visualization_noresults.tsx | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_type_vislib/public/vislib/errors.ts b/src/plugins/vis_type_vislib/public/vislib/errors.ts index c2965e8165759..b047d0900cd48 100644 --- a/src/plugins/vis_type_vislib/public/vislib/errors.ts +++ b/src/plugins/vis_type_vislib/public/vislib/errors.ts @@ -19,6 +19,7 @@ /* eslint-disable max-classes-per-file */ +import { i18n } from '@kbn/i18n'; import { KbnError } from '../../../kibana_utils/public'; export class VislibError extends KbnError { @@ -51,6 +52,10 @@ export class PieContainsAllZeros extends VislibError { export class NoResults extends VislibError { constructor() { - super('No results found'); + super( + i18n.translate('visTypeVislib.vislib.errors.noResultsFoundTitle', { + defaultMessage: 'No results found', + }) + ); } } diff --git a/src/plugins/visualizations/public/components/visualization_noresults.tsx b/src/plugins/visualizations/public/components/visualization_noresults.tsx index 1b45463f1d2ef..c77ef4490a4b3 100644 --- a/src/plugins/visualizations/public/components/visualization_noresults.tsx +++ b/src/plugins/visualizations/public/components/visualization_noresults.tsx @@ -18,6 +18,7 @@ */ import { EuiIcon, EuiSpacer, EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import React from 'react'; interface VisualizationNoResultsProps { @@ -37,7 +38,11 @@ export class VisualizationNoResults extends React.Component -

    No results found

    +

    + {i18n.translate('visualizations.noResultsFoundTitle', { + defaultMessage: 'No results found', + })} +

    From 697cd6412e40a69ce72080c048d557430694f11b Mon Sep 17 00:00:00 2001 From: Constance Date: Mon, 10 Aug 2020 10:37:12 -0700 Subject: [PATCH 076/106] [Enterprise Search] Update the browser/document title on plugin navigation (#74392) * Rename kibana_breadcrumbs to kibana_chrome - in anticipation of upcoming refactor where SetPageChrome now handles document title as well as Kibana breadcrumbs + cleanup exports * Add generate_title helpers - will be used by new set_chrome helper * Add setDocTitle context + behavior to set_chrome + refactor set_chrome.test.tsx: - add title tests - add SetWorkplaceSearchChrome test to increase coverage - clean up inner/outer call in favor of simpler mocks/imports - simplify isRoot tests * Update plugins to set product titles - on mount but before render * Copy feedback - change pipe separator to hyphen - to match ' - Elastic' * Add functional tests confirming that document titles updated --- test/functional/services/common/browser.ts | 8 ++ .../__mocks__/kibana_context.mock.ts | 1 + .../components/empty_states/empty_state.tsx | 4 +- .../components/empty_states/error_state.tsx | 4 +- .../components/empty_states/loading_state.tsx | 4 +- .../engine_overview/engine_overview.tsx | 4 +- .../setup_guide/setup_guide.test.tsx | 4 +- .../components/setup_guide/setup_guide.tsx | 4 +- .../public/applications/index.tsx | 2 + .../set_breadcrumbs.test.tsx | 63 -------------- .../generate_breadcrumbs.test.ts | 8 +- .../generate_breadcrumbs.ts | 0 .../kibana_chrome/generate_title.test.ts | 60 +++++++++++++ .../shared/kibana_chrome/generate_title.ts | 38 +++++++++ .../index.ts | 7 +- .../shared/kibana_chrome/set_chrome.test.tsx | 84 +++++++++++++++++++ .../set_chrome.tsx} | 15 ++-- .../components/error_state/error_state.tsx | 4 +- .../components/overview/overview.tsx | 4 +- .../setup_guide/setup_guide.test.tsx | 4 +- .../components/setup_guide/setup_guide.tsx | 4 +- .../enterprise_search/public/plugin.ts | 4 + .../app_search/engines.ts | 3 + .../app_search/setup_guide.ts | 3 + .../workplace_search/setup_guide.ts | 3 + 25 files changed, 243 insertions(+), 96 deletions(-) delete mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/set_breadcrumbs.test.tsx rename x-pack/plugins/enterprise_search/public/applications/shared/{kibana_breadcrumbs => kibana_chrome}/generate_breadcrumbs.test.ts (97%) rename x-pack/plugins/enterprise_search/public/applications/shared/{kibana_breadcrumbs => kibana_chrome}/generate_breadcrumbs.ts (100%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.ts rename x-pack/plugins/enterprise_search/public/applications/shared/{kibana_breadcrumbs => kibana_chrome}/index.ts (52%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx rename x-pack/plugins/enterprise_search/public/applications/shared/{kibana_breadcrumbs/set_breadcrumbs.tsx => kibana_chrome/set_chrome.tsx} (66%) diff --git a/test/functional/services/common/browser.ts b/test/functional/services/common/browser.ts index c38ac771e4162..b0eec5e24f635 100644 --- a/test/functional/services/common/browser.ts +++ b/test/functional/services/common/browser.ts @@ -163,6 +163,14 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { return currentWithoutTime; } + /** + * Gets the page/document title of the focused window/frame. + * https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/chrome_exports_Driver.html#getTitle + */ + public async getTitle() { + return await driver.getTitle(); + } + /** * Navigates the focused window/frame to a new URL. * https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/chrome_exports_Driver.html#get diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts index fcfa1b0a21f13..b1d7341d51a4c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts @@ -13,5 +13,6 @@ import { httpServiceMock } from 'src/core/public/mocks'; export const mockKibanaContext = { http: httpServiceMock.createSetupContract(), setBreadcrumbs: jest.fn(), + setDocTitle: jest.fn(), enterpriseSearchUrl: 'http://localhost:3002', }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/empty_state.tsx index 9bb5cd3bffdf5..d6c38629d8143 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/empty_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/empty_state.tsx @@ -9,7 +9,7 @@ import { EuiPage, EuiPageBody, EuiPageContent, EuiEmptyPrompt, EuiButton } from import { FormattedMessage } from '@kbn/i18n/react'; import { sendTelemetry } from '../../../shared/telemetry'; -import { SetAppSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; +import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { KibanaContext, IKibanaContext } from '../../../index'; import { EngineOverviewHeader } from '../engine_overview_header'; @@ -33,7 +33,7 @@ export const EmptyState: React.FC = () => { return ( - + diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/error_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/error_state.tsx index 346e70d32f7b1..3753ad5433e8f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/error_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/error_state.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui'; import { ErrorStatePrompt } from '../../../shared/error_state'; -import { SetAppSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; +import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import { EngineOverviewHeader } from '../engine_overview_header'; @@ -17,7 +17,7 @@ import './empty_states.scss'; export const ErrorState: React.FC = () => { return ( - + diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/loading_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/loading_state.tsx index 2be917c8df096..533dca7d0ab79 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/loading_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/loading_state.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiLoadingContent } from '@elastic/eui'; -import { SetAppSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; +import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { EngineOverviewHeader } from '../engine_overview_header'; import './empty_states.scss'; @@ -15,7 +15,7 @@ import './empty_states.scss'; export const LoadingState: React.FC = () => { return ( - + diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.tsx index 13d092a657d11..286c32b2a443b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.tsx @@ -16,7 +16,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { SetAppSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; +import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import { LicenseContext, ILicenseContext, hasPlatinumLicense } from '../../../shared/licensing'; import { KibanaContext, IKibanaContext } from '../../../index'; @@ -93,7 +93,7 @@ export const EngineOverview: React.FC = () => { return ( - + diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.test.tsx index 82cc344d49632..5936b8f2d4283 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { SetAppSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; +import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SetupGuide as SetupGuideLayout } from '../../../shared/setup_guide'; import { SetupGuide } from './'; @@ -16,6 +16,6 @@ describe('SetupGuide', () => { const wrapper = shallow(); expect(wrapper.find(SetupGuideLayout)).toHaveLength(1); - expect(wrapper.find(SetBreadcrumbs)).toHaveLength(1); + expect(wrapper.find(SetPageChrome)).toHaveLength(1); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx index f899423319afc..fa55289e73e0b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { APP_SEARCH_PLUGIN } from '../../../../../common/constants'; import { SetupGuide as SetupGuideLayout } from '../../../shared/setup_guide'; -import { SetAppSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; +import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import GettingStarted from '../../assets/getting_started.png'; @@ -22,7 +22,7 @@ export const SetupGuide: React.FC = () => ( standardAuthLink="https://swiftype.com/documentation/app-search/self-managed/security#standard" elasticsearchNativeAuthLink="https://swiftype.com/documentation/app-search/self-managed/security#elasticsearch-native-realm" > - diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/set_breadcrumbs.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/set_breadcrumbs.test.tsx deleted file mode 100644 index 974ca54277c51..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/set_breadcrumbs.test.tsx +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; - -import '../../__mocks__/react_router_history.mock'; -import { mountWithKibanaContext } from '../../__mocks__'; - -jest.mock('./generate_breadcrumbs', () => ({ appSearchBreadcrumbs: jest.fn() })); -import { appSearchBreadcrumbs, SetAppSearchBreadcrumbs } from './'; - -describe('SetAppSearchBreadcrumbs', () => { - const setBreadcrumbs = jest.fn(); - const builtBreadcrumbs = [] as any; - const appSearchBreadCrumbsInnerCall = jest.fn().mockReturnValue(builtBreadcrumbs); - const appSearchBreadCrumbsOuterCall = jest.fn().mockReturnValue(appSearchBreadCrumbsInnerCall); - (appSearchBreadcrumbs as jest.Mock).mockImplementation(appSearchBreadCrumbsOuterCall); - - afterEach(() => { - jest.clearAllMocks(); - }); - - const mountSetAppSearchBreadcrumbs = (props: any) => { - return mountWithKibanaContext(, { - http: {}, - enterpriseSearchUrl: 'http://localhost:3002', - setBreadcrumbs, - }); - }; - - describe('when isRoot is false', () => { - const subject = () => mountSetAppSearchBreadcrumbs({ text: 'Page 1', isRoot: false }); - - it('calls appSearchBreadcrumbs to build breadcrumbs, then registers them with Kibana', () => { - subject(); - - // calls appSearchBreadcrumbs to build breadcrumbs with the target page and current location - expect(appSearchBreadCrumbsInnerCall).toHaveBeenCalledWith([ - { text: 'Page 1', path: '/current-path' }, - ]); - - // then registers them with Kibana - expect(setBreadcrumbs).toHaveBeenCalledWith(builtBreadcrumbs); - }); - }); - - describe('when isRoot is true', () => { - const subject = () => mountSetAppSearchBreadcrumbs({ text: 'Page 1', isRoot: true }); - - it('calls appSearchBreadcrumbs to build breadcrumbs with an empty breadcrumb, then registers them with Kibana', () => { - subject(); - - // uses an empty bredcrumb - expect(appSearchBreadCrumbsInnerCall).toHaveBeenCalledWith([]); - - // then registers them with Kibana - expect(setBreadcrumbs).toHaveBeenCalledWith(builtBreadcrumbs); - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/generate_breadcrumbs.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts similarity index 97% rename from x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/generate_breadcrumbs.test.ts rename to x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts index 70aa723d62601..0f34bbb6b65bc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/generate_breadcrumbs.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts @@ -4,8 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { generateBreadcrumb } from './generate_breadcrumbs'; -import { appSearchBreadcrumbs, enterpriseSearchBreadcrumbs, workplaceSearchBreadcrumbs } from './'; +import { + generateBreadcrumb, + appSearchBreadcrumbs, + enterpriseSearchBreadcrumbs, + workplaceSearchBreadcrumbs, +} from './generate_breadcrumbs'; import { mockHistory as mockHistoryUntyped } from '../../__mocks__'; const mockHistory = mockHistoryUntyped as any; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/generate_breadcrumbs.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/generate_breadcrumbs.ts rename to x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.test.ts new file mode 100644 index 0000000000000..0c1c18b98e33e --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.test.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + generateTitle, + enterpriseSearchTitle, + appSearchTitle, + workplaceSearchTitle, +} from './generate_title'; + +describe('generateTitle', () => { + it('creates a hyphen separated string from an array of page titles', () => { + const title = generateTitle(['Curations', 'some Engine', 'App Search']); + expect(title).toEqual('Curations - some Engine - App Search'); + }); +}); + +describe('enterpriseSearchTitle', () => { + it('automatically appends the Enterprise Search product onto the pages array', () => { + const title = enterpriseSearchTitle(['Setup Guide']); + expect(title).toEqual('Setup Guide - Enterprise Search'); + }); + + it('can be mixed and matched', () => { + const title = enterpriseSearchTitle([appSearchTitle(['Some Page'])]); + expect(title).toEqual('Some Page - App Search - Enterprise Search'); + }); + + it('falls back to product name', () => { + const title = enterpriseSearchTitle(); + expect(title).toEqual('Enterprise Search'); + }); +}); + +describe('appSearchTitle', () => { + it('automatically appends the App Search product onto the pages array', () => { + const title = appSearchTitle(['Engines']); + expect(title).toEqual('Engines - App Search'); + }); + + it('falls back to product name', () => { + const title = appSearchTitle(); + expect(title).toEqual('App Search'); + }); +}); + +describe('workplaceSearchTitle', () => { + it('automatically appends the Workplace Search product onto the pages array', () => { + const title = workplaceSearchTitle(['Sources']); + expect(title).toEqual('Sources - Workplace Search'); + }); + + it('falls back to product name', () => { + const title = workplaceSearchTitle(); + expect(title).toEqual('Workplace Search'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.ts new file mode 100644 index 0000000000000..706baefc00cc2 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + ENTERPRISE_SEARCH_PLUGIN, + APP_SEARCH_PLUGIN, + WORKPLACE_SEARCH_PLUGIN, +} from '../../../../common/constants'; + +/** + * Generate a document title that generally follows our breadcrumb trails + * https://github.com/elastic/kibana/blob/master/docs/development/core/public/kibana-plugin-core-public.chromedoctitle.md + */ + +export type TTitle = string[]; + +/** + * Given an array of page titles, return a final formatted document title + * @param pages - e.g., ['Curations', 'some Engine', 'App Search'] + * @returns - e.g., 'Curations | some Engine | App Search' + */ +export const generateTitle = (pages: TTitle) => pages.join(' - '); + +/** + * Product-specific helpers + */ + +export const enterpriseSearchTitle = (page: TTitle = []) => + generateTitle([...page, ENTERPRISE_SEARCH_PLUGIN.NAME]); + +export const appSearchTitle = (page: TTitle = []) => + generateTitle([...page, APP_SEARCH_PLUGIN.NAME]); + +export const workplaceSearchTitle = (page: TTitle = []) => + generateTitle([...page, WORKPLACE_SEARCH_PLUGIN.NAME]); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts similarity index 52% rename from x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/index.ts rename to x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts index c4ef68704b7e0..4468d11ba94c9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts @@ -4,9 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { - enterpriseSearchBreadcrumbs, - appSearchBreadcrumbs, - workplaceSearchBreadcrumbs, -} from './generate_breadcrumbs'; -export { SetAppSearchBreadcrumbs, SetWorkplaceSearchBreadcrumbs } from './set_breadcrumbs'; +export { SetAppSearchChrome, SetWorkplaceSearchChrome } from './set_chrome'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx new file mode 100644 index 0000000000000..aba0b250e56c0 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import '../../__mocks__/react_router_history.mock'; +import { mockKibanaContext, mountWithKibanaContext } from '../../__mocks__'; + +jest.mock('./generate_breadcrumbs', () => ({ + appSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), + workplaceSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), +})); +import { appSearchBreadcrumbs, workplaceSearchBreadcrumbs } from './generate_breadcrumbs'; + +jest.mock('./generate_title', () => ({ + appSearchTitle: jest.fn((title: any) => title), + workplaceSearchTitle: jest.fn((title: any) => title), +})); +import { appSearchTitle, workplaceSearchTitle } from './generate_title'; + +import { SetAppSearchChrome, SetWorkplaceSearchChrome } from './'; + +describe('SetAppSearchChrome', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + afterEach(() => { + expect(appSearchBreadcrumbs).toHaveBeenCalled(); + expect(appSearchTitle).toHaveBeenCalled(); + }); + + it('sets breadcrumbs and document title', () => { + mountWithKibanaContext(); + + expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalledWith([ + { + text: 'Engines', + path: '/current-path', + }, + ]); + expect(mockKibanaContext.setDocTitle).toHaveBeenCalledWith(['Engines']); + }); + + it('sets empty breadcrumbs and document title when isRoot is true', () => { + mountWithKibanaContext(); + + expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalledWith([]); + expect(mockKibanaContext.setDocTitle).toHaveBeenCalledWith([]); + }); +}); + +describe('SetWorkplaceSearchChrome', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + afterEach(() => { + expect(workplaceSearchBreadcrumbs).toHaveBeenCalled(); + expect(workplaceSearchTitle).toHaveBeenCalled(); + }); + + it('sets breadcrumbs and document title', () => { + mountWithKibanaContext(); + + expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalledWith([ + { + text: 'Sources', + path: '/current-path', + }, + ]); + expect(mockKibanaContext.setDocTitle).toHaveBeenCalledWith(['Sources']); + }); + + it('sets empty breadcrumbs and document title when isRoot is true', () => { + mountWithKibanaContext(); + + expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalledWith([]); + expect(mockKibanaContext.setDocTitle).toHaveBeenCalledWith([]); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/set_breadcrumbs.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx similarity index 66% rename from x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/set_breadcrumbs.tsx rename to x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx index e54f1a12b73cb..59e83a2cb13c2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_breadcrumbs/set_breadcrumbs.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx @@ -13,9 +13,10 @@ import { workplaceSearchBreadcrumbs, TBreadcrumbs, } from './generate_breadcrumbs'; +import { appSearchTitle, workplaceSearchTitle, TTitle } from './generate_title'; /** - * Small on-mount helper for setting Kibana's chrome breadcrumbs on any App Search view + * Helpers for setting Kibana chrome (breadcrumbs, doc titles) on React view mount * @see https://github.com/elastic/kibana/blob/master/src/core/public/chrome/chrome_service.tsx */ @@ -31,27 +32,31 @@ interface IRootBreadcrumbsProps { } type TBreadcrumbsProps = IBreadcrumbsProps | IRootBreadcrumbsProps; -export const SetAppSearchBreadcrumbs: React.FC = ({ text, isRoot }) => { +export const SetAppSearchChrome: React.FC = ({ text, isRoot }) => { const history = useHistory(); - const { setBreadcrumbs } = useContext(KibanaContext) as IKibanaContext; + const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; const crumb = isRoot ? [] : [{ text, path: history.location.pathname }]; + const title = isRoot ? [] : [text]; useEffect(() => { setBreadcrumbs(appSearchBreadcrumbs(history)(crumb as TBreadcrumbs | [])); + setDocTitle(appSearchTitle(title as TTitle | [])); }, []); return null; }; -export const SetWorkplaceSearchBreadcrumbs: React.FC = ({ text, isRoot }) => { +export const SetWorkplaceSearchChrome: React.FC = ({ text, isRoot }) => { const history = useHistory(); - const { setBreadcrumbs } = useContext(KibanaContext) as IKibanaContext; + const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; const crumb = isRoot ? [] : [{ text, path: history.location.pathname }]; + const title = isRoot ? [] : [text]; useEffect(() => { setBreadcrumbs(workplaceSearchBreadcrumbs(history)(crumb as TBreadcrumbs | [])); + setDocTitle(workplaceSearchTitle(title as TTitle | [])); }, []); return null; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx index a1bc17e05dc05..e1114986d2244 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx @@ -9,14 +9,14 @@ import { EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui'; import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; import { ErrorStatePrompt } from '../../../shared/error_state'; -import { SetWorkplaceSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; +import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import { ViewContentHeader } from '../shared/view_content_header'; export const ErrorState: React.FC = () => { return ( - + diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx index b75a2841dad9b..2c3e78b404d42 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx @@ -9,7 +9,7 @@ import { EuiPage, EuiPageBody, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useActions, useValues } from 'kea'; -import { SetWorkplaceSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; +import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import { KibanaContext, IKibanaContext } from '../../../index'; @@ -72,7 +72,7 @@ export const Overview: React.FC = () => { return ( - + diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.test.tsx index b87c35d5a5942..73cf4b419f944 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { SetWorkplaceSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; +import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SetupGuide as SetupGuideLayout } from '../../../shared/setup_guide'; import { SetupGuide } from './'; @@ -16,6 +16,6 @@ describe('SetupGuide', () => { const wrapper = shallow(); expect(wrapper.find(SetupGuideLayout)).toHaveLength(1); - expect(wrapper.find(SetBreadcrumbs)).toHaveLength(1); + expect(wrapper.find(SetPageChrome)).toHaveLength(1); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx index e96d114c67c5d..f9b00bdf29642 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; import { SetupGuide as SetupGuideLayout } from '../../../shared/setup_guide'; -import { SetWorkplaceSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs'; +import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import GettingStarted from '../../assets/getting_started.png'; @@ -26,7 +26,7 @@ export const SetupGuide: React.FC = () => { standardAuthLink="https://www.elastic.co/guide/en/workplace-search/current/workplace-search-security.html#standard" elasticsearchNativeAuthLink="https://www.elastic.co/guide/en/workplace-search/current/workplace-search-security.html#elasticsearch-native-realm" > - { const [coreStart] = await core.getStartServices(); + const { chrome } = coreStart; + chrome.docTitle.change(APP_SEARCH_PLUGIN.NAME); await this.setPublicUrl(config, coreStart.http); @@ -68,6 +70,8 @@ export class EnterpriseSearchPlugin implements Plugin { category: DEFAULT_APP_CATEGORIES.enterpriseSearch, mount: async (params: AppMountParameters) => { const [coreStart] = await core.getStartServices(); + const { chrome } = coreStart; + chrome.docTitle.change(WORKPLACE_SEARCH_PLUGIN.NAME); const { renderApp } = await import('./applications'); const { WorkplaceSearch } = await import('./applications/workplace_search'); diff --git a/x-pack/test/functional_enterprise_search/apps/enterprise_search/with_host_configured/app_search/engines.ts b/x-pack/test/functional_enterprise_search/apps/enterprise_search/with_host_configured/app_search/engines.ts index 1742ed443984b..85ae4d77b828f 100644 --- a/x-pack/test/functional_enterprise_search/apps/enterprise_search/with_host_configured/app_search/engines.ts +++ b/x-pack/test/functional_enterprise_search/apps/enterprise_search/with_host_configured/app_search/engines.ts @@ -52,6 +52,9 @@ export default function enterpriseSearchSetupEnginesTests({ await retry.try(async function () { const currentUrl = await browser.getCurrentUrl(); expect(currentUrl).to.contain('/app_search'); + + const documentTitle = await browser.getTitle(); + expect(documentTitle).to.contain('App Search - Elastic'); }); }); diff --git a/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/app_search/setup_guide.ts b/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/app_search/setup_guide.ts index 76a47cc4a7e10..86c35db504eab 100644 --- a/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/app_search/setup_guide.ts +++ b/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/app_search/setup_guide.ts @@ -29,6 +29,9 @@ export default function enterpriseSearchSetupGuideTests({ await retry.try(async function () { const currentUrl = await browser.getCurrentUrl(); expect(currentUrl).to.contain('/app_search/setup_guide'); + + const documentTitle = await browser.getTitle(); + expect(documentTitle).to.contain('Setup Guide - App Search - Elastic'); }); }); }); diff --git a/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/workplace_search/setup_guide.ts b/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/workplace_search/setup_guide.ts index 20145306b21c8..81d600952cd43 100644 --- a/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/workplace_search/setup_guide.ts +++ b/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/workplace_search/setup_guide.ts @@ -29,6 +29,9 @@ export default function enterpriseSearchSetupGuideTests({ await retry.try(async function () { const currentUrl = await browser.getCurrentUrl(); expect(currentUrl).to.contain('/workplace_search/setup_guide'); + + const documentTitle = await browser.getTitle(); + expect(documentTitle).to.contain('Setup Guide - Workplace Search - Elastic'); }); }); }); From 543109b6019421fb4bea9f7a3c44d5779387bca2 Mon Sep 17 00:00:00 2001 From: Sandra Gonzales Date: Mon, 10 Aug 2020 13:52:30 -0500 Subject: [PATCH 077/106] [Ingest Manager] stop creating events-* index pattern and placeholder index (#74683) * stop creating events-* index pattern and indices * add integration test to check for placeholder indices --- .../epm/kibana/index_pattern/install.ts | 7 +------ .../apis/epm/install_remove_assets.ts | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/services/epm/kibana/index_pattern/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/kibana/index_pattern/install.ts index 69cd35f3050cd..7fe3713e186ee 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/kibana/index_pattern/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/kibana/index_pattern/install.ts @@ -72,7 +72,6 @@ export interface IndexPatternField { export enum IndexPatternType { logs = 'logs', metrics = 'metrics', - events = 'events', } // TODO: use a function overload and make pkgName and pkgVersion required for install/update // and not for an update removal. or separate out the functions @@ -111,11 +110,7 @@ export async function installIndexPatterns( const installedPackagesInfo = await Promise.all(installedPackagesFetchInfoPromise); // for each index pattern type, create an index pattern - const indexPatternTypes = [ - IndexPatternType.logs, - IndexPatternType.metrics, - IndexPatternType.events, - ]; + const indexPatternTypes = [IndexPatternType.logs, IndexPatternType.metrics]; indexPatternTypes.forEach(async (indexPatternType) => { // if this is an update because a package is being unisntalled (no pkgkey argument passed) and no other packages are installed, remove the index pattern if (!pkgName && installedPackages.length === 0) { diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts index 03d0b6abb4802..7fb8b0a2b1708 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts @@ -85,11 +85,6 @@ export default function (providerContext: FtrProviderContext) { id: 'metrics-*', }); expect(resIndexPatternMetrics.id).equal('metrics-*'); - const resIndexPatternEvents = await kibanaServer.savedObjects.get({ - type: 'index-pattern', - id: 'events-*', - }); - expect(resIndexPatternEvents.id).equal('events-*'); const resDashboard = await kibanaServer.savedObjects.get({ type: 'dashboard', id: 'sample_dashboard', @@ -111,6 +106,18 @@ export default function (providerContext: FtrProviderContext) { }); expect(resSearch.id).equal('sample_search'); }); + it('should have installed placeholder indices', async function () { + const resLogsIndexPatternPlaceholder = await es.transport.request({ + method: 'GET', + path: `/logs-index_pattern_placeholder`, + }); + expect(resLogsIndexPatternPlaceholder.statusCode).equal(200); + const resMetricsIndexPatternPlaceholder = await es.transport.request({ + method: 'GET', + path: `/metrics-index_pattern_placeholder`, + }); + expect(resMetricsIndexPatternPlaceholder.statusCode).equal(200); + }); it('should have created the correct saved object', async function () { const res = await kibanaServer.savedObjects.get({ type: 'epm-packages', From 680516154c38d9f59aeb48ced9ce5dbb53c2c4ab Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Mon, 10 Aug 2020 15:10:03 -0400 Subject: [PATCH 078/106] Remove karma tests from legacy maps (#74668) --- .../public/__tests__/map/kibana_map.js | 329 --- .../public/__tests__/aftercolorchange.png | Bin 125255 -> 0 bytes .../public/__tests__/afterdatachange.png | Bin 125103 -> 0 bytes .../__tests__/afterdatachangeandresize.png | Bin 26010 -> 0 bytes .../public/__tests__/afterresize.png | Bin 18316 -> 0 bytes .../public/__tests__/changestartup.png | Bin 56334 -> 0 bytes .../region_map/public/__tests__/initial.png | Bin 126352 -> 0 bytes .../__tests__/region_map_visualization.js | 417 ---- .../region_map/public/__tests__/toiso3.png | Bin 122129 -> 0 bytes .../region_map/public/__tests__/world.json | 1 - .../tile_map/public/__tests__/blues.png | Bin 14095 -> 0 bytes .../coordinate_maps_visualization.js | 356 ---- .../public/__tests__/dummy_es_response.json | 1810 ----------------- .../public/__tests__/geohash_layer.js | 160 -- .../tile_map/public/__tests__/heatmap.png | Bin 87025 -> 0 bytes .../tile_map/public/__tests__/heatmap_raw.png | Bin 16071 -> 0 bytes .../tile_map/public/__tests__/initial.png | Bin 14011 -> 0 bytes .../__tests__/scaled_circle_markers.png | Bin 26698 -> 0 bytes .../__tests__/shaded_circle_markers.png | Bin 44077 -> 0 bytes .../public/__tests__/shaded_geohash_grid.png | Bin 10196 -> 0 bytes 20 files changed, 3073 deletions(-) delete mode 100644 src/plugins/maps_legacy/public/__tests__/map/kibana_map.js delete mode 100644 src/plugins/region_map/public/__tests__/aftercolorchange.png delete mode 100644 src/plugins/region_map/public/__tests__/afterdatachange.png delete mode 100644 src/plugins/region_map/public/__tests__/afterdatachangeandresize.png delete mode 100644 src/plugins/region_map/public/__tests__/afterresize.png delete mode 100644 src/plugins/region_map/public/__tests__/changestartup.png delete mode 100644 src/plugins/region_map/public/__tests__/initial.png delete mode 100644 src/plugins/region_map/public/__tests__/region_map_visualization.js delete mode 100644 src/plugins/region_map/public/__tests__/toiso3.png delete mode 100644 src/plugins/region_map/public/__tests__/world.json delete mode 100644 src/plugins/tile_map/public/__tests__/blues.png delete mode 100644 src/plugins/tile_map/public/__tests__/coordinate_maps_visualization.js delete mode 100644 src/plugins/tile_map/public/__tests__/dummy_es_response.json delete mode 100644 src/plugins/tile_map/public/__tests__/geohash_layer.js delete mode 100644 src/plugins/tile_map/public/__tests__/heatmap.png delete mode 100644 src/plugins/tile_map/public/__tests__/heatmap_raw.png delete mode 100644 src/plugins/tile_map/public/__tests__/initial.png delete mode 100644 src/plugins/tile_map/public/__tests__/scaled_circle_markers.png delete mode 100644 src/plugins/tile_map/public/__tests__/shaded_circle_markers.png delete mode 100644 src/plugins/tile_map/public/__tests__/shaded_geohash_grid.png diff --git a/src/plugins/maps_legacy/public/__tests__/map/kibana_map.js b/src/plugins/maps_legacy/public/__tests__/map/kibana_map.js deleted file mode 100644 index ae6d3144335cf..0000000000000 --- a/src/plugins/maps_legacy/public/__tests__/map/kibana_map.js +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import { KibanaMap } from '../../map/kibana_map'; -import { KibanaMapLayer } from '../../map/kibana_map_layer'; - -describe('kibana_map tests', function () { - let domNode; - let kibanaMap; - - function createDiv(width, height) { - const div = document.createElement('div'); - div.style.top = '0'; - div.style.left = '0'; - div.style.width = width; - div.style.height = height; - div.style.position = 'fixed'; - div.style['pointer-events'] = 'none'; - return div; - } - - function setupDOM(width, height) { - domNode = createDiv(width, height); - document.body.appendChild(domNode); - } - - function teardownDOM() { - domNode.innerHTML = ''; - document.body.removeChild(domNode); - } - - describe('KibanaMap - basics', function () { - beforeEach(async function () { - setupDOM('512px', '512px'); - kibanaMap = new KibanaMap(domNode, { - minZoom: 1, - maxZoom: 10, - center: [0, 0], - zoom: 0, - }); - }); - - afterEach(function () { - kibanaMap.destroy(); - teardownDOM(); - }); - - it('should instantiate at zoom level 2', function () { - const bounds = kibanaMap.getBounds(); - expect(bounds.bottom_right.lon).to.equal(90); - expect(bounds.top_left.lon).to.equal(-90); - expect(kibanaMap.getCenter().lon).to.equal(0); - expect(kibanaMap.getCenter().lat).to.equal(0); - expect(kibanaMap.getZoomLevel()).to.equal(2); - }); - - it('should resize to fit container', function () { - kibanaMap.setZoomLevel(2); - expect(kibanaMap.getCenter().lon).to.equal(0); - expect(kibanaMap.getCenter().lat).to.equal(0); - - domNode.style.width = '1024px'; - domNode.style.height = '1024px'; - kibanaMap.resize(); - - expect(kibanaMap.getCenter().lon).to.equal(0); - expect(kibanaMap.getCenter().lat).to.equal(0); - }); - }); - - describe('getBounds', function () { - afterEach(function () { - kibanaMap.destroy(); - teardownDOM(); - }); - - describe('extended bounds', function () { - beforeEach(async function () { - setupDOM('1600px', '1024px'); - kibanaMap = new KibanaMap(domNode, { - minZoom: 1, - maxZoom: 10, - center: [0, 0], - zoom: 2, - }); - }); - - it('should get untrimmed map bounds', function () { - const bounds = kibanaMap.getBounds(); - expect(bounds.bottom_right.lon.toFixed(2)).to.equal('281.25'); - expect(bounds.top_left.lon.toFixed(2)).to.equal('-281.25'); - }); - }); - - describe('no map height (should default to size of 1px for height)', function () { - beforeEach(async function () { - setupDOM('386px', '256px'); - const noHeightNode = createDiv('386px', '0px'); - domNode.appendChild(noHeightNode); - kibanaMap = new KibanaMap(noHeightNode, { - minZoom: 1, - maxZoom: 10, - center: [0, 0], - zoom: 10, - }); - }); - - it('should calculate map dimensions based on enforcement of single pixel min-width CSS-rule', function () { - const bounds = kibanaMap.getBounds(); - expect(bounds).to.have.property('bottom_right'); - expect(round(bounds.bottom_right.lon, 2)).to.equal(0.27); - expect(round(bounds.bottom_right.lat, 2)).to.equal(0); - expect(bounds).to.have.property('top_left'); - expect(round(bounds.top_left.lon, 2)).to.equal(-0.27); - expect(round(bounds.top_left.lat, 2)).to.equal(0); - }); - - function round(num, dig) { - return Math.round(num * Math.pow(10, dig)) / Math.pow(10, dig); - } - }); - - describe('no map width (should default to size of 1px for width)', function () { - beforeEach(async function () { - setupDOM('386px', '256px'); - const noWidthNode = createDiv('0px', '256px'); - domNode.appendChild(noWidthNode); - kibanaMap = new KibanaMap(noWidthNode, { - minZoom: 1, - maxZoom: 10, - center: [0, 0], - zoom: 10, - }); - }); - - it('should calculate map dimensions based on enforcement of single pixel min-width CSS-rule', function () { - const bounds = kibanaMap.getBounds(); - expect(bounds).to.have.property('bottom_right'); - expect(Math.round(bounds.bottom_right.lon)).to.equal(0); - expect(bounds.bottom_right.lat.toFixed(2)).to.equal('-0.18'); - expect(bounds).to.have.property('top_left'); - expect(Math.round(bounds.top_left.lon)).to.equal(0); - expect(bounds.top_left.lat.toFixed(2)).to.equal('0.18'); - }); - }); - - describe('wrapping', function () { - beforeEach(async function () { - setupDOM('1600px', '1024px'); - kibanaMap = new KibanaMap(domNode, { - minZoom: 1, - maxZoom: 10, - center: [0, -800], //swing the map over two earth-rotations west - zoom: 2, - }); - }); - - it('coordinates should be corrected to center the -180,180 range', function () { - const bounds = kibanaMap.getBounds(); - expect(bounds.bottom_right.lon.toFixed(2)).to.equal('201.09'); - expect(bounds.top_left.lon.toFixed(2)).to.equal('-361.41'); - }); - }); - - describe('wrapping - zoomed in', function () { - beforeEach(async function () { - setupDOM('1600px', '1024px'); - kibanaMap = new KibanaMap(domNode, { - minZoom: 1, - maxZoom: 10, - center: [0, -800], //swing the map over two earth-rotations west - zoom: 8, - }); - }); - - it('coordinates should be corrected to fall within the -180,180 range', function () { - const bounds = kibanaMap.getBounds(); - expect(bounds.bottom_right.lon.toFixed(2)).to.equal('-75.61'); - expect(bounds.top_left.lon.toFixed(2)).to.equal('-84.40'); - }); - }); - }); - - describe('KibanaMap - attributions', function () { - beforeEach(async function () { - setupDOM('512px', '512px'); - kibanaMap = new KibanaMap(domNode, { - minZoom: 1, - maxZoom: 10, - center: [0, 0], - zoom: 0, - }); - }); - - afterEach(function () { - kibanaMap.destroy(); - teardownDOM(); - }); - - function makeMockLayer(attribution) { - const layer = new KibanaMapLayer(); - layer._attribution = attribution; - // eslint-disable-next-line no-undef - layer._leafletLayer = L.geoJson(null); - return layer; - } - - it('should update attributions correctly', function () { - kibanaMap.addLayer(makeMockLayer('foo|bar')); - expect(domNode.querySelectorAll('.leaflet-control-attribution')[0].innerHTML).to.equal( - 'foo, bar' - ); - - kibanaMap.addLayer(makeMockLayer('bar')); - expect(domNode.querySelectorAll('.leaflet-control-attribution')[0].innerHTML).to.equal( - 'foo, bar' - ); - - const layer = makeMockLayer('bar,stool'); - kibanaMap.addLayer(layer); - expect(domNode.querySelectorAll('.leaflet-control-attribution')[0].innerHTML).to.equal( - 'foo, bar, stool' - ); - - kibanaMap.removeLayer(layer); - expect(domNode.querySelectorAll('.leaflet-control-attribution')[0].innerHTML).to.equal( - 'foo, bar' - ); - }); - }); - - describe('KibanaMap - baseLayer', function () { - beforeEach(async function () { - setupDOM('512px', '512px'); - kibanaMap = new KibanaMap(domNode, { - minZoom: 1, - maxZoom: 10, - center: [0, 0], - zoom: 0, - }); - }); - - afterEach(function () { - kibanaMap.destroy(); - teardownDOM(); - }); - - it('TMS', async function () { - const options = { - url: - 'https://tiles-stage.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana', - minZoom: 0, - maxZoom: 12, - attribution: '© [Elastic Maps Service](https://www.elastic.co/elastic-maps-service)', - }; - - return new Promise(function (resolve) { - kibanaMap.on('baseLayer:loaded', () => { - resolve(); - }); - kibanaMap.setBaseLayer({ - baseLayerType: 'tms', - options: options, - }); - }); - }); - - it('WMS - should handle empty settings', async function () { - const invalidOptions = { - url: undefined, - version: undefined, - layers: undefined, - format: 'image/png', - transparent: true, - attribution: undefined, - styles: '', - minZoom: 1, - maxZoom: 18, - }; - - kibanaMap.setBaseLayer({ - baseLayerType: 'wms', - options: invalidOptions, - }); - - expect(kibanaMap.getLeafletBaseLayer()).to.eql(null); - }); - - it('WMS - should clean attribution', async function () { - const options = { - url: 'https://basemap.nationalmap.gov/arcgis/services/USGSTopo/MapServer/WMSServer', - version: '1.1.0', - layers: '0', - format: 'image/png', - transparent: true, - attribution: '
    foobar
    ', - styles: '', - minZoom: 1, - maxZoom: 18, - }; - - kibanaMap.setBaseLayer({ - baseLayerType: 'wms', - options: options, - }); - - expect(domNode.querySelectorAll('.leaflet-control-attribution')[0].innerHTML).to.equal( - '<div>foobar</div>' - ); - }); - }); -}); diff --git a/src/plugins/region_map/public/__tests__/aftercolorchange.png b/src/plugins/region_map/public/__tests__/aftercolorchange.png deleted file mode 100644 index d5a5316e2e99c6a83967e3d28f5e5ff5ec21cfb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125255 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
    orfP=-cf6iM%i!y6VcnY_$oCHcB@8z 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 pB)v)weze}&%Z!D95STpz{~s0Lkou{+Z%6No%Z diff --git a/src/plugins/region_map/public/__tests__/afterdatachange.png b/src/plugins/region_map/public/__tests__/afterdatachange.png deleted file mode 100644 index ba388f18d7f3580af64e550d4a390ef1350c84ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125103 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

    kBXP)9w^>KKPT+&g0DtRtqsA7~x8X|bbO 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 M07*qoM6N<$f|YRVLjV8( diff --git a/src/plugins/region_map/public/__tests__/afterdatachangeandresize.png b/src/plugins/region_map/public/__tests__/afterdatachangeandresize.png deleted file mode 100644 index 7da57511c583112e72160ca970ce803cb92b4710..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26010 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%0AQ&Y} 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

    H}@nUBfjOvK~hFq&7#dSJ4gM0m&zI}gnB z0i4ys@p~1pf;0nX(2GmwW-w7rr#%dxmcNeof~S^moBv}${anXQRurVF@$Iw^L(~Z^OnCiMJy=U zW9w8XN>nG|e5S0`JBP127_G~fFY=*e;$B^ixn=XEf5-L8uTLWCxbk(p+4C3f*#0h^ ziL&l?WV0lhXSp9QvVM?JO?v1OV|o|!V%3*31S<3G8i8iI$^o0#Ju+;KZ3ax)jnQ3; z^Z@w#5Ne{=cQMzGO0^4uLgz^bw48%+%x(Q4X#iIO9eTJtefcLd+JS$XP;JDpbrG08 zjyNk4irN?-H_?Msp?qHU*KZ063M!919nQ@`xkwQr8W~H>3~5*px`anUE@LEpe4uOm z+CeOUt)kHqc60IC&fMs;3S-;YnnKe9h~{v8p*Xcxf4xQxL1W*Ya~HeCf=PO~rlC3h za*0%8+G@*9{gbapoq~96O8H5|gwOw{&0NaW{OU7GOloPcBnW+il>Ky+)YySa1OPU$iE2)sq zeiNPKu5&x9OSi8<0%!JL_5pB^SRN?21P*z-XV|06jUj@Mcn*gnV7R+g}~D3+J7bvKVvfuXj0Zp(EM& zR>NqiIqA015fGo`ZVj9f9nGn`#dQYnOkR#XtD~>>?vY@iAAh?VT&Br+@vK@GO!k(U zGF(e>fPEbUux}uoNp4a@eTJJg{5vCX7m0UgXu7nqzrS?Sdk9F*72yJrf_rE-cb2;^ zyPQUqRkT672E^%201V!`2rd0}gU(t?HZgbA*D3ovYqX?t_wf2`05b5gSlWGVI%1~$ z%+ZC5kIhfk&e`PTE~!;m$M0>c)%Da9RqVlZjYs5xg3K7ghGNQ4vw$xhnM-rK)15?X z@5^3;Ar-4li!QYH6P)GX*S+r4Gc<_0)SSE!fdXO)O)v=V*XR2ezYp1r1xTnuJ5BKt+UCouQCIVyJ95n@^sEZAF>q*1Z#RTOY$WyTLNjA zgm@`d>~@sXn9Wro$cx4)qs| z9mqTampl_3AT1qp`Jp};lyh$VKlY>&-lqTJbh))W`A?u^QTE4fW2DvGpcdY+#1h%2ztui8kpH2u2`pgP|c z4_#DTY~Es2d$)e|AMGSjH&#_csXbayxP9h=BPa=lk?4#%6vB9ha?pg%sKwvQo#SSd zJQ3-;MY!vgtgeEe;M`Vgs0mjUYLeRFNWJJ#Q<>A6{FWASz4rD}Tr^-~LHRWO8hUuZ zZM4a5)s2_G?&@%^A7sUE<No?51M|eh#4&!FyTy}M9VC?; zZIjK_Cq#%an5^CYe~sAxS<^FuO{(MQ3%c-PfKK!j;`aRd{q716XVa3fjmZN3)9!Bu zOq-lf244fWf@|v)4@6~S{6ANV5RM$?EOj`U;@&NC4_|n}3 z0?>QkPa3F?ao#QACY0&OoAHxYst1^$fCNG|LC#T19d~v7C;%|!N465L(^-4Te3aev zY^)QxYQm5Mu|n}E-Zi1X`jpR6KFSn}$a3#YB%Wn+)f$WC5TgqJ9=b_Vth55zq^%fy zAxADj_KjhXJ%ha0NQ}(kOi!LLA38ppLvaCu>B`P*=?o~l*pvF_6((^rKw-LiTFh+* z%I%NH*QEOEb0?h3E`=hMVk9`}XU28Z{18@}4%3hL7CN9|%LiTGF0|zdH?CWMOVM>m zZL)9<7SLc1TP6d7W}ld{IvbivBx0hMRscec1`AYsa`VGzlo&}VF2`oo21rEmrv(LM z)wCtNq89IwBPyvt(GOG0lfHt*KHs@dQOQr}Uw33;ez$DO^rU<%SVD7tFB(H0%X4yPbaydc**KBfEr21NQqSNOF8qkRMpu0XEB-dZKj#L)|)KC z4q=YY`I~a;qpacxgpb}P^}b$y5Vy2ol_D!E>w6kPPIVb`Mc1+8;^vt81^$}d22d?R zfEb%SrycM|5BZedB2oN3Fk1Dh@c&)i4l|lu8Ci7k&%0sAA~Y3uSgwY4N@JtF5<6?T z!m4`!i5eFU{kK^7-$x^)I$%kzp{?$U+SZ!3p?>EdsjmIO?(CH)u1#d=f9_fNEB}HD zl6@YV(d_lp%3O;ORuDK6baTcq?OU?egKh;2VP;Fy1B@w3HT6vj;Cp!L5G|~VM>IYM zxuwAWhN&+V{kN_{J&E!nips!dj9##t zUsvaZ%P>!q3TXE!!{3b3)#SVAuHfncz;n!Js2;=mVV+_y44m;m@}Urm7DQS4!Go$e zeKhXyCQl~|Ai;MQYY*t%69mlMd0=Z>%=3FjCN}t6P_p?K{FrmU+fI0n&MH5uy+CP7 zDu8-J0zQv?A-R`;&Cyqx<9S>RLciJxk-Y{e5a$At zTz4^@UV&q;Jv|?K<=P3VFz+pu12C9-voKZyy_SMlCl)z1I!;ubgsYMIVtVdj2tUsp z3C7qd9xB3%cUJW;T5KF0g+D&}sS;`ut`!t7sj?cO(xR{_w8@?}rlCDTm3H!04J}_K zPC*}AD<200OdO{G)x{~xgL5q_%{K*bA5|Nc7e4bSM$try82&rxQl6gnY|tQTJ{110r>*HXeC^SG%f$*4qf`DJeYC-`#7QWl2qzVPWVi$MoSkzROz3uDA6TO-uzDm z71J;Xn=v!yKoKVY%P>PQatuG7C;_OrW>O@+30KQz0xrp$C-vG=s^@ktD)*eFZIs}Z z>)UHe0jPExyjUb?q`xF`?Iw}q^72E{zc-M(-lo-ymE8H!zbS71CBlmzE@Zx~_1G%N zz5Z3v!RXeQsb5W=W%fAYy zsGMd=K9u^gE>oo<=52GZRC7H(GBVPpyQio8i_;kTs$@!V+?jJt8FX!fRS!r^Yy6j( z{^{IP>O`kQ0=Wz1qCYdxZY>L?0ZCpx(QVYc$nW(T6NVkTYZYl<$#5C(C02)Xecz|U z#W-&-62ib-2CzHXpRaV|60TEOpI~35YvhdSI0Rd4cTWauRQq=CTKy1W)oe&MIzaSw zAkIRCqMYxrv&+jzSEe7ljH&kp5c2zh9ObJV&7MEYLb4Uy0zL}fsL6AZ-s6v) z5woun4j#&8EB(!sCjb$v%@4RkD=;0y;4Z8f;kB*%-fl`1>(M$~u-pcqP1gD;3S#HA z`shfzO%YwQ5-)?`w5!+*AnI=e9dYy5WqI}^<8bg=^JJ_Sm9-&bXUr|o&!-~yfpUcd zFS@{r`A|BPw3XJCU#h(qWk?4{Dy_3P?^4iqQZ{Bc#HQlj=FR<52jqWx)f-k{EH=BV zu1TZ{*=O5eWkb1-ndt8n;bx0x@h@2|sBVn&|6Q0-%CEVsa0YgP+}i!{yNF$XG(GnZ zHS`G%@_zyl1@HPA-5ND-pIe~b0=?LcWeH+9T1qKDu9Vt3>CkccX@HCpR=Sz9~^g2SYg zi0cBs*6)Q7+Xx|W0fl7ovJhg9QfkX~<63L&(9qB^wPcCy+9dtF-vO?*^O{}|+vFKD z3%k6vDqwIr5kW&QFS!N!W`S;ZV_6>|YZq><#qH$PLI|8rK!))sGk=zdz=8pKs_k$@ z1ogJ(dCzTUG-J$nnfW^3_d!jRY3Y=Lr`w}s#SZ1)zvqEWS5wzn4I4$PVZf_&P%r0^ z_nljykp-47Uw&%2Tn6)NM^wta0w762=$l=3X4)C)W5 zw1*&e4>SKzYyHkv^SbfI8+Y7flTH4twQif)5+6&USNZZz*4nO3T3YIEZzX#VVs%GF zq&vi0;I_tYXRQ45+yYrzpqnF2FF?#%dpYFIlv2-1vd%CJA1fA%M<0Cf!7WK2SFBjE zNx57$N~!&m^qaO01VV^txl-z)ByGE~du{*O?Zg0DI~=`*m@&JaMmo=bO!7qYI@4wW zYwh*UxwCxV57JH|YY;QW97IIFoIQK?E_>~@7xX3DmM{$e7DdsuzVE-iUFDd}@qJ3E zo7>e*`*|9_SXM{L%El-QpBT+~(Ux-d^Fh;FUvT4?r}CtI8}j;nwSY0^E5%~*w<9AX z7o;6HYY?;6K0riY@;onbP^vLzX`xVXNkmM-FuabLf2x$aFzs5~)lcIW%jziEHHcMm z9d|rwb{yk{{*brziaboB-Q&(bA0!KORr0K37EU8~CtD|IBAVyoM&E%YyZ5l_}qc0GxHH;Qc^FZ>txdr-d zfo`1pS%Fv>hVz_rKkY;x^X8jxKCE0WU+H;XHC$<}32VU%QfzbQ&b_{u_Kp2wPbj6{ z)odJV?Ri3ot-GZhs`j7yIEmdC&3WmTwE2PH`>K}Q@72pUBk#NC7U*W;?nC>2gIDdG zk!(&xETz1l3Yw)-X=fqCNl_FXE~Wgd=Xu9;vd%_rQiE87xUW1!BCDs7_cLu4=+wDi zjo2?1i?=rNNrhqf05cbb5Hld1N<{ZN=a$!kS{Q~mF!QELDcz|7j4=2>fUW(p~MGL$<;7g+k$?(b3U+J6&g^cK;s}GTeyZ1na3 diff --git a/src/plugins/region_map/public/__tests__/changestartup.png b/src/plugins/region_map/public/__tests__/changestartup.png deleted file mode 100644 index a94affddbd941fa3a219a4ddf93d858aafd93510..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56334 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
    SBogIF@MQ3C{Ebf$f=_kzLSYTA`7{swP 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 diff --git a/src/plugins/region_map/public/__tests__/initial.png b/src/plugins/region_map/public/__tests__/initial.png deleted file mode 100644 index 9ec48af9fe1e29157aeef3c5ad7a8ae3c2a4ce0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126352 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 FV1miqJEs5u diff --git a/src/plugins/region_map/public/__tests__/region_map_visualization.js b/src/plugins/region_map/public/__tests__/region_map_visualization.js deleted file mode 100644 index 648193e8e2490..0000000000000 --- a/src/plugins/region_map/public/__tests__/region_map_visualization.js +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import ngMock from 'ng_mock'; -import _ from 'lodash'; - -import ChoroplethLayer from '../choropleth_layer'; -import { ImageComparator } from 'test_utils/image_comparator'; -import worldJson from './world.json'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_CATALOGUE from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_manifest.json'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_FILES from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_files.json'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_TILES from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_tiles.json'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_STYLE_ROAD_MAP_BRIGHT from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_style_bright'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_STYLE_ROAD_MAP_DESATURATED from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_style_desaturated'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_STYLE_DARK_MAP from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_style_dark'; - -import initialPng from './initial.png'; -import toiso3Png from './toiso3.png'; -import afterresizePng from './afterresize.png'; -import afterdatachangePng from './afterdatachange.png'; -import afterdatachangeandresizePng from './afterdatachangeandresize.png'; -import aftercolorchangePng from './aftercolorchange.png'; -import changestartupPng from './changestartup.png'; - -import { createRegionMapVisualization } from '../region_map_visualization'; -import { createRegionMapTypeDefinition } from '../region_map_type'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ExprVis } from '../../../visualizations/public/expressions/vis'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { BaseVisType } from '../../../visualizations/public/vis_types/base_vis_type'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ServiceSettings } from '../../../maps_legacy/public/map/service_settings'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { BaseMapsVisualizationProvider } from '../../../maps_legacy/public/map/base_maps_visualization'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { KibanaMap } from '../../../maps_legacy/public/map/kibana_map'; - -const THRESHOLD = 0.45; -const PIXEL_DIFF = 96; - -describe('RegionMapsVisualizationTests', function () { - let domNode; - let RegionMapsVisualization; - let vis; - let regionMapVisType; - let dependencies; - - let imageComparator; - - const _makeJsonAjaxCallOld = ChoroplethLayer.prototype._makeJsonAjaxCall; - - const dummyTableGroup = { - columns: [ - { - id: 'col-0', - aggConfig: { - id: '2', - enabled: true, - type: 'terms', - schema: 'segment', - params: { field: 'geo.dest', size: 5, order: 'desc', orderBy: '1' }, - }, - title: 'geo.dest: Descending', - }, - { - id: 'col-1', - aggConfig: { id: '1', enabled: true, type: 'count', schema: 'metric', params: {} }, - title: 'Count', - }, - ], - rows: [ - { 'col-0': 'CN', 'col-1': 26 }, - { 'col-0': 'IN', 'col-1': 17 }, - { 'col-0': 'US', 'col-1': 6 }, - { 'col-0': 'DE', 'col-1': 4 }, - { 'col-0': 'BR', 'col-1': 3 }, - ], - }; - - beforeEach(ngMock.module('kibana')); - - let getManifestStub; - beforeEach( - ngMock.inject(() => { - const mapConfig = { - emsFileApiUrl: '', - emsTileApiUrl: '', - emsLandingPageUrl: '', - }; - const tilemapsConfig = { - options: { - attribution: '123', - }, - }; - const serviceSettings = new ServiceSettings(mapConfig, tilemapsConfig); - const regionmapsConfig = { - includeElasticMapsService: true, - layers: [], - }; - const coreSetupMock = { - notifications: { - toasts: {}, - }, - uiSettings: { - get: () => {}, - }, - injectedMetadata: { - getInjectedVar: () => {}, - }, - }; - const BaseMapsVisualization = new BaseMapsVisualizationProvider( - (...args) => new KibanaMap(...args), - serviceSettings - ); - - dependencies = { - serviceSettings, - regionmapsConfig, - uiSettings: coreSetupMock.uiSettings, - BaseMapsVisualization, - }; - - regionMapVisType = new BaseVisType(createRegionMapTypeDefinition(dependencies)); - RegionMapsVisualization = createRegionMapVisualization(dependencies); - - ChoroplethLayer.prototype._makeJsonAjaxCall = async function () { - //simulate network call - return new Promise((resolve) => { - setTimeout(() => { - resolve(worldJson); - }, 10); - }); - }; - - getManifestStub = serviceSettings.__debugStubManifestCalls(async (url) => { - //simulate network calls - if (url.startsWith('https://foobar')) { - return EMS_CATALOGUE; - } else if (url.startsWith('https://tiles.foobar')) { - return EMS_TILES; - } else if (url.startsWith('https://files.foobar')) { - return EMS_FILES; - } else if (url.startsWith('https://raster-style.foobar')) { - if (url.includes('osm-bright-desaturated')) { - return EMS_STYLE_ROAD_MAP_DESATURATED; - } else if (url.includes('osm-bright')) { - return EMS_STYLE_ROAD_MAP_BRIGHT; - } else if (url.includes('dark-matter')) { - return EMS_STYLE_DARK_MAP; - } - } - }); - }) - ); - - afterEach(function () { - ChoroplethLayer.prototype._makeJsonAjaxCall = _makeJsonAjaxCallOld; - getManifestStub.removeStub(); - }); - - describe('RegionMapVisualization - basics', function () { - beforeEach(async function () { - setupDOM('512px', '512px'); - - imageComparator = new ImageComparator(); - - vis = new ExprVis({ - type: regionMapVisType, - }); - - vis.params.bucket = { - accessor: 0, - }; - vis.params.metric = { - accessor: 1, - }; - - vis.params.selectedJoinField = { name: 'iso2', description: 'Two letter abbreviation' }; - vis.params.selectedLayer = { - attribution: - ' ', - name: 'World Countries', - format: 'geojson', - url: - 'https://vector-staging.maps.elastic.co/blob/5715999101812736?elastic_tile_service_tos=agree&my_app_version=7.0.0-alpha1', - fields: [ - { name: 'iso2', description: 'Two letter abbreviation' }, - { - name: 'iso3', - description: 'Three letter abbreviation', - }, - { name: 'name', description: 'Country name' }, - ], - created_at: '2017-07-31T16:00:19.996450', - id: 5715999101812736, - layerId: 'elastic_maps_service.World Countries', - }; - }); - - afterEach(function () { - teardownDOM(); - imageComparator.destroy(); - }); - - it('should instantiate at zoom level 2 (may fail in dev env)', async function () { - const regionMapsVisualization = new RegionMapsVisualization(domNode, vis); - await regionMapsVisualization.render(dummyTableGroup, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - const mismatchedPixels = await compareImage(initialPng); - regionMapsVisualization.destroy(); - expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF); - }); - - it('should update after resetting join field', async function () { - const regionMapsVisualization = new RegionMapsVisualization(domNode, vis); - await regionMapsVisualization.render(dummyTableGroup, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - - //this will actually create an empty image - vis.params.selectedJoinField = { name: 'iso3', description: 'Three letter abbreviation' }; - vis.params.isDisplayWarning = false; //so we don't get notifications - await regionMapsVisualization.render(dummyTableGroup, vis.params, { - resize: false, - params: true, - aggs: false, - data: false, - uiState: false, - }); - - const mismatchedPixels = await compareImage(toiso3Png); - regionMapsVisualization.destroy(); - expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF); - }); - - it('should resize (may fail in dev env)', async function () { - const regionMapsVisualization = new RegionMapsVisualization(domNode, vis); - await regionMapsVisualization.render(dummyTableGroup, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - - domNode.style.width = '256px'; - domNode.style.height = '128px'; - await regionMapsVisualization.render(dummyTableGroup, vis.params, { - resize: true, - params: false, - aggs: false, - data: false, - uiState: false, - }); - const mismatchedPixelsAfterFirstResize = await compareImage(afterresizePng); - - domNode.style.width = '512px'; - domNode.style.height = '512px'; - await regionMapsVisualization.render(dummyTableGroup, vis.params, { - resize: true, - params: false, - aggs: false, - data: false, - uiState: false, - }); - const mismatchedPixelsAfterSecondResize = await compareImage(initialPng); - - regionMapsVisualization.destroy(); - expect(mismatchedPixelsAfterFirstResize).to.be.lessThan(PIXEL_DIFF); - expect(mismatchedPixelsAfterSecondResize).to.be.lessThan(PIXEL_DIFF); - }); - - it('should redo data (may fail in dev env)', async function () { - const regionMapsVisualization = new RegionMapsVisualization(domNode, vis); - await regionMapsVisualization.render(dummyTableGroup, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - - const newTableGroup = _.cloneDeep(dummyTableGroup); - - newTableGroup.rows.pop(); //remove one shape - - await regionMapsVisualization.render(newTableGroup, vis.params, { - resize: false, - params: false, - aggs: false, - data: true, - uiState: false, - }); - - const mismatchedPixelsAfterDataChange = await compareImage(afterdatachangePng); - const anotherTableGroup = _.cloneDeep(newTableGroup); - - anotherTableGroup.rows.pop(); //remove one shape - domNode.style.width = '412px'; - domNode.style.height = '112px'; - await regionMapsVisualization.render(anotherTableGroup, vis.params, { - resize: true, - params: false, - aggs: false, - data: true, - uiState: false, - }); - const mismatchedPixelsAfterDataChangeAndResize = await compareImage( - afterdatachangeandresizePng - ); - - regionMapsVisualization.destroy(); - expect(mismatchedPixelsAfterDataChange).to.be.lessThan(PIXEL_DIFF); - expect(mismatchedPixelsAfterDataChangeAndResize).to.be.lessThan(PIXEL_DIFF); - }); - - it('should redo data and color ramp (may fail in dev env)', async function () { - const regionMapsVisualization = new RegionMapsVisualization(domNode, vis); - await regionMapsVisualization.render(dummyTableGroup, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - - const newTableGroup = _.cloneDeep(dummyTableGroup); - newTableGroup.rows.pop(); //remove one shape - vis.params.colorSchema = 'Blues'; - await regionMapsVisualization.render(newTableGroup, vis.params, { - resize: false, - params: true, - aggs: false, - data: true, - uiState: false, - }); - const mismatchedPixelsAfterDataAndColorChange = await compareImage(aftercolorchangePng); - - regionMapsVisualization.destroy(); - expect(mismatchedPixelsAfterDataAndColorChange).to.be.lessThan(PIXEL_DIFF); - }); - - it('should zoom and center elsewhere', async function () { - vis.params.mapZoom = 4; - vis.params.mapCenter = [36, -85]; - const regionMapsVisualization = new RegionMapsVisualization(domNode, vis); - await regionMapsVisualization.render(dummyTableGroup, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - - const mismatchedPixels = await compareImage(changestartupPng); - regionMapsVisualization.destroy(); - - expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF); - }); - }); - - async function compareImage(expectedImageSource) { - const elementList = domNode.querySelectorAll('canvas'); - expect(elementList.length).to.equal(1); - const firstCanvasOnMap = elementList[0]; - return imageComparator.compareImage(firstCanvasOnMap, expectedImageSource, THRESHOLD); - } - - function setupDOM(width, height) { - domNode = document.createElement('div'); - domNode.style.top = '0'; - domNode.style.left = '0'; - domNode.style.width = width; - domNode.style.height = height; - domNode.style.position = 'fixed'; - domNode.style.border = '1px solid blue'; - domNode.style['pointer-events'] = 'none'; - document.body.appendChild(domNode); - } - - function teardownDOM() { - domNode.innerHTML = ''; - document.body.removeChild(domNode); - } -}); diff --git a/src/plugins/region_map/public/__tests__/toiso3.png b/src/plugins/region_map/public/__tests__/toiso3.png deleted file mode 100644 index eebae19ae4364ba5abc15efb9430e66e2637b9dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122129 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

    Q7nSGY~*+K%?pzgzb-(m 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 bds`l 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�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 diff --git a/src/plugins/region_map/public/__tests__/world.json b/src/plugins/region_map/public/__tests__/world.json deleted file mode 100644 index 162e1f456e183..0000000000000 --- a/src/plugins/region_map/public/__tests__/world.json +++ /dev/null @@ -1 +0,0 @@ -{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"Antigua and Barbuda","iso2":"AG","iso3":"ATG"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-61.686668,17.024441000000152],[-61.887222,17.105274],[-61.794449,17.1633300000001],[-61.686668,17.024441000000152]]],[[[-61.72917199999989,17.608608],[-61.853058,17.583054000000104],[-61.873062,17.703888],[-61.72917199999989,17.608608]]]]}},{"type":"Feature","properties":{"name":"Algeria","iso2":"DZ","iso3":"DZA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[2.96361,36.802216],[4.785832,36.894722],[5.328055,36.640274],[6.398333,37.086388],[8.62203,36.941368],[8.183611,36.524162],[8.251665,34.64444],[7.492499000000123,33.887497],[8.34861,32.533333],[9.055277,32.099998],[9.537113,30.23439],[9.303888,30.122498],[9.766388,29.427776],[9.948332,27.824444],[9.871666,26.514164],[9.398333,26.153332],[10.252222,24.605831],[11.558887,24.302498],[11.986475,23.522305],[7.450807,20.852863],[5.812499,19.44611],[4.245277,19.146664],[3.331944,18.976387],[3.233055,19.820274],[1.795833,20.308331],[1.1675,20.741108],[1.169662,21.102543],[-4.806111,25.000275],[-6.662778,26.129166],[-8.66679,27.290459],[-8.666668,27.666664],[-8.667223,28.709442],[-7.123889,29.636944],[-5.538334,29.902496],[-4.920556,30.508053],[-3.626667,30.970554],[-3.818334,31.695553],[-2.853889,32.088333],[-1.180556,32.11055],[-1.010278,32.508331],[-1.668056,33.261108],[-1.747222,34.747215],[-2.209445,35.085831],[0.95,36.450272],[2.96361,36.802216]]]]}},{"type":"Feature","properties":{"name":"Azerbaijan","iso2":"AZ","iso3":"AZE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[45.083322525024414,39.76804542541504],[45.81998634338379,39.54972267150879],[46.17824745178223,38.84115028381348],[45.00443458557129,39.41638374328613],[44.81304359436035,39.630815505981445],[44.77886390686035,39.70638465881348],[45.083322525024414,39.76804542541504]]],[[[45.513051986694336,40.607221603393555],[45.51749229431152,40.66554069519043],[45.57305335998535,40.632490158081055],[45.513051986694336,40.607221603393555]]],[[[45.24527168273926,40.97694206237793],[45.22916221618652,40.96915245056152],[45.19582176208496,40.99777030944824],[45.24527168273926,40.97694206237793]]],[[[45.045270919799805,41.0352725982666],[45.009992599487305,41.03305244445801],[45.00111198425293,41.08888053894043],[45.045270919799805,41.0352725982666]]],[[[46.57138252258301,41.87193489074707],[47.76693153381348,41.19609260559082],[48.58395576477051,41.835771560668945],[49.52804756164551,40.66276741027832],[50.3749942779541,40.262216567993164],[49.488046646118164,40.15053749084473],[48.88828468322754,38.44240760803223],[48.020822525024414,38.83554267883301],[48.35978889465332,39.38521766662598],[47.97666358947754,39.7192325592041],[46.54037666320801,38.87558937072754],[46.54138374328613,39.56443977355957],[45.5958194732666,39.978044509887695],[46.00193977355957,40.22554969787598],[45.15387153625488,41.1986026763916],[45.0229434967041,41.29705238342285],[45.33665657043457,41.46249580383301],[46.520822525024414,41.04998970031738],[46.69387245178223,41.312204360961914],[46.19442939758301,41.68582344055176],[46.45175361633301,41.89705848693848],[46.57138252258301,41.87193489074707]]]]}},{"type":"Feature","properties":{"name":"Albania","iso2":"AL","iso3":"ALB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[19.436214,41.021065],[19.600555,41.796661],[19.367771,41.848999],[19.645832,42.61805],[20.071423,42.560913],[20.589642,41.882187],[20.492775,41.331108],[20.82111,40.908882],[20.98349,40.855888],[20.671944,40.09805300000012],[20.010029,39.6912],[19.863052,40.039719],[19.288609,40.417496],[19.478611,40.350273],[19.436214,41.021065]]]]}},{"type":"Feature","properties":{"name":"Armenia","iso2":"AM","iso3":"ARM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[45.15387153625488,41.1986026763916],[46.00193977355957,40.22554969787598],[45.5958194732666,39.978044509887695],[46.54138374328613,39.56443977355957],[46.54037666320801,38.87558937072754],[46.17824745178223,38.84115028381348],[45.81998634338379,39.54972267150879],[45.083322525024414,39.76804542541504],[44.77886390686035,39.70638465881348],[44.34721565246582,40.02388954162598],[43.65749549865723,40.108598709106445],[43.75193977355957,40.739999771118164],[43.460771560668945,41.11296272277832],[45.0229434967041,41.29705238342285],[45.15387153625488,41.1986026763916]],[[45.009992599487305,41.03305244445801],[45.045270919799805,41.0352725982666],[45.00111198425293,41.08888053894043],[45.009992599487305,41.03305244445801]],[[45.19582176208496,40.99777030944824],[45.22916221618652,40.96915245056152],[45.24527168273926,40.97694206237793],[45.19582176208496,40.99777030944824]],[[45.57305335998535,40.632490158081055],[45.51749229431152,40.66554069519043],[45.513051986694336,40.607221603393555],[45.57305335998535,40.632490158081055]]]]}},{"type":"Feature","properties":{"name":"Angola","iso2":"AO","iso3":"AGO"},"geometry":{"type":"MultiPolygon","coordinates":[[[[11.750833511352539,-16.755279541015625],[11.693609237670898,-16.53555679321289],[11.774999618530273,-16.804725646972656],[11.750833511352539,-16.755279541015625]]],[[[13.997499465942383,-5.848611831665039],[16.579721450805664,-5.900833129882813],[16.941667556762695,-7.198610305786133],[17.62416648864746,-8.09805679321289],[19.373056411743164,-7.996110916137695],[19.538949966430664,-6.996614456176758],[20.62974739074707,-6.913881301879883],[20.548715591430664,-7.283615112304688],[21.782960891723633,-7.280841827392578],[21.790555953979492,-9.405555725097656],[22.312223434448242,-10.364444732666016],[22.253889083862305,-11.209722518920898],[23.986207962036133,-10.870460510253906],[24.02055549621582,-13.006389617919922],[21.998334884643555,-13.004167556762695],[22.000150680541992,-16.171661376953125],[23.476110458374023,-17.625835418701172],[23.28472328186035,-17.66250228881836],[20.85416603088379,-18.01639175415039],[18.915834426879883,-17.815555572509766],[18.451539993286133,-17.389835357666016],[13.993219375610352,-17.423946380615234],[13.160554885864258,-16.952777862548828],[11.752782821655273,-17.254833221435547],[11.820833206176758,-16.503055572509766],[11.810834884643555,-15.993057250976562],[11.731389999389648,-15.846668243408203],[12.509721755981445,-13.42527961730957],[13.792501449584961,-11.791667938232422],[13.773611068725586,-10.684722900390625],[12.984445571899414,-9.087501525878906],[13.391389846801758,-8.387222290039062],[12.245000839233398,-6.098054885864258],[13.17888069152832,-5.856328964233398],[13.997499465942383,-5.848611831665039]]],[[[13.088888168334961,-4.662500381469727],[12.565553665161133,-5.025554656982422],[12.526666641235352,-5.724166870117188],[12.21455192565918,-5.7685546875],[12.026132583618164,-5.014995574951172],[12.779047012329102,-4.38899040222168],[13.091390609741211,-4.633054733276367],[13.088888168334961,-4.662500381469727]]]]}},{"type":"Feature","properties":{"name":"American Samoa","iso2":"AS","iso3":"ASM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-170.542511,-14.297503],[-170.560822,-14.287781],[-170.540039,-14.283892],[-170.542511,-14.297503]]],[[[-170.637268,-14.289446],[-170.826111,-14.325003],[-170.560028,-14.265837],[-170.637268,-14.289446]]],[[[-169.444489,-14.261667],[-169.513062,-14.275833],[-169.536133,-14.231668],[-169.444489,-14.261667]]],[[[-169.62558,-14.189722],[-169.644745,-14.176111],[-169.621948,-14.168612],[-169.62558,-14.189722]]],[[[-169.685577,-14.191944],[-169.690857,-14.167501],[-169.662231,-14.175001],[-169.685577,-14.191944]]]]}},{"type":"Feature","properties":{"name":"Argentina","iso2":"AR","iso3":"ARG"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-68.60861199999988,-54.891396],[-68.643112,-54.888611],[-68.636124,-54.804771],[-68.60861199999988,-54.891396]]],[[[-63.813614,-54.731392],[-64.678345,-54.907227],[-64.75528,-54.835007],[-63.813614,-54.731392]]],[[[-68.261948,-52.98806],[-68.543625,-53.229446],[-67.359177,-54.028893],[-65.138062,-54.651672],[-65.353897,-54.929169],[-66.44612099999989,-55.051674],[-68.635834,-54.788338],[-68.617584,-52.64151],[-68.261948,-52.98806]]],[[[-61.878891,-39.2425],[-62.095284,-39.089172],[-61.890556,-39.139168],[-61.878891,-39.2425]]],[[[-61.996948,-39.066948],[-62.132782,-39.01889],[-61.981392,-39.026947],[-61.996948,-39.066948]]],[[[-65.748062,-22.111668],[-65.190201,-22.09473],[-64.590561,-22.214725],[-64.324722,-22.873611],[-63.941116,-22.000835],[-62.811951,-21.996948],[-62.643768,-22.238903],[-61.007782,-23.813335],[-57.75611099999986,-25.176945],[-57.576668,-25.549446],[-58.604622,-27.316921],[-55.736115,-27.439445],[-54.698334,-26.438335],[-54.59891499999989,-25.573223],[-53.863335,-25.681114],[-53.807785,-27.129169],[-55.765282,-28.226112],[-57.608002,-30.184925],[-57.806396,-30.748219],[-58.199242,-32.45031],[-58.147224,-33.051674],[-58.426948999999865,-33.096947],[-58.531951999999876,-33.516945],[-58.383896,-34.05584],[-58.469726999999864,-34.539726],[-57.188339,-35.320557],[-57.376671,-35.962784],[-56.741669,-36.318336],[-56.663063,-36.900558],[-57.571671,-38.133057],[-58.301117,-38.485001],[-61.094452,-38.995834],[-62.38139299999989,-38.798615],[-62.020004,-39.378059],[-62.277229,-39.335281],[-62.06778,-39.505562],[-62.489449,-40.299446],[-62.183891,-40.629723],[-62.390006999999855,-40.901947],[-63.765839,-41.16584],[-65.134445,-40.847778],[-65.013626,-42.092224],[-64.45195,-42.445839],[-63.746948,-42.090561],[-63.580559,-42.623894],[-64.086945,-42.890282],[-64.398056,-42.515839],[-64.960556,-42.666389],[-64.295013,-42.991951],[-65.32251,-43.653061],[-65.249451,-44.313057],[-65.691681,-44.716949],[-65.604736,-45.016396],[-66.949448,-45.255562],[-67.584351,-46.000298],[-67.506119,-46.458893],[-66.816956,-46.991669],[-65.779449,-47.189445],[-65.871948,-47.758057],[-66.243622,-47.860283],[-65.787231,-47.962502],[-67.579453,-49.034172],[-67.897232,-49.98584],[-69.011124,-50.011948],[-68.37028499999988,-50.146667],[-68.941116,-50.388062],[-69.40888999999987,-51.077782],[-69.183624,-50.970558],[-68.968063,-51.573891],[-69.613892,-51.625839],[-68.988068,-51.624725],[-68.441757,-52.377777],[-69.998337,-51.996391],[-71.910568,-51.995834],[-72.400558,-51.513618],[-72.294174,-50.649727],[-73.16612199999986,-50.753334],[-73.58361799999989,-49.538063],[-72.564178,-48.804451],[-72.287231,-48.341949],[-72.53639199999986,-47.921394],[-72.360291,-47.470001],[-71.868622,-47.221672],[-71.940292,-46.815559],[-71.669449,-46.679169],[-71.780563,-45.648895],[-71.297791,-45.293335],[-72.078613,-44.769447],[-71.282227,-44.800285],[-71.108063,-44.539726],[-71.855011,-44.371674],[-71.732788,-43.188057],[-72.136948,-43.009171],[-72.131958,-42.288895],[-71.72612,-42.096672],[-71.95056199999988,-40.73278],[-71.695557,-39.58445],[-71.401398,-38.92028],[-70.824173,-38.568062],[-71.185287,-36.842224],[-70.424316,-36.13604],[-70.567505,-35.24778],[-69.8125,-34.235558],[-69.774445,-33.381111],[-70.098892,-33.172501],[-70.533066,-31.188057],[-69.83168,-30.190556],[-70.031403,-29.306393],[-69.65538,-28.400932],[-68.810837,-27.120556],[-68.287231,-26.915279],[-68.583618,-26.50528],[-68.35195899999988,-25.117226],[-68.56500199999988,-24.774445],[-67.335846,-24.021667],[-67.00083899999987,-23.002781],[-67.183624,-22.821667],[-66.22300699999988,-21.780521],[-65.748062,-22.111668]]]]}},{"type":"Feature","properties":{"name":"Australia","iso2":"AU","iso3":"AUS"},"geometry":{"type":"MultiPolygon","coordinates":[[[[158.882173538208,-54.711387634277344],[158.83331489562988,-54.749725341796875],[158.95746040344238,-54.47471618652344],[158.882173538208,-54.711387634277344]]],[[[147.36273384094238,-43.39805603027344],[147.1230182647705,-43.42194366455078],[147.29193305969238,-43.26194763183594],[147.36273384094238,-43.39805603027344]]],[[[147.42968940734863,-43.25361633300781],[147.29193305969238,-43.16444396972656],[147.359956741333,-43.07361602783203],[147.42968940734863,-43.25361633300781]]],[[[148.17053413391113,-42.66388702392578],[148.01416206359863,-42.75305938720703],[148.021089553833,-42.61805725097656],[148.17053413391113,-42.66388702392578]]],[[[148.33331489562988,-42.35889434814453],[148.23108100891113,-42.30194091796875],[148.31912422180176,-42.312774658203125],[148.33331489562988,-42.35889434814453]]],[[[145.10772895812988,-40.82167053222656],[146.58609199523926,-41.18666076660156],[148.22329902648926,-40.85083770751953],[148.36551094055176,-42.215003967285156],[148.18387031555176,-41.94305419921875],[147.84301948547363,-42.86944580078125],[147.99524116516113,-43.22972106933594],[147.317476272583,-42.84666442871094],[146.91670417785645,-43.61784362792969],[146.0383014678955,-43.49805450439453],[146.23636054992676,-43.32722473144531],[145.496919631958,-42.95777893066406],[145.20523262023926,-42.25695037841797],[145.55191230773926,-42.34416198730469],[144.682466506958,-41.22332763671875],[144.70135688781738,-40.75917053222656],[145.10772895812988,-40.82167053222656]]],[[[144.926362991333,-40.722496032714844],[144.92413520812988,-40.61528015136719],[145.0160846710205,-40.69554901123047],[144.926362991333,-40.722496032714844]]],[[[148.20025825500488,-40.59416198730469],[148.09720039367676,-40.53388977050781],[148.2157917022705,-40.501943588256836],[148.20025825500488,-40.59416198730469]]],[[[144.75555610656738,-40.59666442871094],[144.71747016906738,-40.50389099121094],[144.77969551086426,-40.40943908691406],[144.75555610656738,-40.59666442871094]]],[[[144.94134712219238,-40.458892822265625],[144.83218574523926,-40.43360900878906],[144.94970893859863,-40.38722229003906],[144.94134712219238,-40.458892822265625]]],[[[148.35467720031738,-40.3155517578125],[148.4758014678955,-40.443885803222656],[147.99356269836426,-40.420555114746094],[148.35467720031738,-40.3155517578125]]],[[[148.1774616241455,-40.25695037841797],[147.88189888000488,-39.754173278808594],[148.27942085266113,-39.96583557128906],[148.1774616241455,-40.25695037841797]]],[[[143.9577350616455,-40.11000061035156],[143.97302436828613,-39.573333740234375],[144.14749336242676,-39.927223205566406],[143.9577350616455,-40.11000061035156]]],[[[147.35357856750488,-39.49944305419922],[147.307466506958,-39.48750305175781],[147.34442329406738,-39.44805145263672],[147.35357856750488,-39.49944305419922]]],[[[147.29998970031738,-39.482215881347656],[147.285249710083,-39.47388458251953],[147.315523147583,-39.43194580078125],[147.29998970031738,-39.482215881347656]]],[[[146.65555000305176,-38.76972198486328],[146.54471015930176,-38.80027770996094],[146.4677448272705,-38.758056640625],[146.65555000305176,-38.76972198486328]]],[[[145.31164741516113,-38.4677734375],[145.36136054992676,-38.56916809082031],[145.11358833312988,-38.52888488769531],[145.31164741516113,-38.4677734375]]],[[[145.49273872375488,-38.37444305419922],[145.271089553833,-38.36333465576172],[145.30581855773926,-38.29695129394531],[145.49273872375488,-38.37444305419922]]],[[[137.58496284484863,-35.65083312988281],[138.11273384094238,-35.869720458984375],[136.53442573547363,-35.912498474121094],[137.58496284484863,-35.65083312988281]]],[[[136.49524116516113,-35.175559997558594],[136.434419631958,-35.158050537109375],[136.466646194458,-35.13861083984375],[136.49524116516113,-35.175559997558594]]],[[[136.20276069641113,-35.07695007324219],[136.0866413116455,-34.94721984863281],[136.19580268859863,-35.026390075683594],[136.20276069641113,-35.07695007324219]]],[[[118.4719181060791,-34.938331604003906],[118.4246997833252,-34.90777587890625],[118.47638130187988,-34.918060302734375],[118.4719181060791,-34.938331604003906]]],[[[137.358003616333,-34.540283203125],[137.33441352844238,-34.51555633544922],[137.36578559875488,-34.47777557373047],[137.358003616333,-34.540283203125]]],[[[122.24693489074707,-34.15166473388672],[122.22998237609863,-34.112220764160156],[122.25554847717285,-34.12444305419922],[122.24693489074707,-34.15166473388672]]],[[[123.20749092102051,-34.11194610595703],[123.16776466369629,-34.094444274902344],[123.21582221984863,-34.08611297607422],[123.20749092102051,-34.11194610595703]]],[[[134.48663520812988,-33.779998779296875],[134.48025703430176,-33.71416473388672],[134.5402545928955,-33.69666290283203],[134.48663520812988,-33.779998779296875]]],[[[133.58941841125488,-32.311668395996094],[133.53360176086426,-32.304443359375],[133.67498970031738,-32.24055480957031],[133.58941841125488,-32.311668395996094]]],[[[115.68026924133301,-32.22833251953125],[115.66081428527832,-32.233612060546875],[115.64888191223145,-32.1522216796875],[115.68026924133301,-32.22833251953125]]],[[[159.07080268859863,-31.52361297607422],[159.101900100708,-31.57111358642578],[159.07080268859863,-31.599998474121094],[159.07080268859863,-31.52361297607422]]],[[[153.45135688781738,-27.729164123535156],[153.43359565734863,-27.41611099243164],[153.53857612609863,-27.416664123535156],[153.45135688781738,-27.729164123535156]]],[[[153.41497993469238,-27.24805450439453],[153.45413398742676,-27.017780303955078],[153.4252643585205,-27.362777709960938],[153.41497993469238,-27.24805450439453]]],[[[113.20915412902832,-26.14083480834961],[112.95332527160645,-25.786945343017578],[112.95110511779785,-25.488609313964844],[113.20915412902832,-26.14083480834961]]],[[[153.00360298156738,-25.34000015258789],[152.94885444641113,-25.272502899169922],[152.99246406555176,-25.307777404785156],[153.00360298156738,-25.34000015258789]]],[[[113.07361030578613,-25.23360824584961],[113.06165504455566,-25.278614044189453],[113.10164833068848,-25.09722137451172],[113.07361030578613,-25.23360824584961]]],[[[113.13971138000488,-24.926666259765625],[113.11499214172363,-24.995830535888672],[113.14721870422363,-24.76000213623047],[113.13971138000488,-24.926666259765625]]],[[[153.07718086242676,-25.79861068725586],[152.94302558898926,-25.558334350585938],[153.28164863586426,-24.69916534423828],[153.07718086242676,-25.79861068725586]]],[[[151.382173538208,-23.88277816772461],[151.3305377960205,-23.813335418701172],[151.32690620422363,-23.753055572509766],[151.382173538208,-23.88277816772461]]],[[[151.26944160461426,-23.780555725097656],[151.0199909210205,-23.454444885253906],[151.20303535461426,-23.528888702392578],[151.26944160461426,-23.780555725097656]]],[[[150.98217964172363,-23.195552825927734],[150.94720649719238,-23.195552825927734],[150.97830390930176,-23.150554656982422],[150.98217964172363,-23.195552825927734]]],[[[149.73550605773926,-22.423053741455078],[149.73358345031738,-22.340557098388672],[149.76080513000488,-22.363887786865234],[149.73550605773926,-22.423053741455078]]],[[[150.49164009094238,-22.354721069335938],[150.4899616241455,-22.213054656982422],[150.56024360656738,-22.304447174072266],[150.49164009094238,-22.354721069335938]]],[[[149.90081977844238,-22.22833251953125],[149.86578559875488,-22.17388916015625],[149.90832710266113,-22.046945571899414],[149.90081977844238,-22.22833251953125]]],[[[150.33691596984863,-21.775558471679688],[150.29443550109863,-21.744441986083984],[150.3588581085205,-21.73332977294922],[150.33691596984863,-21.775558471679688]]],[[[150.28692817687988,-21.6875],[150.2538776397705,-21.63805389404297],[150.30523872375488,-21.65999984741211],[150.28692817687988,-21.6875]]],[[[115.45498847961426,-20.782501220703125],[115.30386543273926,-20.87277603149414],[115.43525886535645,-20.667221069335938],[115.45498847961426,-20.782501220703125]]],[[[149.06665229797363,-20.526668548583984],[149.03692817687988,-20.501667022705078],[149.07498359680176,-20.486942291259766],[149.06665229797363,-20.526668548583984]]],[[[149.00638008117676,-20.31833267211914],[148.9555377960205,-20.29138946533203],[148.97552680969238,-20.154998779296875],[149.00638008117676,-20.31833267211914]]],[[[148.93579292297363,-20.17194366455078],[148.88189888000488,-20.130279541015625],[148.97024726867676,-20.04861068725586],[148.93579292297363,-20.17194366455078]]],[[[148.47134590148926,-20.046390533447266],[148.44970893859863,-19.97083282470703],[148.48217964172363,-20.00611114501953],[148.47134590148926,-20.046390533447266]]],[[[146.86773872375488,-19.165000915527344],[146.7760944366455,-19.13111114501953],[146.86969184875488,-19.106666564941406],[146.86773872375488,-19.165000915527344]]],[[[146.299409866333,-18.48944091796875],[146.08331489562988,-18.25611114501953],[146.26971626281738,-18.308334350585938],[146.299409866333,-18.48944091796875]]],[[[139.57608222961426,-17.09583282470703],[139.39886665344238,-17.091388702392578],[139.502779006958,-16.996665954589844],[139.57608222961426,-17.09583282470703]]],[[[139.11218452453613,-16.862220764160156],[139.0907917022705,-16.82666778564453],[139.139986038208,-16.810558319091797],[139.11218452453613,-16.862220764160156]]],[[[139.73636054992676,-16.49721908569336],[139.14026069641113,-16.755001068115234],[139.30664253234863,-16.46249771118164],[139.73636054992676,-16.49721908569336]]],[[[136.6672077178955,-15.776666641235352],[136.6349811553955,-15.676111221313477],[136.71301460266113,-15.697778701782227],[136.6672077178955,-15.776666641235352]]],[[[136.7419147491455,-15.75222396850586],[136.73413276672363,-15.648056030273438],[136.809419631958,-15.650278091430664],[136.7419147491455,-15.75222396850586]]],[[[137.06720161437988,-15.829444885253906],[136.934419631958,-15.698888778686523],[137.00305366516113,-15.591388702392578],[137.06720161437988,-15.829444885253906]]],[[[136.52997016906738,-15.645278930664062],[136.57940864562988,-15.511112213134766],[136.597749710083,-15.616109848022461],[136.52997016906738,-15.645278930664062]]],[[[136.85135078430176,-15.634166717529297],[136.84192085266113,-15.549722671508789],[136.87857246398926,-15.501943588256836],[136.85135078430176,-15.634166717529297]]],[[[124.62164497375488,-15.412221908569336],[124.52249336242676,-15.44527816772461],[124.45942878723145,-15.366943359375],[124.54221534729004,-15.261667251586914],[124.62164497375488,-15.412221908569336]]],[[[124.42637825012207,-15.315000534057617],[124.33664894104004,-15.296112060546875],[124.43747901916504,-15.249443054199219],[124.42637825012207,-15.315000534057617]]],[[[124.81609535217285,-15.281112670898438],[124.79749488830566,-15.239721298217773],[124.8499927520752,-15.247220993041992],[124.81609535217285,-15.281112670898438]]],[[[128.19192695617676,-15.18861198425293],[128.11468696594238,-15.131942749023438],[128.12051582336426,-15.043054580688477],[128.19192695617676,-15.18861198425293]]],[[[124.94331550598145,-15.030000686645508],[124.87468910217285,-14.95222282409668],[124.92442512512207,-14.944999694824219],[124.94331550598145,-15.030000686645508]]],[[[128.44107246398926,-15.037500381469727],[128.35717964172363,-14.959999084472656],[128.35635566711426,-14.870277404785156],[128.44107246398926,-15.037500381469727]]],[[[135.764986038208,-14.904167175292969],[135.69940376281738,-14.907777786254883],[135.72830390930176,-14.836666107177734],[135.764986038208,-14.904167175292969]]],[[[129.62994575500488,-14.879444122314453],[129.5805377960205,-14.802778244018555],[129.63080024719238,-14.850831985473633],[129.62994575500488,-14.879444122314453]]],[[[129.58941841125488,-14.907777786254883],[129.59247016906738,-14.966665267944336],[129.5019245147705,-14.788612365722656],[129.58941841125488,-14.907777786254883]]],[[[125.1383228302002,-14.648611068725586],[125.08471870422363,-14.61722183227539],[125.1594181060791,-14.438333511352539],[125.1383228302002,-14.648611068725586]]],[[[126.60637092590332,-13.895553588867188],[126.51193428039551,-13.909444808959961],[126.50248908996582,-13.877777099609375],[126.60637092590332,-13.895553588867188]]],[[[136.7116413116455,-13.835832595825195],[136.91247749328613,-13.774444580078125],[136.69940376281738,-14.120832443237305],[136.94165229797363,-14.277778625488281],[136.378023147583,-14.216388702392578],[136.7116413116455,-13.835832595825195]]],[[[136.2883014678955,-13.733331680297852],[136.10553169250488,-13.818056106567383],[136.19885444641113,-13.664722442626953],[136.2883014678955,-13.733331680297852]]],[[[136.15081977844238,-13.485832214355469],[136.16165351867676,-13.531112670898438],[136.0988483428955,-13.36111068725586],[136.15081977844238,-13.485832214355469]]],[[[132.40469551086426,-12.14083480834961],[132.34024238586426,-12.0897216796875],[132.402193069458,-12.072221755981445],[132.40469551086426,-12.14083480834961]]],[[[136.8205280303955,-12.140556335449219],[136.80053901672363,-12.094165802001953],[136.82608222961426,-12.072221755981445],[136.8205280303955,-12.140556335449219]]],[[[134.90997505187988,-12.121110916137695],[134.8669147491455,-12.066665649414062],[134.92776679992676,-12.072776794433594],[134.90997505187988,-12.121110916137695]]],[[[134.98578071594238,-12.03416633605957],[134.94497871398926,-12.061389923095703],[134.91137886047363,-12.022222518920898],[134.98578071594238,-12.03416633605957]]],[[[136.28192329406738,-12.03555679321289],[136.15832710266113,-12.071388244628906],[136.3063678741455,-11.976943969726562],[136.28192329406738,-12.03555679321289]]],[[[135.11551094055176,-11.934444427490234],[135.04748725891113,-11.945554733276367],[135.06497383117676,-11.913612365722656],[135.11551094055176,-11.934444427490234]]],[[[136.47357368469238,-11.911111831665039],[136.46942329406738,-11.840555191040039],[136.494966506958,-11.803054809570312],[136.47357368469238,-11.911111831665039]]],[[[136.58941841125488,-11.780555725097656],[136.5160846710205,-11.79861068725586],[136.62466621398926,-11.740276336669922],[136.58941841125488,-11.780555725097656]]],[[[136.01275825500488,-11.719165802001953],[135.95996284484863,-11.684165954589844],[136.05386543273926,-11.65999984741211],[136.01275825500488,-11.719165802001953]]],[[[132.56024360656738,-11.724443435668945],[132.5138874053955,-11.643890380859375],[132.6430377960205,-11.648056030273438],[132.56024360656738,-11.724443435668945]]],[[[133.383882522583,-11.667499542236328],[133.3669147491455,-11.614721298217773],[133.48245429992676,-11.586944580078125],[133.383882522583,-11.667499542236328]]],[[[136.47052192687988,-11.519166946411133],[136.178316116333,-11.68777847290039],[136.478853225708,-11.466110229492188],[136.47052192687988,-11.519166946411133]]],[[[133.50555610656738,-11.503889083862305],[133.39135932922363,-11.543889999389648],[133.46942329406738,-11.460832595825195],[133.50555610656738,-11.503889083862305]]],[[[130.491060256958,-11.68861198425293],[130.01638984680176,-11.779722213745117],[130.34247016906738,-11.323610305786133],[130.491060256958,-11.68861198425293]]],[[[130.57330513000488,-11.349443435668945],[131.274995803833,-11.189167022705078],[131.539155960083,-11.461666107177734],[130.95886421203613,-11.938888549804688],[130.37744331359863,-11.170555114746094],[130.57330513000488,-11.349443435668945]]],[[[132.62384223937988,-11.279167175292969],[132.51248359680176,-11.143056869506836],[132.57885932922363,-11.022500991821289],[132.62384223937988,-11.279167175292969]]],[[[136.5361042022705,-11.454999923706055],[136.77191352844238,-11.019721984863281],[136.72497749328613,-11.20694351196289],[136.5361042022705,-11.454999923706055]]],[[[142.51275825500488,-10.866943359375],[143.42914009094238,-12.614444732666016],[143.7821979522705,-14.413333892822266],[144.51053047180176,-14.168333053588867],[145.31579780578613,-14.945554733276367],[145.40359687805176,-16.46221923828125],[145.96051216125488,-16.895278930664062],[145.878023147583,-17.06277847290039],[146.10663032531738,-17.683609008789062],[146.00943183898926,-18.238052368164062],[146.33691596984863,-18.536666870117188],[146.27527046203613,-18.883888244628906],[148.77746772766113,-20.232498168945312],[148.9355182647705,-20.532779693603516],[148.69165229797363,-20.62444305419922],[149.214693069458,-21.080001831054688],[149.6611042022705,-22.496665954589844],[150.043306350708,-22.650833129882812],[150.0341510772705,-22.149723052978516],[150.59301948547363,-22.58611297607422],[150.63720893859863,-22.343891143798828],[150.86718940734863,-23.505001068115234],[151.53857612609863,-24.089168548583984],[151.68387031555176,-23.988887786865234],[151.93719673156738,-24.221664428710938],[153.18191719055176,-25.949443817138672],[153.03387641906738,-27.179443359375],[153.62552070617676,-28.666664123535156],[153.0524616241455,-31.03499984741211],[152.52969551086426,-32.40361022949219],[151.45276069641113,-33.31916809082031],[150.84051704406738,-35.08277893066406],[150.16247749328613,-35.9405517578125],[149.9738483428955,-37.52055358886719],[147.76443672180176,-37.97999572753906],[146.87356758117676,-38.65166473388672],[146.22302436828613,-38.712501525878906],[146.394136428833,-39.14722442626953],[145.41607856750488,-38.54583740234375],[145.55719184875488,-38.37638854980469],[145.44134712219238,-38.226104736328125],[144.89886665344238,-38.50444793701172],[145.13244819641113,-38.140281677246094],[144.92914009094238,-37.869163513183594],[143.54385566711426,-38.86000061035156],[142.3888874053955,-38.364723205566406],[141.57135200500488,-38.41722106933594],[140.52997016906738,-38.000282287597656],[139.8144245147705,-37.29972839355469],[139.8205280303955,-36.54583740234375],[139.07734870910645,-35.68263626098633],[139.66775703430176,-36.23082733154297],[139.09674263000488,-35.61588668823242],[139.33719062805176,-35.69416046142578],[139.35522651672363,-35.37249755859375],[138.09301948547363,-35.62083435058594],[138.51416206359863,-35.028053283691406],[138.09802436828613,-34.13722229003906],[137.74469184875488,-35.13861083984375],[136.8305377960205,-35.254722595214844],[137.0199909210205,-34.90110778808594],[137.43774604797363,-34.934722900390625],[137.44998359680176,-34.151390075683594],[137.95025825500488,-33.55944061279297],[137.77331733703613,-32.52361297607422],[137.77832221984863,-32.99250030517578],[137.20996284484863,-33.666107177734375],[135.93274116516113,-34.54194641113281],[135.95413398742676,-35.010284423828125],[135.105806350708,-34.599998474121094],[135.506929397583,-34.61805725097656],[134.70913887023926,-33.179168701171875],[134.269136428833,-33.15972137451172],[134.18414497375488,-32.486663818359375],[133.851900100708,-32.545005798339844],[133.95218086242676,-32.39472198486328],[133.62219429016113,-32.09833526611328],[133.4172077178955,-32.21333312988281],[132.76443672180176,-31.95083236694336],[132.20385932922363,-32.03166961669922],[131.152193069458,-31.474166870117188],[128.98745918273926,-31.694164276123047],[127.26776313781738,-32.27833557128906],[125.96832466125488,-32.26611328125],[124.28193855285645,-32.985557556152344],[123.54081916809082,-33.90583038330078],[120.00499153137207,-33.92888641357422],[117.93441963195801,-35.125831604003906],[116.46331977844238,-35.00083923339844],[115.00804328918457,-34.2630615234375],[114.98872566223145,-33.52253723144531],[115.36360359191895,-33.633056640625],[115.71111488342285,-33.269996643066406],[115.73943519592285,-31.865276336669922],[115.04553413391113,-30.506946563720703],[114.88553810119629,-29.20111083984375],[113.22442817687988,-26.239166259765625],[113.27916145324707,-26.018333435058594],[113.6413745880127,-26.65277862548828],[113.85582160949707,-26.507503509521484],[113.39166450500488,-25.718055725097656],[113.46943855285645,-25.540836334228516],[113.7119312286377,-26.19527816772461],[113.87886238098145,-26.028888702392578],[114.06609535217285,-26.461944580078125],[114.22083473205566,-26.30638885498047],[114.25916481018066,-25.846668243408203],[113.38971138000488,-24.429443359375],[114.01805305480957,-21.850833892822266],[114.15387153625488,-22.52777862548828],[114.65109443664551,-21.84000015258789],[116.70749092102051,-20.649166107177734],[117.68802833557129,-20.675830841064453],[119.08249092102051,-19.967498779296875],[121.0274829864502,-19.59222412109375],[122.35331916809082,-18.105554580688477],[122.17498970031738,-17.243331909179688],[122.91776466369629,-16.41555404663086],[123.57527351379395,-17.59749984741211],[123.59665107727051,-16.98999786376953],[123.91832160949707,-17.204444885253906],[123.42442512512207,-16.50250244140625],[123.7088794708252,-16.430278778076172],[123.5697193145752,-16.17194366455078],[123.72943305969238,-16.13888931274414],[123.8913745880127,-16.378887176513672],[123.96443367004395,-16.24555206298828],[124.23858833312988,-16.406665802001953],[124.8994312286377,-16.415000915527344],[124.40054512023926,-16.329444885253906],[124.72831916809082,-15.810556411743164],[124.4013843536377,-15.871110916137695],[124.4477481842041,-15.486387252807617],[124.65637397766113,-15.479721069335938],[124.70221138000488,-15.252500534057617],[125.18181037902832,-15.520685195922852],[124.82554817199707,-15.155834197998047],[125.43332099914551,-15.138612747192383],[125.13553810119629,-14.741388320922852],[125.5888843536377,-14.549444198608398],[125.60693550109863,-14.223054885864258],[125.63720893859863,-14.635000228881836],[125.71887397766113,-14.400278091430664],[126.03720283508301,-14.516666412353516],[126.01944160461426,-13.919166564941406],[126.28777503967285,-14.233055114746094],[126.86276435852051,-13.749164581298828],[127.42082405090332,-13.949722290039062],[128.16943550109863,-14.702777862548828],[128.01361274719238,-15.5],[128.129243850708,-15.212888717651367],[128.28997993469238,-15.405279159545898],[128.19412422180176,-15.05666732788086],[128.31497383117676,-14.907777786254883],[128.3508014678955,-15.044723510742188],[128.45245552062988,-15.046388626098633],[128.38189888000488,-14.802499771118164],[128.53027534484863,-14.759166717529297],[129.73245429992676,-15.197221755981445],[129.64386177062988,-14.837221145629883],[129.944429397583,-14.767778396606445],[129.37024116516113,-14.333332061767578],[129.88611030578613,-13.44527816772461],[130.26443672180176,-13.325277328491211],[130.14081001281738,-12.92416763305664],[130.69525337219238,-12.702499389648438],[130.58304023742676,-12.395278930664062],[130.89636421203613,-12.640277862548828],[131.027193069458,-12.145553588867188],[132.38360786437988,-12.379999160766602],[132.75442695617676,-12.132776260375977],[132.62774848937988,-12.04194450378418],[132.69107246398926,-11.655000686645508],[132.4899616241455,-11.476943969726562],[132.09247016906738,-11.526390075683594],[131.766939163208,-11.316389083862305],[131.9799518585205,-11.125555038452148],[132.19970893859863,-11.412778854370117],[132.14331245422363,-11.133333206176758],[132.33746528625488,-11.129165649414062],[133.18304634094238,-11.716665267944336],[135.23135566711426,-12.294445037841797],[135.90802192687988,-11.763055801391602],[135.66971015930176,-12.196666717529297],[136.023042678833,-12.111944198608398],[136.03970527648926,-12.47166633605957],[136.56219673156738,-11.934444427490234],[136.9819049835205,-12.356943130493164],[136.49441719055176,-12.779167175292969],[136.45800971984863,-13.252500534057617],[136.35052680969238,-13.052499771118164],[135.92386054992676,-13.281389236450195],[136.02026557922363,-13.762500762939453],[135.456636428833,-14.941110610961914],[136.76581001281738,-15.90444564819336],[137.730806350708,-16.246109008789062],[138.19024848937988,-16.704998016357422],[139.01748847961426,-16.903053283691406],[139.26053047180176,-17.342498779296875],[140.494966506958,-17.64083480834961],[141.42691230773926,-16.079166412353516],[141.58386421203613,-12.989166259765625],[141.79858589172363,-12.685832977294922],[141.94079780578613,-12.875831604003906],[141.75247383117676,-12.467222213745117],[141.58941841125488,-12.546945571899414],[142.02887153625488,-12.06222152709961],[142.141939163208,-10.956666946411133],[142.51275825500488,-10.866943359375]]],[[[142.26581001281738,-10.683610916137695],[142.1833209991455,-10.770278930664062],[142.11523628234863,-10.66055679321289],[142.26581001281738,-10.683610916137695]]],[[[142.2780475616455,-10.643611907958984],[142.24969673156738,-10.587499618530273],[142.31414985656738,-10.584165573120117],[142.2780475616455,-10.643611907958984]]],[[[142.230806350708,-10.568889617919922],[142.19134712219238,-10.565834045410156],[142.22662544250488,-10.525278091430664],[142.230806350708,-10.568889617919922]]],[[[142.32107734680176,-10.54861068725586],[142.2922077178955,-10.533889770507812],[142.31802558898926,-10.51388931274414],[142.32107734680176,-10.54861068725586]]],[[[142.28552436828613,-10.26472282409668],[142.2258014678955,-10.146112442016602],[142.3305377960205,-10.171945571899414],[142.28552436828613,-10.26472282409668]]],[[[142.15774726867676,-10.189722061157227],[142.089693069458,-10.133890151977539],[142.14358711242676,-10.051666259765625],[142.15774726867676,-10.189722061157227]]]]}},{"type":"Feature","properties":{"name":"Bahrain","iso2":"BH","iso3":"BHR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[50.812492000000105,25.64222],[50.782219,25.65944300000011],[50.821388,25.651943],[50.812492000000105,25.64222]]],[[[50.813332,25.678608],[50.804161,25.680553],[50.807777,25.68972],[50.813332,25.678608]]],[[[50.76194000000012,25.595276],[50.741661000000164,25.683052],[50.796661,25.72833300000012],[50.76194000000012,25.595276]]],[[[50.769722,25.746944],[50.760551000000106,25.750275],[50.764717000000104,25.75471900000015],[50.769722,25.746944]]],[[[50.532219,26.234444],[50.57333,25.809723],[50.46166200000019,25.965275],[50.532219,26.234444]]],[[[50.6536100000001,26.247498],[50.604439,26.267776],[50.62722,26.288887],[50.6536100000001,26.247498]]]]}},{"type":"Feature","properties":{"name":"Barbados","iso2":"BB","iso3":"BRB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-59.533058,13.050554],[-59.641113,13.331388],[-59.429169,13.164999],[-59.533058,13.050554]]]]}},{"type":"Feature","properties":{"name":"Bermuda","iso2":"BM","iso3":"BMU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-64.855835,32.278610000000114],[-64.874451,32.293053],[-64.838058,32.314163000000136],[-64.855835,32.278610000000114]]],[[[-64.643341,32.35443900000014],[-64.685837,32.357216],[-64.6552889999999,32.370827],[-64.643341,32.35443900000014]]],[[[-64.78334,32.270554],[-64.858269,32.266796],[-64.671677,32.379997],[-64.78334,32.270554]]]]}},{"type":"Feature","properties":{"name":"Bahamas","iso2":"BS","iso3":"BHS"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-73.0372314453125,21.13944435119629],[-73.68583679199219,20.935556411743164],[-73.02444458007812,21.33249855041504],[-73.0372314453125,21.13944435119629]]],[[[-72.92472839355469,21.483610153198242],[-73.03807067871094,21.434999465942383],[-73.0675048828125,21.507776260375977],[-72.92472839355469,21.483610153198242]]],[[[-72.82917785644531,22.38222312927246],[-72.78140258789062,22.28416633605957],[-73.16473388671875,22.370832443237305],[-72.82917785644531,22.38222312927246]]],[[[-73.61029052734375,22.579721450805664],[-73.62055969238281,22.599721908569336],[-73.59834289550781,22.614721298217773],[-73.61029052734375,22.579721450805664]]],[[[-73.46278381347656,22.601945877075195],[-73.5513916015625,22.61222267150879],[-73.49778747558594,22.6188907623291],[-73.46278381347656,22.601945877075195]]],[[[-74.37779235839844,22.538888931274414],[-74.37945556640625,22.576387405395508],[-74.28001403808594,22.662500381469727],[-74.37779235839844,22.538888931274414]]],[[[-73.84722900390625,22.72361183166504],[-73.86750793457031,22.469446182250977],[-74.28140258789062,22.17305564880371],[-73.84722900390625,22.72361183166504]]],[[[-74.07362365722656,22.663331985473633],[-74.34390258789062,22.83500099182129],[-74.01779174804688,22.71639060974121],[-74.07362365722656,22.663331985473633]]],[[[-73.72889709472656,23.070554733276367],[-73.81361389160156,23.09694480895996],[-73.66500854492188,23.08888816833496],[-73.72889709472656,23.070554733276367]]],[[[-75.55111694335938,23.4313907623291],[-75.52500915527344,23.404443740844727],[-75.65084838867188,23.45583152770996],[-75.55111694335938,23.4313907623291]]],[[[-75.02139282226562,23.10638999938965],[-75.30751037597656,23.667776107788086],[-74.83056640625,22.8608341217041],[-75.02139282226562,23.10638999938965]]],[[[-75.77195739746094,23.499723434448242],[-75.99111938476562,23.599443435668945],[-76.02862358093262,23.67249870300293],[-75.77195739746094,23.499723434448242]]],[[[-74.78195190429688,23.683889389038086],[-74.81973266601562,23.63944435119629],[-74.94862365722656,23.685277938842773],[-74.78195190429688,23.683889389038086]]],[[[-76.3638916015625,24.072221755981445],[-76.32167053222656,23.972776412963867],[-76.39834594726562,24.113332748413086],[-76.3638916015625,24.072221755981445]]],[[[-74.49028015136719,23.954442977905273],[-74.52694702148438,24.100831985473633],[-74.46084594726562,24.142778396606445],[-74.49028015136719,23.954442977905273]]],[[[-77.94667053222656,24.149999618530273],[-77.9716796875,24.1936092376709],[-77.80029296875,24.253332138061523],[-77.94667053222656,24.149999618530273]]],[[[-77.93667602539062,24.225831985473633],[-78.01945495605469,24.25083351135254],[-77.93112182617188,24.279443740844727],[-77.93667602539062,24.225831985473633]]],[[[-76.46890258789062,24.21000099182129],[-76.50361633300781,24.2177791595459],[-76.5452880859375,24.2902774810791],[-76.46890258789062,24.21000099182129]]],[[[-77.73556518554688,24.02861213684082],[-77.60667419433594,24.21388816833496],[-77.56695556640625,23.739168167114258],[-77.87667846679688,24.073057174682617],[-77.6763916015625,24.296110153198242],[-77.73556518554688,24.02861213684082]]],[[[-77.68695068359375,24.337221145629883],[-77.80667114257812,24.31972312927246],[-77.70333862304688,24.369722366333008],[-77.68695068359375,24.337221145629883]]],[[[-75.31472778320312,24.21388816833496],[-75.5150146484375,24.13972282409668],[-75.73945617675781,24.69500160217285],[-75.31472778320312,24.21388816833496]]],[[[-77.4364013671875,25.008054733276367],[-77.5614013671875,25.027498245239258],[-77.25862121582031,25.0494441986084],[-77.4364013671875,25.008054733276367]]],[[[-78.19195556640625,25.203611373901367],[-77.7166748046875,24.50666618347168],[-78.02139282226562,24.27277946472168],[-78.44056701660156,24.613611221313477],[-78.19277954101562,24.597501754760742],[-78.19195556640625,25.203611373901367]]],[[[-76.53334045410156,25.398332595825195],[-76.34970092773438,25.34328269958496],[-76.11889457702637,25.1311092376709],[-76.1683349609375,24.690000534057617],[-76.17167663574219,25.140832901000977],[-76.3558349609375,25.318334579467773],[-76.71583557128906,25.441667556762695],[-76.73529052734375,25.559167861938477],[-76.53334045410156,25.398332595825195]]],[[[-77.82194519042969,25.70222282409668],[-77.8880615234375,25.785001754760742],[-77.85639953613281,25.775278091430664],[-77.82194519042969,25.70222282409668]]],[[[-77.56333923339844,26.268888473510742],[-77.572509765625,26.336111068725586],[-77.5372314453125,26.306943893432617],[-77.56333923339844,26.268888473510742]]],[[[-77.917236328125,26.74527931213379],[-78.7086181640625,26.489721298217773],[-78.97889709472656,26.695276260375977],[-77.917236328125,26.74527931213379]]],[[[-77.73500061035156,26.914445877075195],[-77.042236328125,26.50889015197754],[-77.20472717285156,25.880834579467773],[-77.39805603027344,26.02638816833496],[-77.14889526367188,26.548887252807617],[-77.95028686523438,26.89777946472168],[-77.73500061035156,26.914445877075195]]]]}},{"type":"Feature","properties":{"name":"Bangladesh","iso2":"BD","iso3":"BGD"},"geometry":{"type":"MultiPolygon","coordinates":[[[[91.89749336242676,21.47666358947754],[91.88109016418457,21.755277633666992],[91.98221015930176,21.62388801574707],[91.89749336242676,21.47666358947754]]],[[[90.49054145812988,21.80360984802246],[90.46748542785645,21.820554733276367],[90.49275398254395,21.814443588256836],[90.49054145812988,21.80360984802246]]],[[[90.43248176574707,21.819997787475586],[90.41276741027832,21.823610305786133],[90.4527759552002,21.85027503967285],[90.43248176574707,21.819997787475586]]],[[[89.12664985656738,21.714162826538086],[89.05053901672363,21.91472053527832],[89.1463794708252,21.748884201049805],[89.12664985656738,21.714162826538086]]],[[[90.75305366516113,21.891942977905273],[90.74443244934082,21.92249870300293],[90.76220893859863,21.90638542175293],[90.75305366516113,21.891942977905273]]],[[[91.83276557922363,21.722219467163086],[91.86303901672363,21.92805290222168],[91.88638496398926,21.842775344848633],[91.83276557922363,21.722219467163086]]],[[[90.64387702941895,21.90610694885254],[90.63333320617676,21.930551528930664],[90.6655445098877,21.95555305480957],[90.64387702941895,21.90610694885254]]],[[[90.69914436340332,21.9547176361084],[90.67526435852051,21.94999885559082],[90.69053840637207,21.9727725982666],[90.69914436340332,21.9547176361084]]],[[[90.52249336242676,21.855833053588867],[90.51971626281738,21.9355525970459],[90.58831977844238,21.981386184692383],[90.52249336242676,21.855833053588867]]],[[[90.41081428527832,21.899442672729492],[90.43026924133301,22.04222297668457],[90.48498725891113,21.964998245239258],[90.41081428527832,21.899442672729492]]],[[[90.37414741516113,22.010000228881836],[90.34166145324707,21.966386795043945],[90.3802661895752,22.050554275512695],[90.37414741516113,22.010000228881836]]],[[[90.52360725402832,21.991106033325195],[90.48692512512207,22.078886032104492],[90.6121997833252,22.16388511657715],[90.52360725402832,21.991106033325195]]],[[[90.51693916320801,22.16221809387207],[90.51220893859863,22.171110153198242],[90.52777290344238,22.179441452026367],[90.51693916320801,22.16221809387207]]],[[[90.93748664855957,22.112775802612305],[90.91470527648926,22.131940841674805],[90.95221138000488,22.209440231323242],[90.93748664855957,22.112775802612305]]],[[[90.98498725891113,22.182497024536133],[90.97192573547363,22.24083137512207],[90.99165534973145,22.259164810180664],[90.98498725891113,22.182497024536133]]],[[[90.94941902160645,22.221384048461914],[90.97638130187988,22.35777473449707],[90.98858833312988,22.286943435668945],[90.94941902160645,22.221384048461914]]],[[[91.00583076477051,22.36805534362793],[90.98526191711426,22.38527488708496],[90.98997688293457,22.41416358947754],[91.00583076477051,22.36805534362793]]],[[[90.66026496887207,22.356386184692383],[90.6402759552002,22.308332443237305],[90.61026191711426,22.451940536499023],[90.66026496887207,22.356386184692383]]],[[[91.03610420227051,22.404996871948242],[91.01805305480957,22.41472053527832],[91.0405445098877,22.4536075592041],[91.03610420227051,22.404996871948242]]],[[[91.21054267883301,22.41221809387207],[91.18553352355957,22.39249610900879],[91.1685962677002,22.46138572692871],[91.21054267883301,22.41221809387207]]],[[[91.00749397277832,22.424997329711914],[90.98776435852051,22.440832138061523],[91.00915718078613,22.47638511657715],[91.00749397277832,22.424997329711914]]],[[[90.66304206848145,22.434995651245117],[90.64749336242676,22.42777442932129],[90.65555000305176,22.478609085083008],[90.66304206848145,22.434995651245117]]],[[[91.03166389465332,22.084165573120117],[91.08804512023926,22.52583122253418],[91.1746997833252,22.21860694885254],[91.03166389465332,22.084165573120117]]],[[[91.52971076965332,22.347776412963867],[91.40832710266113,22.472219467163086],[91.4316577911377,22.62388801574707],[91.52971076965332,22.347776412963867]]],[[[91.33943367004395,22.6299991607666],[91.3177661895752,22.608888626098633],[91.3047046661377,22.628332138061523],[91.33943367004395,22.6299991607666]]],[[[90.76388740539551,22.064443588256836],[90.6010913848877,22.03416633605957],[90.6847095489502,22.39249610900879],[90.64276313781738,22.55305290222168],[90.55693244934082,22.605276107788086],[90.58777046203613,22.771944046020508],[90.87747383117676,22.45722007751465],[90.76388740539551,22.064443588256836]]],[[[90.54721260070801,22.71944236755371],[90.46971321105957,22.868886947631836],[90.69108772277832,22.84694480895996],[90.5416202545166,22.7831974029541],[90.54721260070801,22.71944236755371]]],[[[90.66220283508301,22.956384658813477],[90.63275337219238,22.94916343688965],[90.65609931945801,22.91221809387207],[90.50915718078613,22.951108932495117],[90.57083320617676,23.0402774810791],[90.66220283508301,22.956384658813477]]],[[[90.47747993469238,23.007776260375977],[90.46331977844238,23.05916404724121],[90.51082038879395,23.06194496154785],[90.47747993469238,23.007776260375977]]],[[[90.52971076965332,23.04722023010254],[90.52192878723145,23.054719924926758],[90.54498481750488,23.065275192260742],[90.52971076965332,23.04722023010254]]],[[[90.54081916809082,23.343889236450195],[90.59027290344238,23.302499771118164],[90.4216480255127,23.383054733276367],[90.54081916809082,23.343889236450195]]],[[[90.57361030578613,23.564722061157227],[90.56442451477051,23.57694435119629],[90.58415412902832,23.583887100219727],[90.57361030578613,23.564722061157227]]],[[[88.43304634094238,26.551389694213867],[89.34277534484863,26.017030715942383],[89.7391529083252,26.15638542175293],[89.84526252746582,25.288610458374023],[92.40637397766113,25.030553817749023],[92.12137031555176,24.39333152770996],[91.37329292297363,24.10194206237793],[91.15942573547363,23.640554428100586],[91.61360359191895,22.943052291870117],[91.94999885559082,23.73221778869629],[92.28332710266113,23.70527458190918],[92.60081672668457,21.98221778869629],[92.66934394836426,21.29698371887207],[92.26082038879395,21.41444206237793],[92.26193428039551,21.054311752319336],[92.32361030578613,20.73805046081543],[91.69999885559082,22.48832893371582],[91.4558277130127,22.78999900817871],[90.83360481262207,22.6855525970459],[90.59382820129395,23.59796714782715],[90.30887031555176,23.41444206237793],[90.61248970031738,23.222219467163086],[90.57859992980957,23.089998245239258],[90.44664192199707,23.065000534057617],[90.42440223693848,22.77018928527832],[90.61775398254395,22.3538875579834],[90.44053840637207,22.071664810180664],[90.4013843536377,22.260557174682617],[90.27249336242676,21.849164962768555],[90.02470588684082,21.85999870300293],[90.07304573059082,22.16277503967285],[89.93220710754395,21.997774124145508],[90.00000190734863,22.48375129699707],[89.58110237121582,21.701662063598633],[89.62082099914551,22.32444190979004],[89.24914741516113,21.64249610900879],[89.0630054473877,22.115476608276367],[88.9861011505127,23.208330154418945],[88.56387519836426,23.652219772338867],[88.75053596496582,24.220983505249023],[88.04332160949707,24.68416404724121],[88.4508228302002,25.187776565551758],[89.00943183898926,25.288331985473633],[88.11053657531738,25.835554122924805],[88.43304634094238,26.551389694213867]],[[90.23776435852051,22.192773818969727],[90.06137275695801,21.99177360534668],[90.21609687805176,22.114442825317383],[90.23776435852051,22.192773818969727]],[[90.68498420715332,23.48277473449707],[90.69192695617676,23.497217178344727],[90.65027046203613,23.504167556762695],[90.68498420715332,23.48277473449707]]]]}},{"type":"Feature","properties":{"name":"Belize","iso2":"BZ","iso3":"BLZ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-87.803345,17.294167000000144],[-87.825012,17.291664000000154],[-87.82695,17.400276],[-87.803345,17.294167000000144]]],[[[-87.820557,17.426941],[-87.926682,17.275555],[-87.81945799999988,17.549999],[-87.820557,17.426941]]],[[[-88.045013,17.552776],[-88.070282,17.638332],[-88.053619,17.613052],[-88.045013,17.552776]]],[[[-88.132507,17.667221],[-88.167511,17.66972],[-88.072784,17.73388700000011],[-88.132507,17.667221]]],[[[-87.892227,18.0425],[-88.006119,17.901943000000145],[-87.853058,18.164719],[-87.892227,18.0425]]],[[[-88.377792,18.482777000000127],[-88.2995,18.482929],[-88.077789,18.215553],[-88.281403,17.636108],[-88.208618,16.968609],[-88.910568,15.893610000000123],[-89.216171,15.88985100000015],[-89.141953,17.818886],[-88.377792,18.482777000000127]]]]}},{"type":"Feature","properties":{"name":"Bosnia and Herzegovina","iso2":"BA","iso3":"BIH"},"geometry":{"type":"MultiPolygon","coordinates":[[[[17.649841,42.889076],[17.578526000000124,42.943825],[16.143055,44.19944],[15.786665,45.171944],[18.251942,45.138885],[19.039719,44.861382],[19.371387,44.88916],[19.104443,44.355827],[19.620476,44.048454],[19.237019,44.011009],[19.51083,43.679718],[19.228809,43.513214],[18.699997,43.255554],[18.455555,42.565826],[17.649841,42.889076]]]]}},{"type":"Feature","properties":{"name":"Bolivia","iso2":"BO","iso3":"BOL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-65.190201,-22.09473],[-65.748062,-22.111668],[-66.22300699999988,-21.780521],[-67.183624,-22.821667],[-67.876404,-22.828056],[-68.188614,-21.296947],[-68.756958,-20.406948],[-68.4375,-19.430279],[-68.907791,-19.055279],[-69.071671,-18.038891],[-69.48361199999988,-17.635559],[-69.499725,-17.50528],[-69.618896,-17.214725],[-68.82251,-16.339725],[-69.421951,-15.618057],[-69.136948,-15.245834],[-69.366394,-14.802502],[-68.853058,-14.199167],[-68.974457,-12.869722],[-68.673904,-12.50115],[-69.568436,-10.951092],[-68.58344999999986,-11.106138],[-66.634445,-9.906946],[-65.381958,-9.697779],[-65.392792,-11.26639],[-64.991669,-12.008057],[-64.39418,-12.461668],[-63.07500499999989,-12.650002],[-61.833893,-13.544724],[-61.038979,-13.493118],[-60.470839999999896,-13.807222],[-60.258896,-15.093613],[-60.571396,-15.097502],[-60.160278,-16.263058],[-58.327507,-16.279167],[-58.397507,-17.249168],[-57.743057,-17.593056],[-57.521118,-18.203892],[-58.121117,-19.74139],[-57.84874699999989,-19.978794],[-58.15889,-20.168056],[-58.15139,-19.828056],[-59.09584,-19.348892],[-61.7425,-19.645],[-62.643768,-22.238903],[-62.811951,-21.996948],[-63.941116,-22.000835],[-64.324722,-22.873611],[-64.590561,-22.214725],[-65.190201,-22.09473]]]]}},{"type":"Feature","properties":{"name":"Burma","iso2":"MM","iso3":"MMR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[98.0358120000001,9.786386],[98.024994,9.838331],[98.060257,9.81361],[98.0358120000001,9.786386]]],[[[98.29332000000014,10.010277],[98.116089,9.852497],[98.17858900000013,10.017776],[98.29332000000014,10.010277]]],[[[98.186646,10.040276],[98.19859300000022,10.189999],[98.238876,10.165833],[98.186646,10.040276]]],[[[97.907486,10.396944000000133],[97.903595,10.490831],[97.942749,10.442776],[97.907486,10.396944000000133]]],[[[98.216385,10.481386],[98.1824800000002,10.5075],[98.238876,10.529999],[98.216385,10.481386]]],[[[98.52360500000012,10.781666],[98.486923,10.883053],[98.550812,10.850275],[98.52360500000012,10.781666]]],[[[97.919708,10.858332],[97.885818,10.843609],[97.91609200000019,10.929443],[97.919708,10.858332]]],[[[98.21220400000018,10.947777000000102],[98.264435,10.68972],[98.075546,10.88611],[98.21220400000018,10.947777000000102]]],[[[98.437195,10.961943000000161],[98.42997700000015,10.995831],[98.452774,11.007776],[98.437195,10.961943000000161]]],[[[98.533875,10.950554],[98.470535,10.983887],[98.524994,11.087219000000147],[98.533875,10.950554]]],[[[98.25610400000019,11.212498],[98.23109400000013,11.262499],[98.27777100000012,11.276388],[98.25610400000019,11.212498]]],[[[98.20748900000015,11.443609000000109],[98.289154,11.798609],[98.28082300000014,11.481665000000106],[98.20748900000015,11.443609000000109]]],[[[98.49832200000012,11.566109],[98.3713680000001,11.78611],[98.548874,11.788332],[98.49832200000012,11.566109]]],[[[97.48719800000012,11.774443000000133],[97.43775900000011,11.803331],[97.4616550000002,11.803053],[97.48719800000012,11.774443000000133]]],[[[98.089981,11.631109000000109],[98.033051,11.683054000000169],[98.007217,11.858332],[98.089981,11.631109000000109]]],[[[97.66832,11.836943],[97.633881,11.876108],[97.664429,11.901110000000102],[97.66832,11.836943]]],[[[98.271103,11.84972],[98.260269,11.907221],[98.28804,11.887499000000133],[98.271103,11.84972]]],[[[98.256378,11.92111],[98.226379,11.94972],[98.251663,11.980276],[98.256378,11.92111]]],[[[98.5,11.884443],[98.438583,12.111387],[98.664993,11.941942],[98.5,11.884443]]],[[[98.14193700000013,12.141943],[98.05554200000014,12.281111],[98.124695,12.27861],[98.14193700000013,12.141943]]],[[[98.64082300000021,12.372219],[98.619141,12.378885000000153],[98.639709,12.380552],[98.64082300000021,12.372219]]],[[[98.61780500000012,12.352951],[98.68248,12.340553],[98.55970800000014,12.328886],[98.540817,12.370552],[98.57193,12.409164],[98.61780500000012,12.352951]]],[[[98.09166,12.360554],[98.00555400000022,12.281942],[97.937485,12.337498],[98.09166,12.360554]]],[[[98.501099,12.402222],[98.471924,12.417776000000146],[98.49887100000015,12.513887],[98.501099,12.402222]]],[[[98.285812,12.502499000000114],[98.24331700000019,12.49222],[98.229706,12.548054000000107],[98.285812,12.502499000000114]]],[[[97.853592,12.539999000000122],[97.817764,12.583332000000112],[97.837494,12.598053],[97.853592,12.539999000000122]]],[[[98.349426,12.316942000000111],[98.32193000000015,12.67111],[98.46693400000018,12.570831],[98.349426,12.316942000000111]]],[[[97.872208,12.764166000000131],[97.83728,12.772419000000156],[97.84414700000016,12.819443],[97.872208,12.764166000000131]]],[[[98.304153,13.041666000000106],[98.29803500000017,12.941387],[98.23942600000012,13.213331],[98.304153,13.041666000000106]]],[[[97.92109700000012,13.783054],[97.921921,13.861664000000161],[97.934708,13.851664],[97.92109700000012,13.783054]]],[[[97.924423,13.905832],[97.92303500000017,13.894444],[97.91835,13.93908100000013],[97.924423,13.905832]]],[[[93.380539,14.064165],[93.38638300000017,14.151665],[93.4008180000001,14.096109],[93.380539,14.064165]]],[[[97.80636600000011,14.134443],[97.78915400000014,14.155277],[97.814148,14.179998000000126],[97.80636600000011,14.134443]]],[[[93.722488,14.904444],[93.679153,14.848331],[93.6922,14.890833],[93.722488,14.904444]]],[[[97.669708,15.521387],[97.66304,15.497219],[97.65416,15.578331],[97.669708,15.521387]]],[[[94.79776000000012,15.791666],[94.728043,15.815275],[94.82054100000013,15.948053],[94.79776000000012,15.791666]]],[[[94.583328,16.00972],[94.415817,15.868053000000103],[94.38665800000015,15.995831],[94.649429,16.245274],[94.583328,16.00972]]],[[[97.569153,16.233604],[97.515549,16.506107],[97.616653,16.465271000000158],[97.569153,16.233604]]],[[[93.67109700000017,18.867496000000145],[93.703049,18.668053],[93.48442100000014,18.869717],[93.67109700000017,18.867496000000145]]],[[[93.79092400000016,19.231342],[93.94220000000021,18.862495],[93.49054000000015,19.400829],[93.79092400000016,19.231342]]],[[[93.801651,19.268608],[93.682755,19.560555],[93.96832300000014,19.42083],[93.801651,19.268608]]],[[[93.51304600000017,19.744438],[93.395828,19.955273],[93.498596,19.88055],[93.51304600000017,19.744438]]],[[[93.024429,19.827774000000105],[92.912491,20.086662],[92.954437,20.06361],[93.024429,19.827774000000105]]],[[[97.806641,28.344162],[98.316376,27.541943],[98.699707,27.539165],[98.77832,26.636383],[98.710815,25.855553],[97.5524750000001,24.74305],[97.759995,24.257496],[97.535538,23.939716],[98.890732,24.16006900000015],[98.6772,23.968052],[98.927475,23.189163000000107],[99.566376,22.938049],[99.162766,22.159161],[99.964432,22.048885],[100.212753,21.432552],[101.10526300000018,21.771385],[101.14823900000013,21.572636],[100.09137,20.348606],[100.08132200000014,20.348841],[99.522766,20.352776000000134],[98.995529,19.780552],[98.049988,19.807499000000135],[97.774704,18.569996],[97.346375,18.562496000000138],[98.68969700000011,16.284996],[98.92804,16.38583],[98.201096,15.074999],[99.173965,13.727781],[99.112198,13.055832],[99.661652,11.826942],[98.742752,10.348608],[98.54664600000015,9.981665],[98.46026600000019,10.734442],[98.710815,10.918331],[98.743591,11.666943000000117],[98.890549,11.700275],[98.597488,11.751665],[98.72192400000014,11.976109],[98.705872,12.224465],[98.533165,12.245721],[98.70359000000022,12.340046],[98.583328,13.172775],[98.18553200000011,14.059164000000138],[98.13888500000016,13.539721],[97.797256,14.881962],[97.737488,16.563885],[97.378036,16.494995],[96.87803600000021,17.449997],[96.77777100000017,16.703884000000116],[96.3797,16.501389],[96.241928,16.803734],[96.268326,16.389717000000147],[95.42858900000013,15.729719],[95.3608090000001,16.144718],[95.216385,15.782776000000112],[95.13720700000013,16.137218],[94.848877,15.77972],[94.99081400000014,16.246662000000114],[94.650543,15.854164],[94.793045,16.153606],[94.560257,15.941942],[94.679703,16.115829],[94.631088,16.34277300000015],[94.24552900000018,15.959997],[94.6147,17.546387],[93.99192800000017,19.457218],[93.599152,19.719715],[93.728592,19.931664],[93.128311,20.085552],[93.12997400000015,19.835552000000106],[93.081665,20.548607],[92.860809,20.121109],[92.261932,21.05431],[92.26081800000011,21.41444000000014],[92.669342,21.296982],[92.600815,21.982216],[93.19664,22.256386],[93.33873,24.077915],[94.151093,23.855274],[94.734421,25.024719],[94.6255340000001,25.397774],[95.17804,26.058887],[95.141373,26.612495000000123],[96.194138,27.270832],[97.13665800000015,27.085831],[96.886658,27.60610600000011],[97.3488770000001,28.222771],[97.555252,28.548054000000107],[97.806641,28.344162]]]]}},{"type":"Feature","properties":{"name":"Benin","iso2":"BJ","iso3":"BEN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[2.484418,6.340486],[1.635404,6.218721],[1.398542,9.429901],[1.355,9.995277],[0.776667,10.376665],[0.91797,10.996399],[1.435278,11.458887],[2.014722,11.422499],[2.397925,11.896152],[2.378054,12.240274],[2.83862,12.396658],[3.604459,11.693274],[3.855,10.584999],[3.095,9.090555],[2.789444,9.043888],[2.719606,6.365505],[2.484418,6.340486]]]]}},{"type":"Feature","properties":{"name":"Solomon Islands","iso2":"SB","iso3":"SLB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[166.85052680969238,-11.696945190429688],[166.76138496398926,-11.579444885253906],[166.93191719055176,-11.66722297668457],[166.85052680969238,-11.696945190429688]]],[[[160.08081245422363,-11.498054504394531],[160.52746772766113,-11.808055877685547],[159.960786819458,-11.521665573120117],[160.08081245422363,-11.498054504394531]]],[[[159.85330390930176,-11.324722290039062],[159.77664375305176,-11.288612365722656],[159.841646194458,-11.303888320922852],[159.85330390930176,-11.324722290039062]]],[[[166.535249710083,-11.363887786865234],[166.5180377960205,-11.271112442016602],[166.5805377960205,-11.324167251586914],[166.535249710083,-11.363887786865234]]],[[[162.47497749328613,-10.855554580688477],[162.48135566711426,-10.807500839233398],[162.50055122375488,-10.84000015258789],[162.47497749328613,-10.855554580688477]]],[[[166.139986038208,-10.761112213134766],[165.77746772766113,-10.805000305175781],[165.904146194458,-10.67361068725586],[166.139986038208,-10.761112213134766]]],[[[161.545259475708,-10.276666641235352],[162.39081001281738,-10.841943740844727],[161.28332710266113,-10.33194351196289],[161.545259475708,-10.276666641235352]]],[[[161.75137519836426,-10.294445037841797],[161.71997261047363,-10.2147216796875],[161.77191352844238,-10.254446029663086],[161.75137519836426,-10.294445037841797]]],[[[167.20385932922363,-9.963611602783203],[167.18829536437988,-9.942222595214844],[167.20800971984863,-9.95083236694336],[167.20385932922363,-9.963611602783203]]],[[[167.12774848937988,-9.88083267211914],[167.108003616333,-9.869165420532227],[167.12634468078613,-9.86722183227539],[167.12774848937988,-9.88083267211914]]],[[[167.10330390930176,-9.851663589477539],[167.08941841125488,-9.84749984741211],[167.10858345031738,-9.84083366394043],[167.10330390930176,-9.851663589477539]]],[[[161.97467231750488,-9.85305404663086],[161.94470405578613,-9.690277099609375],[161.97412300109863,-9.689722061157227],[161.97467231750488,-9.85305404663086]]],[[[161.56912422180176,-9.724166870117188],[161.39721870422363,-9.669445037841797],[161.34997749328613,-9.338888168334961],[161.56912422180176,-9.724166870117188]],[[161.38748359680176,-9.468610763549805],[161.38553047180176,-9.454444885253906],[161.38134956359863,-9.469444274902344],[161.38748359680176,-9.468610763549805]]],[[[159.93829536437988,-9.433610916137695],[160.38638496398926,-9.426666259765625],[160.83108711242676,-9.861944198608398],[159.82803535461426,-9.796945571899414],[159.601900100708,-9.317222595214844],[159.93829536437988,-9.433610916137695]]],[[[159.8285846710205,-9.172500610351562],[159.811372756958,-9.110832214355469],[159.845796585083,-9.138055801391602],[159.8285846710205,-9.172500610351562]]],[[[160.4111042022705,-9.136667251586914],[160.21246528625488,-9.170555114746094],[160.3185749053955,-9.060277938842773],[160.4111042022705,-9.136667251586914]]],[[[159.20440864562988,-9.133333206176758],[159.16803169250488,-9.102775573730469],[159.22830390930176,-9.025556564331055],[159.20440864562988,-9.133333206176758]]],[[[159.14749336242676,-9.108888626098633],[159.03247261047363,-9.060277938842773],[159.13720893859863,-8.994443893432617],[159.14749336242676,-9.108888626098633]]],[[[160.11218452453613,-8.997220993041992],[160.06579780578613,-9.017499923706055],[160.07330513000488,-8.947778701782227],[160.11218452453613,-8.997220993041992]]],[[[160.047212600708,-8.915275573730469],[160.00833320617676,-8.884723663330078],[160.02942085266113,-8.880277633666992],[160.047212600708,-8.915275573730469]]],[[[161.06079292297363,-8.748054504394531],[161.04443550109863,-8.772500991821289],[161.00943183898926,-8.754167556762695],[161.06079292297363,-8.748054504394531]]],[[[157.633882522583,-8.748054504394531],[157.619966506958,-8.800832748413086],[157.44384956359863,-8.71500015258789],[157.633882522583,-8.748054504394531]]],[[[158.20523262023926,-8.833332061767578],[158.14972114562988,-8.781389236450195],[158.2135944366455,-8.681112289428711],[158.20523262023926,-8.833332061767578]]],[[[158.00305366516113,-8.771112442016602],[157.87552070617676,-8.60999870300293],[158.1169147491455,-8.533332824707031],[158.00305366516113,-8.771112442016602]]],[[[157.40832710266113,-8.500833511352539],[157.38443183898926,-8.734443664550781],[157.19912910461426,-8.565834045410156],[157.40832710266113,-8.500833511352539]]],[[[159.6833209991455,-8.546945571899414],[159.53747749328613,-8.468332290649414],[159.56884956359863,-8.378887176513672],[159.6833209991455,-8.546945571899414]]],[[[162.741060256958,-8.37388801574707],[162.76165962219238,-8.378055572509766],[162.72525215148926,-8.381387710571289],[162.741060256958,-8.37388801574707]]],[[[160.97439765930176,-8.84749984741211],[161.378023147583,-9.635000228881836],[160.58026313781738,-8.329999923706055],[160.97439765930176,-8.84749984741211]]],[[[157.12466621398926,-8.255279541015625],[157.15136909484863,-8.342777252197266],[157.023042678833,-8.190834045410156],[157.12466621398926,-8.255279541015625]]],[[[157.20746040344238,-8.270278930664062],[157.09247016906738,-8.165834426879883],[157.18081855773926,-8.170555114746094],[157.20746040344238,-8.270278930664062]]],[[[156.84497261047363,-8.118331909179688],[156.78332710266113,-8.098054885864258],[156.78274726867676,-8.055278778076172],[156.84497261047363,-8.118331909179688]]],[[[157.63162422180176,-8.236387252807617],[157.81192207336426,-8.620832443237305],[157.21441841125488,-8.24305534362793],[157.49746894836426,-7.965555191040039],[157.63162422180176,-8.236387252807617]]],[[[156.5988483428955,-8.203054428100586],[156.53192329406738,-8.091943740844727],[156.5422077178955,-7.944721221923828],[156.5988483428955,-8.203054428100586]]],[[[157.156099319458,-8.150278091430664],[156.9677448272705,-8.046388626098633],[157.027193069458,-7.865276336669922],[157.156099319458,-8.150278091430664]]],[[[158.57190132141113,-7.703611373901367],[158.5321979522705,-7.691387176513672],[158.54998970031738,-7.664165496826172],[158.57190132141113,-7.703611373901367]]],[[[158.53082466125488,-7.654167175292969],[158.35940742492676,-7.640556335449219],[158.31274604797363,-7.580833435058594],[158.53082466125488,-7.654167175292969]]],[[[156.706636428833,-7.897222518920898],[156.5544147491455,-7.578611373901367],[156.80859565734863,-7.726665496826172],[156.706636428833,-7.897222518920898]]],[[[159.85244941711426,-8.33388900756836],[159.8869342803955,-8.566389083862305],[158.48745918273926,-7.554166793823242],[159.85244941711426,-8.33388900756836]]],[[[158.4294147491455,-7.529722213745117],[158.37051582336426,-7.552776336669922],[158.26275825500488,-7.477499008178711],[158.4294147491455,-7.529722213745117]]],[[[157.78164863586426,-7.476110458374023],[157.68359565734863,-7.415555953979492],[157.74939155578613,-7.393888473510742],[157.78164863586426,-7.476110458374023]]],[[[155.58746528625488,-7.390556335449219],[155.51080513000488,-7.351110458374023],[155.5846881866455,-7.331943511962891],[155.58746528625488,-7.390556335449219]]],[[[155.8588581085205,-7.100276947021484],[155.66971015930176,-7.088054656982422],[155.74023628234863,-6.967498779296875],[155.8588581085205,-7.100276947021484]]],[[[156.11023139953613,-6.941110610961914],[156.08496284484863,-6.989442825317383],[156.0746784210205,-6.81916618347168],[156.11023139953613,-6.941110610961914]]],[[[156.0199909210205,-6.824722290039063],[156.00000190734863,-6.803609848022461],[156.045259475708,-6.788610458374023],[156.0199909210205,-6.824722290039063]]],[[[157.42886543273926,-7.324443817138672],[156.93609809875488,-7.219165802001953],[156.438570022583,-6.643611907958984],[157.42886543273926,-7.324443817138672]]],[[[159.712739944458,-5.516666412353516],[159.71414375305176,-5.483888626098633],[159.7238483428955,-5.489999771118164],[159.712739944458,-5.516666412353516]]],[[[159.52859687805176,-5.49888801574707],[159.49633979797363,-5.466943740844727],[159.5099811553955,-5.470832824707031],[159.52859687805176,-5.49888801574707]]],[[[159.40387153625488,-5.448331832885742],[159.37161445617676,-5.440832138061523],[159.3488483428955,-5.41583251953125],[159.40387153625488,-5.448331832885742]]],[[[159.25219917297363,-5.312778472900391],[159.25027656555176,-5.324167251586914],[159.24884223937988,-5.293054580688477],[159.25219917297363,-5.312778472900391]]]]}},{"type":"Feature","properties":{"name":"Brazil","iso2":"BR","iso3":"BRA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-48.550559997558594,-27.821392059326172],[-48.51722717285156,-27.430835723876953],[-48.4183349609375,-27.38888931274414],[-48.550559997558594,-27.821392059326172]]],[[[-48.58111572265625,-26.39167022705078],[-48.70777893066406,-26.309722900390625],[-48.53778076171875,-26.167224884033203],[-48.58111572265625,-26.39167022705078]]],[[[-48.282501220703125,-25.486114501953125],[-48.33306121826172,-25.41305923461914],[-48.25666809082031,-25.338890075683594],[-48.282501220703125,-25.486114501953125]]],[[[-47.877784729003906,-25.026947021484375],[-47.816673278808594,-24.900001525878906],[-47.60667419433594,-24.783611297607422],[-47.877784729003906,-25.026947021484375]]],[[[-46.28278350830078,-23.98917007446289],[-46.41638946533203,-23.950279235839844],[-46.32361602783203,-23.93000030517578],[-46.28278350830078,-23.98917007446289]]],[[[-45.12639617919922,-23.821392059326172],[-45.136390686035156,-23.797779083251953],[-45.105003356933594,-23.806392669677734],[-45.12639617919922,-23.821392059326172]]],[[[-45.22084045410156,-23.77944564819336],[-45.21833801269531,-23.955833435058594],[-45.44139099121094,-23.928890228271484],[-45.22084045410156,-23.77944564819336]]],[[[-44.088890075683594,-23.17444610595703],[-44.369171142578125,-23.172225952148438],[-44.228614807128906,-23.07111358642578],[-44.088890075683594,-23.17444610595703]]],[[[-29.84000015258789,-20.49639129638672],[-29.848892211914062,-20.500835418701172],[-29.852222442626953,-20.491111755371094],[-29.84000015258789,-20.49639129638672]]],[[[-30.29528045654297,-20.505834579467773],[-30.319446563720703,-20.520000457763672],[-30.334165573120117,-20.482223510742188],[-30.29528045654297,-20.505834579467773]]],[[[-38.91166687011719,-13.67527961730957],[-38.99195098876953,-13.593055725097656],[-38.91278076171875,-13.587501525878906],[-38.91166687011719,-13.67527961730957]]],[[[-38.93695068359375,-13.5625],[-38.98445129394531,-13.5625],[-38.96444320678711,-13.498844146728516],[-39.041114807128906,-13.462223052978516],[-39.038612365722656,-13.39777946472168],[-38.908058166503906,-13.385557174682617],[-38.93695068359375,-13.5625]]],[[[-38.754722595214844,-13.113056182861328],[-38.643333435058594,-12.892223358154297],[-38.59166717529297,-12.98750114440918],[-38.754722595214844,-13.113056182861328]]],[[[-37.13250732421875,-11.129446029663086],[-37.146392822265625,-11.108612060546875],[-37.036949157714844,-10.95250129699707],[-37.13250732421875,-11.129446029663086]]],[[[-34.87389373779297,-7.073333740234375],[-34.888893127441406,-7.071945190429688],[-34.866668701171875,-7.048610687255859],[-34.87389373779297,-7.073333740234375]]],[[[-34.85417175292969,-7.005277633666992],[-34.863059997558594,-7.013889312744141],[-34.85972595214844,-6.994443893432617],[-34.85417175292969,-7.005277633666992]]],[[[-32.450836181640625,-3.883609771728516],[-32.424171447753906,-3.845832824707031],[-32.38667297363281,-3.840276718139648],[-32.450836181640625,-3.883609771728516]]],[[[-44.61028289794922,-3.008054733276367],[-44.65611267089844,-2.973609924316406],[-44.611671447753906,-2.887222290039063],[-44.61028289794922,-3.008054733276367]]],[[[-44.586395263671875,-3.052499771118164],[-44.57750701904297,-2.801944732666016],[-44.48389434814453,-2.709999084472656],[-44.586395263671875,-3.052499771118164]]],[[[-42.05083465576172,-2.761667251586914],[-42.1844482421875,-2.677499771118164],[-42.06945037841797,-2.685832977294922],[-42.05083465576172,-2.761667251586914]]],[[[-43.69333457946777,-2.326944351196289],[-43.739173889160156,-2.350276947021484],[-43.61528015136719,-2.26249885559082],[-43.69333457946777,-2.326944351196289]]],[[[-50.8638916015625,-1.910833358764648],[-50.988059997558594,-1.993610382080078],[-51.148338317871094,-1.828611373901367],[-50.8638916015625,-1.910833358764648]]],[[[-49.024169921875,-1.829166412353516],[-49.156951904296875,-1.858055114746094],[-49.05555725097656,-1.721111297607422],[-49.024169921875,-1.829166412353516]]],[[[-48.96111297607422,-1.795831680297852],[-49.046112060546875,-1.705278396606445],[-48.90277862548828,-1.577220916748047],[-48.96111297607422,-1.795831680297852]]],[[[-44.65277862548828,-1.62388801574707],[-44.66222381591797,-1.661945343017578],[-44.778892517089844,-1.668054580688477],[-44.78334045410156,-1.619167327880859],[-44.71305847167969,-1.561111450195313],[-44.65277862548828,-1.62388801574707]]],[[[-52.02472686767578,-1.580278396606445],[-52.200836181640625,-1.646665573120117],[-52.029449462890625,-1.439722061157227],[-51.914451599121094,-1.516387939453125],[-52.02472686767578,-1.580278396606445]]],[[[-52.4183349609375,-1.527500152587891],[-52.431114196777344,-1.466388702392578],[-52.168617248535156,-1.408332824707031],[-52.4183349609375,-1.527500152587891]]],[[[-48.63361358642578,-1.484722137451172],[-48.69667053222656,-1.449167251586914],[-48.657501220703125,-1.375833511352539],[-48.63361358642578,-1.484722137451172]]],[[[-48.525840759277344,-1.524999618530273],[-48.592506408691406,-1.442220687866211],[-48.55333709716797,-1.366109848022461],[-48.525840759277344,-1.524999618530273]]],[[[-44.98750305175781,-1.401945114135742],[-44.975563049316406,-1.261667251586914],[-44.88111114501953,-1.283056259155273],[-44.98750305175781,-1.401945114135742]]],[[[-45.63417053222656,-1.34638786315918],[-45.689443588256836,-1.360832214355469],[-45.626943588256836,-1.126943588256836],[-45.63417053222656,-1.34638786315918]]],[[[-48.34027862548828,-1.212778091430664],[-48.46556091308594,-1.162776947021484],[-48.41222381591797,-1.07499885559082],[-48.32250213623047,-1.076944351196289],[-48.34027862548828,-1.212778091430664]]],[[[-46.49889373779297,-1.02027702331543],[-46.53334045410156,-1.017499923706055],[-46.54833984375,-0.972221374511719],[-46.45667266845703,-0.88861083984375],[-46.44000244140625,-1.006387710571289],[-46.49889373779297,-1.02027702331543]]],[[[-50.98722839355469,-0.866388320922852],[-50.92083740234375,-0.869722366333008],[-51.01261901855469,-0.919502258300781],[-51.019447326660156,-0.991666793823242],[-51.070037841796875,-1.03779411315918],[-51.18250274658203,-1.091667175292969],[-50.98722839355469,-0.866388320922852]]],[[[-51.375282287597656,-1.21360969543457],[-51.40028381347656,-1.201944351196289],[-51.363616943359375,-1.129444122314453],[-51.24889373779297,-1.024721145629883],[-51.20305633544922,-0.841667175292969],[-51.23944854736328,-1.143888473510742],[-51.375282287597656,-1.21360969543457]]],[[[-50.92028045654297,-0.844999313354492],[-50.92278289794922,-0.729166030883789],[-50.84278106689453,-0.727777481079102],[-50.92028045654297,-0.844999313354492]]],[[[-47.93500518798828,-0.727222442626953],[-47.95166778564453,-0.731945037841797],[-47.97084045410156,-0.680000305175781],[-47.93250274658203,-0.636667251586914],[-47.87611389160156,-0.673055648803711],[-47.93500518798828,-0.727222442626953]]],[[[-47.668060302734375,-0.709165573120117],[-47.69667053222656,-0.7147216796875],[-47.718894958496094,-0.640556335449219],[-47.665283203125,-0.573610305786133],[-47.63722229003906,-0.620832443237305],[-47.668060302734375,-0.709165573120117]]],[[[-51.13195037841797,-0.959444046020508],[-51.070281982421875,-0.69444465637207],[-50.815834045410156,-0.572221755981445],[-51.13195037841797,-0.959444046020508]]],[[[-51.051116943359375,-0.65916633605957],[-51.09833526611328,-0.633888244628906],[-51.02528381347656,-0.560556411743164],[-51.051116943359375,-0.65916633605957]]],[[[-51.901390075683594,-1.476667404174805],[-51.95222473144531,-1.430831909179688],[-51.88500213623047,-1.178888320922852],[-51.66222381591797,-1.083332061767578],[-51.60972595214844,-0.733888626098633],[-51.38195037841797,-0.541389465332031],[-51.19972229003906,-0.529167175292969],[-51.148338317871094,-0.669721603393555],[-51.27166557312012,-1.014165878295898],[-51.48333740234375,-1.240278244018555],[-51.901390075683594,-1.476667404174805]]],[[[-51.40333557128906,-0.54083251953125],[-51.41139221191406,-0.499721527099609],[-51.23944854736328,-0.454442977905273],[-51.40333557128906,-0.54083251953125]]],[[[-50.9586181640625,-0.567499160766602],[-50.878334045410156,-0.385276794433594],[-50.776947021484375,-0.383888244628906],[-50.9586181640625,-0.567499160766602]]],[[[-51.10778045654297,-0.539999008178711],[-51.03472900390625,-0.283056259155273],[-50.94667053222656,-0.353889465332031],[-51.10778045654297,-0.539999008178711]]],[[[-50.9072265625,-0.335832595825195],[-51.025001525878906,-0.24888801574707],[-50.88861846923828,-0.291389465332031],[-50.9072265625,-0.335832595825195]]],[[[-49.713340759277344,-0.227777481079102],[-48.37306213378906,-0.289167404174805],[-48.627227783203125,-1.064443588256836],[-49.16638946533203,-1.613887786865234],[-50.57805633544922,-1.800832748413086],[-50.803611755371094,-1.440555572509766],[-50.78111267089844,-1.151945114135742],[-50.55000305175781,-1.06916618347168],[-50.79695129394531,-0.971942901611328],[-50.65778350830078,-0.279167175292969],[-49.713340759277344,-0.227777481079102]]],[[[-50.80333709716797,-0.358888626098633],[-50.908058166503906,-0.358331680297852],[-50.74889373779297,-0.226667404174805],[-50.80333709716797,-0.358888626098633]]],[[[-51.38056182861328,-0.484722137451172],[-51.103057861328125,-0.121389389038086],[-51.13750457763672,-0.2852783203125],[-51.38056182861328,-0.484722137451172]]],[[[-50.55694580078125,-0.0625],[-50.85778045654297,-0.283056259155273],[-51.02722930908203,-0.224166870117188],[-50.55694580078125,-0.0625]]],[[[-50.90167236328125,-0.04749870300293],[-50.82972717285156,0.060834884643555],[-50.69750213623047,0.023889541625977],[-50.90167236328125,-0.04749870300293]]],[[[-49.52555847167969,-0.134443283081055],[-49.852500915527344,-0.064443588256836],[-49.501670837402344,0.070558547973633],[-49.52555847167969,-0.134443283081055]]],[[[-50.45555877685547,-0.022777557373047],[-50.643333435058594,0.171110153198242],[-50.465003967285156,0.146669387817383],[-50.45555877685547,-0.022777557373047]]],[[[-49.63611602783203,0.227502822875977],[-49.98472595214844,-0.072221755981445],[-50.39250183105469,0.109445571899414],[-49.63611602783203,0.227502822875977]]],[[[-50.24305725097656,0.22944450378418],[-50.184173583984375,0.324167251586914],[-50.0836181640625,0.320001602172852],[-50.24305725097656,0.22944450378418]]],[[[-50.41638946533203,0.210832595825195],[-50.53639221191406,0.226110458374023],[-50.37389373779297,0.621389389038086],[-50.41638946533203,0.210832595825195]]],[[[-50.23750305175781,0.350835800170898],[-50.30805969238281,0.506391525268555],[-50.06361389160156,0.646112442016602],[-50.23750305175781,0.350835800170898]]],[[[-50.007225036621094,0.88166618347168],[-50.267784118652344,0.751668930053711],[-50.2005615234375,0.879167556762695],[-50.007225036621094,0.88166618347168]]],[[[-50.037506103515625,0.884443283081055],[-50.093894958496094,0.920835494995117],[-50.04222869873047,0.918058395385742],[-50.037506103515625,0.884443283081055]]],[[[-50.00944519042969,0.935277938842773],[-50.07444763183594,0.981111526489258],[-49.947784423828125,1.054445266723633],[-50.00944519042969,0.935277938842773]]],[[[-50.39666557312012,1.881391525268555],[-50.5050048828125,2.024999618530273],[-50.356117248535156,2.116945266723633],[-50.39666557312012,1.881391525268555]]],[[[-50.47528076171875,2.119722366333008],[-50.51722717285156,2.203054428100586],[-50.405555725097656,2.193613052368164],[-50.47528076171875,2.119722366333008]]],[[[-60.09833526611328,5.217222213745117],[-60.14750671386719,4.517499923706055],[-59.67583465576172,4.388887405395508],[-59.56861114501953,3.899446487426758],[-59.98944854736328,2.693613052368164],[-59.642784118652344,1.731111526489258],[-58.80694580078125,1.185556411743164],[-57.32472229003906,1.975278854370117],[-56.47063446044922,1.944498062133789],[-55.90416717529297,1.893056869506836],[-55.96583557128906,2.532777786254883],[-54.603782653808594,2.329195022583008],[-52.90972900390625,2.195833206176758],[-51.68406677246094,4.034162521362305],[-51.447784423828125,3.972501754760742],[-51.537506103515625,4.391389846801758],[-51.08861541748047,3.91166877746582],[-50.679725646972656,2.164724349975586],[-50.445281982421875,1.825834274291992],[-49.93000030517578,1.70805549621582],[-50.1219482421875,1.214166641235352],[-49.903892517089844,1.170278549194336],[-51.25861358642578,-0.142778396606445],[-51.70000457763672,-0.752498626708984],[-51.712501525878906,-1.026666641235352],[-51.920005798339844,-1.166389465332031],[-51.92833709716797,-1.337778091430664],[-52.0675048828125,-1.420000076293945],[-52.232505798339844,-1.345277786254883],[-52.71278381347656,-1.60333251953125],[-52.20846939086914,-1.69207763671875],[-51.257225036621094,-1.218332290649414],[-50.99278259277344,-0.998611450195313],[-51.00917053222656,-0.949167251586914],[-50.992225646972656,-0.925277709960938],[-50.85833740234375,-0.913610458374023],[-50.816673278808594,-1.439722061157227],[-50.66389465332031,-1.767778396606445],[-51.336944580078125,-1.646944046020508],[-51.45195007324219,-2.273611068725586],[-51.30750274658203,-1.76361083984375],[-50.84611511230469,-2.508609771728516],[-50.98389434814453,-2.066110610961914],[-50.706390380859375,-2.220556259155273],[-50.677955627441406,-1.810443878173828],[-49.28972625732422,-1.708332061767578],[-49.49000358581543,-2.564998626708984],[-48.69722557067871,-1.469165802001953],[-48.43055725097656,-1.661666870117188],[-48.413612365722656,-1.499443054199219],[-48.1844482421875,-1.471944808959961],[-48.50305938720703,-1.458332061767578],[-48.47917175292969,-1.301942825317383],[-48.33167266845703,-1.308332443237305],[-48.29222869873047,-0.944999694824219],[-48.06056213378906,-0.710832595825195],[-47.956947326660156,-0.775278091430664],[-47.74945068359375,-0.635276794433594],[-47.726951599121094,-0.758054733276367],[-47.542503356933594,-0.636667251586914],[-47.393890380859375,-0.812778472900391],[-47.43139457702637,-0.582500457763672],[-46.95472717285156,-0.704444885253906],[-46.95111846923828,-0.908056259155273],[-46.82167053222656,-0.712778091430664],[-46.60417175292969,-1.029443740844727],[-46.55778503417969,-0.999166488647461],[-46.53583526611328,-1.032220840454102],[-46.448333740234375,-1.043054580688477],[-46.19194793701172,-0.957500457763672],[-46.25972557067871,-1.183610916137695],[-46.0433349609375,-1.210277557373047],[-45.97472381591797,-1.07499885559082],[-45.851951599121094,-1.271944046020508],[-45.735557556152344,-1.180000305175781],[-45.69611358642578,-1.370277404785156],[-45.44694519042969,-1.310832977294922],[-45.46222686767578,-1.545555114746094],[-45.32666778564453,-1.313333511352539],[-45.347503662109375,-1.740278244018555],[-44.86028289794922,-1.425277709960938],[-44.951393127441406,-1.601667404174805],[-44.820556640625,-1.578332901000977],[-44.799171447753906,-1.704999923706055],[-44.69500732421875,-1.817777633666992],[-44.53889465332031,-1.832221984863281],[-44.490562438964844,-1.980833053588867],[-44.656394958496094,-2.331110000610352],[-44.36000061035156,-2.338888168334961],[-44.58222961425781,-2.556943893432617],[-44.78639221191406,-3.29749870300293],[-44.420562744140625,-2.930000305175781],[-44.35694885253906,-2.526666641235352],[-44.06333923339844,-2.405834197998047],[-44.33972930908203,-2.830278396606445],[-43.347503662109375,-2.365833282470703],[-41.248069763183594,-3.023553848266602],[-39.9969482421875,-2.84638786315918],[-37.17444610595703,-4.918611526489258],[-35.417503356933594,-5.2147216796875],[-34.80083465576172,-7.631111145019531],[-35.29277801513672,-9.180000305175781],[-36.393333435058594,-10.492500305175781],[-37.02166557312012,-10.935834884643555],[-37.15333557128906,-10.748611450195312],[-38.04138946533203,-12.633056640625],[-38.488616943359375,-13.020000457763672],[-38.691673278808594,-12.577777862548828],[-38.90111541748047,-12.705556869506836],[-38.72528076171875,-12.874444961547852],[-38.95667266845703,-13.380001068115234],[-39.05639457702637,-13.377500534057617],[-39.080284118652344,-13.538333892822266],[-38.96305847167969,-13.681390762329102],[-39.03889465332031,-14.175834655761719],[-38.920562744140625,-13.915555953979492],[-39.06694793701172,-14.643890380859375],[-38.8719482421875,-15.874168395996094],[-39.20667266845703,-17.147502899169922],[-39.13083457946777,-17.68389129638672],[-39.64361572265625,-18.22333526611328],[-39.8013916015625,-19.632503509521484],[-40.96055603027344,-21.235836029052734],[-40.97167205810547,-21.988056182861328],[-41.7630615234375,-22.346111297607422],[-42.034446716308594,-22.919170379638672],[-43.091949462890625,-22.954723358154297],[-43.075836181640625,-22.6683349609375],[-43.21833801269531,-22.9969482421875],[-44.662506103515625,-23.048057556152344],[-44.57722473144531,-23.35611343383789],[-45.4183349609375,-23.830833435058594],[-46.382781982421875,-23.868335723876953],[-48.02611541748047,-25.015003204345703],[-48.2086181640625,-25.461669921875],[-48.13139343261719,-25.27222442626953],[-48.71861267089844,-25.424724578857422],[-48.36138916015625,-25.57638931274414],[-48.77056121826172,-25.880001068115234],[-48.581947326660156,-26.18000030517578],[-48.80250358581543,-26.067222595214844],[-48.48528289794922,-27.21139144897461],[-48.77472686767578,-28.52222442626953],[-49.75250244140625,-29.36972427368164],[-50.74945068359375,-31.081111907958984],[-52.07250213623047,-32.174171447753906],[-52.086395263671875,-31.823612213134766],[-51.25139617919922,-31.471668243408203],[-50.567222595214844,-30.457225799560547],[-50.60889434814453,-30.190555572509766],[-50.92833709716797,-30.419445037841797],[-51.28166961669922,-30.01000213623047],[-51.2711181640625,-30.79555892944336],[-51.96527862548828,-31.339447021484375],[-52.63667297363281,-33.12944793701172],[-53.374298095703125,-33.74066925048828],[-53.52278137207031,-33.14778137207031],[-53.093055725097656,-32.72972869873047],[-53.879722595214844,-31.96778106689453],[-55.581947326660156,-30.845836639404297],[-56.0089225769043,-31.07979393005371],[-56.81139373779297,-30.10527801513672],[-57.608001708984375,-30.184925079345703],[-55.765281677246094,-28.226112365722656],[-53.80778503417969,-27.129169464111328],[-53.86333465576172,-25.681114196777344],[-54.598915100097656,-25.573223114013672],[-54.33055877685547,-24.6794490814209],[-54.4072265625,-23.916667938232422],[-55.41166687011719,-23.956390380859375],[-55.84972381591797,-22.288890838623047],[-57.985107421875,-22.091827392578125],[-57.814443588256836,-20.971946716308594],[-58.15888977050781,-20.168054580688477],[-57.84874725341797,-19.97879409790039],[-58.121116638183594,-19.741390228271484],[-57.5211181640625,-18.20389175415039],[-57.74305725097656,-17.593055725097656],[-58.39750671386719,-17.249168395996094],[-58.32750701904297,-16.27916717529297],[-60.1602783203125,-16.263057708740234],[-60.57139587402344,-15.097501754760742],[-60.25889587402344,-15.093612670898438],[-60.47084045410156,-13.807222366333008],[-61.038978576660156,-13.493118286132812],[-61.833892822265625,-13.544723510742188],[-63.07500457763672,-12.650001525878906],[-64.39418029785156,-12.461668014526367],[-64.99166870117188,-12.008056640625],[-65.39279174804688,-11.266389846801758],[-65.3819580078125,-9.697778701782227],[-66.63444519042969,-9.906946182250977],[-68.58345031738281,-11.106138229370117],[-69.56843566894531,-10.951091766357422],[-70.63139343261719,-11.009166717529297],[-70.51466369628906,-9.428001403808594],[-71.29888916015625,-9.996389389038086],[-72.14389038085938,-10.004722595214844],[-72.36639404296875,-9.49444580078125],[-73.20529174804688,-9.407222747802734],[-72.96417236328125,-8.983333587646484],[-74.01055908203125,-7.541389465332031],[-73.74417114257812,-6.876943588256836],[-73.1239013671875,-6.447221755981445],[-72.85195922851562,-5.124721527099609],[-70.76583862304688,-4.146389007568359],[-69.95692443847656,-4.236873626708984],[-69.37806701660156,-1.338054656982422],[-69.60751342773438,-0.517499923706055],[-70.05805969238281,-0.157499313354492],[-70.04417419433594,0.59083366394043],[-69.12472534179688,0.645002365112305],[-69.27000427246094,1.038335800170898],[-69.84222412109375,1.072221755981445],[-69.84609985351562,1.710454940795898],[-68.15306091308594,1.72416877746582],[-68.19639587402344,1.977502822875977],[-67.91473388671875,1.745279312133789],[-67.42417907714844,2.143888473510742],[-67.07667541503906,1.173334121704102],[-66.87188720703125,1.221643447875977],[-66.31195068359375,0.750558853149414],[-65.58973693847656,0.989168167114258],[-65.51889038085938,0.649721145629883],[-63.39305877685547,2.151388168334961],[-63.361114501953125,2.419168472290039],[-64.04501342773438,2.482500076293945],[-64.19111633300781,3.594446182250977],[-64.7952880859375,4.281389236450195],[-64.01779174804688,3.886110305786133],[-63.343055725097656,3.961111068725586],[-62.875,3.560277938842773],[-62.74583435058594,4.032499313354492],[-60.98500061035156,4.52055549621582],[-60.57972717285156,4.94666862487793],[-60.730369567871094,5.204801559448242],[-60.09833526611328,5.217222213745117]]]]}},{"type":"Feature","properties":{"name":"Bulgaria","iso2":"BG","iso3":"BGR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[27.879166,42.841103],[27.44833,42.469994],[28.013054,41.982216],[27.394997,42.008041],[26.361095,41.711052],[26.294167,41.708054],[26.066109,41.69749500000013],[26.139996,41.354713],[25.28500000000014,41.24305],[24.263885,41.570549],[22.935604,41.342125],[23.014721,41.762215],[22.365276,42.323883],[22.442219,42.821663],[23.004997,43.192772],[22.367222,43.826942],[22.681435,44.224701],[23.044167,44.076111],[22.875275,43.842499],[24.179996,43.684715],[25.430229,43.626778],[27.036427,44.147339],[28.583244,43.747765],[27.879166,42.841103]]]]}},{"type":"Feature","properties":{"name":"Brunei Darussalam","iso2":"BN","iso3":"BRN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[115.223038,4.804998000000126],[115.343323,4.311943],[115.029129,4.82021],[115.145782,4.90324],[115.223038,4.804998000000126]]],[[[114.981369,4.892499],[115.018433,4.895795000000135],[114.641098,4.018888],[114.095078,4.590538],[114.981369,4.892499]]]]}},{"type":"Feature","properties":{"name":"Canada","iso2":"CA","iso3":"CAN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-65.61361694335938,43.42027473449707],[-65.633056640625,43.47471046447754],[-65.56610107421875,43.50833320617676],[-65.61361694335938,43.42027473449707]]],[[[-59.81694793701172,43.92833137512207],[-60.12999725341797,43.94193458557129],[-59.72471618652344,43.991106033325195],[-59.81694793701172,43.92833137512207]]],[[[-66.28277587890625,44.28972053527832],[-66.32223510742188,44.25277900695801],[-66.20639038085938,44.395273208618164],[-66.28277587890625,44.28972053527832]]],[[[-66.88612365722656,44.61444282531738],[-66.77250671386719,44.809160232543945],[-66.74028015136719,44.707773208618164],[-66.88612365722656,44.61444282531738]]],[[[-60.99388885498047,45.457773208618164],[-61.10444641113281,45.54638862609863],[-60.87999725341797,45.56054878234863],[-60.99388885498047,45.457773208618164]]],[[[-61.19999694824219,45.55832862854004],[-61.22416687011719,45.564157485961914],[-61.21416473388672,45.56888771057129],[-61.19999694824219,45.55832862854004]]],[[[-63.24639129638672,46.43554878234863],[-63.285003662109375,46.45083045959473],[-63.24583435058594,46.442766189575195],[-63.24639129638672,46.43554878234863]]],[[[-60.445274353027344,46.86166572570801],[-60.609169006347656,46.20193672180176],[-60.41999816894531,46.27999305725098],[-61.149169921875,45.699716567993164],[-60.40916442871094,45.979990005493164],[-60.78972625732422,45.93443489074707],[-60.3477783203125,46.31054878234863],[-59.840553283691406,45.93832588195801],[-61.336944580078125,45.57332801818848],[-61.447776794433594,46.14943885803223],[-60.609169006347656,47.02443885803223],[-60.445274353027344,46.86166572570801]]],[[[-64.03971862792969,46.74332618713379],[-63.742225646972656,46.43943214416504],[-63.64722442626953,46.567216873168945],[-63.216392517089844,46.41221046447754],[-61.965003967285156,46.453325271606445],[-62.76111602783203,45.95416450500488],[-62.96277618408203,46.31999397277832],[-63.591941833496094,46.21193885803223],[-64.41555786132812,46.670549392700195],[-64.02084350585938,47.03860664367676],[-64.03971862792969,46.74332618713379]]],[[[-55.87610626220703,47.26055335998535],[-55.96833038330078,47.25777626037598],[-55.88111114501953,47.2933292388916],[-55.87610626220703,47.26055335998535]]],[[[-61.38055419921875,47.62027168273926],[-62.0130615234375,47.2258243560791],[-61.92805480957031,47.40721321105957],[-61.38055419921875,47.62027168273926]]],[[[-54.261390686035156,47.390275955200195],[-54.36555480957031,47.41166114807129],[-54.128883361816406,47.670549392700195],[-54.261390686035156,47.390275955200195]]],[[[-54.07749938964844,47.47943305969238],[-54.10194396972656,47.50139045715332],[-54.071388244628906,47.68554878234863],[-54.07749938964844,47.47943305969238]]],[[[-55.901939392089844,47.602495193481445],[-56.113616943359375,47.64471626281738],[-55.93388366699219,47.68832588195801],[-55.901939392089844,47.602495193481445]]],[[[-64.48277282714844,47.91777229309082],[-64.6905517578125,47.75305366516113],[-64.66749572753906,47.8669376373291],[-64.48277282714844,47.91777229309082]]],[[[-64.5675048828125,47.89943885803223],[-64.50111389160156,48.02749061584473],[-64.47055053710938,47.953325271606445],[-64.5675048828125,47.89943885803223]]],[[[-53.71277618408203,48.148881912231445],[-53.935829162597656,48.18249702453613],[-53.50972557067871,48.19832801818848],[-53.71277618408203,48.148881912231445]]],[[[-123.47444152832031,48.70916175842285],[-123.5966567993164,48.94693946838379],[-123.37026977539062,48.768327713012695],[-123.47444152832031,48.70916175842285]]],[[[-123.3227767944336,48.86110877990723],[-123.54055786132812,48.94499397277832],[-123.70249938964844,49.10555458068848],[-123.3227767944336,48.86110877990723]]],[[[-125.81610107421875,49.12582588195801],[-125.93305969238281,49.21805000305176],[-125.79915618896484,49.208330154418945],[-125.81610107421875,49.12582588195801]]],[[[-126.13194274902344,49.393327713012695],[-126.06471252441406,49.25083351135254],[-126.23916625976562,49.28972053527832],[-126.13194274902344,49.393327713012695]]],[[[-123.37944030761719,49.32694435119629],[-123.42027282714844,49.381662368774414],[-123.31221008300781,49.414995193481445],[-123.37944030761719,49.32694435119629]]],[[[-54.70527458190918,49.40054512023926],[-54.75917053222656,49.43776893615723],[-54.673057556152344,49.49249458312988],[-54.640838623046875,49.463884353637695],[-54.70527458190918,49.40054512023926]]],[[[-124.17916870117188,49.44110298156738],[-124.381103515625,49.51194190979004],[-124.24472045898438,49.50139045715332],[-124.17916870117188,49.44110298156738]]],[[[-123.33277893066406,49.44110298156738],[-123.45944213867188,49.46721076965332],[-123.43666076660156,49.52221870422363],[-123.3550033569336,49.531938552856445],[-123.33277893066406,49.44110298156738]]],[[[-55.69554901123047,49.50694465637207],[-55.72277069091797,49.55777168273926],[-55.653053283691406,49.55526924133301],[-55.69554901123047,49.50694465637207]]],[[[-124.68943786621094,49.48027229309082],[-124.82362365722656,49.539438247680664],[-124.83168029785156,49.610551834106445],[-124.68943786621094,49.48027229309082]]],[[[-55.69305419921875,49.5674991607666],[-55.65972137451172,49.63555335998535],[-55.5675048828125,49.60000038146973],[-55.69305419921875,49.5674991607666]]],[[[-54.57666778564453,49.558603286743164],[-54.894447326660156,49.58526802062988],[-54.53611755371094,49.66415596008301],[-54.57666778564453,49.558603286743164]]],[[[-54.00444793701172,49.64749336242676],[-54.29888916015625,49.609994888305664],[-54.141944885253906,49.75000190734863],[-54.00444793701172,49.64749336242676]]],[[[-124.12970733642578,49.650827407836914],[-124.19943237304688,49.70610237121582],[-124.01611328125,49.77555274963379],[-124.12970733642578,49.650827407836914]]],[[[-124.44611358642578,49.72332191467285],[-124.12277221679688,49.493608474731445],[-124.65666198730469,49.796945571899414],[-124.44611358642578,49.72332191467285]]],[[[-62.0897216796875,49.38638496398926],[-61.66166687011719,49.14444160461426],[-63.089996337890625,49.228044509887695],[-64.51390075683594,49.86361122131348],[-62.0897216796875,49.38638496398926]]],[[[-126.67610168457031,49.58360481262207],[-126.9405517578125,49.83138465881348],[-126.77749633789062,49.879716873168945],[-126.67804718017578,49.825273513793945],[-126.61332702636719,49.648332595825195],[-126.67610168457031,49.58360481262207]]],[[[-124.92415618896484,50.058603286743164],[-125.06696319580078,50.107500076293945],[-124.98332214355469,50.22554969787598],[-124.92415618896484,50.058603286743164]]],[[[-63.85944366455078,50.197771072387695],[-63.93055725097656,50.22943305969238],[-63.88972473144531,50.24221992492676],[-63.85944366455078,50.197771072387695]]],[[[-125.16777038574219,49.98082160949707],[-125.33999633789062,50.26888465881348],[-125.25473022460938,50.29361152648926],[-125.16722106933594,50.21360969543457],[-125.16777038574219,49.98082160949707]]],[[[-124.8125,50.11138343811035],[-124.91832733154297,50.29972267150879],[-124.75666809082031,50.17833137512207],[-124.8125,50.11138343811035]]],[[[-124.73082733154297,50.30221748352051],[-124.65943908691406,50.25833320617676],[-124.69583129882812,50.15749549865723],[-124.79499816894531,50.2288761138916],[-124.73082733154297,50.30221748352051]]],[[[-125.16555786132812,50.37443733215332],[-125.14028930664062,50.121660232543945],[-125.15611267089844,50.23916053771973],[-125.213623046875,50.316667556762695],[-125.40028381347656,50.32083320617676],[-125.16555786132812,50.37443733215332]]],[[[-125.80722045898438,50.41360664367676],[-125.95111083984375,50.43387794494629],[-125.73805236816406,50.428049087524414],[-125.80722045898438,50.41360664367676]]],[[[-125.54387664794922,50.39388465881348],[-125.76363372802734,50.39749336242676],[-125.5239028930664,50.43443489074707],[-125.54387664794922,50.39388465881348]]],[[[-125.42610168457031,50.35555458068848],[-125.52806091308594,50.381662368774414],[-125.33194732666016,50.43554878234863],[-125.42610168457031,50.35555458068848]]],[[[-126.225830078125,50.55526924133301],[-126.62389373779297,50.533884048461914],[-126.28611755371094,50.59832954406738],[-126.225830078125,50.55526924133301]]],[[[-126.46640014648438,50.57583045959473],[-126.55416870117188,50.6027774810791],[-126.36138916015625,50.61583137512207],[-126.46640014648438,50.57583045959473]]],[[[-59.34583282470703,50.533884048461914],[-59.37194061279297,50.65277290344238],[-59.30027770996094,50.58194160461426],[-59.34583282470703,50.533884048461914]]],[[[-126.87332153320312,50.6633243560791],[-126.83112335205078,50.629159927368164],[-127.14472961425781,50.63388252258301],[-126.87332153320312,50.6633243560791]]],[[[-126.64389038085938,50.69193458557129],[-126.685546875,50.75889015197754],[-126.53639221191406,50.76361274719238],[-126.64389038085938,50.69193458557129]]],[[[-127.22693634033203,50.63611030578613],[-125.44972229003906,50.32361030578613],[-124.78943634033203,49.46415901184082],[-123.69943237304688,49.14388465881348],[-123.8505630493164,49.14554786682129],[-123.28971862792969,48.4133243560791],[-125.1138916015625,48.73110389709473],[-124.80776977539062,49.240549087524414],[-125.48361206054688,48.91582679748535],[-125.90471458435059,49.43582344055176],[-126.54222106933594,49.37443733215332],[-126.08750915527344,49.66221046447754],[-126.58500671386719,49.70110511779785],[-126.67971801757812,49.87887763977051],[-126.804443359375,49.90915870666504],[-127.1211166381836,49.8522891998291],[-127.24137878417969,49.96193885803223],[-127.15834045410156,50.096384048461914],[-127.89584350585938,50.10888862609863],[-127.92388916015625,50.46277046203613],[-127.44695281982422,50.37276649475098],[-127.41139221191406,50.58749580383301],[-128.05142211914062,50.44669532775879],[-128.416654586792,50.7691593170166],[-127.22693634033203,50.63611030578613]]],[[[-55.564720153808594,50.699716567993164],[-55.624717712402344,50.78721809387207],[-55.45055389404297,50.7983341217041],[-55.564720153808594,50.699716567993164]]],[[[-126.73137664794922,50.77193641662598],[-126.90583801269531,50.822771072387695],[-126.56304931640625,50.799997329711914],[-126.73137664794922,50.77193641662598]]],[[[-126.27306365966797,50.65277290344238],[-126.61749267578125,50.66777229309082],[-126.26640319824219,50.827775955200195],[-126.27306365966797,50.65277290344238]]],[[[-127.65471458435059,50.83777046203613],[-127.83860778808594,50.881662368774414],[-127.72638702392578,50.90860176086426],[-127.65471458435059,50.83777046203613]]],[[[-55.55555725097656,50.88638496398926],[-55.635276794433594,50.961381912231445],[-55.5352783203125,50.98137855529785],[-55.55555725097656,50.88638496398926]]],[[[-58.413330078125,51.2388858795166],[-58.56500244140625,51.23333168029785],[-58.41944885253906,51.27471351623535],[-58.413330078125,51.2388858795166]]],[[[-53.75636672973633,48.50326347351074],[-54.094444274902344,48.42582893371582],[-54.13805389404297,48.35916328430176],[-53.75636672973633,48.50326347351074],[-52.978050231933594,48.604440689086914],[-53.945274353027344,48.17888069152832],[-53.60778045654297,48.051103591918945],[-53.850555419921875,47.76055335998535],[-53.55055236816406,47.52916145324707],[-53.274444580078125,48.01333045959473],[-52.831390380859375,48.10166358947754],[-53.26721954345703,47.60610389709473],[-53.12194061279297,47.4133243560791],[-52.779441833496094,47.803049087524414],[-52.61444854736328,47.51666450500488],[-53.102500915527344,46.63665962219238],[-53.617774963378906,46.6441593170166],[-53.59138488769531,47.15609931945801],[-54.187774658203125,46.819162368774414],[-53.86750030517578,47.40277290344238],[-54.195274353027344,47.857500076293945],[-54.48277282714844,47.39166450500488],[-54.4183349609375,47.60360908508301],[-55.689720153808594,46.85833168029785],[-55.983055114746094,46.95249366760254],[-54.84583282470703,47.55694007873535],[-54.93611145019531,47.78166389465332],[-55.58777618408203,47.39860725402832],[-56.17250061035156,47.49721717834473],[-55.628334045410156,47.67471504211426],[-55.917503356933594,47.65749549865723],[-55.77361297607422,47.95694160461426],[-56.84083557128906,47.521379470825195],[-59.13555908203125,47.55638313293457],[-59.406944274902344,47.889719009399414],[-58.4183349609375,48.48665809631348],[-59.26111602783203,48.47665596008301],[-58.77471923828125,48.778879165649414],[-58.95861053466797,48.6138858795166],[-58.709442138671875,48.57083320617676],[-58.39611053466797,49.13138008117676],[-57.88166809082031,48.968881607055664],[-58.22332763671875,49.390275955200195],[-57.696388244628906,49.46360969543457],[-57.948333740234375,49.67416572570801],[-57.14805603027344,50.62193489074707],[-57.37860870361328,50.68776893615723],[-55.89805603027344,51.62860298156738],[-55.4052734375,51.561662673950195],[-56.08555603027344,51.36832618713379],[-55.73249816894531,51.07999610900879],[-56.1552734375,50.88555335998535],[-56.84888458251953,49.544443130493164],[-56.15388488769531,50.15054512023926],[-55.49169921875,50.00731086730957],[-56.12916564941406,49.425554275512695],[-55.315277099609375,49.31443977355957],[-55.14111328125,49.54527473449707],[-55.383331298828125,49.04083442687988],[-55.07805633544922,49.356943130493164],[-54.82444763183594,49.2691593170166],[-54.52888488769531,49.533334732055664],[-54.48694610595703,49.259721755981445],[-53.775001525878906,49.39610481262207],[-53.488609313964844,49.22054481506348],[-54.09610557556152,48.812211990356445],[-53.60194396972656,48.689714431762695],[-53.95610809326172,48.54388618469238],[-53.75636672973633,48.50326347351074]],[[-56.803611755371094,49.76333045959473],[-56.78221893310547,49.786943435668945],[-56.838050842285156,49.76749610900879],[-56.803611755371094,49.76333045959473]],[[-55.99388885498047,51.200273513793945],[-55.9677734375,51.22665596008301],[-55.99805450439453,51.20749855041504],[-55.99388885498047,51.200273513793945]],[[-58.34222412109375,49.06610298156738],[-58.33361053466797,49.077775955200195],[-58.356109619140625,49.06582832336426],[-58.34222412109375,49.06610298156738]]],[[[-127.91443634033203,51.41082191467285],[-128.14556884765625,51.65360450744629],[-128,51.72054481506348],[-127.91443634033203,51.41082191467285]]],[[[-55.36750030517578,51.874162673950195],[-55.43055725097656,51.89666175842285],[-55.269996643066406,52.00055122375488],[-55.36750030517578,51.874162673950195]]],[[[-128.05389404296875,51.753610610961914],[-128.25308227539062,51.87221717834473],[-127.98332214355469,52.06193733215332],[-128.05389404296875,51.753610610961914]]],[[[-79.25279235839844,52.07138252258301],[-79.37666320800781,51.936105728149414],[-79.6541748046875,51.98665809631348],[-79.25279235839844,52.07138252258301]]],[[[-131.01889038085938,51.94610023498535],[-131.11026000976562,52.15110206604004],[-131.00946044921875,52.1027774810791],[-131.01889038085938,51.94610023498535]]],[[[-127.96278381347656,52.074716567993164],[-128.12081909179688,52.14193916320801],[-127.881103515625,52.17222023010254],[-127.96278381347656,52.074716567993164]]],[[[-128.21194458007812,52.01555061340332],[-128.29415893554688,52.11361122131348],[-128.153076171875,52.195268630981445],[-128.21194458007812,52.01555061340332]]],[[[-128.29998779296875,52.13360786437988],[-128.377197265625,52.22387886047363],[-128.22720336914062,52.218881607055664],[-128.29998779296875,52.13360786437988]]],[[[-128.4283447265625,52.13749885559082],[-128.51113891601562,52.169992446899414],[-128.41641235351562,52.22638130187988],[-128.4283447265625,52.13749885559082]]],[[[-127.92471313476562,52.17416572570801],[-128.17001342773438,52.24971961975098],[-127.9727783203125,52.29527473449707],[-127.92471313476562,52.17416572570801]]],[[[-81.47694396972656,52.249162673950195],[-81.71000671386719,52.26249885559082],[-81.55166625976562,52.298051834106445],[-81.47694396972656,52.249162673950195]]],[[[-127.72444152832031,51.976938247680664],[-127.78916931152344,52.221933364868164],[-127.23473358154297,52.416940689086914],[-127.72444152832031,51.976938247680664]]],[[[-128.1844482421875,52.27860450744629],[-128.10443115234375,52.4213809967041],[-128.05667114257812,52.32888221740723],[-128.1844482421875,52.27860450744629]]],[[[-128.66860961914062,52.26638984680176],[-128.74722290039062,52.47165870666504],[-128.61581420898438,52.4536075592041],[-128.66860961914062,52.26638984680176]]],[[[-128.471923828125,52.49276924133301],[-128.81390380859375,52.52499580383301],[-128.73248291015625,52.59054756164551],[-128.57818603515625,52.593645095825195],[-128.5352783203125,52.64721870422363],[-128.471923828125,52.49276924133301]]],[[[-131.46444702148438,52.62748908996582],[-131.709716796875,52.705270767211914],[-131.47528076171875,52.73665809631348],[-131.46444702148438,52.62748908996582]]],[[[-128.4302978515625,52.368051528930664],[-128.38333129882812,52.797494888305664],[-128.2750244140625,52.48999214172363],[-128.4302978515625,52.368051528930664]]],[[[-128.97442626953125,52.453325271606445],[-129.2772216796875,52.82305335998535],[-128.92333984375,52.60666084289551],[-128.97442626953125,52.453325271606445]]],[[[-128.26974487304688,52.596940994262695],[-128.32501220703125,52.77610206604004],[-128.17779541015625,52.82610511779785],[-128.26974487304688,52.596940994262695]]],[[[-131.63973999023438,52.82805061340332],[-131.73306274414062,52.808603286743164],[-131.83139038085938,52.841936111450195],[-131.63973999023438,52.82805061340332]]],[[[-128.50527954101562,52.6411075592041],[-128.50613403320312,52.87304878234863],[-128.45083618164062,52.80526924133301],[-128.50527954101562,52.6411075592041]]],[[[-129.61053466796875,52.95499610900879],[-129.65084838867188,53.01888465881348],[-129.5574951171875,53.006662368774414],[-129.61053466796875,52.95499610900879]]],[[[-129.53167724609375,53.01055335998535],[-129.6400146484375,53.04416084289551],[-129.56277465820312,53.053049087524414],[-129.53167724609375,53.01055335998535]]],[[[-55.7630615234375,53.029436111450195],[-55.87638854980469,53.02749061584473],[-55.80055236816406,53.09360694885254],[-55.7630615234375,53.029436111450195]]],[[[-129.60247802734375,53.05721473693848],[-129.73831176757812,53.127214431762695],[-129.65444946289062,53.132768630981445],[-129.60247802734375,53.05721473693848]]],[[[-129.4324951171875,53.151384353637695],[-129.28945922851562,52.971933364868164],[-129.5472412109375,53.1330509185791],[-129.4324951171875,53.151384353637695]]],[[[-79.90916442871094,53.08194160461426],[-79.89778137207031,53.17444038391113],[-79.78721618652344,53.101938247680664],[-79.90916442871094,53.08194160461426]]],[[[-81.10610961914062,53.199716567993164],[-80.69972229003906,52.69610023498535],[-82.06332397460938,53.02665901184082],[-81.10610961914062,53.199716567993164]]],[[[-131.76223754882812,53.19665718078613],[-131.5947265625,53.0352725982666],[-131.9647216796875,53.04638862609863],[-131.61553955078125,52.92027473449707],[-131.98248291015625,52.879716873168945],[-131.03030395507812,52.17388343811035],[-132.56362915039062,53.13916206359863],[-132.54916381835938,53.15110206604004],[-132.41363525390625,53.12748908996582],[-132.07083129882812,53.153879165649414],[-131.81112670898438,53.253610610961914],[-131.76223754882812,53.19665718078613]]],[[[-128.689453125,53.164438247680664],[-128.51834106445312,52.91110420227051],[-128.59222412109375,52.6138858795166],[-128.74887084960938,52.59721565246582],[-128.64697265625,52.963327407836914],[-128.88446044921875,52.64805030822754],[-129.12191772460938,52.863054275512695],[-128.84359741210938,53.04416084289551],[-129.19137573242188,53.01333045959473],[-129.07528686523438,53.10305213928223],[-129.066650390625,53.30082893371582],[-128.689453125,53.164438247680664]]],[[[-55.778053283691406,53.28972053527832],[-55.79722595214844,53.295549392700195],[-55.785003662109375,53.303606033325195],[-55.778053283691406,53.28972053527832]]],[[[-129.153076171875,53.09832954406738],[-129.33248901367188,53.13749885559082],[-129.26806640625,53.33194160461426],[-129.16860961914062,53.29610633850098],[-129.153076171875,53.09832954406738]]],[[[-79.94276428222656,53.26693916320801],[-80.08528137207031,53.32694435119629],[-79.94471740722656,53.368051528930664],[-79.94276428222656,53.26693916320801]]],[[[-129.35833740234375,53.30416297912598],[-129.39501953125,53.41082191467285],[-129.3033447265625,53.33111000061035],[-129.35833740234375,53.30416297912598]]],[[[-55.787506103515625,53.3941593170166],[-55.979164123535156,53.45916175842285],[-55.729164123535156,53.455270767211914],[-55.787506103515625,53.3941593170166]]],[[[-128.9425048828125,53.3174991607666],[-129.14334106445312,53.34971809387207],[-128.99942016601562,53.539438247680664],[-128.901123046875,53.38665962219238],[-128.9425048828125,53.3174991607666]]],[[[-79.70973205566406,53.5080509185791],[-79.77362060546875,53.53166389465332],[-79.76139831542969,53.54610633850098],[-79.70973205566406,53.5080509185791]]],[[[-129.93472290039062,53.48416328430176],[-130.0211181640625,53.50527381896973],[-129.94195556640625,53.551103591918945],[-129.88668823242188,53.54222297668457],[-129.93472290039062,53.48416328430176]]],[[[-129.87942504882812,53.392770767211914],[-129.76223754882812,53.158884048461914],[-130.52029418945312,53.624711990356445],[-129.87942504882812,53.392770767211914]]],[[[-129.08639526367188,53.44610023498535],[-129.153076171875,53.63860511779785],[-128.81887817382812,53.70916175842285],[-129.08554077148438,53.5049991607666],[-129.08639526367188,53.44610023498535]]],[[[-56.867218017578125,53.76500129699707],[-57.01445007324219,53.78555488586426],[-56.844444274902344,53.792497634887695],[-56.867218017578125,53.76500129699707]]],[[[-130.09109497070312,53.56944465637207],[-130.40335083007812,53.68249702453613],[-130.26168823242188,53.79638862609863],[-130.09109497070312,53.56944465637207]]],[[[-129.82611083984375,53.72416114807129],[-129.50668334960938,53.21666145324707],[-129.80722045898438,53.384164810180664],[-129.8839111328125,53.579721450805664],[-130.05639457702637,53.60388374328613],[-129.92820739746094,53.639604568481445],[-130.28640747070312,53.83749580383301],[-129.82611083984375,53.72416114807129]]],[[[-79.86416625976562,53.906381607055664],[-79.90611267089844,53.91388130187988],[-79.9263916015625,53.93526649475098],[-79.86416625976562,53.906381607055664]]],[[[-130.14974975585938,53.98916053771973],[-130.193603515625,54.079721450805664],[-130.13247680664062,54.049997329711914],[-130.14974975585938,53.98916053771973]]],[[[-130.25918579101562,54.004716873168945],[-130.7127685546875,53.86110877990723],[-130.4111328125,54.10083198547363],[-130.25918579101562,54.004716873168945]]],[[[-58.518333435058594,54.05166053771973],[-58.56138610839844,54.06388282775879],[-58.37388610839844,54.10416603088379],[-58.518333435058594,54.05166053771973]]],[[[-132.80804443359375,54.12027168273926],[-132.15029907226562,53.99276924133301],[-132.663330078125,53.6794376373291],[-132.41806030273438,53.60610389709473],[-131.66305541992188,54.1522159576416],[-131.98220825195312,53.251665115356445],[-132.27279663085938,53.210275650024414],[-132.12191772460938,53.18943214416504],[-132.18695068359375,53.16054725646973],[-132.45748901367188,53.145273208618164],[-132.53668212890625,53.17888069152832],[-132.59664916992188,53.24749183654785],[-132.68362426757812,53.256662368774414],[-132.5433349609375,53.33055305480957],[-132.73388671875,53.33721351623535],[-132.40667724609375,53.3397159576416],[-132.97250366210938,53.55582618713379],[-133.0716552734375,54.16888618469238],[-132.80804443359375,54.12027168273926]]],[[[-130.195556640625,54.118051528930664],[-130.2528076171875,54.18554878234863],[-130.15194702148438,54.154436111450195],[-130.195556640625,54.118051528930664]]],[[[-79.4697265625,54.167497634887695],[-79.47555541992188,54.19137763977051],[-79.41305541992188,54.191659927368164],[-79.4697265625,54.167497634887695]]],[[[-130.64862060546875,54.11444282531738],[-130.78500366210938,54.14999580383301],[-130.78167724609375,54.2116641998291],[-130.64862060546875,54.11444282531738]]],[[[-130.35556030273438,54.25777626037598],[-130.46722412109375,54.308603286743164],[-130.41778564453125,54.32638740539551],[-130.35556030273438,54.25777626037598]]],[[[-130.26641845703125,54.26055335998535],[-130.35028076171875,54.305551528930664],[-130.27279663085938,54.329721450805664],[-130.26641845703125,54.26055335998535]]],[[[-130.70416259765625,54.35666084289551],[-130.76779174804688,54.38499641418457],[-130.69943237304688,54.40665626525879],[-130.70416259765625,54.35666084289551]]],[[[-57.32472229003906,54.49888038635254],[-57.26721954345703,54.58555030822754],[-57.24028015136719,54.517770767211914],[-57.32472229003906,54.49888038635254]]],[[[-130.95166015625,54.45471382141113],[-130.92556762695312,54.61944007873535],[-130.74777221679688,54.62610054016113],[-130.95166015625,54.45471382141113]]],[[[-79.66722106933594,54.76388740539551],[-79.72694396972656,54.75249671936035],[-79.58721923828125,54.79916572570801],[-79.66722106933594,54.76388740539551]]],[[[-130.51834106445312,54.70249366760254],[-130.61166381835938,54.7580509185791],[-130.46945190429688,54.80777168273926],[-130.51834106445312,54.70249366760254]]],[[[-130.26834106445312,54.71499824523926],[-130.37887573242188,54.695268630981445],[-130.20944213867188,54.80777168273926],[-130.26834106445312,54.71499824523926]]],[[[-57.940834045410156,54.911935806274414],[-57.84166717529297,54.8124942779541],[-58.22471618652344,54.83526802062988],[-57.940834045410156,54.911935806274414]]],[[[-79.12582397460938,54.89721870422363],[-79.77694702148438,54.77804756164551],[-79.0150146484375,54.93832588195801],[-79.12582397460938,54.89721870422363]]],[[[-58.67527770996094,54.91415596008301],[-58.76055908203125,54.920549392700195],[-58.6602783203125,55.00860786437988],[-58.67527770996094,54.91415596008301]]],[[[-130.38528442382812,54.76999092102051],[-130.45999145507812,54.82833290100098],[-130.1683349609375,55.01971626281738],[-130.38528442382812,54.76999092102051]]],[[[-82.9647216796875,55.26361274719238],[-83.0352783203125,55.278879165649414],[-82.9808349609375,55.278879165649414],[-82.9647216796875,55.26361274719238]]],[[[-77.5927734375,55.43526649475098],[-77.6441650390625,55.42582893371582],[-77.19999694824219,55.65027046203613],[-77.5927734375,55.43526649475098]]],[[[-60.97083282470703,55.86944007873535],[-61.070556640625,55.93860054016113],[-60.90833282470703,55.898332595825195],[-60.97083282470703,55.86944007873535]]],[[[-60.858612060546875,55.86471748352051],[-60.86500358581543,55.952775955200195],[-60.68638610839844,55.92193794250488],[-60.858612060546875,55.86471748352051]]],[[[-79.123046875,55.789995193481445],[-78.95750427246094,56.08360481262207],[-78.93971252441406,56.02527046203613],[-79.123046875,55.789995193481445]]],[[[-60.943328857421875,56.006662368774414],[-61.23277282714844,56.09110450744629],[-61.08916473388672,56.169992446899414],[-60.943328857421875,56.006662368774414]]],[[[-61.62361145019531,56.39999580383301],[-61.41221618652344,56.32666206359863],[-61.796112060546875,56.41304969787598],[-61.62361145019531,56.39999580383301]]],[[[-78.83999633789062,56.12999153137207],[-78.66722106933594,56.439714431762695],[-78.6763916015625,56.181108474731445],[-78.83999633789062,56.12999153137207]]],[[[-79.6199951171875,56.385271072387695],[-80.10972595214844,56.197771072387695],[-79.5433349609375,56.52777290344238],[-79.6199951171875,56.385271072387695]]],[[[-61.435829162597656,56.54138374328613],[-61.148887634277344,56.44110298156738],[-61.64222717285156,56.48638343811035],[-61.435829162597656,56.54138374328613]]],[[[-79.02166557312012,56.42694282531738],[-78.92471313476562,56.419443130493164],[-78.94332885742188,56.28499794006348],[-79.19526672363281,55.89193916320801],[-78.97721862792969,56.38860511779785],[-79.2833251953125,55.86444282531738],[-79.15055847167969,56.233049392700195],[-79.47999572753906,55.8638858795166],[-79.78195190429688,55.78804969787598],[-79.5130615234375,56.13499641418457],[-79.98582458496094,55.89805030822754],[-79.46611022949219,56.5483341217041],[-79.51445007324219,56.18638038635254],[-79.28639221191406,56.57027626037598],[-79.02166557312012,56.42694282531738]],[[-79.62693786621094,56.265275955200195],[-79.56111145019531,56.29916572570801],[-79.49221801757812,56.44693946838379],[-79.62693786621094,56.265275955200195]]],[[[-79.14195251464844,56.61666297912598],[-79.28028869628906,56.65499305725098],[-79.20889282226562,56.68387794494629],[-79.14195251464844,56.61666297912598]]],[[[-61.1875,56.58610725402832],[-61.16583251953125,56.68443489074707],[-61.077781677246094,56.674997329711914],[-61.1875,56.58610725402832]]],[[[-79.56082153320312,56.61776924133301],[-79.5675048828125,56.81777381896973],[-79.47471618652344,56.689157485961914],[-79.56082153320312,56.61776924133301]]],[[[-79.88194274902344,56.743608474731445],[-79.9586181640625,56.81138038635254],[-79.8194580078125,56.84027290344238],[-79.88194274902344,56.743608474731445]]],[[[-79.75056457519531,56.90582466125488],[-79.75750732421875,56.781938552856445],[-79.82376861572266,56.89500617980957],[-79.89750671386719,56.88499641418457],[-79.75056457519531,56.90582466125488]]],[[[-61.4292106628418,56.92970848083496],[-61.40913772583008,56.615610122680664],[-61.64439392089844,56.73477745056152],[-61.4292106628418,56.92970848083496]]],[[[-76.62110900878906,57.0755558013916],[-76.7086181640625,57.18832588195801],[-76.66999816894531,57.20249366760254],[-76.62110900878906,57.0755558013916]]],[[[-61.621665954589844,57.33555030822754],[-61.76860809326172,57.32499885559082],[-61.72694396972656,57.37443733215332],[-61.621665954589844,57.33555030822754]]],[[[-76.71501159667969,57.29277229309082],[-76.82167053222656,57.4294376373291],[-76.73110961914062,57.38193702697754],[-76.71501159667969,57.29277229309082]]],[[[-61.6552734375,57.39138221740723],[-61.90027618408203,57.4374942779541],[-61.64805603027344,57.53027534484863],[-61.6552734375,57.39138221740723]]],[[[-61.878334045410156,57.46305274963379],[-62.02027893066406,57.5402774810791],[-61.78361511230469,57.550546646118164],[-61.878334045410156,57.46305274963379]]],[[[-79.79750061035156,57.41888618469238],[-79.82695007324219,57.53804969787598],[-79.727783203125,57.61721229553223],[-79.79750061035156,57.41888618469238]]],[[[-61.68860626220703,57.71305274963379],[-61.89611053466797,57.76971626281738],[-61.71111297607422,57.83416175842285],[-61.68860626220703,57.71305274963379]]],[[[-61.94749450683594,57.78721809387207],[-62.10833740234375,57.824716567993164],[-62.00917053222656,57.904436111450195],[-61.92833709716797,57.90860176086426],[-61.94749450683594,57.78721809387207]]],[[[-67.59611511230469,58.28416633605957],[-67.67666625976562,58.3013858795166],[-67.6199951171875,58.37221717834473],[-67.51750183105469,58.33526802062988],[-67.59611511230469,58.28416633605957]]],[[[-78.45388793945312,58.539995193481445],[-78.67250061035156,58.610551834106445],[-78.6986083984375,58.68860054016113],[-78.45388793945312,58.539995193481445]]],[[[-69.19444274902344,59.064714431762695],[-69.35556030273438,58.949716567993164],[-69.35722351074219,59.139719009399414],[-69.19444274902344,59.064714431762695]]],[[[-80.53443908691406,59.36944007873535],[-80.5494384765625,59.44693946838379],[-80.47555541992188,59.48110389709473],[-80.53443908691406,59.36944007873535]]],[[[-80.27749633789062,59.618600845336914],[-80.34388732910156,59.619157791137695],[-80.14527893066406,59.70555305480957],[-80.27749633789062,59.618600845336914]]],[[[-80.0897216796875,59.75193977355957],[-80.18472290039062,59.75277900695801],[-79.87887573242188,59.85471534729004],[-80.0897216796875,59.75193977355957]]],[[[-64.01972961425781,59.7147159576416],[-64.20445251464844,59.73443794250488],[-64.06138610839844,59.86444282531738],[-64.01972961425781,59.7147159576416]]],[[[-64.42767333984375,60.372934341430664],[-64.4486083984375,60.28416633605957],[-64.86805725097656,60.45888710021973],[-64.42767333984375,60.372934341430664]]],[[[-68.25140380859375,60.23082160949707],[-68.11915588378906,60.577219009399414],[-67.79861450195312,60.45749855041504],[-68.25140380859375,60.23082160949707]]],[[[-64.68998718261719,60.58443641662598],[-64.71083068847656,60.6027774810791],[-64.5927734375,60.68554878234863],[-64.68998718261719,60.58443641662598]]],[[[-78.65638732910156,60.702775955200195],[-78.57362365722656,60.78416633605957],[-78.21945190429688,60.82388496398926],[-78.65638732910156,60.702775955200195]]],[[[-69.97721862792969,60.933053970336914],[-70.02500915527344,61.00193977355957],[-69.943603515625,61.031381607055664],[-69.97721862792969,60.933053970336914]]],[[[-64.72389221191406,61.53833198547363],[-64.87527465820312,61.32249641418457],[-65.4869384765625,61.61082649230957],[-64.72389221191406,61.53833198547363]]],[[[-65.69526672363281,61.77665901184082],[-65.94804382324219,61.7902774810791],[-65.77806091308594,61.865549087524414],[-65.69526672363281,61.77665901184082]]],[[[-64.91610717773438,61.719438552856445],[-65.2550048828125,61.90165901184082],[-64.9808349609375,61.88582801818848],[-64.91610717773438,61.719438552856445]]],[[[-92.96389770507812,61.879159927368164],[-93.07028198242188,61.825273513793945],[-93.22610473632812,61.90832710266113],[-92.96389770507812,61.879159927368164]]],[[[-65.85249328613281,62.08471870422363],[-66.02027893066406,62.12443733215332],[-65.90444946289062,62.15277290344238],[-65.85249328613281,62.08471870422363]]],[[[-92.22361755371094,62.35555458068848],[-92.37249755859375,62.39193916320801],[-92.13972473144531,62.39972114562988],[-92.22361755371094,62.35555458068848]]],[[[-79.54055786132812,62.41110420227051],[-79.26139831542969,62.16360664367676],[-79.65695190429688,61.64249610900879],[-80.27528381347656,61.806657791137695],[-80.01750183105469,62.35860633850098],[-79.54055786132812,62.41110420227051]]],[[[-92.41111755371094,62.39388465881348],[-92.60055541992188,62.38694190979004],[-92.53111267089844,62.43138313293457],[-92.41111755371094,62.39388465881348]]],[[[-64.65388488769531,62.54083442687988],[-64.38276672363281,62.51138496398926],[-64.96583557128906,62.465829849243164],[-64.65388488769531,62.54083442687988]]],[[[-64.98306274414062,62.52804756164551],[-65.14167785644531,62.546945571899414],[-64.83944702148438,62.577775955200195],[-64.98306274414062,62.52804756164551]]],[[[-77.80526733398438,62.59249305725098],[-77.62138366699219,62.58443641662598],[-77.74526977539062,62.53416633605957],[-77.80526733398438,62.59249305725098]]],[[[-78.00834655761719,62.59360694885254],[-77.83778381347656,62.55694007873535],[-78.11305236816406,62.562211990356445],[-78.00834655761719,62.59360694885254]]],[[[-91.57278442382812,62.62748908996582],[-91.66806030273438,62.6491641998291],[-91.685546875,62.666940689086914],[-91.57278442382812,62.62748908996582]]],[[[-90.97999572753906,62.65777015686035],[-91.2711181640625,62.67999458312988],[-91.08029174804688,62.68693733215332],[-90.97999572753906,62.65777015686035]]],[[[-74.3477783203125,62.6794376373291],[-73.95805358886719,62.612497329711914],[-74.65139770507812,62.716936111450195],[-74.3477783203125,62.6794376373291]]],[[[-70.711669921875,62.81499671936035],[-70.21112060546875,62.57916450500488],[-71.24137878417969,62.88138008117676],[-70.711669921875,62.81499671936035]]],[[[-66.36833190917969,62.83526802062988],[-66.60166931152344,62.90665626525879],[-66.54777526855469,62.91054725646973],[-66.36833190917969,62.83526802062988]]],[[[-81.87110900878906,62.92833137512207],[-83.08778381347656,62.17888069152832],[-83.70388793945312,62.14166450500488],[-83.94526672363281,62.42721748352051],[-83.31082153320312,62.92444038391113],[-81.87110900878906,62.92833137512207]]],[[[-66.8255615234375,62.98416328430176],[-67.0694580078125,63.107500076293945],[-66.94610595703125,63.07499885559082],[-66.8255615234375,62.98416328430176]]],[[[-67.76445007324219,63.162492752075195],[-67.875,63.22304725646973],[-67.83195495605469,63.244157791137695],[-67.76445007324219,63.162492752075195]]],[[[-67.92500305175781,63.18332862854004],[-67.96694946289062,63.18387794494629],[-68.11221313476562,63.313608169555664],[-67.92500305175781,63.18332862854004]]],[[[-78.07972717285156,63.469438552856445],[-77.4949951171875,63.26583290100098],[-77.9466552734375,63.09110450744629],[-78.57278442382812,63.44027137756348],[-78.07972717285156,63.469438552856445]]],[[[-90.65388488769531,63.44110298156738],[-90.75723266601562,63.49444007873535],[-90.59805297851562,63.45443916320801],[-90.65388488769531,63.44110298156738]]],[[[-78.5574951171875,63.45749855041504],[-78.51583862304688,63.53166389465332],[-78.461669921875,63.50750160217285],[-78.5574951171875,63.45749855041504]]],[[[-90.79360961914062,63.494157791137695],[-90.96833801269531,63.55027198791504],[-90.67471313476562,63.51388740539551],[-90.79360961914062,63.494157791137695]]],[[[-72.1824951171875,63.51999092102051],[-72.28666687011719,63.583330154418945],[-72.12916564941406,63.55888557434082],[-72.1824951171875,63.51999092102051]]],[[[-64.09249877929688,63.48166084289551],[-64.21278381347656,63.623605728149414],[-64.09333801269531,63.56833076477051],[-64.09249877929688,63.48166084289551]]],[[[-76.810546875,63.60110664367676],[-76.54194641113281,63.46249580383301],[-77.45722961425781,63.643327713012695],[-76.810546875,63.60110664367676]]],[[[-64.06111145019531,63.27054786682129],[-64.47917175292969,63.63694190979004],[-64.32888793945312,63.64444160461426],[-64.06111145019531,63.27054786682129]]],[[[-68.65638732910156,63.62638282775879],[-68.82167053222656,63.65249061584473],[-68.67694091796875,63.6713809967041],[-68.65638732910156,63.62638282775879]]],[[[-72.5947265625,63.64249610900879],[-72.7833251953125,63.664438247680664],[-72.45973205566406,63.67916297912598],[-72.5947265625,63.64249610900879]]],[[[-71.79916381835938,63.615549087524414],[-71.86332702636719,63.61944007873535],[-71.86416625976562,63.669443130493164],[-71.77944946289062,63.68832588195801],[-71.79916381835938,63.615549087524414]]],[[[-64.03250122070312,63.689714431762695],[-64.21250915527344,63.71221351623535],[-64.07528686523438,63.7580509185791],[-64.03250122070312,63.689714431762695]]],[[[-72.66777038574219,63.69582557678223],[-72.7197265625,63.76388740539551],[-72.62666320800781,63.73221015930176],[-72.66777038574219,63.69582557678223]]],[[[-64.28443908691406,63.70860481262207],[-64.381103515625,63.80749702453613],[-64.27861022949219,63.770830154418945],[-64.28443908691406,63.70860481262207]]],[[[-64.57611083984375,63.78082466125488],[-64.38612365722656,63.70166206359863],[-64.92027282714844,63.824716567993164],[-64.57611083984375,63.78082466125488]]],[[[-64.17027282714844,63.85638618469238],[-64.23443603515625,63.771379470825195],[-64.399169921875,63.849435806274414],[-64.17027282714844,63.85638618469238]]],[[[-77.74388122558594,63.92666053771973],[-77.98249816894531,63.983049392700195],[-77.54444885253906,64.02192878723145],[-77.74388122558594,63.92666053771973]]],[[[-89.80888366699219,64.05636787414551],[-89.86111450195312,64.07165718078613],[-89.86776733398438,64.09582710266113],[-89.80888366699219,64.05636787414551]]],[[[-64.96278381347656,64.11081123352051],[-64.8699951171875,64.09332466125488],[-65.0574951171875,64.11303901672363],[-64.96278381347656,64.11081123352051]]],[[[-64.49110412597656,64.1091480255127],[-64.59584045410156,64.15664863586426],[-64.45333862304688,64.14694404602051],[-64.49110412597656,64.1091480255127]]],[[[-73.17694091796875,64.20027351379395],[-73.28277587890625,64.1433277130127],[-73.40167236328125,64.1655445098877],[-73.17694091796875,64.20027351379395]]],[[[-81.47138977050781,64.18887519836426],[-81.53805541992188,64.21805000305176],[-81.37582397460938,64.22082710266113],[-81.47138977050781,64.18887519836426]]],[[[-64.52027893066406,64.22026252746582],[-64.64778137207031,64.25000190734863],[-64.46221923828125,64.23748970031738],[-64.52027893066406,64.22026252746582]]],[[[-64.9385986328125,64.23553657531738],[-65.11250305175781,64.33970832824707],[-64.88473510742188,64.28776741027832],[-64.9385986328125,64.23553657531738]]],[[[-75.5513916015625,64.30386543273926],[-75.70584106445312,64.3419361114502],[-75.49360656738281,64.31637763977051],[-75.5513916015625,64.30386543273926]]],[[[-73.87638854980469,64.30137825012207],[-73.97250366210938,64.3097095489502],[-73.9566650390625,64.36831855773926],[-73.87638854980469,64.30137825012207]]],[[[-73.69776916503906,64.26999092102051],[-73.8336181640625,64.33166694641113],[-73.78138732910156,64.40555000305176],[-73.69776916503906,64.26999092102051]]],[[[-64.8497314453125,64.30748176574707],[-64.9586181640625,64.40582466125488],[-64.77194213867188,64.34887886047363],[-64.8497314453125,64.30748176574707]]],[[[-74.27194213867188,64.41360664367676],[-74.43943786621094,64.45332527160645],[-74.17332458496094,64.43914985656738],[-74.27194213867188,64.41360664367676]]],[[[-73.7449951171875,64.42608833312988],[-73.78138732910156,64.43193244934082],[-73.77333068847656,64.50332832336426],[-73.66860961914062,64.46443367004395],[-73.7449951171875,64.42608833312988]]],[[[-74.21278381347656,64.4830493927002],[-74.35777282714844,64.55108833312988],[-74.16972351074219,64.52388191223145],[-74.21278381347656,64.4830493927002]]],[[[-73.5574951171875,64.3127613067627],[-73.6824951171875,64.50972175598145],[-73.52778625488281,64.56694221496582],[-73.5574951171875,64.3127613067627]]],[[[-65.49276733398438,64.51776313781738],[-65.69027709960938,64.52415657043457],[-65.20805358886719,64.63971138000488],[-65.49276733398438,64.51776313781738]]],[[[-63.35333251953125,64.99498176574707],[-63.25889587402344,64.92109870910645],[-63.42028045654297,64.9760913848877],[-63.35333251953125,64.99498176574707]]],[[[-63.243614196777344,65.25499153137207],[-63.311668395996094,65.29803657531738],[-63.16638946533203,65.28610420227051],[-63.243614196777344,65.25499153137207]]],[[[-66.92471313476562,65.28442573547363],[-67.01055908203125,65.33333015441895],[-66.91082763671875,65.35693550109863],[-66.92471313476562,65.28442573547363]]],[[[-88.43028259277344,65.45526313781738],[-88.51222229003906,65.46971321105957],[-88.3941650390625,65.46582221984863],[-88.43028259277344,65.45526313781738]]],[[[-62.795005798339844,65.51999092102051],[-62.88444519042969,65.60554695129395],[-62.75083923339844,65.55137825012207],[-62.795005798339844,65.51999092102051]]],[[[-83.88276672363281,65.66693305969238],[-83.94221496582031,65.68692207336426],[-83.87277221679688,65.71220588684082],[-83.88276672363281,65.66693305969238]]],[[[-62.268333435058594,65.70166206359863],[-62.13194274902344,65.65721321105957],[-62.48444366455078,65.72693061828613],[-62.268333435058594,65.70166206359863]]],[[[-67.47250366210938,65.70526313781738],[-67.71583557128906,65.70166206359863],[-67.4244384765625,65.73526191711426],[-67.47250366210938,65.70526313781738]]],[[[-85.48056030273438,65.79193305969238],[-85.15638732910156,65.77665901184082],[-85.31193542480469,65.53776741027832],[-84.92471313476562,65.20971870422363],[-84.44027709960938,65.45665168762207],[-81.7630615234375,64.50110054016113],[-81.60249328613281,64.12997627258301],[-81.9869384765625,63.994157791137695],[-80.89083862304688,64.11554145812988],[-80.17166137695312,63.77110481262207],[-81.07640075683594,63.45138740539551],[-82.47222900390625,63.68027687072754],[-82.36138916015625,63.9052677154541],[-83.09889221191406,63.95916175842285],[-83.07278442382812,64.18664741516113],[-85.26640319824219,63.11749458312988],[-85.58917236328125,63.17471504211426],[-85.71749877929688,63.71610450744629],[-87.18804931640625,63.58999061584473],[-86.18943786621094,64.10165596008301],[-86.40167236328125,64.43664741516113],[-86.0977783203125,65.52916145324707],[-85.48056030273438,65.79193305969238]]],[[[-83.28388977050781,65.83415412902832],[-83.48527526855469,65.80081367492676],[-83.58612060546875,65.85415840148926],[-83.28388977050781,65.83415412902832]]],[[[-65.64584350585938,65.81303596496582],[-65.64778137207031,65.87997627258301],[-65.51139831542969,65.90304756164551],[-65.64584350585938,65.81303596496582]]],[[[-62.13666534423828,65.85138130187988],[-62.296669006347656,65.93858528137207],[-62.137779235839844,65.92581367492676],[-62.13666534423828,65.85138130187988]]],[[[-67.13833618164062,65.92692756652832],[-67.21194458007812,65.98275947570801],[-67.15388488769531,65.97859382629395],[-67.13833618164062,65.92692756652832]]],[[[-84.7227783203125,65.54609870910645],[-85.17304992675781,65.99470710754395],[-84.586669921875,65.69220161437988],[-84.7227783203125,65.54609870910645]]],[[[-83.57695007324219,65.9830493927002],[-83.60444641113281,65.98776435852051],[-83.49305725097656,66.01277351379395],[-83.57695007324219,65.9830493927002]]],[[[-83.60861206054688,66.04414558410645],[-83.65361022949219,66.04136848449707],[-83.60722351074219,66.07748603820801],[-83.57084655761719,66.05636787414551],[-83.60861206054688,66.04414558410645]]],[[[-85.0191650390625,66.05720710754395],[-85.149169921875,66.05053901672363],[-85.0997314453125,66.08970832824707],[-85.0191650390625,66.05720710754395]]],[[[-83.64944458007812,66.08360481262207],[-83.68527221679688,66.12109565734863],[-83.58778381347656,66.1172046661377],[-83.64944458007812,66.08360481262207]]],[[[-83.92138671875,66.00972175598145],[-83.69415283203125,65.9246997833252],[-83.72749328613281,65.79971504211426],[-83.21083068847656,65.7058277130127],[-83.8427734375,65.64915657043457],[-83.68276977539062,65.74942207336426],[-84.14361572265625,65.76416206359863],[-84.12361145019531,65.90027046203613],[-84.47027587890625,66.13333320617676],[-83.92138671875,66.00972175598145]]],[[[-84.57972717285156,66.1413745880127],[-84.63999938964844,66.14055061340332],[-84.67860412597656,66.18248176574707],[-84.57972717285156,66.1413745880127]]],[[[-84.26528930664062,66.17776679992676],[-84.36361694335938,66.20942878723145],[-84.27305603027344,66.19664192199707],[-84.26528930664062,66.17776679992676]]],[[[-62.18388366699219,66.2371997833252],[-62.43000030517578,66.22915840148926],[-62.26167297363281,66.28027534484863],[-62.18388366699219,66.2371997833252]]],[[[-83.06723022460938,66.25555610656738],[-83.29833984375,66.31387519836426],[-82.90249633789062,66.27165412902832],[-83.06723022460938,66.25555610656738]]],[[[-66.62332153320312,66.28082466125488],[-66.95834350585938,66.41192817687988],[-66.57501220703125,66.31387519836426],[-66.62332153320312,66.28082466125488]]],[[[-66.99833679199219,66.49304389953613],[-66.86888122558594,66.46443367004395],[-67.03666687011719,66.45610237121582],[-66.99833679199219,66.49304389953613]]],[[[-107.92304992675781,66.85054206848145],[-107.79499816894531,66.9972095489502],[-107.82389831542969,66.90109443664551],[-107.92304992675781,66.85054206848145]]],[[[-63.059165954589844,66.95776557922363],[-63.166107177734375,67.00499153137207],[-63,66.98442268371582],[-63.059165954589844,66.95776557922363]]],[[[-108.01445007324219,66.89776802062988],[-108.10659790039062,67.02600288391113],[-107.93831634521484,66.94693183898926],[-108.01445007324219,66.89776802062988]]],[[[-62.9183349609375,67.00972175598145],[-63.13805389404297,67.06526374816895],[-63.002227783203125,67.06944465637207],[-62.9183349609375,67.00972175598145]]],[[[-62.6441650390625,67.05748176574707],[-62.899444580078125,67.05832099914551],[-62.375274658203125,67.16581916809082],[-62.6441650390625,67.05748176574707]]],[[[-107.40778350830078,67.08305549621582],[-107.52778625488281,67.07805061340332],[-107.62666320800781,67.20027351379395],[-107.40778350830078,67.08305549621582]]],[[[-95.36166381835938,67.19775581359863],[-95.55278015136719,67.23526191711426],[-95.30722045898438,67.25248908996582],[-95.36166381835938,67.19775581359863]]],[[[-107.66278076171875,67.22026252746582],[-107.72501373291016,67.31303596496582],[-107.66000366210938,67.29887580871582],[-107.66278076171875,67.22026252746582]]],[[[-63.36639404296875,67.28776741027832],[-63.82972717285156,67.28415107727051],[-63.58583068847656,67.35331916809082],[-63.36639404296875,67.28776741027832]]],[[[-107.91082763671875,67.31053352355957],[-108.07389831542969,67.43081855773926],[-107.89472961425781,67.48553657531738],[-107.91082763671875,67.31053352355957]]],[[[-108.36833190917969,67.46721076965332],[-108.49137878417969,67.56303596496582],[-108.29750061035156,67.55720710754395],[-108.36833190917969,67.46721076965332]]],[[[-108.14111328125,67.44999885559082],[-108.27194213867188,67.47137641906738],[-108.21916198730469,67.57110786437988],[-108.14111328125,67.44999885559082]]],[[[-108.3227767944336,67.5899829864502],[-108.48388671875,67.63665962219238],[-108.39028930664062,67.63109016418457],[-108.3227767944336,67.5899829864502]]],[[[-63.88194274902344,67.50332832336426],[-64.02972412109375,67.51388740539551],[-63.97694396972656,67.6494312286377],[-63.758056640625,67.52054023742676],[-63.88194274902344,67.50332832336426]]],[[[-108.05999755859375,67.47526741027832],[-108.11361694335938,67.67526435852051],[-107.92138671875,67.5466480255127],[-108.05999755859375,67.47526741027832]]],[[[-97.50279235839844,67.62442207336426],[-97.560546875,67.69275093078613],[-97.33778381347656,67.72415351867676],[-97.50279235839844,67.62442207336426]]],[[[-109.11221313476562,67.7633228302002],[-109.20777893066406,67.78387641906738],[-109.03916931152344,67.79332160949707],[-109.11221313476562,67.7633228302002]]],[[[-96.17054557800293,67.77304267883301],[-96.07722473144531,67.8388843536377],[-95.99749755859375,67.82083320617676],[-96.17054557800293,67.77304267883301]]],[[[-114.1150131225586,67.88388252258301],[-114.29695129394531,67.89526557922363],[-113.92138671875,67.87803840637207],[-114.1150131225586,67.88388252258301]]],[[[-113.39028930664062,67.89776802062988],[-113.60333251953125,67.90304756164551],[-113.2469482421875,67.91443061828613],[-113.39028930664062,67.89776802062988]]],[[[-112.93055725097656,67.91665840148926],[-113.14750671386719,67.91220283508301],[-112.88722229003906,67.92720222473145],[-112.93055725097656,67.91665840148926]]],[[[-108.64695739746094,67.86943244934082],[-108.54472351074219,67.92831611633301],[-108.35944366455078,67.89999580383301],[-108.64695739746094,67.86943244934082]]],[[[-114.21916198730469,67.94525337219238],[-114.31723022460938,67.94970893859863],[-114.12110900878906,67.9619312286377],[-114.21916198730469,67.94525337219238]]],[[[-108.1380615234375,67.87248420715332],[-108.25556945800781,67.88720893859863],[-108.054443359375,67.96331977844238],[-108.1380615234375,67.87248420715332]]],[[[-113.72000122070312,67.97331428527832],[-113.99305725097656,67.96110725402832],[-113.77223205566406,67.98027229309082],[-113.72000122070312,67.97331428527832]]],[[[-109.19526672363281,67.98997688293457],[-108.95111083984375,67.97331428527832],[-108.8660945892334,67.90027046203613],[-109.19526672363281,67.98997688293457]]],[[[-110.33444213867188,68.01165962219238],[-110.42083740234375,68.02083015441895],[-110.31749725341797,68.04971504211426],[-110.33444213867188,68.01165962219238]]],[[[-98.95140075683594,67.97998237609863],[-99.07861328125,68.04559516906738],[-98.97555541992188,68.07721138000488],[-98.95140075683594,67.97998237609863]]],[[[-108.50611877441406,68.03471565246582],[-108.540283203125,68.03997993469238],[-108.4474868774414,68.08777046203613],[-108.50611877441406,68.03471565246582]]],[[[-65.39723205566406,68.03997993469238],[-65.51972961425781,68.06749153137207],[-65.38639831542969,68.08831977844238],[-65.39723205566406,68.03997993469238]]],[[[-109.32167053222656,67.9810962677002],[-109.54306030273438,68.05220222473145],[-109.44721984863281,68.09221076965332],[-109.32167053222656,67.9810962677002]]],[[[-108.36054992675781,68.04971504211426],[-108.40805053710938,68.0697193145752],[-108.29444885253906,68.09721565246582],[-108.36054992675781,68.04971504211426]]],[[[-74.21556091308594,68.11775398254395],[-73.34861755371094,67.82805061340332],[-74.7772216796875,67.97387886047363],[-74.21556091308594,68.11775398254395]]],[[[-110.213623046875,68.03804206848145],[-110.25862121582031,68.04193305969238],[-109.87721252441406,68.12692451477051],[-110.213623046875,68.03804206848145]]],[[[-65.64222717285156,68.15942573547363],[-65.49554443359375,68.1283130645752],[-65.70973205566406,68.1060962677002],[-65.64222717285156,68.15942573547363]]],[[[-112.78056335449219,68.13109016418457],[-112.92223358154297,68.14665412902832],[-112.75167846679688,68.16470527648926],[-112.78056335449219,68.13109016418457]]],[[[-107.47361755371094,68.14471626281738],[-107.55416870117188,68.16609382629395],[-107.46806335449219,68.18858528137207],[-107.47361755371094,68.14471626281738]]],[[[-104.45305633544922,68.10220527648926],[-104.55387878417969,68.16165351867676],[-104.37721252441406,68.19970893859863],[-104.45305633544922,68.10220527648926]]],[[[-107.38890075683594,68.17221260070801],[-107.44526672363281,68.20166206359863],[-107.29167175292969,68.2027759552002],[-107.38890075683594,68.17221260070801]]],[[[-98.65028381347656,68.18026924133301],[-98.70445251464844,68.17608833312988],[-98.69332885742188,68.21360969543457],[-98.65028381347656,68.18026924133301]]],[[[-111.83332824707031,68.18193244934082],[-111.86554718017578,68.18803596496582],[-111.75499725341797,68.21582221984863],[-111.83332824707031,68.18193244934082]]],[[[-96.38417053222656,68.2008228302002],[-96.46278381347656,68.21609687805176],[-96.3175048828125,68.23193550109863],[-96.38417053222656,68.2008228302002]]],[[[-74.06277465820312,68.15165901184082],[-74.1763916015625,68.20416450500488],[-74.07972717285156,68.23248481750488],[-74.06277465820312,68.15165901184082]]],[[[-108.59028625488281,68.21443367004395],[-108.677490234375,68.16887092590332],[-108.55972290039062,68.2361011505127],[-108.59028625488281,68.21443367004395]]],[[[-66.31361389160156,68.14776802062988],[-66.60722351074219,68.21721076965332],[-66.22193908691406,68.24109077453613],[-66.31361389160156,68.14776802062988]]],[[[-109.78388977050781,68.13749885559082],[-109.85665893554688,68.14776802062988],[-109.56806945800781,68.2472095489502],[-109.78388977050781,68.13749885559082]]],[[[-78.57167053222656,68.20027351379395],[-78.66221618652344,68.18914985656738],[-78.54804992675781,68.26304817199707],[-78.57167053222656,68.20027351379395]]],[[[-111.71028137207031,68.22053718566895],[-111.7772216796875,68.25305366516113],[-111.49944305419922,68.29693794250488],[-111.71028137207031,68.22053718566895]]],[[[-75.58277893066406,68.30026435852051],[-75.00306701660156,68.13220405578613],[-75.1986083984375,67.44331550598145],[-76.66361999511719,67.2199878692627],[-77.2469482421875,67.45193672180176],[-77.251953125,67.82638740539551],[-76.72610473632812,68.23887825012207],[-75.58277893066406,68.30026435852051]]],[[[-86.4263916015625,68.06915473937988],[-86.5836181640625,67.72526741027832],[-86.99276733398438,68.0666675567627],[-86.67500305175781,68.30609321594238],[-86.4263916015625,68.06915473937988]]],[[[-79.02055358886719,68.16914558410645],[-79.19110107421875,68.31944465637207],[-78.80166625976562,68.27916145324707],[-79.02055358886719,68.16914558410645]]],[[[-100.07472229003906,68.34971809387207],[-100.09944152832031,68.27859687805176],[-100.23082733154297,68.3197193145752],[-100.07472229003906,68.34971809387207]]],[[[-82.05999755859375,68.30609321594238],[-82.34555053710938,68.36775398254395],[-81.99722290039062,68.34137153625488],[-82.05999755859375,68.30609321594238]]],[[[-111.11444091796875,68.40582466125488],[-111.149169921875,68.43997383117676],[-111.0824966430664,68.44470405578613],[-111.11444091796875,68.40582466125488]]],[[[-74.16221618652344,68.24609565734863],[-74.39306640625,68.44525337219238],[-74.07945251464844,68.33859443664551],[-74.16221618652344,68.24609565734863]]],[[[-99.04527282714844,68.42387580871582],[-99.05499267578125,68.40832710266113],[-99.15916442871094,68.45109748840332],[-99.04527282714844,68.42387580871582]]],[[[-100.71056365966797,68.4024829864502],[-100.88971710205078,68.4527759552002],[-100.79332733154297,68.46887397766113],[-100.71056365966797,68.4024829864502]]],[[[-110.86250305175781,68.47415351867676],[-111.09750366210938,68.48275947570801],[-110.69611358642578,68.48637580871582],[-110.86250305175781,68.47415351867676]]],[[[-110.5869369506836,68.52415657043457],[-110.76194763183594,68.56164741516113],[-110.51834106445312,68.53915596008301],[-110.5869369506836,68.52415657043457]]],[[[-104.54527282714844,68.39610481262207],[-105.08168029785156,68.54637336730957],[-104.68250274658203,68.57388496398926],[-104.54527282714844,68.39610481262207]]],[[[-105.1391830444336,68.53637886047363],[-105.05888366699219,68.5041675567627],[-105.29222106933594,68.58221626281738],[-105.1391830444336,68.53637886047363]]],[[[-113.78611755371094,68.58276557922363],[-113.96611022949219,68.6111011505127],[-113.76194763183594,68.59221076965332],[-113.78611755371094,68.58276557922363]]],[[[-100.74054718017578,68.59637641906738],[-100.88249206542969,68.61137580871582],[-100.81388854980469,68.61914253234863],[-100.74054718017578,68.59637641906738]]],[[[-78.46888732910156,68.56387519836426],[-78.95973205566406,68.47470283508301],[-78.8638916015625,68.65971565246582],[-78.46888732910156,68.56387519836426]]],[[[-74.81138610839844,68.32054328918457],[-75.39695739746094,68.6111011505127],[-75,68.67224311828613],[-74.81138610839844,68.32054328918457]]],[[[-74.76889038085938,68.67387580871582],[-74.51834106445312,68.55859565734863],[-74.89028930664062,68.62498664855957],[-74.76889038085938,68.67387580871582]]],[[[-114.04723358154297,68.61360359191895],[-114.18998718261719,68.68026924133301],[-114.14195251464844,68.67692756652832],[-114.04723358154297,68.61360359191895]]],[[[-101.83112335205078,68.56694221496582],[-102.31639099121094,68.67221260070801],[-101.69387817382812,68.76805305480957],[-101.83112335205078,68.56694221496582]]],[[[-68.11027526855469,68.78276252746582],[-67.66139221191406,68.70193672180176],[-68.45944213867188,68.79109382629395],[-68.11027526855469,68.78276252746582]]],[[[-102.600830078125,68.81331062316895],[-102.70722961425781,68.8166675567627],[-102.61277770996094,68.84305000305176],[-102.600830078125,68.81331062316895]]],[[[-89.94444274902344,68.66220283508301],[-89.94444274902344,68.84749031066895],[-89.78167724609375,68.76666450500488],[-89.94444274902344,68.66220283508301]]],[[[-114.350830078125,68.87164497375488],[-114.4716567993164,68.89248847961426],[-114.32333374023438,68.88304328918457],[-114.350830078125,68.87164497375488]]],[[[-67.8477783203125,68.85193061828613],[-67.96055603027344,68.92997932434082],[-67.87638854980469,68.94941902160645],[-67.8477783203125,68.85193061828613]]],[[[-100.17555236816406,68.79471015930176],[-100.623046875,68.76193428039551],[-100.59999084472656,69.00055122375488],[-100.17555236816406,68.79471015930176]]],[[[-85.3416748046875,68.98359870910645],[-85.45306396484375,69.00583076477051],[-85.3699951171875,69.00193977355957],[-85.3416748046875,68.98359870910645]]],[[[-89.90834045410156,68.91775703430176],[-90.070556640625,68.98193550109863],[-89.92083740234375,69.0102710723877],[-89.90834045410156,68.91775703430176]]],[[[-85.11944580078125,69.01471138000488],[-85.17027282714844,69.03581428527832],[-85.06138610839844,69.03665351867676],[-85.11944580078125,69.01471138000488]]],[[[-85.26528930664062,69.07249641418457],[-85.39889526367188,69.08610725402832],[-85.241943359375,69.09137153625488],[-85.26528930664062,69.07249641418457]]],[[[-99.99943542480469,68.94359016418457],[-100.25862121582031,69.04193305969238],[-100.05304718017578,69.10247993469238],[-99.99943542480469,68.94359016418457]]],[[[-90.12471008300781,69.04942512512207],[-90.27639770507812,69.12581062316895],[-90.14723205566406,69.10359382629395],[-90.12471008300781,69.04942512512207]]],[[[-101.66416931152344,69.08360481262207],[-101.69526672363281,69.20694160461426],[-101.49500274658203,69.1655445098877],[-101.66416931152344,69.08360481262207]]],[[[-90.51251220703125,69.20248603820801],[-90.77583312988281,69.32998847961426],[-90.58250427246094,69.35971260070801],[-90.51251220703125,69.20248603820801]]],[[[-78.41221618652344,69.37970161437988],[-78.21083068847656,69.29443550109863],[-78.83029174804688,68.91304206848145],[-79.40028381347656,68.87191963195801],[-78.41221618652344,69.37970161437988]]],[[[-135.28890991210938,69.30941963195801],[-135.5655517578125,69.39055061340332],[-135.3377685546875,69.38859748840332],[-135.28890991210938,69.30941963195801]]],[[[-76.95083618164062,69.39526557922363],[-76.64666557312012,69.3369312286377],[-77.38194274902344,69.24748420715332],[-76.95083618164062,69.39526557922363]]],[[[-90.32945251464844,69.23581123352051],[-90.51445007324219,69.36387825012207],[-90.20083618164062,69.44442939758301],[-90.32945251464844,69.23581123352051]]],[[[-135.59222412109375,69.48221015930176],[-135.57443237304688,69.44664192199707],[-135.8155517578125,69.50248908996582],[-135.59222412109375,69.48221015930176]]],[[[-101.05304718017578,69.50444221496582],[-101.23029327392578,69.36859321594238],[-101.38722229003906,69.53776741027832],[-101.05304718017578,69.50444221496582]]],[[[-96.66305541992188,69.5697193145752],[-96.09611511230469,69.46805000305176],[-96.23388671875,69.35971260070801],[-96.66305541992188,69.5697193145752]]],[[[-67.310546875,69.54915046691895],[-67.74972534179688,69.52110481262207],[-67.48443603515625,69.59027290344238],[-67.310546875,69.54915046691895]]],[[[-95.4888916015625,69.56553840637207],[-95.51583862304688,69.3308277130127],[-95.7369384765625,69.32443428039551],[-95.66915893554688,69.50749397277832],[-95.81582641601562,69.5627613067627],[-95.99082946777344,69.35331916809082],[-95.91999816894531,69.59526252746582],[-95.4888916015625,69.56553840637207]]],[[[-96.76055908203125,69.54553413391113],[-96.88389587402344,69.55914497375488],[-96.9022216796875,69.59776496887207],[-96.76055908203125,69.54553413391113]]],[[[-91.11000061035156,69.54942512512207],[-91.10888671875,69.60220527648926],[-90.91915893554688,69.6060962677002],[-91.11000061035156,69.54942512512207]]],[[[-133.93222045898438,69.56025886535645],[-134.01666259765625,69.57609748840332],[-133.93362426757812,69.61609077453613],[-133.8447265625,69.60081672668457],[-133.93222045898438,69.56025886535645]]],[[[-135.51724243164062,69.56915473937988],[-135.58944702148438,69.59610176086426],[-135.39779663085938,69.64694404602051],[-135.51724243164062,69.56915473937988]]],[[[-138.86721801757812,69.58831977844238],[-139.33248901367188,69.56608772277832],[-139.12026977539062,69.64999580383301],[-138.86721801757812,69.58831977844238]]],[[[-67.92027282714844,69.52192878723145],[-68.24888610839844,69.59665107727051],[-67.88972473144531,69.70833015441895],[-67.92027282714844,69.52192878723145]]],[[[-134.26058959960938,68.7335376739502],[-134.49554443359375,68.7522144317627],[-134.82583618164062,68.97886848449707],[-134.91473388671875,68.96666145324707],[-134.96112060546875,68.89248847961426],[-135.1419677734375,68.9013843536377],[-135.20166015625,68.9327564239502],[-135.3919677734375,68.9266529083252],[-135.4608154296875,68.94275093078613],[-135.90585327148438,68.91137886047363],[-135.97833251953125,69.04081916809082],[-135.51779174804688,69.02388191223145],[-135.96722412109375,69.21470832824707],[-135.4869384765625,69.11331367492676],[-135.854154586792,69.29081916809082],[-135.17056274414062,69.25776863098145],[-135.2872314453125,69.41914558410645],[-135.15084838867188,69.47693061828613],[-134.43832397460938,69.45471382141113],[-134.4910888671875,69.72221565246582],[-134.11331176757812,69.53888130187988],[-133.77835083007812,69.57638740539551],[-134.67361450195312,69.01776313781738],[-134.26058959960938,68.7335376739502]]],[[[-102.14527893066406,69.64860725402832],[-102.24137878417969,69.71026802062988],[-102.1347427368164,69.72470283508301],[-102.14527893066406,69.64860725402832]]],[[[-77.9466552734375,69.64665412902832],[-78.88027954101562,69.47693061828613],[-78.18055725097656,69.7522144317627],[-77.9466552734375,69.64665412902832]]],[[[-82.50778198242188,69.70498847961426],[-82.87944030761719,69.77859687805176],[-82.46028137207031,69.76165962219238],[-82.50778198242188,69.70498847961426]]],[[[-79.42304992675781,69.78499031066895],[-80.01194763183594,69.49165534973145],[-80.80943298339844,69.68304634094238],[-79.42304992675781,69.78499031066895]]],[[[-83.6744384765625,69.7199878692627],[-83.91722106933594,69.77859687805176],[-83.5291748046875,69.78665351867676],[-83.7086181640625,69.75943183898926],[-83.6744384765625,69.7199878692627]]],[[[-82.429443359375,69.78221321105957],[-82.6885986328125,69.85081672668457],[-82.51722717285156,69.85415840148926],[-82.429443359375,69.78221321105957]]],[[[-91.81916809082031,69.82165718078613],[-91.86416625976562,69.84414863586426],[-91.63972473144531,69.85498237609863],[-91.81916809082031,69.82165718078613]]],[[[-91.52000427246094,69.73137092590332],[-91.73554992675781,69.78915596008301],[-91.40916442871094,69.87498664855957],[-91.52000427246094,69.73137092590332]]],[[[-97.39778137207031,69.68553352355957],[-95.20695495605469,68.85026741027832],[-96.53056335449219,68.44497871398926],[-99.59638977050781,69.02054023742676],[-98.39334106445312,69.30803108215332],[-98.55665588378906,69.5808277130127],[-98.00389099121094,69.4358081817627],[-98.36776733398438,69.6010913848877],[-98.01222229003906,69.88582038879395],[-97.39778137207031,69.68553352355957]]],[[[-97.32501220703125,69.88916206359863],[-97.48860168457031,69.9438648223877],[-97.22694396972656,69.87359809875488],[-97.32501220703125,69.88916206359863]]],[[[-100.8497314453125,69.92553901672363],[-100.85861206054688,69.97776985168457],[-100.80695343017578,69.98581123352051],[-100.8497314453125,69.92553901672363]]],[[[-87.09138488769531,70.15027046203613],[-86.4566650390625,70.00749397277832],[-87.37832641601562,70.09610176086426],[-87.09138488769531,70.15027046203613]]],[[[-125.05695343017578,70.11831855773926],[-125.12332153320312,70.13546943664551],[-124.95500183105469,70.16415596008301],[-125.05695343017578,70.11831855773926]]],[[[-124.679443359375,70.16165351867676],[-124.76194763183594,70.19192695617676],[-124.50527954101562,70.19832038879395],[-124.679443359375,70.16165351867676]]],[[[-112.9697265625,70.28137397766113],[-113.20361328125,70.29248237609863],[-112.94554138183594,70.28665351867676],[-112.9697265625,70.28137397766113]]],[[[-112.6552734375,70.26609992980957],[-112.76139831542969,70.2986011505127],[-112.6875,70.30636787414551],[-112.6552734375,70.26609992980957]]],[[[-100.76528930664062,70.25000190734863],[-100.85193634033203,70.32388496398926],[-100.748046875,70.31694221496582],[-100.76528930664062,70.25000190734863]]],[[[-116.80526733398438,70.50943183898926],[-116.56833457946777,70.47387886047363],[-116.71916198730469,70.47026252746582],[-116.80526733398438,70.50943183898926]]],[[[-116.28778076171875,70.55331611633301],[-116.12748718261719,70.53581428527832],[-116.4958267211914,70.52276802062988],[-116.28778076171875,70.55331611633301]]],[[[-116.56304931640625,70.53442573547363],[-116.7744369506836,70.54525947570801],[-116.50945281982422,70.55609321594238],[-116.56304931640625,70.53442573547363]]],[[[-115.92054557800293,70.54136848449707],[-116.06111145019531,70.54832649230957],[-115.80803680419922,70.57054328918457],[-115.92054557800293,70.54136848449707]]],[[[-116.87944030761719,70.54748725891113],[-117.30166625976562,70.56192207336426],[-117.19943237304688,70.59166145324707],[-116.87944030761719,70.54748725891113]]],[[[-128.08612060546875,70.60554695129395],[-128.3416748046875,70.54220771789551],[-128.23416137695312,70.65609931945801],[-128.08612060546875,70.60554695129395]]],[[[-100.23082733154297,70.45166206359863],[-100.67083740234375,70.55887031555176],[-100.65194702148438,70.66971015930176],[-100.23082733154297,70.45166206359863]]],[[[-103.17778015136719,70.62248420715332],[-103.28138732910156,70.63804817199707],[-103.21000671386719,70.6766529083252],[-103.17778015136719,70.62248420715332]]],[[[-103.350830078125,70.68719673156738],[-103.46278381347656,70.73221015930176],[-103.34111022949219,70.72026252746582],[-103.350830078125,70.68719673156738]]],[[[-71.47166442871094,71.01277351379395],[-71.95556640625,70.81833076477051],[-72.22639465332031,70.93054389953613],[-71.47166442871094,71.01277351379395]]],[[[-96.56332397460938,71.29220771789551],[-96.47250366210938,71.23221015930176],[-96.4808349609375,71.2088794708252],[-96.63861083984375,71.2260913848877],[-96.56332397460938,71.29220771789551]]],[[[-98.89555358886719,71.27777290344238],[-99.00889587402344,71.31387519836426],[-98.95584106445312,71.35220527648926],[-98.89555358886719,71.27777290344238]]],[[[-73.12054443359375,71.47970771789551],[-73.37998962402344,71.51971626281738],[-72.8175048828125,71.44497871398926],[-73.12054443359375,71.47970771789551]]],[[[-72.76083374023438,71.53193855285645],[-73.03999328613281,71.57998847961426],[-72.69583129882812,71.65109443664551],[-72.76083374023438,71.53193855285645]]],[[[-73.37026977539062,71.55443000793457],[-73.44804382324219,71.59414863586426],[-73.14889526367188,71.67997932434082],[-73.37026977539062,71.55443000793457]]],[[[-96.95889282226562,71.70443916320801],[-97.05027770996094,71.70416450500488],[-96.84445190429688,71.74414253234863],[-96.95889282226562,71.70443916320801]]],[[[-95.33999633789062,71.73137092590332],[-95.48805236816406,71.74553108215332],[-95.26583862304688,71.83665657043457],[-95.33999633789062,71.73137092590332]]],[[[-134.49554443359375,68.7522144317627],[-134.33999633789062,68.67886543273926],[-134.2269287109375,68.69413948059082],[-134.26058959960938,68.7335376739502],[-134.56222534179688,69.08276557922363],[-130.54306030273438,70.16832160949707],[-129.40335083007812,70.11775398254395],[-130.92861938476562,69.56331062316895],[-131.05307006835938,69.63720893859863],[-131.99722290039062,69.53137397766113],[-133.49081420898438,68.82165718078613],[-132.47027587890625,68.80693244934082],[-132.86944580078125,69.0627613067627],[-131.6522216796875,69.47192573547363],[-131.32470703125,69.31999397277832],[-131.16650390625,69.40493202209473],[-131.2538604736328,69.57184791564941],[-131.11053466796875,69.48533058166504],[-131.13583374023438,69.35998725891113],[-131.06394958496094,69.51239204406738],[-131.19610595703125,69.5899829864502],[-131.08306884765625,69.60054206848145],[-131.02780151367188,69.4638843536377],[-131.10888671875,69.32165718078613],[-130.95278930664062,69.54332160949707],[-130.93722534179688,69.13443183898926],[-130.3660888671875,69.68637275695801],[-128.90084838867188,69.97192573547363],[-129.16946411132812,69.82470893859863],[-128.92501831054688,69.68081855773926],[-127.51500701904297,70.22165107727051],[-128.1966552734375,70.39193916320801],[-127.99665832519531,70.59054756164551],[-125.4263916015625,69.31218147277832],[-125.08944702148438,69.44970893859863],[-125.62249755859375,69.4185962677002],[-125.11805725097656,69.48579597473145],[-125.36554718017578,69.69026374816895],[-124.82195281982422,69.71499824523926],[-125.27639770507812,69.8082447052002],[-124.79527282714844,70.00888252258301],[-125.1974868774414,70.00450325012207],[-124.43611145019531,70.15109443664551],[-124.50055694580078,69.72581672668457],[-124.04083251953125,69.70138740539551],[-124.44666290283203,69.3672046661377],[-123.46611022949219,69.38388252258301],[-122.95916557312012,69.83360481262207],[-121.68388366699219,69.7935962677002],[-117.15387725830078,68.88554573059082],[-115.59306335449219,68.97165107727051],[-114.070556640625,68.47747993469238],[-114.02333068847656,68.24136543273926],[-115.5425033569336,67.9216480255127],[-115.10360717773438,67.7966480255127],[-112.39584350585938,67.67915534973145],[-111.00583457946777,67.76500129699707],[-110.08389282226562,68.00694465637207],[-109.06582641601562,67.71415901184082],[-108.82501220703125,67.34942817687988],[-108.6552734375,67.6283130645752],[-108.48416137695312,67.34942817687988],[-108.366943359375,67.44497871398926],[-108.01528930664062,67.29304695129395],[-107.88054656982422,67.04832649230957],[-108.62277221679688,67.14999580383301],[-107.248046875,66.3499927520752],[-107.74665832519531,66.92276191711426],[-107.0836181640625,66.82054328918457],[-108.0069580078125,67.70749092102051],[-107.65110778808594,67.94053840637207],[-107.89055633544922,68.08166694641113],[-106.43195343017578,68.15304756164551],[-106.46501159667969,68.33581733703613],[-105.7397232055664,68.41526985168457],[-105.6449966430664,68.63388252258301],[-106.54387664794922,68.51193428039551],[-106.54332733154297,68.29136848449707],[-106.80278015136719,68.41443061828613],[-107.8852767944336,68.26887702941895],[-107.60305786132812,68.16526985168457],[-108.81916809082031,68.26666450500488],[-108.31416320800781,68.61137580871582],[-106.22917175292969,68.9408130645752],[-105.4869384765625,68.72943305969238],[-105.38082885742188,68.48665046691895],[-105.54110717773438,68.41276741027832],[-104.60973358154297,68.24136543273926],[-104.67027282714844,68.13859748840332],[-104.5,68.03193855285645],[-103.42166137695312,68.16665840148926],[-102.25110626220703,67.72526741027832],[-98.35444641113281,67.79609870910645],[-98.61555480957031,68.07470893859863],[-98.09445190429688,67.76609992980957],[-97.50973510742188,67.59915351867676],[-97.11915588378906,67.79248237609863],[-97.68305969238281,68.01860237121582],[-98.02999877929688,67.94192695617676],[-98.07861328125,67.83027839660645],[-98.58750915527344,68.1494312286377],[-98.32611083984375,68.17137336730957],[-98.71444702148438,68.3722095489502],[-96.4041748046875,68.31137275695801],[-96.70834350585938,68.00860786437988],[-95.98028564453125,68.25471687316895],[-96.4647216796875,67.4780445098877],[-96.09722900390625,67.46470832824707],[-96.11444091796875,67.21331977844238],[-95.56582641601562,67.37664985656738],[-95.83332824707031,67.16276741027832],[-95.32611083984375,67.02720832824707],[-95.90249633789062,66.94664192199707],[-96.46055603027344,67.06219673156738],[-95.62971496582031,66.67553901672363],[-95.90249633789062,66.94664192199707],[-95.22084045410156,66.96832466125488],[-95.163330078125,67.28720283508301],[-95.70916557312012,67.72776985168457],[-95.4727783203125,68.06053352355957],[-94.72222900390625,68.05497932434082],[-93.55332946777344,68.58638191223145],[-93.66694641113281,68.97221565246582],[-94.625,68.76138496398926],[-94.07278442382812,69.12664985656738],[-94.30332946777344,69.30497932434082],[-93.36277770996094,69.37164497375488],[-95.96083068847656,69.77804756164551],[-96.53167724609375,70.13109016418457],[-96.23277282714844,70.56219673156738],[-95.78944396972656,70.53665351867676],[-96.6119384765625,70.79443550109863],[-96.3699951171875,71.0899829864502],[-96.560546875,71.12637519836426],[-96.46722412109375,71.16526985168457],[-96.46220397949219,71.25550270080566],[-96.50389099121094,71.27720832824707],[-95.5352783203125,71.29081916809082],[-95.94305419921875,71.55359077453613],[-94.60665893554688,71.86331367492676],[-95.21749877929688,71.94497871398926],[-93.711669921875,71.76138496398926],[-92.97389221191406,71.34082221984863],[-93.02749633789062,70.85276985168457],[-91.51362609863281,70.16720771789551],[-92.26834106445312,70.2088794708252],[-92.45028686523438,70.07110786437988],[-91.93971252441406,70.02026557922363],[-92.92027282714844,69.66971015930176],[-90.30776977539062,69.45027351379395],[-91.44721984863281,69.35276985168457],[-90.43638610839844,68.87442207336426],[-90.60665893554688,68.44609260559082],[-90.27139282226562,68.23887825012207],[-89.30665588378906,69.25139045715332],[-88.05221557617188,68.82304573059082],[-87.79222106933594,68.33442878723145],[-88.39222717285156,68.2874927520752],[-88.37083435058594,67.95915412902832],[-87.35777282714844,67.26220893859863],[-87.51028442382812,67.1121997833252],[-86.52362060546875,67.35220527648926],[-85.66361999511719,68.72693061828613],[-84.78721618652344,68.73359870910645],[-85.19444274902344,68.8672046661377],[-84.52833557128906,69.01748847961426],[-85.47332763671875,69.27192878723145],[-85.33195495605469,69.77916145324707],[-85.57194519042969,69.8560962677002],[-85.06443786621094,69.76999092102051],[-84.37582397460938,69.85748481750488],[-83.70500183105469,69.70359992980957],[-82.26333618164062,69.63804817199707],[-83.22805786132812,69.5385913848877],[-81.33250427246094,69.18248176574707],[-82.05722045898438,68.87387275695801],[-81.26750183105469,68.63304328918457],[-82.63890075683594,68.4972095489502],[-81.24305725097656,67.4749927520752],[-81.50306701660156,66.99971199035645],[-83.4022216796875,66.34749031066895],[-83.97749328613281,66.58221626281738],[-83.91639709472656,66.88109016418457],[-84.14028930664062,66.70193672180176],[-84.43638610839844,66.81833076477051],[-84.37083435058594,66.97137641906738],[-84.91500854492188,67.0608081817627],[-84.63972473144531,66.9780445098877],[-85.22833251953125,66.8783130645752],[-84.60221862792969,66.9358081817627],[-84.74638366699219,66.89749336242676],[-84.50584411621094,66.8277759552002],[-84.6905517578125,66.8399829864502],[-84.46694946289062,66.78776741027832],[-84.44248962402344,66.71081733703613],[-84.14445495605469,66.68136787414551],[-83.69305419921875,66.1908130645752],[-86.77528381347656,66.52609443664551],[-85.89723205566406,66.16832160949707],[-87.39584350585938,65.32138252258301],[-89.67166137695312,65.93942451477051],[-91.42916870117188,65.95109748840332],[-86.93331909179688,65.13804817199707],[-88.11332702636719,64.13611030578613],[-90.12416076660156,64.12858772277832],[-89.81361389160156,63.937211990356445],[-90.2791748046875,64.00360298156738],[-89.96417236328125,63.81193733215332],[-90.20527458190918,63.61221504211426],[-92.48277282714844,63.81193733215332],[-92.10166931152344,63.69693946838379],[-92.4808349609375,63.5272159576416],[-91.76333618164062,63.713327407836914],[-90.741943359375,63.36082649230957],[-90.62748718261719,63.05943489074707],[-92.42083740234375,62.83138465881348],[-91.885009765625,62.59916114807129],[-92.71000671386719,62.465829849243164],[-92.47001457214355,62.146615982055664],[-93.12222290039062,62.33499336242676],[-92.76472473144531,62.219438552856445],[-93.61610412597656,61.93998908996582],[-93.23777770996094,61.7772159576416],[-93.98472595214844,61.45610237121582],[-94.67332458496094,60.52249336242676],[-94.81916809082031,59.63638496398926],[-94.78971862792969,59.09221839904785],[-94.2288818359375,58.78499794006348],[-94.36332702636719,58.218881607055664],[-94.14389038085938,58.76361274719238],[-93.1522216796875,58.73777198791504],[-92.41888427734375,57.33749580383301],[-92.8760986328125,56.90749549865723],[-90.81527709960938,57.25583076477051],[-85.71444702148438,55.631662368774414],[-85.12193298339844,55.33777046203613],[-85.42388916015625,54.990549087524414],[-85.001953125,55.29666328430176],[-82.30776977539062,55.148881912231445],[-82.29666137695312,53.01860237121582],[-81.54998779296875,52.44110298156738],[-81.88362121582031,52.1874942779541],[-80.99444580078125,52.01138496398926],[-80.43638610839844,51.46415901184082],[-81.0150146484375,51.028329849243164],[-80.12026977539062,51.29638862609863],[-79.33222961425781,50.72387886047363],[-79.75222778320312,51.18443489074707],[-79.32223510742188,51.66276741027832],[-78.85333251953125,51.165544509887695],[-79.03555297851562,51.770273208618164],[-78.5069580078125,52.46055030822754],[-79.11027526855469,53.50249671936035],[-79.04888916015625,54.18332862854004],[-79.76445007324219,54.6522159576416],[-77.74861145019531,55.30082893371582],[-77.13722229003906,55.65416145324707],[-76.538330078125,56.29777717590332],[-76.52972412109375,57.1058292388916],[-76.8619384765625,57.71915626525879],[-78.57472229003906,58.635271072387695],[-78.570556640625,58.961381912231445],[-77.67721557617188,59.39999580383301],[-77.9102783203125,59.40555000305176],[-77.77389526367188,59.70971870422363],[-77.31388854980469,59.56499671936035],[-77.427490234375,59.91471290588379],[-76.75889587402344,60.15915870666504],[-77.59222412109375,60.064157485961914],[-77.74775695800781,60.40813636779785],[-77.413330078125,60.54416084289551],[-77.83389282226562,60.63943672180176],[-77.51167297363281,60.836381912231445],[-78.19276428222656,60.79083442687988],[-77.47471618652344,61.54166603088379],[-77.99249267578125,61.7147159576416],[-78.15583801269531,62.278329849243164],[-77.50834655761719,62.561662673950195],[-74.57167053222656,62.10305213928223],[-74.75973510742188,62.20638465881348],[-73.67887878417969,62.479990005493164],[-72.01005554199219,61.67527198791504],[-72.30332946777344,61.567216873168945],[-71.57501220703125,61.60860633850098],[-71.88751220703125,61.428049087524414],[-71.38999938964844,61.137773513793945],[-70.1461181640625,61.08471870422363],[-69.927490234375,60.80777168273926],[-69.51972961425781,61.07332801818848],[-69.37193298339844,60.8044376373291],[-69.82611083984375,60.52555274963379],[-69.62471008300781,60.0674991607666],[-70.94583129882812,60.06305122375488],[-69.60055541992188,59.83305549621582],[-69.75834655761719,59.32027626037598],[-69.23472595214844,59.2338809967041],[-69.53056335449219,59.18221473693848],[-69.54750061035156,58.80804634094238],[-69.86915588378906,59.053049087524414],[-69.81582641601562,58.82388496398926],[-70.15361022949219,58.77749061584473],[-69.81889343261719,58.58860206604004],[-69.2791748046875,58.88804817199707],[-68.36054992675781,58.781938552856445],[-68.34416198730469,58.12748908996582],[-69.36904907226562,57.7652530670166],[-68.4041748046875,58.03972053527832],[-68.00334167480469,58.57638740539551],[-67.89389038085938,58.496660232543945],[-67.85749816894531,58.32027626037598],[-68.12832641601562,58.07361030578613],[-67.8013916015625,58.29666328430176],[-67.81332397460938,58.41610145568848],[-67.72389221191406,58.45888710021973],[-67.71389770507812,57.923051834106445],[-66.38861083984375,58.85054969787598],[-65.93582153320312,58.60972023010254],[-66.05888366699219,58.32027626037598],[-65.87998962402344,58.627214431762695],[-66.1038818359375,58.77360725402832],[-65.78944396972656,58.86194038391113],[-65.98860168457031,58.90360450744629],[-65.3175048828125,59.04138374328613],[-65.71806335449219,59.15304756164551],[-65.35722351074219,59.2772159576416],[-65.56138610839844,59.48610877990723],[-64.98332214355469,59.37638282775879],[-65.52778625488281,59.716936111450195],[-64.98388671875,59.762773513793945],[-65.23194885253906,59.88582801818848],[-64.85444641113281,60.36110877990723],[-64.4669189453125,60.27860450744629],[-64.82749938964844,59.98638343811035],[-64.16694641113281,60.02499580383301],[-64.26666259765625,59.77916145324707],[-64.05776977539062,59.62526893615723],[-64.116943359375,59.51749610900879],[-63.722496032714844,59.51388740539551],[-64.06221008300781,59.38249397277832],[-63.35639190673828,59.20499610900879],[-64.04388427734375,59.015275955200195],[-63.13417053222656,59.05832862854004],[-63.32500457763672,58.8558292388916],[-62.847496032714844,58.6905460357666],[-63.589439392089844,58.30082893371582],[-62.55750274658203,58.482492446899414],[-62.82805633544922,58.25222206115723],[-62.584442138671875,58.21444129943848],[-63.34083557128906,57.979990005493164],[-62.452781677246094,58.17527198791504],[-62.30694580078125,58.03110694885254],[-62.67277526855469,57.92999458312988],[-62.12749481201172,57.96805000305176],[-62.059722900390625,57.897775650024414],[-62.13805389404297,57.835824966430664],[-62.125274658203125,57.80694007873535],[-61.88444519042969,57.62693977355957],[-62.54528045654297,57.501108169555664],[-61.35833740234375,57.08749580383301],[-61.90638732910156,56.79527473449707],[-61.67250061035156,56.6199893951416],[-62.573890686035156,56.79277229309082],[-61.65833282470703,56.53750038146973],[-62.14305877685547,56.44915962219238],[-61.66138458251953,56.270273208618164],[-62.01167297363281,56.23582649230957],[-61.35083770751953,56.22221565246582],[-61.45222473144531,56.05694007873535],[-61.23750305175781,56.04277229309082],[-61.50361633300781,56.00694465637207],[-61.117774963378906,55.96610450744629],[-61.07666778564453,55.906938552856445],[-61.20166778564453,55.884164810180664],[-61.10444641113281,55.84554481506348],[-60.72972106933594,55.82943916320801],[-60.87944030761719,55.73276710510254],[-60.60194396972656,55.814714431762695],[-60.668060302734375,55.589433670043945],[-60.328887939453125,55.78166389465332],[-60.47833251953125,55.347490310668945],[-60.19554901123047,55.43138313293457],[-60.683326721191406,54.99499702453613],[-59.77916717529297,55.329721450805664],[-59.96361541748047,55.11027717590332],[-59.42778015136719,55.13582801818848],[-59.93860626220703,54.74638557434082],[-59.16138458251953,55.23694038391113],[-59.38861083984375,54.97665596008301],[-59.02361297607422,55.15665626525879],[-58.90416717529297,54.84471321105957],[-57.347496032714844,54.57943916320801],[-59.5755615234375,54.04944038391113],[-58.37194061279297,54.228044509887695],[-60.133888244628906,53.528329849243164],[-60.85694885253906,53.79277229309082],[-60.103614807128906,53.50055122375488],[-60.4183349609375,53.26944160461426],[-57.78639221191406,54.071664810180664],[-58.4183349609375,54.139719009399414],[-58.17778015136719,54.23694038391113],[-57.38417053222656,54.15054512023926],[-57.076393127441406,53.82305335998535],[-57.54999542236328,53.591936111450195],[-57.336944580078125,53.44027137756348],[-56.464691162109375,53.78227424621582],[-56.68028259277344,53.67276954650879],[-55.80805206298828,53.34054756164551],[-56.16694641113281,53.029436111450195],[-55.75750732421875,52.61444282531738],[-56.49687194824219,52.59414863586426],[-55.64861297607422,52.439714431762695],[-56.19694519042969,52.43998908996582],[-55.70166778564453,52.08221626281738],[-56.94972229003906,51.42471504211426],[-58.6280517578125,51.27555274963379],[-60.0050048828125,50.24888038635254],[-66.4697265625,50.26194190979004],[-67.375,49.327219009399414],[-69.06082153320312,48.76749610900879],[-71.29916381835938,46.74221992492676],[-68.21112060546875,48.63665962219238],[-66.30610656738281,49.18693733215332],[-64.9969482421875,49.22027015686035],[-64.22166442871094,48.898332595825195],[-64.54888916015625,48.87832832336426],[-64.24638366699219,48.488046646118164],[-65.30583190917969,48.00555610656738],[-65.9041748046875,48.205827713012695],[-66.84249877929688,47.99221992492676],[-66.35665893554688,48.07332801818848],[-65.63473510742188,47.62082862854004],[-64.79722595214844,47.80638313293457],[-65.3699951171875,47.08665657043457],[-64.79861450195312,47.07999610900879],[-64.50418090820312,46.24027442932129],[-62.461944580078125,45.612497329711914],[-61.917503356933594,45.88555335998535],[-61.26000213623047,45.51027870178223],[-61.463890075683594,45.346940994262695],[-60.9647216796875,45.31305122375488],[-63.65833282470703,44.71499824523926],[-63.63111114501953,44.43582344055176],[-64.20083618164062,44.57638740539551],[-65.48138427734375,43.46444129943848],[-66.16694641113281,43.85860633850098],[-65.84445190429688,44.57833290100098],[-66.19110107421875,44.42332649230957],[-64.48916625976562,45.33526802062988],[-64.15638732910156,44.97832679748535],[-63.36083221435547,45.36082649230957],[-64.93721008300781,45.32694435119629],[-64.27555847167969,45.799997329711914],[-64.74749755859375,46.09054756164551],[-64.77833557128906,45.60721778869629],[-65.90361022949219,45.20555305480957],[-66.00250244140625,45.4616641998291],[-66.42778015136719,45.08499336242676],[-67.20654296875,45.18303871154785],[-67.79916381835938,45.70110511779785],[-67.79499816894531,47.06999397277832],[-69.23249816894531,47.47137641906738],[-70.87860107421875,45.238603591918945],[-74.99082946777344,44.98665809631348],[-76.80194091796875,43.63360786437988],[-78.72471618652344,43.62943458557129],[-79.18472290039062,43.46554756164551],[-78.9869384765625,42.81999397277832],[-82.6966552734375,41.68387794494629],[-83.16860961914062,42.04610633850098],[-82.52139282226562,42.61888313293457],[-82.13027954101562,43.58526802062988],[-82.54306030273438,45.3558292388916],[-83.5977783203125,45.827219009399414],[-83.57749938964844,46.10527229309082],[-83.95889282226562,46.071664810180664],[-84.12638854980469,46.531938552856445],[-84.56500244140625,46.466386795043945],[-84.85694885253906,46.9022159576416],[-88.36805725097656,48.312211990356445],[-89.35665893554688,47.97971534729004],[-90.86860656738281,48.237497329711914],[-91.4183349609375,48.04110908508301],[-92.95306396484375,48.62332344055176],[-94.6058349609375,48.724435806274414],[-95.07806396484375,49.35916328430176],[-95.1541748046875,48.99943733215332],[-122.76029968261719,48.99943733215332],[-123.03431701660156,48.99943733215332],[-123.09375,48.99943733215332],[-123.24889373779297,49.27360725402832],[-122.852783203125,49.436105728149414],[-123.23638916015625,49.338884353637695],[-123.15972900390625,49.69915962219238],[-123.49249267578125,49.509721755981445],[-123.53555297851562,49.38138008117676],[-124.06806945800781,49.63388252258301],[-123.53362274169922,49.689714431762695],[-123.93499755859375,49.768327713012695],[-123.82140350341797,50.1522159576416],[-123.9263916015625,49.82583045959473],[-124.41361999511719,49.76361274719238],[-124.82972717285156,50.06193733215332],[-124.70333862304688,49.99554634094238],[-124.60138702392578,50.2388858795166],[-124.71501159667969,50.32749366760254],[-124.3477783203125,50.50249671936035],[-125.07833862304688,50.32249641418457],[-124.80583190917969,50.92083168029785],[-125.11945343017578,50.43277168273926],[-125.54811096191406,50.49205207824707],[-125.443603515625,50.71415901184082],[-125.70584106445312,50.42777442932129],[-126.27471923828125,50.631662368774414],[-125.62249755859375,50.75000190734863],[-125.63390350341797,51.096940994262695],[-125.73110961914062,50.735551834106445],[-126.1310043334961,50.678659439086914],[-126.19888305664062,50.8558292388916],[-126.55972290039062,50.843881607055664],[-126.17778015136719,50.95138740539551],[-127.538330078125,51.00555610656738],[-126.66251373291016,51.19499397277832],[-127.78999328613281,51.165544509887695],[-127.133056640625,51.3255558013916],[-127.77887725830078,51.324716567993164],[-127.48805236816406,51.61944007873535],[-126.62000274658203,51.67999458312988],[-127.43222045898438,51.6683292388916],[-127.3510971069336,51.86361122131348],[-127.70639038085938,51.45638465881348],[-127.8780517578125,51.67388343811035],[-127.17166137695312,52.3124942779541],[-126.66944885253906,51.98360633850098],[-126.94082641601562,52.30388069152832],[-126.73249816894531,52.37388038635254],[-127.18639373779297,52.38082313537598],[-127.01777458190918,52.84554481506348],[-127.61833190917969,52.291940689086914],[-128.01251220703125,52.34110450744629],[-127.87970733642578,52.579721450805664],[-128.39389038085938,52.29138374328613],[-128.221923828125,52.46527290344238],[-128.13165283203125,52.87638282775879],[-128.44110107421875,52.822771072387695],[-128.53973388671875,53.13193702697754],[-128.85888671875,53.28360939025879],[-128.8879852294922,53.42496681213379],[-128.9727783203125,53.553049087524414],[-127.86776733398438,53.23971748352051],[-128.81304931640625,53.619157791137695],[-128.47137451171875,53.83249855041504],[-128.60055541992188,54.03166389465332],[-129.23248291015625,53.62582588195801],[-129.27279663085938,53.379159927368164],[-130.05029296875,53.88694190979004],[-130.04666137695312,54.15332221984863],[-129.47000122070312,54.23721504211426],[-130.48110961914062,54.36471748352051],[-130.416654586792,54.63027381896973],[-129.95916557312012,54.31610298156738],[-130.3741455078125,54.65499305725098],[-129.9102783203125,54.60555458068848],[-130.17388916015625,54.84665870666504],[-129.62249755859375,54.99777412414551],[-129.99636840820312,55.0241641998291],[-129.47164916992188,55.46721076965332],[-129.78695678710938,55.566667556762695],[-129.8175048828125,55.283334732055664],[-130.11361694335938,54.99638557434082],[-129.94387817382812,55.28221321105957],[-130.12887573242188,55.72221565246582],[-130.01507568359375,55.90918159484863],[-131.82415771484375,56.596940994262695],[-133.42999267578125,58.45916175842285],[-135.47360229492188,59.80193519592285],[-137.47805786132812,58.90721321105957],[-137.5908203125,59.238603591918945],[-139.18890380859375,60.088884353637695],[-139.06805419921875,60.35222053527832],[-140.99554443359375,60.30721473693848],[-141.00299072265625,69.64236640930176],[-139.14306640625,69.51082038879395],[-138.60498046875,69.24748420715332],[-135.40695190429688,68.67997932434082],[-135.14639282226562,68.66388130187988],[-135.50613403320312,68.83249092102051],[-135.33804321289062,68.83499336242676],[-135.62359619140625,68.88611030578613],[-135.24166870117188,68.92692756652832],[-135.18695068359375,68.90027046203613],[-134.97747802734375,68.8783130645752],[-134.84555053710938,68.92943000793457],[-134.49554443359375,68.7522144317627]],[[-89.00556945800781,65.38554573059082],[-89.03195190429688,65.40721321105957],[-89.09999084472656,65.40582466125488],[-89.00556945800781,65.38554573059082]],[[-93.51972961425781,63.839433670043945],[-92.50750732421875,63.81638526916504],[-93.77972412109375,64.18969917297363],[-93.51972961425781,63.839433670043945]],[[-70.78306579589844,48.38054847717285],[-69.82833862304688,48.16638374328613],[-71.04861450195312,48.445268630981445],[-70.78306579589844,48.38054847717285]],[[-71.11111450195312,46.85054969787598],[-70.9041748046875,46.91360664367676],[-70.80915832519531,47.015275955200195],[-71.11111450195312,46.85054969787598]],[[-77.67832946777344,58.235551834106445],[-77.8074951171875,58.30526924133301],[-77.95083618164062,58.324167251586914],[-77.67832946777344,58.235551834106445]],[[-91.32917785644531,63.55971717834473],[-91.54055786132812,63.60666084289551],[-91.43638610839844,63.55193519592285],[-91.32917785644531,63.55971717834473]],[[-84.80804443359375,68.76388740539551],[-84.8558349609375,68.8108081817627],[-84.93916320800781,68.7935962677002],[-84.80804443359375,68.76388740539551]]],[[[-108.13890075683594,71.98166084289551],[-108.19972229003906,72.05053901672363],[-108.06416320800781,72.03027534484863],[-108.13890075683594,71.98166084289551]]],[[[-85.84722900390625,72.29414558410645],[-85.88917541503906,72.21805000305176],[-86.11000061035156,72.28970527648926],[-85.84722900390625,72.29414558410645]]],[[[-78.73500061035156,72.36554145812988],[-78.95028686523438,72.33499336242676],[-79.07501220703125,72.40971565246582],[-78.73500061035156,72.36554145812988]]],[[[-79.508056640625,72.34860420227051],[-79.68331909179688,72.43054389953613],[-79.42971801757812,72.41165351867676],[-79.508056640625,72.34860420227051]]],[[[-79.99360656738281,72.41331672668457],[-80.13333129882812,72.51944160461426],[-79.91639709472656,72.45804023742676],[-79.99360656738281,72.41331672668457]]],[[[-110.46916198730469,72.56915473937988],[-110.54415893554688,72.56915473937988],[-110.59388732910156,72.59414863586426],[-110.46916198730469,72.56915473937988]]],[[[-110.35582733154297,72.60193061828613],[-110.49472045898438,72.61914253234863],[-110.34500122070312,72.61192512512207],[-110.35582733154297,72.60193061828613]]],[[[-108.51055908203125,72.60276985168457],[-108.61361694335938,72.63665962219238],[-108.49665832519531,72.6413745880127],[-108.51055908203125,72.60276985168457]]],[[[-110.30722045898438,72.63081550598145],[-110.41082763671875,72.63943672180176],[-110.28083801269531,72.64221382141113],[-110.30722045898438,72.63081550598145]]],[[[-95.73500061035156,72.79887580871582],[-95.85417175292969,72.85359382629395],[-95.7691650390625,72.87803840637207],[-95.73500061035156,72.79887580871582]]],[[[-96.75418090820312,72.72137641906738],[-97.01112365722656,72.77581977844238],[-96.71333312988281,72.8933277130127],[-96.75418090820312,72.72137641906738]]],[[[-95.7569580078125,72.89248847961426],[-95.78666687011719,73.01249885559082],[-95.70249938964844,72.93359565734863],[-95.7569580078125,72.89248847961426]]],[[[-96.80833435058594,72.92637825012207],[-97.14111328125,73.08554267883301],[-96.57501220703125,73.07499885559082],[-96.80833435058594,72.92637825012207]]],[[[-95.73388671875,73.12886238098145],[-95.74554443359375,73.04942512512207],[-95.89334106445312,73.09582710266113],[-95.73388671875,73.12886238098145]]],[[[-96.90583801269531,73.22082710266113],[-97.11776733398438,73.24914741516113],[-96.9677734375,73.27331733703613],[-96.90583801269531,73.22082710266113]]],[[[-113.99749755859375,72.79942512512207],[-114.60472106933594,72.60165596008301],[-113.65750122070312,72.61137580871582],[-113.02806091308594,73.00943183898926],[-111.22000122070312,72.71832466125488],[-111.90556335449219,72.34971809387207],[-111.66388702392578,72.2763843536377],[-110.70140075683594,72.57554817199707],[-109.78278350830078,72.42943000793457],[-110.29110717773438,72.67109870910645],[-109.77027893066406,72.72221565246582],[-110.75666809082031,72.97137641906738],[-109.65943908691406,72.92498970031738],[-109.75473022460938,72.87858772277832],[-109.227783203125,72.76165962219238],[-109.04332733154297,72.56749153137207],[-108.62138366699219,72.54998970031738],[-108.24276733398438,71.71859931945801],[-107.82888793945312,71.60443305969238],[-107.25250244140625,71.89554023742676],[-107.77887725830078,72.13665962219238],[-108.29194641113281,73.15359687805176],[-106.76139831542969,73.29304695129395],[-105.32611083984375,72.74637031555176],[-104.35527038574219,71.57443428039551],[-104.58583068847656,71.0666675567627],[-103.55638122558594,70.60081672668457],[-100.9997329711914,70.17276191711426],[-100.87000274658203,69.78831672668457],[-103.47693634033203,69.69359016418457],[-103.02333068847656,69.49386787414551],[-103.19499206542969,69.11442756652832],[-102.31304931640625,69.49832344055176],[-101.75473022460938,69.17581367492676],[-102.89472961425781,68.79998970031738],[-105.14472961425781,68.89915657043457],[-104.91500854492188,69.07054328918457],[-106.40611267089844,69.18054389953613],[-106.60221862792969,69.49887275695801],[-107.34221458435059,69.01887702941895],[-109.10472106933594,68.71054267883301],[-113.26944732666016,68.4538745880127],[-113.03388977050781,68.49498176574707],[-113.67694091796875,68.81109809875488],[-113.5211181640625,69.17859077453613],[-116.52583312988281,69.4074878692627],[-117.43611145019531,69.99304389953613],[-115.1675033569336,70.27777290344238],[-112.56471252441406,70.19832038879395],[-111.48721313476562,70.3369312286377],[-113.93831634521484,70.71527290344238],[-117.55943298339844,70.59721565246582],[-118.41944885253906,70.99193000793457],[-115.05750274658203,71.52304267883301],[-118.11221313476562,71.37359809875488],[-118.30943298339844,71.46582221984863],[-117.69638061523438,71.66609382629395],[-119.13445281982422,71.7652759552002],[-118.10804557800293,72.23776435852051],[-118.53694152832031,72.49386787414551],[-117.35360717773438,72.91638374328613],[-114.56166076660156,73.37553596496582],[-113.961669921875,73.15304756164551],[-113.99749755859375,72.79942512512207]]],[[[-107.89555358886719,73.54136848449707],[-108.08332824707031,73.59721565246582],[-107.5824966430664,73.59776496887207],[-107.89555358886719,73.54136848449707]]],[[[-95.66972351074219,73.60498237609863],[-95.711669921875,73.6121997833252],[-95.65556335449219,73.61665534973145],[-95.66972351074219,73.60498237609863]]],[[[-124.30750274658203,73.55636787414551],[-124.35861206054688,73.6302661895752],[-124.1138916015625,73.56414985656738],[-124.30750274658203,73.55636787414551]]],[[[-124.58473205566406,73.67915534973145],[-124.73361206054688,73.70054817199707],[-124.56443786621094,73.68719673156738],[-124.58473205566406,73.67915534973145]]],[[[-105.08944702148438,73.73526191711426],[-104.48306274414062,73.53442573547363],[-105.27555847167969,72.84553718566895],[-107.03555297851562,73.48082160949707],[-105.08944702148438,73.73526191711426]]],[[[-80.14222717285156,73.69664192199707],[-77.4244384765625,73.5547046661377],[-76.05943298339844,72.90081977844238],[-79.42916870117188,72.73581123352051],[-80.8760986328125,73.3277759552002],[-80.85777282714844,73.74193000793457],[-80.14222717285156,73.69664192199707]]],[[[-73.35467529296875,68.3292179107666],[-73.211669921875,68.37692451477051],[-73.31806945800781,68.39305305480957],[-73.35467529296875,68.3292179107666],[-73.85166931152344,68.34221076965332],[-73.76139831542969,68.68637275695801],[-74.09416198730469,68.7199878692627],[-73.99028015136719,68.49275398254395],[-74.91777038574219,68.80137825012207],[-74.82084655761719,69.08221626281738],[-76.66082763671875,68.69941902160645],[-76.62554931640625,69.0183277130127],[-75.5916748046875,69.22165107727051],[-76.64111328125,69.55415534973145],[-76.18777465820312,69.66526985168457],[-77.2005615234375,69.64610481262207],[-76.79388427734375,69.71859931945801],[-77.310546875,69.83581733703613],[-76.98056030273438,69.93803596496582],[-77.62638854980469,69.74498176574707],[-77.67832946777344,70.1877613067627],[-78.40167236328125,70.21249580383301],[-79.070556640625,70.46971321105957],[-78.71888732910156,70.54776191711426],[-79.00944519042969,70.6797046661377],[-79.58889770507812,70.3994312286377],[-78.92166137695312,70.30081367492676],[-78.79194641113281,69.89109992980957],[-81.76333618164062,70.12303352355957],[-80.95249938964844,69.7138843536377],[-82.10110473632812,70.10803413391113],[-83.0069580078125,70.3047046661377],[-81.71083068847656,69.93414497375488],[-82.14334106445312,69.78137397766113],[-83.06666564941406,70.01082038879395],[-85.66639709472656,70.10470771789551],[-85.8780517578125,70.07693672180176],[-85.23611450195312,69.9891529083252],[-85.82333374023438,70.00027656555176],[-86.55194091796875,70.23498725891113],[-86.37471008300781,70.52527046203613],[-87.92304992675781,70.24275398254395],[-89.54972839355469,71.08859443664551],[-87.00279235839844,70.99414253234863],[-89.83000183105469,71.3288745880127],[-90.04861450195312,71.9538745880127],[-89.57472229003906,72.16360664367676],[-89.9566650390625,72.32165718078613],[-89.22833251953125,73.12581062316895],[-88.40916442871094,73.52360725402832],[-85.0694580078125,73.80192756652832],[-84.83778381347656,73.74165534973145],[-86.73277282714844,72.71609687805176],[-86.24082946777344,72.42025947570801],[-86.42054557800293,72.01277351379395],[-84.83389282226562,71.27415657043457],[-86.82000732421875,70.98858833312988],[-84.961669921875,71.18858528137207],[-85.14695739746094,71.08276557922363],[-84.79888916015625,70.9216480255127],[-84.625,71.66581916809082],[-86.05082702636719,72.01111030578613],[-85.48721313476562,72.2602710723877],[-84.16471862792969,72.02110481262207],[-84.93527221679688,72.28943061828613],[-84.44221496582031,72.38304328918457],[-85.5352783203125,72.46971321105957],[-85.68804931640625,72.89360237121582],[-83.95306396484375,72.75248908996582],[-85.44776916503906,73.1202564239502],[-83.63444519042969,72.98248481750488],[-85.1885986328125,73.22886848449707],[-81.55387878417969,73.71721076965332],[-80.24749755859375,72.73054695129395],[-81.37944030761719,72.24165534973145],[-80.51640319824219,72.50387763977051],[-80.90556335449219,72.18054389953613],[-80.56723022460938,72.0727710723877],[-81.08029174804688,72.0516529083252],[-80.79277038574219,72.02777290344238],[-80.97166442871094,71.88165473937988],[-80.385009765625,72.04832649230957],[-80.48666381835938,72.18942451477051],[-80.26083374023438,72.29498481750488],[-79.6744384765625,72.12664985656738],[-80.16639709472656,72.32222175598145],[-79.79916381835938,72.50139045715332],[-79.75,72.21554756164551],[-79.01278686523438,72.27388191223145],[-79.20306396484375,71.9619312286377],[-78.50361633300781,71.86886787414551],[-78.85444641113281,72.17303657531738],[-77.78555297851562,71.7874927520752],[-78.87083435058594,72.22665596008301],[-76.99583435058594,72.12886238098145],[-78.55915832519531,72.43803596496582],[-77.6138916015625,72.75166511535645],[-75.19248962402344,72.49193000793457],[-74.94749450683594,72.24971199035645],[-76.34805297851562,71.89166450500488],[-75.21945190429688,72.07443428039551],[-76.08528137207031,71.69192695617676],[-75.03582763671875,72.12581062316895],[-74.12222290039062,71.98359870910645],[-75.38999938964844,71.68109321594238],[-74.63194274902344,71.6624927520752],[-75.15194702148438,71.47165107727051],[-74.69943237304688,71.39082527160645],[-75.08139038085938,71.17943000793457],[-73.748046875,71.77693367004395],[-74.24082946777344,71.2008228302002],[-73.62193298339844,71.58333015441895],[-73.38027954101562,71.3852710723877],[-73.89834594726562,71.05748176574707],[-73.0494384765625,71.2683277130127],[-73.37748718261719,70.98054695129395],[-72.53805541992188,71.66081428527832],[-71.11972045898438,71.26416206359863],[-72.65361022949219,70.8277759552002],[-72.16361999511719,70.83638191223145],[-72.5694580078125,70.60998725891113],[-70.60166931152344,71.05386543273926],[-70.7469482421875,70.74553108215332],[-71.80305480957031,70.42831611633301],[-71.16250610351562,70.52527046203613],[-71.53582763671875,70.01971626281738],[-70.99722290039062,70.62581062316895],[-69.90472412109375,70.8813648223877],[-70.49610900878906,70.47943305969238],[-69.45140075683594,70.79193305969238],[-68.31388854980469,70.56303596496582],[-70.46861267089844,69.84276008605957],[-68.64250183105469,70.1494312286377],[-69.99055480957031,69.61499214172363],[-67.79472351074219,70.25888252258301],[-67.12777709960938,69.72693061828613],[-67.99610900878906,69.7744312286377],[-68.32945251464844,69.62776374816895],[-70.03083801269531,69.53610420227051],[-66.79554557800293,69.34109687805176],[-66.75862121582031,69.12803840637207],[-69.0150146484375,69.35498237609863],[-69.25778198242188,69.27026557922363],[-68.07749938964844,69.21748542785645],[-68.9677734375,69.22110176086426],[-68.50250244140625,69.19859504699707],[-69.02583312988281,68.96859931945801],[-68.17832946777344,69.14665412902832],[-67.70584106445312,69.01638984680176],[-68.55610656738281,68.96415901184082],[-67.77139282226562,68.78137397766113],[-69.39805603027344,68.8621997833252],[-67.61250305175781,68.37942695617676],[-66.70695495605469,68.44470405578613],[-67.87832641601562,68.2652759552002],[-67.23249816894531,68.35748481750488],[-67.01167297363281,68.31608772277832],[-67.59834289550781,68.16276741027832],[-67.01139831542969,68.29498481750488],[-66.76583862304688,68.23858833312988],[-66.9466552734375,68.01361274719238],[-66.69444274902344,68.14305305480957],[-66.69721984863281,67.98748970031738],[-66.54194641113281,68.1483325958252],[-66.18415832519531,68.01887702941895],[-66.73222351074219,67.8672046661377],[-66.35665893554688,67.82138252258301],[-65.91194152832031,68.15887641906738],[-66.00862121582031,67.62553596496582],[-65.80776977539062,67.97110176086426],[-65.443603515625,67.9922046661377],[-65.61582946777344,67.78610420227051],[-65.34638977050781,67.59332466125488],[-65.42361450195312,67.89804267883301],[-64.72361755371094,67.99054145812988],[-65.20417785644531,67.6483325958252],[-64.5069580078125,67.80720710754395],[-64.03860473632812,67.52859687805176],[-64.4405517578125,67.4749927520752],[-63.90416717529297,67.30581855773926],[-64.79750061035156,67.35664558410645],[-63.96277618408203,67.27249336242676],[-64.69194030761719,67.00055122375488],[-63.45055389404297,67.22249031066895],[-63.772499084472656,66.9588794708252],[-63.11028289794922,67.32998847961426],[-63.24083709716797,66.96165657043457],[-63.771385192871094,66.81109809875488],[-62.846946716308594,66.9619312286377],[-62.89972686767578,66.63665962219238],[-62.10139465332031,67.0547046661377],[-61.26250457763672,66.62942695617676],[-62.12388610839844,66.62637519836426],[-61.462501525878906,66.36914253234863],[-61.87749481201172,66.28332710266113],[-62.89500427246094,66.32971382141113],[-61.954444885253906,66.01915168762207],[-62.970550537109375,66.14804267883301],[-62.317222595214844,65.80803108215332],[-63.723609924316406,65.68026924133301],[-63.31999969482422,65.59332466125488],[-63.655555725097656,65.47082710266113],[-63.33555603027344,65.30053901672363],[-63.54695129394531,64.88720893859863],[-64.38082885742188,65.18109321594238],[-64.23721313476562,65.42997932434082],[-64.55555725097656,65.09221076965332],[-64.91221618652344,65.33804512023926],[-64.4183349609375,65.48275947570801],[-65.14999389648438,65.43414497375488],[-64.71000671386719,65.65220832824707],[-65.33860778808594,65.57554817199707],[-64.79499816894531,65.7280445098877],[-65.50556945800781,65.74331855773926],[-64.35638427734375,66.34971809387207],[-65.91610717773438,65.95109748840332],[-65.47361755371094,66.38582038879395],[-66.07362365722656,66.12053108215332],[-67.04888916015625,66.64471626281738],[-67.74276733398438,66.56833076477051],[-67.14862060546875,66.4438648223877],[-67.2822265625,66.27527046203613],[-67.99276733398438,66.50694465637207],[-67.19444274902344,65.90971565246582],[-67.82417297363281,65.88081550598145],[-67.9385986328125,65.90803718566895],[-68.03056335449219,65.99803352355957],[-68.02583312988281,66.0658130645752],[-68.24472045898438,66.1827564239502],[-68.85139465332031,66.18997383117676],[-68.41471862792969,66.15942573547363],[-68.23777770996094,66.06999397277832],[-68.2469482421875,66.11276435852051],[-68.15750122070312,66.11747932434082],[-68.04722595214844,66.06498908996582],[-68.05360412597656,65.99109077453613],[-68.12388610839844,65.96304512023926],[-68.304443359375,66.02804756164551],[-68.3336181640625,65.93193244934082],[-67.82112121582031,65.76805305480957],[-68.02583312988281,65.4810962677002],[-67.28056335449219,65.64248847961426],[-67.45889282226562,65.49803352355957],[-67.05833435058594,65.4266529083252],[-67.41610717773438,65.33915901184082],[-66.92887878417969,65.22970771789551],[-67.09611511230469,65.05609321594238],[-66.72610473632812,65.18026924133301],[-66.69804382324219,64.76193428039551],[-66.68865966796875,65.03877449035645],[-66.21221923828125,64.68553352355957],[-65.7177734375,64.84027290344238],[-65.72166442871094,64.49414253234863],[-65.07167053222656,64.4408130645752],[-65.65834045410156,64.30276679992676],[-65.0494384765625,64.07222175598145],[-65.21417236328125,64.02554512023926],[-64.66111755371094,64.02859687805176],[-64.98750305175781,63.82305335998535],[-64.52250671386719,63.67276954650879],[-64.53111267089844,63.24971961975098],[-65.30387878417969,63.80694007873535],[-64.62721252441406,62.90416145324707],[-65.25473022460938,62.98526954650879],[-64.94888305664062,62.64860725402832],[-65.1875,62.562211990356445],[-65.83833312988281,63.033334732055664],[-66.44444274902344,63.02054786682129],[-66.64277458190918,63.37249183654785],[-66.54666137695312,62.99138069152832],[-67.91471862792969,63.75943946838379],[-67.68527221679688,63.36888313293457],[-68.54277038574219,63.732492446899414],[-68.9969482421875,63.753610610961914],[-68.1461181640625,63.15027046203613],[-67.59999084472656,63.08443641662598],[-67.76972961425781,62.958330154418945],[-67.55305480957031,63.04860877990723],[-67.67277526855469,62.92332649230957],[-67.39805603027344,62.96721076965332],[-66.35166931152344,62.44499397277832],[-66.47000122070312,62.33221626281738],[-65.99305725097656,62.244157791137695],[-66.13249206542969,62.089433670043945],[-65.9466552734375,61.8991641998291],[-66.06610107421875,61.868600845336914],[-71.15666198730469,62.98916053771973],[-70.90888977050781,63.17083168029785],[-71.40055847167969,63.05166053771973],[-72.14555358886719,63.44610023498535],[-71.22972106933594,63.60471534729004],[-71.57695007324219,63.58166694641113],[-71.58111572265625,63.71499824523926],[-71.90444946289062,63.80999183654785],[-71.93388366699219,63.64943885803223],[-72.32417297363281,63.67666053771973],[-72.2388916015625,63.95249366760254],[-72.52639770507812,63.78777503967285],[-72.66471862792969,64.08055305480957],[-72.72000122070312,63.96110725402832],[-72.91166687011719,64.16887092590332],[-73.38055419921875,64.26860237121582],[-73.30278015136719,64.65887641906738],[-73.46333312988281,64.50248908996582],[-73.46722412109375,64.61276435852051],[-73.929443359375,64.60220527648926],[-73.8447265625,64.50193977355957],[-74.06277465820312,64.33442878723145],[-74.05387878417969,64.72859382629395],[-74.39028930664062,64.5697193145752],[-74.63999938964844,64.90359687805176],[-74.98527526855469,64.79582405090332],[-74.47000122070312,64.55748176574707],[-74.68582153320312,64.37109565734863],[-75.82417297363281,64.61165046691895],[-75.72694396972656,64.3672046661377],[-76.67054557800293,64.18414497375488],[-78.18331909179688,64.57249641418457],[-78.14527893066406,64.95749092102051],[-77.31582641601562,65.19053840637207],[-77.42166137695312,65.46138191223145],[-75.7691650390625,65.21887397766113],[-75.4244384765625,65.04387092590332],[-75.66749572753906,64.9408130645752],[-75.373046875,64.71499824523926],[-75.5675048828125,64.88360786437988],[-75.18693542480469,65.10165596008301],[-75.95028686523438,65.31833076477051],[-73.50056457519531,65.47442817687988],[-74.46611022949219,66.15193367004395],[-72.25834655761719,67.24803352355957],[-73.35467529296875,68.3292179107666]]],[[[-99.80455780029297,73.88910102844238],[-99.23500061035156,73.73776435852051],[-97.76194763183594,73.91192817687988],[-96.96221923828125,73.73858833312988],[-97.6683349609375,73.48332405090332],[-97.17193603515625,73.35276985168457],[-98.4505615234375,72.87498664855957],[-97.84695434570312,73.0486011505127],[-97.22500610351562,72.93997383117676],[-97.1966552734375,72.60443305969238],[-96.51750183105469,72.71470832824707],[-96.29833984375,72.41581916809082],[-96.87193298339844,72.32110786437988],[-96.48306274414062,72.11303901672363],[-96.866943359375,72.04109382629395],[-96.49305725097656,71.91415596008301],[-97.5050048828125,71.61165046691895],[-98.21806335449219,71.64972114562988],[-98.26722717285156,71.90416145324707],[-98.49388122558594,71.7138843536377],[-98.03750610351562,71.52665901184082],[-98.72972106933594,71.27054023742676],[-100.63445281982422,72.18553352355957],[-102.74166870117188,72.72415351867676],[-102.13722229003906,73.0869312286377],[-101.29750061035156,72.70999336242676],[-100.41221618652344,72.74193000793457],[-100.45195007324219,73.02054023742676],[-100.03138732910156,72.93498420715332],[-100.58000183105469,73.17303657531738],[-99.77166557312012,73.20804023742676],[-101.62138366699219,73.49026679992676],[-100.43055725097656,73.40693855285645],[-101.12000274658203,73.72720527648926],[-99.80455780029297,73.88910102844238]]],[[[-124.43055725097656,73.87858772277832],[-124.55278015136719,73.91693305969238],[-124.42027282714844,73.90915107727051],[-124.43055725097656,73.87858772277832]]],[[[-89.9888916015625,73.98831367492676],[-90.28500366210938,74.02971076965332],[-89.90194702148438,74.03776741027832],[-89.9888916015625,73.98831367492676]]],[[[-98.91860961914062,73.80609321594238],[-99.4375,73.89694404602051],[-97.63778686523438,74.07554817199707],[-98.91860961914062,73.80609321594238]]],[[[-92.6380615234375,74.1030445098877],[-90.19444274902344,73.89972114562988],[-92.09584045410156,72.74304389953613],[-94.3155517578125,72.76304817199707],[-93.46333312988281,72.46220588684082],[-94.06304931640625,71.97831916809082],[-95.21333312988281,71.99443244934082],[-94.75222778320312,72.15332221984863],[-95.17111206054688,72.13916206359863],[-95.13333129882812,72.46026802062988],[-95.67361450195312,72.81387519836426],[-95.68331909179688,73.0758228302002],[-95.57501220703125,73.16499519348145],[-95.68388366699219,73.45027351379395],[-95.70028686523438,73.55386543273926],[-95.61256408691406,73.6109790802002],[-95.67304992675781,73.72331428527832],[-94.61805725097656,73.6513843536377],[-95.32778930664062,73.90915107727051],[-94.73222351074219,74.09526252746582],[-92.6380615234375,74.1030445098877]]],[[[-98.6572265625,74.29942512512207],[-98.86471557617188,74.3047046661377],[-98.51112365722656,74.31833076477051],[-98.6572265625,74.29942512512207]]],[[[-120.14998626708984,74.27249336242676],[-119.60916137695312,74.23332405090332],[-119.74481201171875,74.02551460266113],[-119.14862060546875,74.21220588684082],[-119.1675033569336,73.9871997833252],[-117.42223358154297,74.22693061828613],[-115.31500244140625,73.47970771789551],[-119.13751220703125,72.63247871398926],[-119.31111145019531,72.35220527648926],[-120.25110626220703,72.25860786437988],[-120.54332733154297,71.51666450500488],[-122.78111267089844,71.08610725402832],[-125.25361633300781,71.95025825500488],[-124.94833374023438,71.96110725402832],[-125.99777221679688,71.97360420227051],[-125.02610778808594,72.82109260559082],[-124.475830078125,72.92720222473145],[-124.86888122558594,73.08055305480957],[-123.77471923828125,73.76443672180176],[-124.77084350585938,74.34027290344238],[-121.56416320800781,74.55108833312988],[-120.14998626708984,74.27249336242676]]],[[[-97.65278625488281,74.4558277130127],[-97.79249572753906,74.48581123352051],[-97.2569580078125,74.59054756164551],[-97.65278625488281,74.4558277130127]]],[[[-95.31111145019531,74.49775886535645],[-95.86639404296875,74.57415962219238],[-95.51750183105469,74.6302661895752],[-95.31111145019531,74.49775886535645]]],[[[-97.17582702636719,75.24414253234863],[-97.27528381347656,75.34749031066895],[-97.15306091308594,75.31526374816895],[-97.17582702636719,75.24414253234863]]],[[[-103.9175033569336,75.05497932434082],[-104.85722351074219,75.16470527648926],[-104.18222045898438,75.43553352355957],[-103.58306884765625,75.16470527648926],[-103.9175033569336,75.05497932434082]]],[[[-95.91000366210938,75.56025886535645],[-96.85110473632812,75.35026741027832],[-97.05305480957031,75.4922046661377],[-95.91000366210938,75.56025886535645]]],[[[-94.3638916015625,75.59082221984863],[-93.48750305175781,75.25665473937988],[-93.4677734375,74.70305061340332],[-96.616943359375,74.99109077453613],[-95.74972534179688,75.5133228302002],[-94.3638916015625,75.59082221984863]]],[[[-100.17223358154297,75.60138130187988],[-100.45417785644531,75.54637336730957],[-101.03943634033203,75.56721687316895],[-100.17223358154297,75.60138130187988]]],[[[-96.95445251464844,75.59553718566895],[-97.0050048828125,75.60443305969238],[-96.71583557128906,75.65999031066895],[-96.95445251464844,75.59553718566895]]],[[[-96.57917785644531,75.73692512512207],[-96.71722412109375,75.73970222473145],[-96.45584106445312,75.8177661895752],[-96.57917785644531,75.73692512512207]]],[[[-111.79998779296875,75.83915901184082],[-111.92250061035156,75.85276985168457],[-111.57861328125,75.87997627258301],[-111.79998779296875,75.83915901184082]]],[[[-122.3408432006836,75.86276435852051],[-122.69554138183594,75.90803718566895],[-122.35305786132812,75.91443061828613],[-122.3408432006836,75.86276435852051]]],[[[-121.09306335449219,75.7260913848877],[-121.288330078125,75.75277900695801],[-120.87777709960938,75.93609809875488],[-121.09306335449219,75.7260913848877]]],[[[-103.13778686523438,75.74275398254395],[-103.38276672363281,75.76555061340332],[-101.98332214355469,75.9458179473877],[-103.13778686523438,75.74275398254395]]],[[[-95.79277038574219,75.89972114562988],[-95.89999389648438,75.9538745880127],[-95.73582458496094,75.96832466125488],[-95.79277038574219,75.89972114562988]]],[[[-94.40556335449219,75.75082588195801],[-94.90444946289062,75.93692207336426],[-94.48194885253906,75.97442817687988],[-94.40556335449219,75.75082588195801]]],[[[-122.81916809082031,76.06053352355957],[-122.63082885742188,76.0466480255127],[-122.89250183105469,76.01361274719238],[-122.81916809082031,76.06053352355957]]],[[[-118.31639099121094,75.57249641418457],[-119.40805053710938,75.60582160949707],[-117.46389770507812,76.08305549621582],[-118.31639099121094,75.57249641418457]]],[[[-102.38999938964844,76.08360481262207],[-102.3194580078125,76.02470588684082],[-103.9716567993164,75.93831062316895],[-102.38999938964844,76.08360481262207]]],[[[-78.9263916015625,75.87581062316895],[-79.75222778320312,75.87858772277832],[-78.80583190917969,76.09305000305176],[-79.1763916015625,75.9527759552002],[-78.9263916015625,75.87581062316895]]],[[[-94.84361267089844,76.1222095489502],[-95.00666809082031,76.04748725891113],[-95.14723205566406,76.11693000793457],[-94.84361267089844,76.1222095489502]]],[[[-81.32778930664062,76.14721870422363],[-81.46250915527344,76.15887641906738],[-81.20140075683594,76.17776679992676],[-81.32778930664062,76.14721870422363]]],[[[-102.53083801269531,76.22331428527832],[-103.34221458435059,76.03665351867676],[-104.48277282714844,76.14221382141113],[-102.53083801269531,76.22331428527832]]],[[[-89.39889526367188,76.43553352355957],[-89.62554931640625,76.44497871398926],[-89.53306579589844,76.47665596008301],[-89.39889526367188,76.43553352355957]]],[[[-83.96278381347656,76.42637825012207],[-84.13945007324219,76.5072193145752],[-83.90805053710938,76.46499824523926],[-83.96278381347656,76.42637825012207]]],[[[-104.05387878417969,76.56303596496582],[-103.00446319580078,76.42997932434082],[-104.33500671386719,76.31860542297363],[-104.66583251953125,76.5516529083252],[-104.05387878417969,76.56303596496582]]],[[[-98.41806030273438,76.66832160949707],[-97.50917053222656,76.18887519836426],[-97.9385986328125,75.74136543273926],[-97.38667297363281,75.6827564239502],[-97.28083801269531,75.39694404602051],[-97.74415588378906,75.57110786437988],[-98.165283203125,75.33415412902832],[-97.58250427246094,75.13749885559082],[-100.14584350585938,74.99109077453613],[-100.54695129394531,75.19941902160645],[-99.98777770996094,75.2361011505127],[-100.77887725830078,75.35054206848145],[-98.95028686523438,75.70999336242676],[-102.88390350341797,75.61914253234863],[-101.18222045898438,75.77971076965332],[-101.9072265625,76.07859992980957],[-101.38778686523438,76.25193977355957],[-102.16583251953125,76.23831367492676],[-101.88583374023438,76.44497871398926],[-99.88833618164062,75.88638496398926],[-99.43943786621094,75.97053718566895],[-100.15278625488281,76.13247871398926],[-99.41444396972656,76.15832710266113],[-100.98249816894531,76.50499153137207],[-99.68443298339844,76.63333320617676],[-99.07972717285156,76.39721870422363],[-98.41806030273438,76.66832160949707]]],[[[-99.9969482421875,76.73442268371582],[-99.43055725097656,76.69941902160645],[-100.12860107421875,76.72192573547363],[-99.9969482421875,76.73442268371582]]],[[[-101.38054656982422,76.55359077453613],[-101.68831634521484,76.58638191223145],[-100.24889373779297,76.73471260070801],[-101.38054656982422,76.55359077453613]]],[[[-120.88362121582031,76.73970222473145],[-120.97000122070312,76.71666145324707],[-121.18472290039062,76.7310962677002],[-120.88362121582031,76.73970222473145]]],[[[-89.93443298339844,76.47665596008301],[-90.59999084472656,76.74664497375488],[-89.67388916015625,76.73748970031738],[-89.93443298339844,76.47665596008301]]],[[[-108.65110778808594,76.81360054016113],[-108.55803680419922,76.40860176086426],[-108.07749938964844,76.28055000305176],[-108.3961181640625,76.04609870910645],[-107.63249206542969,75.99109077453613],[-108.02027893066406,75.78082466125488],[-106.89666557312012,75.72026252746582],[-106.336669921875,76.0547046661377],[-105.39195251464844,75.63888740539551],[-106.01112365722656,75.05081367492676],[-108.8324966430664,75.06999397277832],[-112.75306701660156,74.4013843536377],[-114.44776916503906,74.6746997833252],[-110.91278076171875,75.23387336730957],[-113.9175033569336,75.05359077453613],[-113.34056091308594,75.41331672668457],[-114.06500244140625,75.46609687805176],[-115.05082702636719,74.96110725402832],[-117.68388366699219,75.25305366516113],[-114.9997329711914,75.6908130645752],[-117.25110626220703,75.59749031066895],[-114.81749725341797,75.88081550598145],[-116.73416137695312,75.92248725891113],[-116.29611206054688,76.18858528137207],[-114.66251373291016,76.1605396270752],[-115.92500305175781,76.28665351867676],[-114.89972686767578,76.51693916320801],[-112.45388793945312,76.17637825012207],[-111.727783203125,75.9216480255127],[-112.2255630493164,75.81109809875488],[-111.45195007324219,75.83665657043457],[-111.24722290039062,75.51805305480957],[-108.8994369506836,75.47638130187988],[-108.82695007324219,75.68664741516113],[-110.05555725097656,75.89055061340332],[-109.31360626220703,76.1091480255127],[-110.39306640625,76.39193916320801],[-108.65110778808594,76.81360054016113]]],[[[-97.04527282714844,76.79776191711426],[-97.20083618164062,76.85748481750488],[-96.99722290039062,76.81331062316895],[-97.04527282714844,76.79776191711426]]],[[[-113.46611022949219,76.76638984680176],[-114.87581634521484,76.77083015441895],[-113.88555908203125,76.89166450500488],[-113.46611022949219,76.76638984680176]]],[[[-109.06610107421875,76.90054512023926],[-109.30776977539062,76.92804145812988],[-109.179443359375,76.93248176574707],[-109.06610107421875,76.90054512023926]]],[[[-97.25639343261719,76.96748542785645],[-97.47305297851562,76.98054695129395],[-97.09222412109375,77.01082038879395],[-97.25639343261719,76.96748542785645]]],[[[-95.65972900390625,77.05887031555176],[-93.17971801757812,76.74109077453613],[-93.54833984375,76.38611030578613],[-91.41055297851562,76.68914985656738],[-90.46806335449219,76.4730396270752],[-91.56666564941406,76.49887275695801],[-89.29249572753906,76.29609870910645],[-91.61361694335938,76.26220893859863],[-90.1905517578125,76.06109809875488],[-91.12998962402344,75.83915901184082],[-90.0150146484375,76.0102710723877],[-89.17277526855469,75.78055000305176],[-89.76528930664062,75.57554817199707],[-88.9505615234375,75.4297046661377],[-88.7388916015625,75.67943000793457],[-86.54472351074219,75.3591480255127],[-83.8781509399414,75.8189640045166],[-81.53694152832031,75.80941963195801],[-79.57472229003906,75.44999885559082],[-79.57112121582031,75.19914436340332],[-80.4405517578125,75.03804206848145],[-79.3336181640625,74.89444160461426],[-80.32167053222656,74.9377613067627],[-80.23167419433594,74.57805061340332],[-81.81082153320312,74.45694160461426],[-83.51139831542969,74.90165901184082],[-83.47444152832031,74.57971382141113],[-84.28555297851562,74.50360298156738],[-88.4969482421875,74.49775886535645],[-88.54777526855469,74.90776252746582],[-89.48971557617188,74.54553413391113],[-91.02471923828125,74.7027759552002],[-90.77223205566406,74.88499641418457],[-91.53999328613281,74.6463794708252],[-92.49082946777344,75.21360969543457],[-92.0050048828125,75.5949878692627],[-92.10861206054688,75.85887336730957],[-93.0836181640625,76.35803413391113],[-95.3760986328125,76.23442268371582],[-94.80082702636719,76.32165718078613],[-96.96444702148438,76.73332405090332],[-96.30555725097656,76.75387763977051],[-96.81027221679688,76.97915840148926],[-95.65972900390625,77.05887031555176]]],[[[-113.32888793945312,77.07998847961426],[-113.49749755859375,77.08831977844238],[-113.3447265625,77.12776374816895],[-113.32888793945312,77.07998847961426]]],[[[-113.77861022949219,77.10415840148926],[-113.93138122558594,77.12970161437988],[-113.65778350830078,77.12915229797363],[-113.77861022949219,77.10415840148926]]],[[[-104.25250244140625,77.0727710723877],[-104.43167114257812,77.09887886047363],[-104.00110626220703,77.13582038879395],[-104.25250244140625,77.0727710723877]]],[[[-95.22444152832031,77.16720771789551],[-95.63999938964844,77.23776435852051],[-95.35610961914062,77.23637580871582],[-95.22444152832031,77.16720771789551]]],[[[-90.93305969238281,77.25444221496582],[-90.713623046875,77.2008228302002],[-91.29916381835938,77.21776008605957],[-90.93305969238281,77.25444221496582]]],[[[-116.3510971069336,77.53915596008301],[-115.39028930664062,77.30636787414551],[-116.28056335449219,77.18359565734863],[-115.73137664794922,76.94970893859863],[-116.36528015136719,76.92637825012207],[-115.89666557312012,76.69165229797363],[-117.05387878417969,76.53305244445801],[-117.09555053710938,76.29525947570801],[-118.05999755859375,76.40915107727051],[-117.84221458435059,76.82388496398926],[-118.96806335449219,76.5052661895752],[-118.56749725341797,76.33665657043457],[-119.07584381103516,76.08333015441895],[-119.65499877929688,76.30304145812988],[-119.80499267578125,76.10887336730957],[-119.48110961914062,75.97082710266113],[-119.87000274658203,75.85748481750488],[-120.45445251464844,75.8158130645752],[-120.85722351074219,76.19664192199707],[-120.99944305419922,75.93969917297363],[-123.03778076171875,76.08471870422363],[-122.59889221191406,76.34832954406738],[-121.53307342529297,76.43719673156738],[-121.21250915527344,76.64972114562988],[-120.40167236328125,76.79721260070801],[-119.1533432006836,77.3258228302002],[-116.3510971069336,77.53915596008301]]],[[[-85.2852783203125,77.58749580383301],[-84.81388854980469,77.4972095489502],[-85.538330078125,77.53997993469238],[-85.2852783203125,77.58749580383301]]],[[[-90.60305786132812,77.6283130645752],[-89.63612365722656,77.33915901184082],[-91.20889282226562,77.41499519348145],[-90.60305786132812,77.6283130645752]]],[[[-105.0102767944336,77.40803718566895],[-104.36554718017578,77.23027229309082],[-105.2469482421875,77.1938648223877],[-106.0947265625,77.72415351867676],[-105.0102767944336,77.40803718566895]]],[[[-95.40583801269531,77.76388740539551],[-93.10194396972656,77.6624927520752],[-93.570556640625,77.4377613067627],[-96.32888793945312,77.60498237609863],[-95.40583801269531,77.76388740539551]]],[[[-77.85194396972656,77.7744312286377],[-77.95500183105469,77.83027839660645],[-77.56861877441406,77.84971809387207],[-77.85194396972656,77.7744312286377]]],[[[-101.7114028930664,77.90165901184082],[-100.92555236816406,77.7371997833252],[-102.52971458435059,77.83415412902832],[-101.7114028930664,77.90165901184082]]],[[[-114.07305908203125,77.98166084289551],[-113.57611083984375,77.81414985656738],[-115.1160945892334,77.95833015441895],[-114.07305908203125,77.98166084289551]]],[[[-109.58805847167969,78.06469917297363],[-110.90471458435059,77.84387397766113],[-110.09028625488281,77.76915168762207],[-110.20333862304688,77.51138496398926],[-112.03111267089844,77.32470893859863],[-113.19803619384766,77.52388191223145],[-113.31973266601562,77.79553413391113],[-109.58805847167969,78.06469917297363]]],[[[-103.05695343017578,78.11970710754395],[-103.2822265625,78.15776252746582],[-102.7822265625,78.23858833312988],[-103.05695343017578,78.11970710754395]]],[[[-94.36665344238281,78.15915107727051],[-94.69415283203125,78.25860786437988],[-94.48194885253906,78.2683277130127],[-94.36665344238281,78.15915107727051]]],[[[-88.28721618652344,78.24331855773926],[-88.40972900390625,78.29220771789551],[-88.0433349609375,78.43664741516113],[-88.28721618652344,78.24331855773926]]],[[[-74.30694580078125,78.6766529083252],[-74.71028137207031,78.7310962677002],[-74.16361999511719,78.71609687805176],[-74.30694580078125,78.6766529083252]]],[[[-109.64806365966797,78.58804512023926],[-109.26055908203125,78.4558277130127],[-113.33416557312012,78.33276557922363],[-110.63751220703125,78.74859809875488],[-109.64806365966797,78.58804512023926]]],[[[-96.76806640625,78.68414497375488],[-94.87777709960938,78.3913745880127],[-95.399169921875,78.2310962677002],[-94.88694763183594,78.10276985168457],[-97.09695434570312,77.80331611633301],[-97.77555847167969,78.03499031066895],[-96.87054443359375,78.13333320617676],[-98.41139221191406,78.4952564239502],[-98.02223205566406,78.53637886047363],[-98.37165832519531,78.7199878692627],[-98.14445495605469,78.8166675567627],[-96.76806640625,78.68414497375488]]],[[[-86.3194580078125,78.88360786437988],[-86.48443603515625,78.89276313781738],[-85.16722106933594,79.02083015441895],[-86.3194580078125,78.88360786437988]]],[[[-103.59388732910156,79.3258228302002],[-102.56082153320312,78.86970710754395],[-101.6489028930664,79.0758228302002],[-99.95249938964844,78.72554206848145],[-99.52972412109375,78.57805061340332],[-99.79388427734375,78.29721260070801],[-98.94583129882812,78.05581855773926],[-99.90695190429688,77.77859687805176],[-101.03555297851562,78.19609260559082],[-102.61860656738281,78.24136543273926],[-102.80610656738281,78.37776374816895],[-104.46749877929688,78.2652759552002],[-105.0513916015625,78.49443244934082],[-103.52362060546875,78.49609565734863],[-104.04222106933594,78.62997627258301],[-103.31639099121094,78.73442268371582],[-104.19888305664062,78.77026557922363],[-103.82167053222656,78.8983325958252],[-104.20361328125,78.99165534973145],[-104.98832702636719,78.79832649230957],[-104.68110656738281,79.01666450500488],[-105.62860107421875,79.16137886047363],[-103.59388732910156,79.3258228302002]]],[[[-99.47166442871094,80.10971260070801],[-98.6441650390625,79.79414558410645],[-100.177490234375,79.90999031066895],[-99.47166442871094,80.10971260070801]]],[[[-99.15556335449219,80.1746997833252],[-99.1138916015625,80.16388130187988],[-99.41806030273438,80.15721321105957],[-99.15556335449219,80.1746997833252]]],[[[-95.03083801269531,80.67025947570801],[-94.97055053710938,80.6352710723877],[-96.149169921875,80.66470527648926],[-95.03083801269531,80.67025947570801]]],[[[-92.727783203125,81.30554389953613],[-90.76640319824219,80.56553840637207],[-89.2449951171875,80.51721382141113],[-88.77667236328125,80.1313648223877],[-88.14555358886719,80.09387397766113],[-88.61528015136719,80.40387153625488],[-87.68388366699219,80.41026496887207],[-87.56277465820312,80.17915534973145],[-88.0655517578125,80.12082099914551],[-86.95777893066406,79.90359687805176],[-87.46250915527344,79.53471565246582],[-86.33416557312012,79.64554023742676],[-86.04611206054688,79.56888008117676],[-86.07084655761719,79.43414497375488],[-85.68194580078125,79.61331367492676],[-84.9041748046875,79.26776313781738],[-86.98332214355469,79.05664253234863],[-87.61582946777344,78.64526557922363],[-88.00334167480469,78.80720710754395],[-87.72471618652344,79.0758228302002],[-88.16250610351562,78.99054145812988],[-87.90834045410156,78.5486011505127],[-88.80416870117188,78.60971260070801],[-88.53555297851562,78.41304206848145],[-88.81777954101562,78.1544361114502],[-89.98056030273438,78.60971260070801],[-89.45249938964844,78.1624927520752],[-92.05833435058594,78.2088794708252],[-92.98750305175781,78.46554756164551],[-91.63528442382812,78.54609870910645],[-93.2711181640625,78.58415412902832],[-93.81361389160156,78.76582527160645],[-93.03778076171875,78.76582527160645],[-94.28860473632812,78.98637580871582],[-90.36326599121094,79.24681282043457],[-92.2388916015625,79.20555305480957],[-92.69471740722656,79.2572193145752],[-91.1199951171875,79.38638496398926],[-93.09056091308594,79.48221015930176],[-95.08755493164062,79.27075386047363],[-95.77944946289062,79.42581367492676],[-94.28277587890625,79.75749397277832],[-95.85333251953125,79.64610481262207],[-96.80278015136719,80.09082221984863],[-94.38362121582031,79.98248481750488],[-94.74888610839844,80.07998847961426],[-94.08389282226562,80.17553901672363],[-96.68167114257812,80.34221076965332],[-93.78639221191406,80.52554512023926],[-95.53416442871094,80.81888008117676],[-93.0916748046875,81.15999031066895],[-94.26861572265625,81.34610176086426],[-92.727783203125,81.30554389953613]]],[[[-91.71833801269531,81.54915046691895],[-91.96055603027344,81.5949878692627],[-91.58222961425781,81.57805061340332],[-91.71833801269531,81.54915046691895]]],[[[-78.36582946777344,82.88360786437988],[-78.41471862792969,82.94192695617676],[-78.116943359375,82.94220161437988],[-78.36582946777344,82.88360786437988]]],[[[-70.1119384765625,83.10942268371582],[-66.2994384765625,82.92943000793457],[-68.64250183105469,82.62858772277832],[-64.72972106933594,82.90416145324707],[-64.93693542480469,82.87137031555176],[-62.926109313964844,82.57609748840332],[-63.3699951171875,82.43887519836426],[-61.076393127441406,82.32083320617676],[-64.35527038574219,81.72638130187988],[-69.2913818359375,81.71887397766113],[-66.60861206054688,81.51277351379395],[-70.21000671386719,81.17387580871582],[-64.43638610839844,81.47943305969238],[-69.427490234375,80.38275337219238],[-70.82528686523438,80.55859565734863],[-70.14555358886719,80.19359016418457],[-72.42083740234375,80.21110725402832],[-70.49749755859375,80.08276557922363],[-71.46055603027344,79.9013843536377],[-70.9102783203125,79.88582038879395],[-71.18388366699219,79.7774829864502],[-74.2388916015625,79.88720893859863],[-74.84638977050781,79.84721565246582],[-73.12582397460938,79.55832099914551],[-78.0513916015625,79.35470771789551],[-74.43666076660156,79.0577564239502],[-78.89138793945312,79.06331062316895],[-77.70333862304688,79.00694465637207],[-78.248046875,78.77026557922363],[-76.71055603027344,79.02832221984863],[-74.7197265625,78.70749092102051],[-76.693603515625,78.50972175598145],[-75.0625,78.3097095489502],[-76.91221618652344,78.20109748840332],[-75.5755615234375,78.10775947570801],[-75.92277526855469,77.95665168762207],[-78.26083374023438,77.9952564239502],[-77.71861267089844,77.60582160949707],[-78.6905517578125,77.31553840637207],[-80.45611572265625,77.29609870910645],[-81.93028259277344,77.68498420715332],[-81.16583251953125,77.33720588684082],[-82.16610717773438,77.29248237609863],[-81.83416557312012,77.1624927520752],[-79.2550048828125,77.21859931945801],[-79.0050048828125,77.0969409942627],[-79.38694763183594,76.92747688293457],[-77.77944946289062,76.79136848449707],[-78.37748718261719,76.45804023742676],[-81.05332946777344,76.12803840637207],[-80.77166557312012,76.41914558410645],[-82.72500610351562,76.81915473937988],[-82.12721252441406,76.44165229797363],[-83.00361633300781,76.42915534973145],[-83.40083312988281,76.75999641418457],[-83.18832397460938,76.41943550109863],[-84.31082153320312,76.65832710266113],[-84.19554138183594,76.45637702941895],[-85.02833557128906,76.57499885559082],[-84.3760986328125,76.3177661895752],[-84.92832946777344,76.28637886047363],[-86.59416198730469,76.63499641418457],[-86.34222412109375,76.51220893859863],[-88.38999938964844,76.38971138000488],[-88.49472045898438,76.81721687316895],[-88.60804557800293,76.39999580383301],[-89.679443359375,76.57165718078613],[-88.54583740234375,77.10026741027832],[-86.739990234375,77.17415046691895],[-87.71194458007812,77.35998725891113],[-88.2147216796875,77.65054512023926],[-88.06806945800781,77.82026863098145],[-86.42222595214844,77.8308277130127],[-85.79444885253906,77.41971015930176],[-84.47944641113281,77.29443550109863],[-83.4647216796875,77.34832954406738],[-83.83555603027344,77.45526313781738],[-82.31861877441406,78.07083320617676],[-83.89834594726562,77.49054145812988],[-85.40249633789062,77.81999397277832],[-84.32501220703125,77.89610481262207],[-85.67887878417969,77.92943000793457],[-84.12777709960938,78.17109870910645],[-84.96861267089844,78.20248603820801],[-84.5755615234375,78.34637641906738],[-84.866943359375,78.36914253234863],[-84.63861083984375,78.59414863586426],[-85.48611450195312,78.10247993469238],[-86.288330078125,78.07638740539551],[-85.83306884765625,78.37997627258301],[-87.53860473632812,78.13804817199707],[-87.08944702148438,78.20193672180176],[-87.52471923828125,78.41638374328613],[-86.85694885253906,78.73498725891113],[-85.06416320800781,78.91914558410645],[-82.33778381347656,78.5666675567627],[-82.59445190429688,78.70305061340332],[-82.22055053710938,78.73221015930176],[-83.25473022460938,78.83499336242676],[-81.47721862792969,79.04721260070801],[-84.748046875,79.03193855285645],[-83.35861206054688,79.05081367492676],[-84.32695007324219,79.18858528137207],[-84.48472595214844,79.40637397766113],[-85.06889343261719,79.62608528137207],[-86.48638916015625,79.76361274719238],[-85.2550048828125,79.92082405090332],[-86.48277282714844,80.00860786437988],[-86.51472473144531,80.29915046691895],[-83.78195190429688,80.24582099914551],[-81.7066650390625,79.58665657043457],[-79.90472412109375,79.64694404602051],[-81.51972961425781,79.73082160949707],[-81.66305541992188,79.90304756164551],[-81.40028381347656,79.9377613067627],[-83.20388793945312,80.31805610656738],[-78.03805541992188,80.56721687316895],[-79.96055603027344,80.60803413391113],[-76.48472595214844,80.86554145812988],[-78.93499755859375,80.87553596496582],[-76.74526977539062,81.43914985656738],[-79.50167846679688,81.19359016418457],[-79.06361389160156,81.08554267883301],[-80.91944885253906,80.65555000305176],[-83.5694580078125,80.7391529083252],[-83.2569580078125,80.83859443664551],[-85.06695556640625,80.5052661895752],[-86.7449951171875,80.6030445098877],[-85.6058349609375,80.97581672668457],[-82.36444091796875,81.17943000793457],[-85.68167114257812,81.04942512512207],[-87.5947265625,80.62858772277832],[-89.46611022949219,80.91415596008301],[-84.73388671875,81.28109931945801],[-89.82084655761719,81.01082038879395],[-90.35194396972656,81.16748237609863],[-87.24472045898438,81.49026679992676],[-90.44305419921875,81.36665534973145],[-90.85665893554688,81.44413948059082],[-89.58500671386719,81.62581062316895],[-91.9566650390625,81.65860176086426],[-88.0755615234375,82.10498237609863],[-84.60499572753906,81.88998603820801],[-86.8760986328125,82.20221138000488],[-85.04695129394531,82.48193550109863],[-79.22917175292969,81.81608772277832],[-82.73222351074219,82.40165901184082],[-81.54167175292969,82.49609565734863],[-82.21528625488281,82.6685962677002],[-80.57806396484375,82.54609870910645],[-81.47305297851562,82.82499885559082],[-78.50279235839844,82.68109321594238],[-80.43028259277344,82.88749885559082],[-79.7933349609375,82.95749092102051],[-75.89222717285156,82.5919361114502],[-76.2308349609375,82.44470405578613],[-75.3961181640625,82.61470222473145],[-77.38137817382812,82.99443244934082],[-74.43582153320312,83.02720832824707],[-72.63389587402344,82.69442939758301],[-73.65055847167969,82.92581367492676],[-70.1119384765625,83.10942268371582]]],[[[-92.95417785644531,63.871103286743164],[-93.09445190429688,63.90499305725098],[-92.97833251953125,63.90832710266113],[-92.95417785644531,63.871103286743164]]]]}},{"type":"Feature","properties":{"name":"Cambodia","iso2":"KH","iso3":"KHM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[103.77525520324707,10.442499160766602],[103.74858283996582,10.476388931274414],[103.75581550598145,10.511667251586914],[103.79886054992676,10.500001907348633],[103.77525520324707,10.442499160766602]]],[[[103.31414985656738,10.723054885864258],[103.26970863342285,10.669721603393555],[103.19331550598145,10.756387710571289],[103.31414985656738,10.723054885864258]]],[[[107.4891529083252,14.448610305786133],[107.54749488830566,12.353609085083008],[106.42024421691895,11.973608016967773],[106.45821571350098,11.665864944458008],[105.8510684967041,11.659997940063477],[106.20331001281738,10.77055549621582],[105.10191535949707,10.95555305480957],[104.4453296661377,10.422739028930664],[104.24774360656738,10.567499160766602],[103.92691230773926,10.590276718139648],[103.6233081817627,10.495553970336914],[103.55523872375488,11.156942367553711],[103.12970161437988,10.883054733276367],[102.91609382629395,11.63585090637207],[102.37719917297363,13.573888778686523],[103.18054389953613,14.329721450805664],[105.21060371398926,14.349649429321289],[106.05664253234863,13.929998397827148],[106.00470924377441,14.373052597045898],[106.54074287414551,14.598726272583008],[106.85359382629395,14.30305290222168],[107.54660224914551,14.708620071411133],[107.4891529083252,14.448610305786133]],[[103.03275489807129,11.431943893432617],[103.04551887512207,11.469720840454102],[103.00940895080566,11.524999618530273],[103.03275489807129,11.431943893432617]],[[103.02803230285645,11.24638557434082],[103.04192543029785,11.375555038452148],[102.98636054992676,11.422220230102539],[103.02803230285645,11.24638557434082]]]]}},{"type":"Feature","properties":{"name":"Sri Lanka","iso2":"LK","iso3":"LKA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[81.71499600000018,7.681388],[81.708328,7.674166],[81.70166,7.68111],[81.71276900000012,7.704999],[81.71499600000018,7.681388]]],[[[81.80693100000022,7.477777],[81.7233120000001,7.738610000000122],[81.804153,7.600554],[81.80693100000022,7.477777]]],[[[79.91249100000013,9.018055],[79.85054000000017,9.00111000000011],[79.693039,9.092497],[79.91249100000013,9.018055]]],[[[79.716385,9.477221],[79.658035,9.499165],[79.657486,9.555832000000152],[79.716385,9.477221]]],[[[79.974426,9.615274],[79.871918,9.634443],[79.854706,9.750832],[79.974426,9.615274]]],[[[80.27470400000013,9.775],[80.824432,9.261944],[80.91470300000017,8.94305400000016],[81.231094,8.65111],[81.130539,8.5],[81.361374,8.487219],[81.391937,8.149443],[81.881653,7.288054000000102],[81.66110200000017,6.439999000000128],[80.587204,5.9177770000001],[80.04609700000012,6.239721],[79.702484,8.079443],[80.051926,9.594442000000157],[80.61219800000012,9.443054],[79.925812,9.74472],[80.44413800000015,9.57166500000011],[80.27470400000013,9.775]]]]}},{"type":"Feature","properties":{"name":"Congo","iso2":"CG","iso3":"COG"},"geometry":{"type":"MultiPolygon","coordinates":[[[[12.779047,-4.388991],[12.026131,-5.014997],[11.140661000000108,-3.925277],[11.496944,-3.506945],[11.925833,-3.636945],[11.574165,-2.333333],[12.478054000000128,-2.327222],[12.65,-1.8225],[13.001507,-2.367672],[13.482777000000112,-2.4375],[13.76222,-2.088889],[14.110832,-2.493056],[14.429722000000112,-1.891667],[14.51861,-0.609167],[13.848331000000144,-0.198611],[14.487221,0.913611000000117],[14.188889,1.391389],[13.186785,1.222476],[13.293888,2.163611],[14.564999,2.169444],[16.07222000000013,1.654166],[16.207222,2.220833],[16.659721,3.533333],[17.475277,3.713055],[18.624958,3.479444],[18.09194200000013,2.224166],[17.714996,-0.537222],[16.195831,-2.175834],[16.226944,-3.328333],[15.890505000000132,-3.943009],[14.661388,-4.909445],[14.418888000000152,-4.887222],[14.400833,-4.2775],[13.729443,-4.445834],[13.413887000000102,-4.882501],[13.091389,-4.633056],[12.779047,-4.388991]]]]}},{"type":"Feature","properties":{"name":"Democratic Republic of the Congo","iso2":"CD","iso3":"COD"},"geometry":{"type":"MultiPolygon","coordinates":[[[[25.89166831970215,5.192499160766602],[27.455278396606445,5.016389846801758],[28.363054275512695,4.290002822875977],[29.64333152770996,4.643613815307617],[30.85881996154785,3.49339485168457],[30.72972297668457,2.448057174682617],[31.302778244018555,2.121389389038086],[29.960554122924805,0.825555801391602],[29.59694480895996,-1.385833740234375],[28.86833381652832,-2.394443511962891],[29.024442672729492,-2.744722366333008],[29.22989845275879,-3.75096321105957],[29.423887252807617,-4.448055267333984],[29.55027961730957,-6.295278549194336],[30.771242141723633,-8.19224739074707],[28.90166664123535,-8.478612899780273],[28.372220993041992,-9.260833740234375],[28.69972038269043,-10.65333366394043],[28.363332748413086,-11.550834655761719],[29.031389236450195,-12.383056640625],[29.49361228942871,-12.458057403564453],[29.805051803588867,-12.15524673461914],[29.801389694213867,-13.454168319702148],[29.589445114135742,-13.221944808959961],[29.015832901000977,-13.39777946472168],[28.441946029663086,-12.519723892211914],[27.660001754760742,-12.296667098999023],[27.199251174926758,-11.56790542602539],[26.86861228942871,-11.973611831665039],[26.00472068786621,-11.90250015258789],[25.359724044799805,-11.641668319702148],[25.332223892211914,-11.193334579467773],[24.448331832885742,-11.463611602783203],[23.986207962036133,-10.870460510253906],[22.253889083862305,-11.209722518920898],[22.312223434448242,-10.364444732666016],[21.790555953979492,-9.405555725097656],[21.782960891723633,-7.280841827392578],[20.548715591430664,-7.283615112304688],[20.62974739074707,-6.913881301879883],[19.538949966430664,-6.996614456176758],[19.373056411743164,-7.996110916137695],[17.62416648864746,-8.09805679321289],[16.941667556762695,-7.198610305786133],[16.579721450805664,-5.900833129882813],[13.997499465942383,-5.848611831665039],[13.17888069152832,-5.856328964233398],[12.435834884643555,-6.016666412353516],[12.21455192565918,-5.7685546875],[12.526666641235352,-5.724166870117188],[12.565553665161133,-5.025554656982422],[13.088888168334961,-4.662500381469727],[13.091390609741211,-4.633054733276367],[13.413888931274414,-4.882499694824219],[13.72944450378418,-4.445833206176758],[14.400835037231445,-4.277500152587891],[14.418889999389648,-4.887222290039063],[14.66139030456543,-4.909444808959961],[15.890504837036133,-3.943008422851563],[16.226945877075195,-3.328332901000977],[16.195833206176758,-2.175832748413086],[17.714998245239258,-0.537221908569336],[18.091943740844727,2.22416877746582],[18.62495994567871,3.47944450378418],[18.54194450378418,4.335554122924805],[19.421388626098633,5.13416862487793],[20.585554122924805,4.410001754760742],[22.379167556762695,4.127500534057617],[22.89583396911621,4.821111679077148],[23.420278549194336,4.59111213684082],[24.394166946411133,5.115556716918945],[24.734445571899414,4.910833358764648],[25.54222297668457,5.381391525268555],[25.89166831970215,5.192499160766602]],[[12.953054428100586,-5.87611198425293],[12.844167709350586,-5.850555419921875],[12.737222671508789,-5.943611145019531],[12.953054428100586,-5.87611198425293]]]]}},{"type":"Feature","properties":{"name":"Burundi","iso2":"BI","iso3":"BDI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[29.229897,-3.750964],[29.024441,-2.744722],[29.85083,-2.759722],[29.952221,-2.309445],[30.57333,-2.399167],[30.4175,-2.861945],[30.843662,-2.978794],[30.83499900000018,-3.256945],[30.026108000000107,-4.269444],[29.423885,-4.448056],[29.229897,-3.750964]]]]}},{"type":"Feature","properties":{"name":"China","iso2":"CN","iso3":"CHN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[110.72054481506348,20.06333351135254],[111.03109931945801,19.639997482299805],[110.04776191711426,18.380552291870117],[109.56667518615723,18.168886184692383],[108.68553352355957,18.505277633666992],[108.6283130645752,19.2802791595459],[109.25943183898926,19.901662826538086],[110.72054481506348,20.06333351135254]],[[110.52414894104004,19.134443283081055],[110.5102710723877,19.1391658782959],[110.51500129699707,19.132776260375977],[110.52414894104004,19.134443283081055]]],[[[116.71887397766113,20.709440231323242],[116.70526313781738,20.71138572692871],[116.70192909240723,20.719995498657227],[116.71887397766113,20.709440231323242]]],[[[110.59721565246582,20.87944221496582],[110.54802894592285,20.91388511657715],[110.59665107727051,20.958330154418945],[110.59721565246582,20.87944221496582]]],[[[109.12191963195801,21.05527687072754],[109.0727710723877,21.010278701782227],[109.07193183898926,21.050275802612305],[109.12191963195801,21.05527687072754]]],[[[110.54886817932129,21.05916404724121],[110.49803352355957,20.95583152770996],[110.24887275695801,20.97722053527832],[110.54886817932129,21.05916404724121]]],[[[110.49942207336426,21.193330764770508],[110.6141529083252,21.193330764770508],[110.53665351867676,21.09694480895996],[110.49942207336426,21.193330764770508]]],[[[111.83611488342285,21.565275192260742],[111.84055519104004,21.64305305480957],[112.00248908996582,21.651941299438477],[111.83611488342285,21.565275192260742]]],[[[112.53386878967285,21.59083366394043],[112.64804267883301,21.702775955200195],[112.64694404602051,21.638608932495117],[112.53386878967285,21.59083366394043]]],[[[112.80581855773926,21.653329849243164],[112.70332527160645,21.687776565551758],[112.86887550354004,21.766389846801758],[112.80581855773926,21.653329849243164]]],[[[113.38333320617676,22.00889015197754],[113.30748176574707,22.01972007751465],[113.37803840637207,22.0847225189209],[113.38333320617676,22.00889015197754]]],[[[113.29665565490723,22.063886642456055],[113.26776313781738,22.113611221313477],[113.36026191711426,22.153608322143555],[113.29665565490723,22.063886642456055]]],[[[113.59499549865723,22.652219772338867],[113.4861011505127,22.720273971557617],[113.54358863830566,22.73638343811035],[113.59499549865723,22.652219772338867]]],[[[113.58804512023926,22.75055503845215],[113.38720893859863,22.897497177124023],[113.48387336730957,22.90083122253418],[113.58804512023926,22.75055503845215]]],[[[117.11804389953613,23.3991641998291],[116.94470405578613,23.438886642456055],[117.0980396270752,23.49055290222168],[117.11804389953613,23.3991641998291]]],[[[117.40471076965332,23.7711124420166],[117.50749397277832,23.72638511657715],[117.31165504455566,23.579721450805664],[117.40471076965332,23.7711124420166]]],[[[118.12692451477051,24.42582893371582],[118.06218910217285,24.45722007751465],[118.09108924865723,24.54972267150879],[118.18887519836426,24.493886947631836],[118.12692451477051,24.42582893371582]]],[[[119.3016529083252,25.419443130493164],[119.2774829864502,25.503053665161133],[119.3338794708252,25.570276260375977],[119.3016529083252,25.419443130493164]]],[[[119.82666206359863,25.58277702331543],[119.69637489318848,25.42805290222168],[119.7230396270752,25.638887405395508],[119.82666206359863,25.58277702331543]]],[[[119.27777290344238,26.035276412963867],[119.21132850646973,26.071931838989258],[119.40833473205566,25.983606338500977],[119.27777290344238,26.035276412963867]]],[[[121.17082405090332,28.046945571899414],[121.11914253234863,28.133886337280273],[121.24193000793457,28.200551986694336],[121.17082405090332,28.046945571899414]]],[[[121.94109535217285,29.052778244018555],[121.87359809875488,29.1491641998291],[121.94136238098145,29.16499900817871],[121.94109535217285,29.052778244018555]]],[[[122.11192512512207,29.787778854370117],[122.16609382629395,29.652498245239258],[122.03082466125488,29.716108322143555],[122.11192512512207,29.787778854370117]]],[[[122.41137886047363,29.933053970336914],[122.39082527160645,29.829442977905273],[122.31860542297363,29.94166374206543],[122.41137886047363,29.933053970336914]]],[[[121.86580848693848,29.969995498657227],[121.8611011505127,30.081666946411133],[121.90664863586426,30.0322208404541],[121.86580848693848,29.969995498657227]]],[[[122.32527351379395,30.01861000061035],[122.00804328918457,30.004446029663086],[121.96164894104004,30.1391658782959],[122.32527351379395,30.01861000061035]]],[[[122.21111488342285,30.241106033325195],[122.07470893859863,30.287221908569336],[122.21219825744629,30.33916664123535],[122.21111488342285,30.241106033325195]]],[[[122.42025947570801,30.413610458374023],[122.27554512023926,30.432218551635742],[122.27277565002441,30.47499656677246],[122.42025947570801,30.413610458374023]]],[[[121.84499549865723,31.288053512573242],[121.79193305969238,31.369997024536133],[121.87886238098145,31.356664657592773],[121.84499549865723,31.288053512573242]]],[[[121.48776435852051,31.717775344848633],[121.86831855773926,31.489164352416992],[121.20385932922363,31.800539016723633],[121.48776435852051,31.717775344848633]]],[[[119.8994312286377,32.07110786437988],[119.71608924865723,32.27193641662598],[119.82388496398926,32.26805305480957],[119.8994312286377,32.07110786437988]]],[[[121.43609809875488,39.39166450500488],[121.25583076477051,39.409433364868164],[121.39305305480957,39.47915840148926],[121.43609809875488,39.39166450500488]]],[[[123.38220405578613,53.52665901184082],[126.09554481506348,52.76444435119629],[127.58606910705566,50.208566665649414],[127.52942848205566,49.78916358947754],[130.67163276672363,48.864999771118164],[130.52163887023926,48.60777473449707],[130.98855781555176,47.68860054016113],[132.521089553833,47.710275650024414],[133.08856391906738,48.10166358947754],[134.74075508117676,48.26712989807129],[134.76721382141113,47.70749855041504],[134.182466506958,47.32332801818848],[133.90017890930176,46.250314712524414],[133.12219429016113,45.12860298156738],[131.86468696594238,45.34554481506348],[130.94998359680176,44.84110450744629],[131.311372756958,43.392221450805664],[131.12329292297363,42.91082191467285],[130.4052448272705,42.71805000305176],[130.60437202453613,42.42186164855957],[129.90753364562988,43.00582313537598],[129.71191596984863,42.44415473937988],[128.92581367492676,42.02443885803223],[128.05887031555176,42.00332832336426],[128.15582466125488,41.38249397277832],[126.91304206848145,41.79610633850098],[126.01693916320801,40.89999580383301],[124.37359809875488,40.0936222076416],[121.14694404602051,38.72276496887207],[121.75110054016113,39.35166358947754],[121.22886848449707,39.53833198547363],[122.29971504211426,40.511667251586914],[121.17746925354004,40.92193794250488],[120.45526313781738,40.20054817199707],[119.51970863342285,39.868051528930664],[118.92442512512207,39.1280460357666],[117.74387550354004,39.104997634887695],[117.67221260070801,38.38665962219238],[118.84192848205566,38.15054512023926],[118.95665168762207,37.300546646118164],[119.23275947570801,37.14361000061035],[119.76721382141113,37.151384353637695],[120.74054145812988,37.83526802062988],[121.57054328918457,37.42471504211426],[122.56218910217285,37.39638710021973],[122.50470924377441,36.89361000061035],[121.94914436340332,37.00000190734863],[120.78333473205566,36.62193489074707],[120.68081855773926,36.12748146057129],[120.08885383605957,36.19998359680176],[120.23776435852051,35.95943641662598],[119.17608833312988,34.88499641418457],[120.25388526916504,34.30999183654785],[120.83582496643066,32.64083290100098],[121.89554023742676,31.7469425201416],[120.60193061828613,32.09360694885254],[120.10608863830566,31.94388771057129],[119.82666206359863,32.30638313293457],[119.62970161437988,32.26082801818848],[120.12915229797363,31.905553817749023],[120.71443367004395,31.983606338500977],[121.88472175598145,30.97499656677246],[120.14610481262207,30.194719314575195],[121.2844181060791,30.304445266723633],[121.67775917053223,29.96305274963379],[122.12664985656738,29.888887405395508],[121.44832038879395,29.511667251586914],[121.97971534729004,29.585275650024414],[121.93359565734863,29.195276260375977],[121.41192817687988,29.163331985473633],[121.61026191711426,28.72499656677246],[121.13860511779785,28.84055519104004],[121.57859992980957,28.269166946411133],[120.59082221984863,28.079442977905273],[120.84305000305176,27.876943588256836],[120.47747993469238,27.1774959564209],[120.19359016418457,27.2902774810791],[120.42221260070801,27.14527702331543],[120.03386878967285,26.899721145629883],[120.12719917297363,26.641664505004883],[119.54915046691895,26.753610610961914],[119.65804481506348,26.33860969543457],[119.93942451477051,26.35416603088379],[119.42526435852051,25.9969425201416],[119.09276008605957,26.14249610900879],[119.34499549865723,25.938329696655273],[119.70555305480957,25.993608474731445],[119.45110511779785,25.68027687072754],[119.65220832824707,25.357221603393555],[119.30887031555176,25.606943130493164],[119.10220527648926,25.408052444458008],[119.3530445098877,25.250276565551758],[118.87191963195801,25.243886947631836],[119.01609992980957,24.954164505004883],[118.57388496398926,24.884164810180664],[118.62275886535645,24.54388999938965],[118.23970222473145,24.536386489868164],[118.1605396270752,24.688608169555664],[118.01805305480957,24.436384201049805],[117.79202461242676,24.461320877075195],[118.1233081817627,24.2561092376709],[116.5213794708252,23.42083168029785],[116.7874927520752,23.233884811401367],[116.48082160949707,22.938051223754883],[114.22259712219238,22.55055046081543],[114.0333309173584,22.509138107299805],[113.5244312286377,23.011110305786133],[113.82971382141113,23.117219924926758],[113.47747993469238,23.052778244018555],[113.35915565490723,22.883333206176758],[113.5658130645752,22.550275802612305],[113.55443000793457,22.212732315063477],[113.53166389465332,22.194738388061523],[113.16526985168457,22.571386337280273],[113.38804817199707,22.176664352416992],[113.29915046691895,22.175554275512695],[113.22415351867676,22.037500381469727],[113.08638191223145,22.206941604614258],[112.93914985656738,21.868608474731445],[111.89248847961426,21.92027473449707],[111.63720893859863,21.5211124420166],[110.39824867248535,21.38067054748535],[110.15804481506348,20.845552444458008],[110.52916145324707,20.473329544067383],[110.27887153625488,20.24610710144043],[109.92442512512207,20.233606338500977],[109.66192817687988,20.918886184692383],[109.94109535217285,21.446943283081055],[109.57332038879395,21.723329544067383],[109.14276313781738,21.396665573120117],[108.47580909729004,21.940275192260742],[108.51138496398926,21.58916664123535],[107.99002265930176,21.54241371154785],[106.69331550598145,22.030832290649414],[106.70720863342285,22.864999771118164],[105.57747840881348,23.05916404724121],[105.35386848449707,23.3347225189209],[103.96443367004395,22.499113082885742],[103.33638191223145,22.796388626098633],[103.03055000305176,22.4355525970459],[102.47971534729004,22.773889541625977],[102.14074897766113,22.39628791809082],[101.73803901672363,22.4969425201416],[101.57443428039551,22.20916175842285],[101.78720283508301,21.144163131713867],[101.28193855285645,21.18027687072754],[101.14824104309082,21.5726375579834],[101.10526466369629,21.771387100219727],[100.21275520324707,21.432554244995117],[99.96443367004395,22.048887252807617],[99.16276741027832,22.159162521362305],[99.56637763977051,22.938051223754883],[98.92747688293457,23.189165115356445],[98.67720222473145,23.968053817749023],[98.89073371887207,24.160070419311523],[97.5355396270752,23.93971824645996],[97.75999641418457,24.257497787475586],[97.55247688293457,24.743051528930664],[98.71081733703613,25.855554580688477],[98.77832221984863,26.636384963989258],[98.69970893859863,27.539167404174805],[98.31637763977051,27.54194450378418],[97.80664253234863,28.34416389465332],[97.55525398254395,28.54805564880371],[97.34887886047363,28.2227725982666],[96.40193367004395,28.351110458374023],[96.61581611633301,28.7902774810791],[96.47082710266113,29.056665420532227],[96.16914558410645,28.903608322143555],[96.39526557922363,29.255277633666992],[96.07748603820801,29.46860694885254],[95.38777351379395,29.035276412963867],[94.64750862121582,29.333459854125977],[92.54498481750488,27.861940383911133],[91.65776252746582,27.76472282409668],[91.30137825012207,28.08111000061035],[90.46638679504395,28.071664810180664],[90.01748847961426,28.32527732849121],[89.59027290344238,28.14333152770996],[88.91772651672363,27.32032585144043],[88.83166694641113,28.013334274291992],[88.14279365539551,27.866056442260742],[87.19275093078613,27.82305335998535],[86.68637275695801,28.112218856811523],[86.44497871398926,27.908052444458008],[86.18359565734863,28.16388511657715],[86.01443672180176,27.882776260375977],[85.72137641906738,28.279165267944336],[85.10664558410645,28.3094425201416],[85.18997383117676,28.603330612182617],[84.4810962677002,28.736661911010742],[84.11914253234863,29.260000228881836],[83.55276679992676,29.18583106994629],[82.10054206848145,30.342222213745117],[81.42109870910645,30.38527488708496],[81.22360420227051,30.010278701782227],[81.02536201477051,30.204355239868164],[79.09248542785645,31.437498092651367],[78.76721382141113,31.309999465942383],[78.39776802062988,32.54860877990723],[78.76054573059082,32.63555335998535],[78.97110176086426,32.35083198547363],[79.53027534484863,32.754167556762695],[78.81164741516113,33.525827407836914],[78.98535346984863,34.35001564025879],[78.30914497375488,34.64249610900879],[78.07554817199707,35.44582557678223],[77.82393074035645,35.50132942199707],[76.16638374328613,35.819719314575195],[75.86442756652832,36.659677505493164],[74.81749153137207,37.02176856994629],[74.56543159484863,37.02781867980957],[74.39221382141113,37.17507362365723],[74.91574287414551,37.23732948303223],[75.18748664855957,37.40658760070801],[74.90277290344238,37.64715766906738],[74.85664558410645,38.47048377990723],[73.8177661895752,38.60771369934082],[73.65568733215332,39.4548282623291],[73.99443244934082,40.04604530334473],[74.86026191711426,40.51938819885254],[75.57805061340332,40.64799690246582],[75.69720649719238,40.29911231994629],[76.34582710266113,40.35022163391113],[76.87387275695801,41.014108657836914],[78.0808277130127,41.040788650512695],[80.2340259552002,42.19622230529785],[80.17192268371582,42.66050910949707],[80.57859992980957,42.89107704162598],[80.37664985656738,43.02523994445801],[80.81721687316895,43.15606880187988],[80.36276435852051,44.12524604797363],[80.52083015441895,44.73247718811035],[79.87109565734863,44.904977798461914],[81.68831062316895,45.35081672668457],[82.56164741516113,45.12941932678223],[82.6494312286377,45.43026161193848],[82.3177661895752,45.57053565979004],[83.0405445098877,47.21221351623535],[84.75943183898926,46.82638740539551],[85.5293140411377,47.06016731262207],[85.75915718078613,48.387773513793945],[86.59610176086426,48.53611183166504],[86.87469673156738,49.11082649230957],[87.34820747375488,49.09262275695801],[87.84070014953613,49.17295265197754],[87.97331428527832,48.57694435119629],[88.65332221984863,48.18277168273926],[90.07443428039551,47.88638496398926],[91.02025032043457,46.60011100769043],[90.68193244934082,45.579721450805664],[90.89694404602051,45.25305366516113],[93.5547046661377,44.95721626281738],[95.41665840148926,44.29388618469238],[95.33610725402832,44.020830154418945],[96.38304328918457,42.73110389709473],[100.83554267883301,42.678049087524414],[105.01220893859863,41.58138465881348],[107.4719181060791,42.46610450744629],[109.31360054016113,42.42999458312988],[110.44053840637207,42.77777290344238],[111.95833015441895,43.692216873168945],[111.42137336730957,44.38249397277832],[111.98082160949707,45.09166145324707],[113.63804817199707,44.74527168273926],[114.54525947570801,45.38943672180176],[115.70192909240723,45.45860481262207],[116.58554267883301,46.29583168029785],[117.42109870910645,46.57833290100098],[119.89749336242676,46.675554275512695],[119.72998237609863,47.16415596008301],[118.53933906555176,47.99475288391113],[117.80108833312988,48.01055335998535],[117.37219429016113,47.65359687805176],[115.59219551086426,47.919443130493164],[116.71138191223145,49.83046913146973],[117.87471199035645,49.520578384399414],[119.21415901184082,50.015275955200195],[119.36136817932129,50.33693885803223],[119.13860511779785,50.39471626281738],[120.77665901184082,52.114999771118164],[120.71360969543457,52.54471778869629],[120.02916145324707,52.76805305480957],[120.86387825012207,53.27971839904785],[123.38220405578613,53.52665901184082]],[[108.32971382141113,21.654165267944336],[108.3288745880127,21.67860984802246],[108.32083320617676,21.665830612182617],[108.32971382141113,21.654165267944336]]]]}},{"type":"Feature","properties":{"name":"Afghanistan","iso2":"AF","iso3":"AFG"},"geometry":{"type":"MultiPolygon","coordinates":[[[[74.915741,37.237328],[74.392212,37.175072],[74.56543,37.027817],[72.556641,36.821266],[71.2435760000001,36.129715],[71.64942900000014,35.424995],[70.987488,34.551102000000114],[71.08194000000012,34.05582400000013],[69.90637200000018,34.035271],[70.326935,33.33194],[69.505264,33.034164],[69.32824700000012,31.940365000000114],[68.833054,31.603886],[68.166092,31.833054000000104],[67.575546,31.53194000000012],[67.778046,31.33221800000014],[66.72303800000012,31.212215],[66.395538,30.94083],[66.256653,29.851940000000113],[62.4844360000001,29.406105],[60.86859900000016,29.863884],[61.8511050000001,31.021111],[61.713608,31.383331],[60.84388,31.498329],[60.582497,33.06610100000013],[60.94304700000012,33.51944],[60.527771,33.64415700000011],[60.50833100000014,34.140274],[60.87887600000013,34.319717],[60.721657,34.522217],[61.27655800000011,35.60724600000013],[62.30915800000011,35.141663],[62.722214,35.254715],[63.10527000000016,35.45082900000013],[63.1194380000002,35.861938],[64.503601,36.280548],[64.798035,37.12499200000015],[65.70887800000011,37.538605],[66.537735,37.366379],[67.779877,37.185822],[68.058014,36.932526],[68.887772,37.3386],[69.315262,37.115273],[69.515823,37.580826],[70.155823,37.536232],[70.161377,37.933372],[70.967209,38.472115],[71.363037,38.248497],[71.252777,37.922035],[71.591934,37.902618],[71.429428,37.075829],[71.6772,36.67601],[73.307205,37.462753],[74.915741,37.237328]]]]}},{"type":"Feature","properties":{"name":"Bhutan","iso2":"BT","iso3":"BTN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[90.466385,28.071663],[91.301376,28.081108],[91.657761,27.764721],[92.113602,27.29749700000012],[92.069992,26.861942],[89.643051,26.715271],[88.89387500000012,26.975552],[88.9177250000001,27.320324],[89.59027100000012,28.14333],[90.017487,28.325275],[90.466385,28.071663]]]]}},{"type":"Feature","properties":{"name":"Chile","iso2":"CL","iso3":"CHL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-67.49305725097656,-55.82917022705078],[-67.61195373535156,-55.90222930908203],[-67.85751342773438,-55.84916687011719],[-67.49305725097656,-55.82917022705078]]],[[[-67.21278381347656,-55.89361572265625],[-67.41389465332031,-55.83222961425781],[-67.2469482421875,-55.82805633544922],[-67.21278381347656,-55.89361572265625]]],[[[-67.08528137207031,-55.917503356933594],[-67.17167663574219,-55.874168395996094],[-67.1058349609375,-55.80194854736328],[-67.08528137207031,-55.917503356933594]]],[[[-67.167236328125,-55.78639221191406],[-67.24139404296875,-55.790283203125],[-67.17388916015625,-55.75972557067871],[-67.167236328125,-55.78639221191406]]],[[[-67.26806640625,-55.72138977050781],[-67.55639457702637,-55.71222686767578],[-67.35667419433594,-55.57472229003906],[-67.26806640625,-55.72138977050781]]],[[[-67.72862243652344,-55.62445068359375],[-67.68806457519531,-55.501670837402344],[-67.58973693847656,-55.540557861328125],[-67.72862243652344,-55.62445068359375]]],[[[-69.69056701660156,-55.412506103515625],[-69.76472473144531,-55.33778381347656],[-69.63751220703125,-55.38250732421875],[-69.69056701660156,-55.412506103515625]]],[[[-69.98529052734375,-55.364173889160156],[-70.10612487792969,-55.29583740234375],[-69.94223022460938,-55.28722381591797],[-69.98529052734375,-55.364173889160156]]],[[[-66.87472534179688,-55.33222961425781],[-67.07362365722656,-55.27611541748047],[-66.87861633300781,-55.22888946533203],[-66.87472534179688,-55.33222961425781]]],[[[-66.57139587402344,-55.28472900390625],[-66.62611389160156,-55.19972229003906],[-66.42056274414062,-55.194725036621094],[-66.57139587402344,-55.28472900390625]]],[[[-66.81668090820312,-55.118614196777344],[-67.07223510742188,-55.002784729003906],[-66.86222839355469,-55.026390075683594],[-66.81668090820312,-55.118614196777344]]],[[[-68.39666557312012,-54.959449768066406],[-69.06111145019531,-55.057228088378906],[-68.21055603027344,-55.26500701904297],[-68.74501037597656,-55.2711181640625],[-68.15945434570312,-55.39861297607422],[-68.05361938476562,-55.712501525878906],[-68.93917846679688,-55.45972442626953],[-68.80361938476562,-55.18861389160156],[-69.43000793457031,-55.161949157714844],[-69.17417907714844,-55.51222229003906],[-70.03334045410156,-55.156394958496094],[-68.39666557312012,-54.959449768066406]]],[[[-67.78056335449219,-54.91944885253906],[-67.05361938476562,-55.136390686035156],[-68.09529113769531,-55.23694610595703],[-68.36445617675781,-54.94445037841797],[-67.78056335449219,-54.91944885253906]]],[[[-70.50875854492188,-54.970054626464844],[-70.73417663574219,-55.015281677246094],[-70.26445007324219,-55.116111755371094],[-71.01583862304688,-54.96666717529297],[-70.31167602539062,-54.90472412109375],[-70.50875854492188,-54.970054626464844]]],[[[-69.76222229003906,-55.038612365722656],[-69.93194580078125,-54.899169921875],[-69.16639709472656,-54.958335876464844],[-69.76222229003906,-55.038612365722656]]],[[[-71.10694885253906,-54.8719482421875],[-70.9122314453125,-54.92444610595703],[-71.45668029785156,-54.88500213623047],[-71.10694885253906,-54.8719482421875]]],[[[-70.60917663574219,-54.90472412109375],[-70.74555969238281,-54.87445068359375],[-70.39361572265625,-54.871673583984375],[-70.60917663574219,-54.90472412109375]]],[[[-72.0211181640625,-54.63472557067871],[-71.93112182617188,-54.744728088378906],[-72.10139465332031,-54.656394958496094],[-72.0211181640625,-54.63472557067871]]],[[[-72.30833435058594,-54.369171142578125],[-72.46334838867188,-54.43000030517578],[-72.54055786132812,-54.341392517089844],[-72.30833435058594,-54.369171142578125]]],[[[-70.28140258789062,-54.27555847167969],[-70.51112365722656,-54.16083526611328],[-70.21890258789062,-54.22666931152344],[-70.28140258789062,-54.27555847167969]]],[[[-71.25750732421875,-54.07611846923828],[-71.00973510742188,-54.102783203125],[-71.11639404296875,-54.38472557067871],[-71.69944763183594,-54.16111755371094],[-71.25750732421875,-54.07611846923828]]],[[[-72.32223510742188,-54.258056640625],[-72.51112365722656,-54.202781677246094],[-72.30168151855469,-54.07167053222656],[-72.20695495605469,-54.148338317871094],[-72.32223510742188,-54.258056640625]]],[[[-73.19416809082031,-54.12889099121094],[-73.47056579589844,-54.072784423828125],[-73.24667358398438,-54.03583526611328],[-73.19416809082031,-54.12889099121094]]],[[[-71.67111206054688,-53.94389343261719],[-71.95361328125,-54.019447326660156],[-71.8466796875,-54.33972930908203],[-72.25750732421875,-53.94111633300781],[-71.67111206054688,-53.94389343261719]]],[[[-70.44195556640625,-53.860557556152344],[-70.67445373535156,-53.926673889160156],[-70.52444458007812,-54.228614807128906],[-70.87861633300781,-54.05083465576172],[-70.53445434570312,-53.56083679199219],[-70.44195556640625,-53.860557556152344]]],[[[-73.83195495605469,-53.59027862548828],[-73.85722351074219,-53.453338623046875],[-73.6875,-53.52166557312012],[-73.83195495605469,-53.59027862548828]]],[[[-72.91111755371094,-53.42945098876953],[-72.87834167480469,-53.68194580078125],[-72.84390258789062,-53.45806121826172],[-72.13945007324219,-53.801673889160156],[-72.87083435058594,-54.13667297363281],[-72.73222351074219,-53.83972930908203],[-73.13250732421875,-54.01167297363281],[-73.25,-53.70722961425781],[-73.58778381347656,-53.75556182861328],[-72.91111755371094,-53.42945098876953]]],[[[-73.46389770507812,-53.475006103515625],[-73.49473571777344,-53.57444763183594],[-73.80195617675781,-53.429168701171875],[-73.46389770507812,-53.475006103515625]]],[[[-74.19168090820312,-53.331947326660156],[-74.24362182617188,-53.29972839355469],[-74.0594482421875,-53.24305725097656],[-74.19168090820312,-53.331947326660156]]],[[[-73.41307067871094,-52.87861633300781],[-73.39111328125,-52.95361328125],[-73.75222778320312,-52.893333435058594],[-73.41307067871094,-52.87861633300781]]],[[[-70.72584533691406,-52.89361572265625],[-70.78083801269531,-52.877784729003906],[-70.61889457702637,-52.82139587402344],[-70.72584533691406,-52.89361572265625]]],[[[-74.36056518554688,-52.948890686035156],[-74.74501037597656,-52.75666809082031],[-73.09001159667969,-53.35472869873047],[-74.36056518554688,-52.948890686035156]]],[[[-70.917236328125,-54.7086181640625],[-70.77139282226562,-54.681114196777344],[-70.87028503417969,-54.68639373779297],[-70.917236328125,-54.7086181640625],[-72.00306701660156,-54.46361541748047],[-70.13084411621094,-54.54888916015625],[-70.88027954101562,-54.13389587402344],[-70.14279174804688,-54.42833709716797],[-70.20083618164062,-54.31611633300781],[-70.05528259277344,-54.249168395996094],[-69.77000427246094,-54.55750274658203],[-69.85917663574219,-54.283058166503906],[-69.24111938476562,-54.44639587402344],[-69.37640380859375,-54.686668395996094],[-69.17750358581543,-54.580833435058594],[-68.99166870117188,-54.43194580078125],[-70.1844482421875,-53.81361389160156],[-69.35639953613281,-53.351112365722656],[-70.44667053222656,-53.36805725097656],[-70.4444580078125,-53.012779235839844],[-70.0997314453125,-52.90416717529297],[-70.42472839355469,-52.77305603027344],[-69.917236328125,-52.825836181640625],[-69.42056274414062,-52.45806121826172],[-68.61758422851562,-52.641510009765625],[-68.63583374023438,-54.78833770751953],[-68.63612365722656,-54.804771423339844],[-68.64311218261719,-54.88861083984375],[-70.917236328125,-54.7086181640625]]],[[[-73.80751037597656,-52.698333740234375],[-74.07778930664062,-52.60667419433594],[-73.74223327636719,-52.40361785888672],[-73.80751037597656,-52.698333740234375]]],[[[-74.73945617675781,-52.31694793701172],[-74.820556640625,-52.22944641113281],[-74.62001037597656,-52.20777893066406],[-74.73945617675781,-52.31694793701172]]],[[[-73.80805969238281,-52.39722442626953],[-74.09278869628906,-52.161949157714844],[-73.78916931152344,-52.26416778564453],[-73.80805969238281,-52.39722442626953]]],[[[-74.19416809082031,-52.13667297363281],[-73.93501281738281,-52.33722686767578],[-74.41862487792969,-52.13972473144531],[-74.19416809082031,-52.13667297363281]]],[[[-74.76251220703125,-52.18833923339844],[-74.7852783203125,-52.12139129638672],[-74.59611511230469,-52.07361602783203],[-74.76251220703125,-52.18833923339844]]],[[[-74.36056518554688,-52.07722473144531],[-74.40583801269531,-52.04722595214844],[-74.35417175292969,-52.056114196777344],[-74.36056518554688,-52.07722473144531]]],[[[-74.71722412109375,-52.08722686767578],[-74.55195617675781,-51.92750358581543],[-74.48779296875,-51.95722961425781],[-74.71722412109375,-52.08722686767578]]],[[[-73.69473266601562,-52.241668701171875],[-74.09529113769531,-51.92278289794922],[-73.76806640625,-52.06833457946777],[-73.69473266601562,-52.241668701171875]]],[[[-74.86361694335938,-52.13916778564453],[-74.7469482421875,-51.833892822265625],[-74.59916687011719,-51.84056091308594],[-74.86361694335938,-52.13916778564453]]],[[[-75.08973693847656,-51.90167236328125],[-75.07084655761719,-51.74028015136719],[-74.97250366210938,-51.72361755371094],[-75.08973693847656,-51.90167236328125]]],[[[-74.14472961425781,-51.951393127441406],[-74.50527954101562,-51.71417236328125],[-74.09222412109375,-51.875],[-74.14472961425781,-51.951393127441406]]],[[[-73.79667663574219,-51.81916809082031],[-73.94000244140625,-51.663063049316406],[-73.7933349609375,-51.728614807128906],[-73.79667663574219,-51.81916809082031]]],[[[-74.78111267089844,-51.82167053222656],[-74.9697265625,-52.11805725097656],[-74.93251037597656,-51.64361572265625],[-74.78111267089844,-51.82167053222656]]],[[[-74.05500793457031,-51.553611755371094],[-73.94000244140625,-51.78583526611328],[-74.23806762695312,-51.701393127441406],[-74.05500793457031,-51.553611755371094]]],[[[-75.00028991699219,-51.39556121826172],[-75.31028747558594,-51.63417053222656],[-75.20529174804688,-51.299171447753906],[-75.00028991699219,-51.39556121826172]]],[[[-74.11778259277344,-51.454444885253906],[-74.26139831542969,-51.300559997558594],[-74.17111206054688,-51.28583526611328],[-74.11778259277344,-51.454444885253906]]],[[[-73.78140258789062,-51.37139129638672],[-73.91445922851562,-51.30000305175781],[-73.79139709472656,-51.26111602783203],[-73.78140258789062,-51.37139129638672]]],[[[-74.04583740234375,-51.379173278808594],[-74.09722900390625,-51.22583770751953],[-73.96806335449219,-51.244171142578125],[-74.04583740234375,-51.379173278808594]]],[[[-74.53611755371094,-51.27916717529297],[-75.0211181640625,-51.46833801269531],[-74.79389953613281,-51.209449768066406],[-74.53611755371094,-51.27916717529297]]],[[[-74.99555969238281,-51.177223205566406],[-74.94000244140625,-51.09861755371094],[-74.85722351074219,-51.135284423828125],[-74.99555969238281,-51.177223205566406]]],[[[-74.41166687011719,-51.208335876464844],[-74.60305786132812,-51.07750701904297],[-74.4666748046875,-51.02833557128906],[-74.41166687011719,-51.208335876464844]]],[[[-74.26333618164062,-51.247779846191406],[-74.32223510742188,-50.91972351074219],[-74.19139099121094,-51.195556640625],[-74.26333618164062,-51.247779846191406]]],[[[-74.39666557312012,-50.860557556152344],[-74.40556335449219,-51.08972930908203],[-74.48222351074219,-50.997779846191406],[-74.72056579589844,-51.11194610595703],[-74.96473693847656,-50.96583557128906],[-74.39666557312012,-50.860557556152344]]],[[[-74.68917846679688,-50.890838623046875],[-74.95472717285156,-50.731117248535156],[-74.7489013671875,-50.70195007324219],[-74.68917846679688,-50.890838623046875]]],[[[-74.99389457702637,-50.81389617919922],[-75.07084655761719,-50.65222930908203],[-74.979736328125,-50.664451599121094],[-74.99389457702637,-50.81389617919922]]],[[[-74.65139770507812,-50.58861541748047],[-74.68583679199219,-50.52166557312012],[-74.58168029785156,-50.5322265625],[-74.65139770507812,-50.58861541748047]]],[[[-75.09638977050781,-50.516395568847656],[-75.28889465332031,-50.78583526611328],[-75.5150146484375,-50.663063049316406],[-75.09638977050781,-50.516395568847656]]],[[[-74.3638916015625,-50.49139404296875],[-74.19334411621094,-50.84833526611328],[-74.5150146484375,-50.733062744140625],[-74.42361450195312,-50.52361297607422],[-74.67001342773438,-50.47944641113281],[-74.3638916015625,-50.49139404296875]]],[[[-74.73834228515625,-50.5],[-74.75306701660156,-50.388336181640625],[-74.54362487792969,-50.38139343261719],[-74.73834228515625,-50.5]]],[[[-75.04861450195312,-50.16694641113281],[-74.78973388671875,-50.149444580078125],[-75.4586181640625,-50.364173889160156],[-75.14361572265625,-50.24639129638672],[-75.39973258972168,-50.03666687011719],[-75.04861450195312,-50.16694641113281]]],[[[-75.30694580078125,-49.67195129394531],[-75.17388916015625,-49.90306091308594],[-75.59194946289062,-49.78388977050781],[-75.30694580078125,-49.67195129394531]]],[[[-75.48056030273438,-49.54722595214844],[-75.57890319824219,-49.46472930908203],[-75.48445129394531,-49.481117248535156],[-75.48056030273438,-49.54722595214844]]],[[[-74.29417419433594,-49.56056213378906],[-74.41944885253906,-49.627784729003906],[-74.43583679199219,-49.42750358581543],[-74.29417419433594,-49.56056213378906]]],[[[-74.92056274414062,-49.295005798339844],[-75.24028015136719,-49.15028381347656],[-74.97250366210938,-49.03111267089844],[-74.92056274414062,-49.295005798339844]]],[[[-75.28584289550781,-49.10028076171875],[-75.65640258789062,-49.216949462890625],[-75.35890197753906,-48.985557556152344],[-75.28584289550781,-49.10028076171875]]],[[[-75.28140258789062,-48.89000701904297],[-75.25778198242188,-49.081947326660156],[-75.322509765625,-48.954444885253906],[-75.5,-49.04639434814453],[-75.65667724609375,-48.93889617919922],[-75.28140258789062,-48.89000701904297]]],[[[-75.17611694335938,-48.999725341796875],[-75.3125,-48.80000305175781],[-75.08222961425781,-48.88916778564453],[-75.17611694335938,-48.999725341796875]]],[[[-74.97944641113281,-48.74250030517578],[-74.99139404296875,-48.648895263671875],[-74.8255615234375,-48.66166687011719],[-74.97944641113281,-48.74250030517578]]],[[[-75.28167724609375,-48.713340759277344],[-75.65472412109375,-48.76805877685547],[-75.34806823730469,-48.63555908203125],[-75.28167724609375,-48.713340759277344]]],[[[-75.12055969238281,-48.8336181640625],[-75.24833679199219,-48.771392822265625],[-75.07139587402344,-48.63444519042969],[-75.12055969238281,-48.8336181640625]]],[[[-75.322509765625,-48.60417175292969],[-75.60111999511719,-48.69194793701172],[-75.65055847167969,-48.48194885253906],[-75.322509765625,-48.60417175292969]]],[[[-74.41139221191406,-48.530006408691406],[-74.49778747558594,-48.399169921875],[-74.30195617675781,-48.47583770751953],[-74.41139221191406,-48.530006408691406]]],[[[-74.04917907714844,-48.44611358642578],[-74.07417297363281,-48.491111755371094],[-74.2489013671875,-48.37639617919922],[-74.04917907714844,-48.44611358642578]]],[[[-74.26445007324219,-48.466949462890625],[-74.49166870117188,-48.351112365722656],[-74.30639457702637,-48.28666687011719],[-74.26445007324219,-48.466949462890625]]],[[[-74.41889953613281,-48.304725646972656],[-74.5372314453125,-48.333892822265625],[-74.5997314453125,-48.15167236328125],[-74.41889953613281,-48.304725646972656]]],[[[-74.60833740234375,-48.455833435058594],[-74.41278076171875,-49.732505798339844],[-74.7711181640625,-50.05500030517578],[-74.92001342773438,-49.68305969238281],[-74.64639282226562,-49.355560302734375],[-75.0050048828125,-49.508056640625],[-75.01722717285156,-49.899444580078125],[-75.47111511230469,-49.33167266845703],[-74.91806030273438,-49.33611297607422],[-74.82722473144531,-49.09584045410156],[-75.0513916015625,-48.79833984375],[-74.61111450195312,-48.69667053222656],[-75.02862358093262,-48.49500274658203],[-74.7086181640625,-48.45417022705078],[-74.73500061035156,-48.12306213378906],[-74.60833740234375,-48.455833435058594]]],[[[-75.23945617675781,-48.27056121826172],[-75.23445129394531,-48.711395263671875],[-75.58250427246094,-48.086669921875],[-75.23945617675781,-48.27056121826172]]],[[[-74.92500305175781,-48.15583801269531],[-75.04417419433594,-48.44361114501953],[-75.2569580078125,-48.073333740234375],[-74.92500305175781,-48.15583801269531]]],[[[-74.80528259277344,-47.89805603027344],[-74.86973571777344,-48.06916809082031],[-75.26667785644531,-48.031951904296875],[-74.80528259277344,-47.89805603027344]]],[[[-73.92445373535156,-47.88611602783203],[-73.79972839355469,-47.887779235839844],[-74.4989013671875,-47.923057556152344],[-73.92445373535156,-47.88611602783203]]],[[[-75.1319580078125,-47.84889221191406],[-75.30361938476562,-47.773338317871094],[-75.13444519042969,-47.698333740234375],[-75.1319580078125,-47.84889221191406]]],[[[-74.95472717285156,-47.783058166503906],[-75.07528686523438,-47.69445037841797],[-74.95140075683594,-47.706390380859375],[-74.95472717285156,-47.783058166503906]]],[[[-74.45529174804688,-47.17694854736328],[-74.48417663574219,-47.083335876464844],[-74.31306457519531,-47.062782287597656],[-74.45529174804688,-47.17694854736328]]],[[[-74.15444946289062,-47.17250061035156],[-74.18362426757812,-47.02528381347656],[-73.97528076171875,-47.04750061035156],[-74.15444946289062,-47.17250061035156]]],[[[-73.7650146484375,-46.21111297607422],[-73.9122314453125,-46.02027893066406],[-73.68333435058594,-46.07666778564453],[-73.7650146484375,-46.21111297607422]]],[[[-73.68112182617188,-46.02833557128906],[-73.8194580078125,-45.99889373779297],[-73.77806091308594,-45.905006408691406],[-73.68112182617188,-46.02833557128906]]],[[[-74.71556091308594,-45.851951599121094],[-75.08306884765625,-46.08861541748047],[-75.10195922851562,-45.874168395996094],[-74.71556091308594,-45.851951599121094]]],[[[-73.70390319824219,-45.84278106689453],[-73.92889404296875,-45.97583770751953],[-73.88417053222656,-45.858612060546875],[-73.70390319824219,-45.84278106689453]]],[[[-74.0150146484375,-45.91777801513672],[-74.10694885253906,-45.78833770751953],[-74.03861999511719,-45.73638916015625],[-74.0150146484375,-45.91777801513672]]],[[[-74.75279235839844,-45.70777893066406],[-74.87667846679688,-45.64972686767578],[-74.86917114257812,-45.6058349609375],[-74.75279235839844,-45.70777893066406]]],[[[-74.62028503417969,-45.75695037841797],[-74.68251037597656,-45.63694763183594],[-74.54861450195312,-45.57750701904297],[-74.62028503417969,-45.75695037841797]]],[[[-73.98695373535156,-45.72472381591797],[-74.11000061035156,-45.59278106689453],[-74.01194763183594,-45.537506103515625],[-73.8961181640625,-45.62055969238281],[-73.98695373535156,-45.72472381591797]]],[[[-74.4586181640625,-45.77916717529297],[-74.39028930664062,-45.44389343261719],[-74.21000671386719,-45.63611602783203],[-74.4586181640625,-45.77916717529297]]],[[[-73.64556884765625,-45.75944519042969],[-73.78195190429688,-45.67028045654297],[-73.7005615234375,-45.44389343261719],[-73.64556884765625,-45.75944519042969]]],[[[-74.01779174804688,-45.43305969238281],[-73.81584167480469,-45.47583770751953],[-74.14472961425781,-45.576393127441406],[-74.01779174804688,-45.43305969238281]]],[[[-74.50445556640625,-45.539451599121094],[-74.57000732421875,-45.52916717529297],[-74.43806457519531,-45.42388916015625],[-74.50445556640625,-45.539451599121094]]],[[[-73.89695739746094,-45.434173583984375],[-74.024169921875,-45.40028381347656],[-73.8255615234375,-45.37306213378906],[-73.89695739746094,-45.434173583984375]]],[[[-74.34140014648438,-45.40611267089844],[-74.52778625488281,-45.30528259277344],[-74.38722229003906,-45.288063049316406],[-74.34140014648438,-45.40611267089844]]],[[[-73.97666931152344,-45.26750183105469],[-73.78306579589844,-45.33528137207031],[-74.16612243652344,-45.25055694580078],[-73.97666931152344,-45.26750183105469]]],[[[-74.30889892578125,-45.30583953857422],[-74.39472961425781,-45.154449462890625],[-74.27056884765625,-45.21417236328125],[-74.30889892578125,-45.30583953857422]]],[[[-73.8466796875,-45.002784729003906],[-73.73139953613281,-45.284446716308594],[-74.23583984375,-45.1602783203125],[-73.8466796875,-45.002784729003906]]],[[[-73.98028564453125,-44.98445129394531],[-74.36666870117188,-45.01055908203125],[-74.1683349609375,-44.866668701171875],[-73.98028564453125,-44.98445129394531]]],[[[-74.026123046875,-44.85694885253906],[-74.18667602539062,-44.8125],[-73.95777893066406,-44.78361511230469],[-74.026123046875,-44.85694885253906]]],[[[-73.79362487792969,-44.965003967285156],[-73.92417907714844,-44.89222717285156],[-73.91778564453125,-44.78166961669922],[-73.79362487792969,-44.965003967285156]]],[[[-75.0694580078125,-44.925559997558594],[-75.11167907714844,-44.77833557128906],[-75.02305603027344,-44.84638977050781],[-75.0694580078125,-44.925559997558594]]],[[[-73.651123046875,-44.844451904296875],[-73.7489013671875,-44.75639343261719],[-73.60833740234375,-44.741111755371094],[-73.651123046875,-44.844451904296875]]],[[[-74.376953125,-44.85945129394531],[-74.52639770507812,-44.74195098876953],[-74.42945861816406,-44.719451904296875],[-74.376953125,-44.85945129394531]]],[[[-74.20973205566406,-44.784446716308594],[-74.40972900390625,-44.63444519042969],[-73.87333679199219,-44.68695068359375],[-74.20973205566406,-44.784446716308594]]],[[[-74.45556640625,-44.69389343261719],[-74.67361450195312,-44.668617248535156],[-74.57833862304688,-44.62000274658203],[-74.45556640625,-44.69389343261719]]],[[[-74.77723693847656,-44.6875],[-74.80416870117188,-44.549171447753906],[-74.72611999511719,-44.5977783203125],[-74.77723693847656,-44.6875]]],[[[-73.74555969238281,-44.743614196777344],[-73.68861389160156,-44.54444885253906],[-73.58973693847656,-44.70972442626953],[-73.74555969238281,-44.743614196777344]]],[[[-74.2952880859375,-44.57722473144531],[-74.36834716796875,-44.53278350830078],[-74.13917541503906,-44.550559997558594],[-74.2952880859375,-44.57722473144531]]],[[[-74.41250610351562,-44.512779235839844],[-74.54750061035156,-44.468055725097656],[-74.21778869628906,-44.468055725097656],[-74.41250610351562,-44.512779235839844]]],[[[-74.01972961425781,-44.556671142578125],[-74.12945556640625,-44.448333740234375],[-73.95945739746094,-44.48278045654297],[-74.01972961425781,-44.556671142578125]]],[[[-73.84417724609375,-44.464447021484375],[-73.89889526367188,-44.371673583984375],[-73.78861999511719,-44.42250061035156],[-73.84417724609375,-44.464447021484375]]],[[[-72.7227783203125,-44.549171447753906],[-72.81916809082031,-44.64055633544922],[-72.98333740234375,-44.606117248535156],[-72.82833862304688,-44.69055938720703],[-73.13833618164062,-44.913063049316406],[-73.28028869628906,-44.94000244140625],[-73.40779113769531,-44.820556640625],[-73.20722961425781,-44.798614501953125],[-73.46473693847656,-44.644447326660156],[-72.99806213378906,-44.367225646972656],[-72.7227783203125,-44.549171447753906]]],[[[-73.68890380859375,-44.439727783203125],[-73.78807067871094,-44.38195037841797],[-73.65278625488281,-44.352783203125],[-73.68890380859375,-44.439727783203125]]],[[[-73.92945861816406,-44.44805908203125],[-74.10556030273438,-44.322784423828125],[-73.93084716796875,-44.355560302734375],[-73.92945861816406,-44.44805908203125]]],[[[-73.24195861816406,-44.388336181640625],[-73.3033447265625,-44.36333465576172],[-73.24972534179688,-44.31083679199219],[-73.16889953613281,-44.37000274658203],[-73.24195861816406,-44.388336181640625]]],[[[-73.84695434570312,-44.33805847167969],[-73.97389221191406,-44.281951904296875],[-73.80223083496094,-44.270835876464844],[-73.84695434570312,-44.33805847167969]]],[[[-73.71139526367188,-44.304168701171875],[-73.76112365722656,-44.25389099121094],[-73.66555786132812,-44.25139617919922],[-73.71139526367188,-44.304168701171875]]],[[[-74.29167175292969,-44.30639457702637],[-74.42140197753906,-44.262779235839844],[-74.32722473144531,-44.24639129638672],[-74.29167175292969,-44.30639457702637]]],[[[-74.32000732421875,-44.19500732421875],[-74.38555908203125,-44.154449462890625],[-74.25917053222656,-44.159446716308594],[-74.32000732421875,-44.19500732421875]]],[[[-74.01167297363281,-44.28417205810547],[-74.12611389160156,-44.20777893066406],[-74.06723022460938,-44.151947021484375],[-74.01167297363281,-44.28417205810547]]],[[[-73.852783203125,-44.195838928222656],[-74.01112365722656,-44.141944885253906],[-73.92222595214844,-44.09889221191406],[-73.852783203125,-44.195838928222656]]],[[[-74.2933349609375,-44.031951904296875],[-74.3194580078125,-44.01722717285156],[-74.20472717285156,-44.01917266845703],[-74.2933349609375,-44.031951904296875]]],[[[-73.6461181640625,-44.13139343261719],[-73.72862243652344,-43.93889617919922],[-73.63444519042969,-44.01000213623047],[-73.6461181640625,-44.13139343261719]]],[[[-73.15501403808594,-44.02278137207031],[-73.26945495605469,-43.92083740234375],[-73.14805603027344,-43.888336181640625],[-73.15501403808594,-44.02278137207031]]],[[[-73.85556030273438,-43.765838623046875],[-73.7650146484375,-43.893333435058594],[-74.17250061035156,-43.877784729003906],[-73.85556030273438,-43.765838623046875]]],[[[-74.6461181640625,-43.61250305175781],[-74.79389953613281,-43.64778137207031],[-74.86250305175781,-43.5625],[-74.6461181640625,-43.61250305175781]]],[[[-73.59750366210938,-42.61805725097656],[-73.75140380859375,-42.617225646972656],[-73.61889457702637,-42.570281982421875],[-73.59750366210938,-42.61805725097656]]],[[[-73.41667175292969,-42.55639457702637],[-73.6541748046875,-42.38750457763672],[-73.53584289550781,-42.38500213623047],[-73.41667175292969,-42.55639457702637]]],[[[-73.10612487792969,-42.31139373779297],[-73.18972778320312,-42.25139617919922],[-73.06916809082031,-42.260284423828125],[-73.10612487792969,-42.31139373779297]]],[[[-72.5130615234375,-42.152503967285156],[-72.61695861816406,-42.0977783203125],[-72.50944519042969,-42.06083679199219],[-72.5130615234375,-42.152503967285156]]],[[[-73.88528442382812,-41.81555938720703],[-73.50111389160156,-41.84333801269531],[-73.36862182617188,-42.25055694580078],[-73.67222595214844,-42.36194610595703],[-73.61805725097656,-42.51722717285156],[-73.82028198242188,-42.50750732421875],[-73.80029296875,-42.61778259277344],[-73.4989013671875,-42.80083465576172],[-73.65390014648438,-42.93333435058594],[-73.48945617675781,-43.114723205566406],[-73.85917663574219,-43.400001525878906],[-74.40779113769531,-43.243614196777344],[-73.88528442382812,-41.81555938720703]]],[[[-73.01583862304688,-41.86444854736328],[-73.08973693847656,-41.84416961669922],[-73.0775146484375,-41.74000358581543],[-73.01583862304688,-41.86444854736328]]],[[[-80.73779296875,-33.779449462890625],[-80.77473258972168,-33.74195098876953],[-80.73529052734375,-33.689443588256836],[-80.73779296875,-33.779449462890625]]],[[[-78.77250671386719,-33.62361145019531],[-78.99166870117188,-33.668060302734375],[-78.88833618164062,-33.58055877685547],[-78.77250671386719,-33.62361145019531]]],[[[-109.24138641357422,-27.133056640625],[-109.44917297363281,-27.193058013916016],[-109.39083862304688,-27.066669464111328],[-109.24138641357422,-27.133056640625]]],[[[-105.45639038085938,-26.460556030273438],[-105.45945739746094,-26.464723587036133],[-105.47416687011719,-26.45305633544922],[-105.45639038085938,-26.460556030273438]]],[[[-79.88250732421875,-26.346946716308594],[-79.90695190429688,-26.346389770507812],[-79.86944580078125,-26.340835571289062],[-79.88250732421875,-26.346946716308594]]],[[[-80.07695007324219,-26.261669158935547],[-80.0997314453125,-26.261390686035156],[-80.08056640625,-26.251392364501953],[-80.07695007324219,-26.261669158935547]]],[[[-69.48361206054688,-17.63555908203125],[-69.07167053222656,-18.038890838623047],[-68.90779113769531,-19.055278778076172],[-68.4375,-19.430278778076172],[-68.7569580078125,-20.40694808959961],[-68.18861389160156,-21.296945571899414],[-67.87640380859375,-22.82805633544922],[-67.18362426757812,-22.821666717529297],[-67.00083923339844,-23.00278091430664],[-67.33584594726562,-24.021665573120117],[-68.56500244140625,-24.774444580078125],[-68.35195922851562,-25.117225646972656],[-68.5836181640625,-26.505279541015625],[-68.2872314453125,-26.915279388427734],[-68.81083679199219,-27.120555877685547],[-69.65538024902344,-28.40093231201172],[-70.03140258789062,-29.306392669677734],[-69.83168029785156,-30.190555572509766],[-70.53306579589844,-31.18805694580078],[-70.09889221191406,-33.17250061035156],[-69.77444458007812,-33.38111114501953],[-69.8125,-34.235557556152344],[-70.5675048828125,-35.247779846191406],[-70.42431640625,-36.13603973388672],[-71.18528747558594,-36.84222412109375],[-70.82417297363281,-38.56806182861328],[-71.40139770507812,-38.92028045654297],[-71.695556640625,-39.584449768066406],[-71.9505615234375,-40.73278045654297],[-71.72611999511719,-42.09667205810547],[-72.1319580078125,-42.28889465332031],[-72.13694763183594,-43.00917053222656],[-71.7327880859375,-43.18805694580078],[-71.85501098632812,-44.371673583984375],[-71.10806274414062,-44.53972625732422],[-71.2822265625,-44.80028533935547],[-72.07861328125,-44.769447326660156],[-71.29779052734375,-45.2933349609375],[-71.78056335449219,-45.648895263671875],[-71.66944885253906,-46.679168701171875],[-71.94029235839844,-46.81555938720703],[-71.86862182617188,-47.22167205810547],[-72.36029052734375,-47.470001220703125],[-72.53639221191406,-47.92139434814453],[-72.2872314453125,-48.341949462890625],[-72.56417846679688,-48.80445098876953],[-73.5836181640625,-49.538063049316406],[-73.16612243652344,-50.753334045410156],[-72.29417419433594,-50.64972686767578],[-72.40055847167969,-51.51361846923828],[-71.91056823730469,-51.99583435058594],[-69.99833679199219,-51.99639129638672],[-68.44175720214844,-52.377777099609375],[-69.26112365722656,-52.206390380859375],[-70.81167602539062,-52.732505798339844],[-70.97361755371094,-53.75556182861328],[-71.28472900390625,-53.886390686035156],[-72.45390319824219,-53.401390075683594],[-71.86445617675781,-53.22167205810547],[-72.00723266601562,-53.56305694580078],[-71.80307006835938,-53.516395568847656],[-71.17056274414062,-52.80805969238281],[-72.55278015136719,-53.07472229003906],[-72.18861389160156,-53.18389129638672],[-72.6541748046875,-53.323890686035156],[-72.40028381347656,-53.540283203125],[-73.21778869628906,-53.231117248535156],[-72.70611572265625,-53.293060302734375],[-72.79306030273438,-53.17833709716797],[-72.65306091308594,-53.146949768066406],[-72.93695068359375,-53.10667419433594],[-72.95834350585938,-52.857505798339844],[-72.71945190429688,-52.746116638183594],[-71.47528076171875,-52.633338928222656],[-72.79917907714844,-52.53972625732422],[-72.89889526367188,-52.62555694580078],[-72.67529296875,-52.65888977050781],[-73.00584411621094,-52.85417175292969],[-72.9808349609375,-53.06611633300781],[-73.45112609863281,-53.00666809082031],[-73.23500061035156,-52.88972473144531],[-73.56278991699219,-52.793617248535156],[-72.885009765625,-52.51555633544922],[-73.69000244140625,-52.725006103515625],[-73.54779052734375,-52.53889465332031],[-73.72334289550781,-52.02472686767578],[-73.3275146484375,-52.22361755371094],[-72.98861694335938,-52.06861114501953],[-72.86195373535156,-52.26416778564453],[-72.69833374023438,-51.98333740234375],[-72.570556640625,-52.315834045410156],[-72.89944458007812,-52.4586181640625],[-72.4908447265625,-52.31889343261719],[-72.46890258789062,-51.78916931152344],[-73.24362182617188,-51.46222686767578],[-72.56083679199219,-51.78166961669922],[-73.28140258789062,-51.61028289794922],[-72.92417907714844,-51.86333465576172],[-73.23695373535156,-52.090003967285156],[-73.38667297363281,-51.655555725097656],[-73.28361511230469,-52.155006408691406],[-73.5452880859375,-52.05639457702637],[-73.461669921875,-51.687225341796875],[-73.90583801269531,-51.62250518798828],[-73.89418029785156,-51.37000274658203],[-73.59806823730469,-51.61833953857422],[-73.711669921875,-51.15972900390625],[-74.25279235839844,-50.940834045410156],[-73.52862358093262,-50.714447021484375],[-73.56639099121094,-50.40167236328125],[-74.04833984375,-50.82750701904297],[-74.29306030273438,-50.48222351074219],[-73.88473510742188,-50.53889465332031],[-74.69361877441406,-50.203338623046875],[-73.8658447265625,-50.29389190673828],[-74.37251281738281,-49.99139404296875],[-73.885009765625,-50.06945037841797],[-74.32528686523438,-49.627227783203125],[-73.71250915527344,-49.757225036621094],[-74.11167907714844,-49.48027801513672],[-73.83416557312012,-49.02916717529297],[-74.3739013671875,-49.42750358581543],[-74.44972229003906,-48.812225341796875],[-74.06083679199219,-48.74139404296875],[-74.40028381347656,-48.61444854736328],[-74.04667663574219,-48.54778289794922],[-74.0211181640625,-48.413612365722656],[-74.65444946289062,-48.023895263671875],[-73.5533447265625,-48.24583435058594],[-73.274169921875,-48.08722686767578],[-73.6541748046875,-47.90361785888672],[-73.22084045410156,-48.00111389160156],[-73.71917724609375,-47.52833557128906],[-73.9344482421875,-47.846946716308594],[-74.74166870117188,-47.71583557128906],[-74.04112243652344,-47.61805725097656],[-74.5291748046875,-47.437782287597656],[-73.9344482421875,-47.03611755371094],[-74.2650146484375,-46.785560607910156],[-75.01390075683594,-46.750282287597656],[-74.94223022460938,-46.44000244140625],[-75.65472412109375,-46.76500701904297],[-75.41307067871094,-46.93389129638672],[-75.71751403808594,-46.72528076171875],[-74.36111450195312,-45.791114807128906],[-74.14083862304688,-45.80583953857422],[-73.97445678710938,-46.0947265625],[-74.0836181640625,-46.18611145019531],[-74.31167602539062,-46.249168395996094],[-74.49444580078125,-46.190284729003906],[-74.34083557128906,-46.266395568847656],[-74.04972839355469,-46.195556640625],[-73.85389709472656,-46.34722900390625],[-73.88278198242188,-46.14111328125],[-73.76806640625,-46.30278015136719],[-73.99501037597656,-46.56139373779297],[-73.84112358093262,-46.588890075683594],[-73.42556762695312,-46.07444763183594],[-73.69084167480469,-46.31916809082031],[-73.66334533691406,-45.97333526611328],[-73.18223571777344,-45.667503356933594],[-73.58723258972168,-45.77972412109375],[-73.51556396484375,-45.45500183105469],[-72.82722473144531,-45.42250061035156],[-73.44694519042969,-45.2852783203125],[-73.39167785644531,-44.980560302734375],[-73.14250183105469,-44.94445037841797],[-72.76611328125,-44.753334045410156],[-72.6138916015625,-44.4727783203125],[-73.28945922851562,-44.14361572265625],[-72.84584045410156,-43.77667236328125],[-73.11639404296875,-43.439727783203125],[-72.74528503417969,-43.04833984375],[-72.86083984375,-42.57444763183594],[-72.53500366210938,-42.559173583984375],[-72.84750366210938,-42.280006408691406],[-72.42140197753906,-42.45305633544922],[-72.46278381347656,-41.97111511230469],[-72.85945129394531,-41.906951904296875],[-72.35057067871094,-41.652503967285156],[-72.31001281738281,-41.43583679199219],[-72.57139587402344,-41.70777893066406],[-72.94667053222656,-41.48333740234375],[-73.20361328125,-41.792503356933594],[-73.75028991699219,-41.754722595214844],[-73.49195861816406,-41.520835876464844],[-73.86889457702637,-41.482505798339844],[-73.99501037597656,-40.970001220703125],[-73.22250366210938,-39.41472625732422],[-73.64334106445312,-37.2086181640625],[-73.19000244140625,-37.1380615234375],[-71.4425048828125,-32.64000701904297],[-71.70333862304688,-30.761669158935547],[-71.28779602050781,-29.89694595336914],[-71.52166557312012,-28.970001220703125],[-70.91084289550781,-27.6219482421875],[-70.44917297363281,-25.364723205566406],[-70.39111328125,-23.561946868896484],[-70.62251281738281,-23.492778778076172],[-70.0533447265625,-21.42565155029297],[-70.40548706054688,-18.34854507446289],[-69.95112609863281,-18.242778778076172],[-69.49972534179688,-17.505279541015625],[-69.48361206054688,-17.63555908203125]],[[-74.0694580078125,-46.00611114501953],[-74.16445922851562,-46.13667297363281],[-74.07223510742188,-46.0977783203125],[-74.0694580078125,-46.00611114501953]],[[-73.38528442382812,-52.74000358581543],[-73.32806396484375,-52.69944763183594],[-73.39805603027344,-52.732505798339844],[-73.38528442382812,-52.74000358581543]]]]}},{"type":"Feature","properties":{"name":"Cayman Islands","iso2":"KY","iso3":"CYM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-81.09722899999988,19.308887000000155],[-81.401123,19.28833],[-81.254456,19.353886],[-81.09722899999988,19.308887000000155]]],[[[-80.097504,19.654163],[-80.0758359999999,19.697498],[-79.966675,19.707222],[-80.097504,19.654163]]],[[[-79.866394,19.686943],[-79.893341,19.693333],[-79.732788,19.748608],[-79.866394,19.686943]]]]}},{"type":"Feature","properties":{"name":"Cameroon","iso2":"CM","iso3":"CMR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[9.687222,3.574722],[9.62611,3.551111000000105],[9.6425,3.578611000000123],[9.687222,3.574722]]],[[[14.577221,12.73860900000011],[15.042597,12.078888],[15.061666,10.789999000000108],[15.68185,9.989649],[14.194769000000122,9.98175],[13.957499000000155,9.638611],[15.201944,8.485832],[15.499008,7.526609],[14.41916700000013,6.035277],[14.732777,4.623055],[16.103054,2.898333],[16.207222,2.220833],[16.07222000000013,1.654166],[14.564999,2.169444],[13.293888,2.163611],[12.523611000000102,2.283333],[11.339764,2.168611],[10.02611,2.168056],[9.811764000000153,2.343698],[9.7225,3.865278],[8.975832000000139,4.09666600000017],[8.845833,4.638055000000151],[8.504166000000168,4.527778],[8.591738000000134,4.810932000000122],[8.865276,5.841944],[9.795555,6.801666],[10.615000000000123,7.06861],[11.340277,6.440833],[11.864166,7.084722],[12.253887000000134,8.408054],[12.79694400000011,8.769722],[13.80722,11.055832],[14.646387,11.575832],[14.645277,12.188332000000145],[14.174444,12.396666],[14.07472,13.0816650000001],[14.500875,13.001314],[14.577221,12.73860900000011]]]]}},{"type":"Feature","properties":{"name":"Chad","iso2":"TD","iso3":"TCD"},"geometry":{"type":"MultiPolygon","coordinates":[[[[14.500875,13.001314],[14.07472,13.0816650000001],[13.62512,13.718338],[13.468887,14.461111],[15.489166,16.914165],[15.996666,20.353054],[15.202499,21.495831],[14.997889,23.000591],[16.000832,23.450554],[24.002747,19.499065],[23.999603,15.698709],[22.937222000000105,15.561943],[22.935833,15.11611],[22.384163,14.55416500000014],[22.55499600000013,14.125555000000148],[22.084442,13.779165],[22.294167,13.35861],[21.827774,12.797499000000144],[22.46694200000013,12.621666],[22.866505,10.922447],[21.719444,10.639444],[21.715553,10.290554],[20.371666,9.108332],[18.988888,8.964167],[19.058792,8.578382],[18.588886,8.040277],[15.499008,7.526609],[15.201944,8.485832],[13.957499000000155,9.638611],[14.194769000000122,9.98175],[15.68185,9.989649],[15.061666,10.789999000000108],[15.042597,12.078888],[14.577221,12.73860900000011],[14.500875,13.001314]]]]}},{"type":"Feature","properties":{"name":"Comoros","iso2":"KM","iso3":"COM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[43.86055000000013,-12.356112],[43.66861,-12.3575],[43.622772,-12.258335],[43.86055000000013,-12.356112]]],[[[44.487495,-12.093056],[44.513611,-12.38028],[44.206665,-12.161945],[44.487495,-12.093056]]],[[[43.459717000000154,-11.935556],[43.219162000000125,-11.761112],[43.281387,-11.379723],[43.459717000000154,-11.935556]]]]}},{"type":"Feature","properties":{"name":"Colombia","iso2":"CO","iso3":"COL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-78.12139892578125,2.500833511352539],[-78.21556091308594,2.577779769897461],[-78.18917846679688,2.640554428100586],[-78.12779235839844,2.643056869506836],[-78.0916748046875,2.539445877075195],[-78.12139892578125,2.500833511352539]]],[[[-77.98638916015625,2.542501449584961],[-78.04556274414062,2.58305549621582],[-77.97750854492188,2.651945114135742],[-77.94833374023438,2.627779006958008],[-77.96028137207031,2.557222366333008],[-77.98638916015625,2.542501449584961]]],[[[-77.85751342773438,2.573335647583008],[-77.92111206054688,2.693891525268555],[-77.78695678710938,2.592779159545898],[-77.85751342773438,2.573335647583008]]],[[[-77.76972961425781,2.591390609741211],[-77.83973693847656,2.640279769897461],[-77.88473510742188,2.717222213745117],[-77.82778930664062,2.703889846801758],[-77.74972534179688,2.614999771118164],[-77.76972961425781,2.591390609741211]]],[[[-77.56889343261719,3.06916618347168],[-77.66278076171875,3.075834274291992],[-77.53056335449219,3.209444046020508],[-77.56889343261719,3.06916618347168]]],[[[-77.44833374023438,4.074167251586914],[-77.53556823730469,4.16722297668457],[-77.49417114257812,4.204168319702148],[-77.44833374023438,4.074167251586914]]],[[[-77.54306030273438,4.193334579467773],[-77.42611694335938,4.334722518920898],[-77.31973266601562,4.251665115356445],[-77.54306030273438,4.193334579467773]]],[[[-71.56361389160156,12.453611373901367],[-71.1158447265625,12.101110458374023],[-71.32472229003906,11.853055953979492],[-71.97723388671875,11.664999008178711],[-72.2093505859375,11.250001907348633],[-72.49305725097656,11.121110916137695],[-73.37806701660156,9.171388626098633],[-72.77972412109375,9.080278396606445],[-72.32528686523438,8.095556259155273],[-72.4716796875,7.491945266723633],[-72,7.018888473510742],[-70.11917114257812,6.975835800170898],[-69.24528503417969,6.081388473510742],[-67.45445251464844,6.193056106567383],[-67.85972595214844,4.558610916137695],[-67.29055786132812,3.397500991821289],[-67.82833862304688,2.825002670288086],[-67.1925048828125,2.392499923706055],[-66.87188720703125,1.221643447875977],[-67.07667541503906,1.173334121704102],[-67.42417907714844,2.143888473510742],[-67.91473388671875,1.745279312133789],[-68.19639587402344,1.977502822875977],[-68.15306091308594,1.72416877746582],[-69.84609985351562,1.710454940795898],[-69.84222412109375,1.072221755981445],[-69.27000427246094,1.038335800170898],[-69.12472534179688,0.645002365112305],[-70.04417419433594,0.59083366394043],[-70.05805969238281,-0.157499313354492],[-69.60751342773438,-0.517499923706055],[-69.37806701660156,-1.338054656982422],[-69.95692443847656,-4.236873626708984],[-70.72416687011719,-3.779722213745117],[-70.0675048828125,-2.755556106567383],[-70.28834533691406,-2.504999160766602],[-71.69805908203125,-2.146944046020508],[-72.8819580078125,-2.506387710571289],[-73.55639457702637,-1.370832443237305],[-74.22723388671875,-1.027776718139648],[-74.77694702148438,-0.204166412353516],[-75.28584289550781,-0.119722366333008],[-76.24305725097656,0.39555549621582],[-77.37945556640625,0.384721755981445],[-78.5916748046875,1.24305534362793],[-78.80972290039062,1.437780380249023],[-79.0533447265625,1.628332138061523],[-78.58416557312012,1.768888473510742],[-78.56529235839844,2.429166793823242],[-78.44056701660156,2.509443283081055],[-78.34361267089844,2.436666488647461],[-78.2650146484375,2.519166946411133],[-78.12556457519531,2.486944198608398],[-77.98695373535156,2.522500991821289],[-77.94862365722656,2.559446334838867],[-77.94000244140625,2.655000686645508],[-77.86723327636719,2.560277938842773],[-77.79251098632812,2.567499160766602],[-77.7408447265625,2.60472297668457],[-77.02862358093262,3.917779922485352],[-77.43417358398438,4.02833366394043],[-77.23918151855469,4.260000228881836],[-77.38417053222656,4.341943740844727],[-77.3477783203125,5.240556716918945],[-77.5322265625,5.518888473510742],[-77.2408447265625,5.75139045715332],[-77.49028015136719,6.190832138061523],[-77.34001159667969,6.567777633666992],[-77.88972473144531,7.228891372680664],[-77.74667358398438,7.722223281860352],[-77.57389831542969,7.525278091430664],[-77.21556091308594,7.937223434448242],[-77.36666870117188,8.67500114440918],[-76.75527954101562,7.918889999389648],[-76.9283447265625,8.568334579467773],[-75.62945556640625,9.453611373901367],[-75.26972961425781,10.798334121704102],[-74.86080932617188,11.125486373901367],[-74.28861999511719,11.002500534057617],[-74.59222412109375,10.878053665161133],[-74.39056396484375,10.74305534362793],[-74.15501403808594,11.331388473510742],[-73.28445434570312,11.295557022094727],[-71.56361389160156,12.453611373901367]],[[-78.5452880859375,2.416112899780273],[-78.54417419433594,2.432500839233398],[-78.55029296875,2.433332443237305],[-78.55361938476562,2.406667709350586],[-78.5452880859375,2.416112899780273]]],[[[-81.71028137207031,12.490835189819336],[-81.7197265625,12.55000114440918],[-81.68833923339844,12.59111213684082],[-81.71028137207031,12.490835189819336]]],[[[-81.36557006835938,13.323057174682617],[-81.38945007324219,13.335000991821289],[-81.35389709472656,13.378610610961914],[-81.36557006835938,13.323057174682617]]]]}},{"type":"Feature","properties":{"name":"Costa Rica","iso2":"CR","iso3":"CRI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-85.115845,10.07361],[-85.17611699999989,10.077499],[-85.198059,10.110554],[-85.161957,10.122499],[-85.109177,10.105833],[-85.115845,10.07361]]],[[[-85.087784,11.009998],[-83.915558,10.708611],[-83.645798,10.924847],[-82.563568,9.562876000000145],[-82.934723,9.471666],[-82.71084599999989,8.93111],[-82.898849,8.025669],[-83.341675,8.726944000000117],[-83.291122,8.370277],[-83.730835,8.583055],[-83.624176,9.035276000000124],[-84.61527999999987,9.575832000000105],[-84.74028,9.966665],[-85.243057,10.204166],[-85.228622,10.088888],[-84.897232,9.807499],[-85.142227,9.589443],[-85.664459,9.908609000000126],[-85.861679,10.368332000000123],[-85.631958,10.626389],[-85.91139199999986,10.891109],[-85.692383,11.076061],[-85.087784,11.009998]]]]}},{"type":"Feature","properties":{"name":"Central African Republic","iso2":"CF","iso3":"CAF"},"geometry":{"type":"MultiPolygon","coordinates":[[[[19.058792,8.578382],[18.988888,8.964167],[20.371666,9.108332],[21.715553,10.290554],[21.719444,10.639444],[22.866505,10.922447],[23.669167,9.866943],[23.517776,8.714167],[24.201111,8.686943],[24.192497000000117,8.30361],[25.25333,7.850555],[25.206944000000135,7.497499],[26.404999,6.646388],[26.437496000000124,6.077777],[27.142776,5.771944],[27.455276,5.016388],[25.891666,5.192499],[25.542221,5.381389],[24.734444,4.910832000000141],[24.394165,5.115555],[23.420277,4.59111],[22.895832,4.821111],[22.37916600000014,4.1275],[20.585552,4.410000000000139],[19.421387,5.134166],[18.541943,4.335555],[18.624958,3.479444],[17.475277,3.713055],[16.659721,3.533333],[16.207222,2.220833],[16.103054,2.898333],[14.732777,4.623055],[14.41916700000013,6.035277],[15.499008,7.526609],[18.588886,8.040277],[19.058792,8.578382]]]]}},{"type":"Feature","properties":{"name":"Cuba","iso2":"CU","iso3":"CUB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-78.32778930664062,20.513612747192383],[-78.45834350585938,20.605554580688477],[-78.34584045410156,20.56944465637207],[-78.32778930664062,20.513612747192383]]],[[[-78.3819580078125,20.63777732849121],[-78.4122314453125,20.6472225189209],[-78.40278625488281,20.675832748413086],[-78.3819580078125,20.63777732849121]]],[[[-78.44168090820312,20.710554122924805],[-78.54750061035156,20.703611373901367],[-78.4586181640625,20.73166847229004],[-78.44168090820312,20.710554122924805]]],[[[-78.76750183105469,20.70611000061035],[-78.82194519042969,20.75694465637207],[-78.76362609863281,20.730554580688477],[-78.76750183105469,20.70611000061035]]],[[[-75.48722839355469,20.7288875579834],[-75.57806396484375,20.781110763549805],[-75.5150146484375,20.79194450378418],[-75.48722839355469,20.7288875579834]]],[[[-78.84750366210938,20.771665573120117],[-78.96583557128906,20.809999465942383],[-78.93167114257812,20.834165573120117],[-78.84750366210938,20.771665573120117]]],[[[-78.977783203125,20.839445114135742],[-79.0775146484375,20.893888473510742],[-78.9697265625,20.87416648864746],[-78.977783203125,20.839445114135742]]],[[[-79.08445739746094,20.898332595825195],[-79.22557067871094,21.00055503845215],[-79.17668151855469,21.00861167907715],[-79.08445739746094,20.898332595825195]]],[[[-79.30223083496094,21.064443588256836],[-79.38417053222656,21.119722366333008],[-79.34140014648438,21.121110916137695],[-79.30223083496094,21.064443588256836]]],[[[-79.40640258789062,21.10472297668457],[-79.45112609863281,21.122777938842773],[-79.40251159667969,21.121110916137695],[-79.40640258789062,21.10472297668457]]],[[[-81.53083801269531,21.600278854370117],[-81.55694580078125,21.622777938842773],[-81.36695861816406,21.711942672729492],[-81.53083801269531,21.600278854370117]]],[[[-82.5452880859375,21.57111167907715],[-82.89723205566406,21.43277931213379],[-83.19306945800781,21.621389389038086],[-82.93722534179688,21.579999923706055],[-83.08944702148438,21.785554885864258],[-82.97445678710938,21.942777633666992],[-82.5452880859375,21.57111167907715]]],[[[-77.91505432128906,22.094697952270508],[-77.65333557128906,22.06972312927246],[-77.63833618164062,21.953054428100586],[-77.91505432128906,22.094697952270508]]],[[[-77.84638977050781,22.10638999938965],[-78.04417419433594,22.18666648864746],[-77.99751281738281,22.285276412963867],[-77.84638977050781,22.10638999938965]]],[[[-77.77723693847656,22.19500160217285],[-77.77166557312012,22.168054580688477],[-77.85000610351562,22.294721603393555],[-77.77723693847656,22.19500160217285]]],[[[-78.11862182617188,22.413888931274414],[-78.01945495605469,22.261945724487305],[-78.3114013671875,22.40389060974121],[-78.11862182617188,22.413888931274414]]],[[[-78.34140014648438,22.53388786315918],[-78.42529296875,22.412500381469727],[-78.69667053222656,22.51472282409668],[-78.34140014648438,22.53388786315918]]],[[[-78.97639465332031,22.63749885559082],[-79.05445861816406,22.6652774810791],[-78.96890258789062,22.66916847229004],[-78.97639465332031,22.63749885559082]]],[[[-79.32305908203125,22.614721298217773],[-79.63250732421875,22.80000114440918],[-79.57612609863281,22.809999465942383],[-79.32305908203125,22.614721298217773]]],[[[-79.89195251464844,22.928335189819336],[-79.9586181640625,22.947500228881836],[-79.883056640625,22.96527671813965],[-79.89195251464844,22.928335189819336]]],[[[-80.2327880859375,22.9950008392334],[-80.23417663574219,22.956388473510742],[-80.34945678710938,22.98166847229004],[-80.2327880859375,22.9950008392334]]],[[[-80.04945373535156,23.02610969543457],[-80.07722473144531,23.04194450378418],[-80.07667541503906,23.074445724487305],[-80.04945373535156,23.02610969543457]]],[[[-80.14639282226562,23.070276260375977],[-80.22416687011719,23.099443435668945],[-80.19944763183594,23.121946334838867],[-80.14639282226562,23.070276260375977]]],[[[-80.92750358581543,23.12555503845215],[-80.79722595214844,23.150556564331055],[-80.97361755371094,23.107500076293945],[-80.92750358581543,23.12555503845215]]],[[[-82.00389099121094,23.18638801574707],[-81.58056640625,23.155553817749023],[-81.50083923339844,23.05555534362793],[-81.22695922851562,23.161664962768555],[-81.28556823730469,23.119722366333008],[-81.13473510742188,23.023054122924805],[-80.633056640625,23.09833335876465],[-80.54444885253906,22.99110984802246],[-80.27862358093262,22.9052791595459],[-80.03334045410156,22.951112747192383],[-77.34112358093262,21.636110305786133],[-77.54306030273438,21.918611526489258],[-76.8961181640625,21.3063907623291],[-75.70722961425781,21.121946334838867],[-75.73667907714844,20.696943283081055],[-74.14140319824219,20.252222061157227],[-75.08528137207031,19.893041610717773],[-75.13973999023438,19.962873458862305],[-75.1591796875,19.960695266723633],[-75.22372436523438,19.90155601501465],[-77.72250366210938,19.83277702331543],[-77.1158447265625,20.364999771118164],[-77.23638916015625,20.663057327270508],[-78.05029296875,20.69972038269043],[-78.75028991699219,21.6391658782959],[-79.98779296875,21.72361183166504],[-80.49195861816406,22.177221298217773],[-81.82305908203125,22.183610916137695],[-82.16307067871094,22.398332595825195],[-81.64889526367188,22.49138832092285],[-81.885009765625,22.68083381652832],[-82.76390075683594,22.7005558013916],[-84.026123046875,21.91499900817871],[-84.95333862304688,21.85999870300293],[-84.33805847167969,22.01222038269043],[-84.07695007324219,22.660554885864258],[-82.00389099121094,23.18638801574707]]],[[[-80.49305725097656,23.18805503845215],[-80.57972717285156,23.176111221313477],[-80.55862426757812,23.203611373901367],[-80.49305725097656,23.18805503845215]]]]}},{"type":"Feature","properties":{"name":"Cape Verde","iso2":"CV","iso3":"CPV"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-24.368336,14.812222],[-24.52528,14.92111],[-24.381668,15.047499],[-24.368336,14.812222]]],[[[-23.446667,14.982777000000112],[-23.681393,14.935555],[-23.76667,15.253054],[-23.446667,14.982777000000112]]],[[[-22.706112,16.036388],[-22.957779,16.089443],[-22.79861499999987,16.23527500000013],[-22.706112,16.036388]]],[[[-24.034168,16.594166],[-24.32139199999989,16.482777],[-24.432224,16.644165],[-24.034168,16.594166]]],[[[-24.926113,16.799999000000142],[-25.093334,16.83083],[-24.933056,16.921387],[-24.926113,16.799999000000142]]],[[[-25.28139099999987,16.91333],[-25.33028,17.096386],[-24.97444499999989,17.112778],[-25.28139099999987,16.91333]]]]}},{"type":"Feature","properties":{"name":"Cook Islands","iso2":"CK","iso3":"COK"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-157.890564,-21.938053],[-157.962799,-21.904167],[-157.921967,-21.880283],[-157.890564,-21.938053]]],[[[-159.741119,-21.254169],[-159.833893,-21.195831],[-159.752502,-21.193054],[-159.741119,-21.254169]]],[[[-157.316437,-20.188053],[-157.332214,-20.13306],[-157.309174,-20.147781],[-157.316437,-20.188053]]],[[[-158.098358,-20.016113],[-158.118591,-19.973057],[-158.08197,-19.986942],[-158.098358,-20.016113]]],[[[-158.27948,-19.817783],[-158.262512,-19.836666],[-158.291382,-19.833332],[-158.27948,-19.817783]]],[[[-157.708649,-19.853054],[-157.741364,-19.814167],[-157.713928,-19.770283],[-157.708649,-19.853054]]],[[[-158.92865,-19.270283],[-158.943909,-19.27195],[-158.951935,-19.242496],[-158.92865,-19.270283]]],[[[-159.78833,-18.890556],[-159.803345,-18.861389],[-159.78421,-18.841393],[-159.78833,-18.890556]]],[[[-163.16333,-18.089443],[-163.170319,-18.079449],[-163.154724,-18.056667],[-163.16333,-18.089443]]],[[[-165.422241,-11.548334],[-165.435028,-11.5375],[-165.414185,-11.537781],[-165.422241,-11.548334]]],[[[-165.82666,-10.888334],[-165.850281,-10.884169],[-165.831146,-10.876945],[-165.82666,-10.888334]]],[[[-161.022827,-10.431391],[-161.043335,-10.419724],[-161.048615,-10.392778],[-161.022827,-10.431391]]],[[[-160.975586,-10.395555],[-161.012512,-10.352777],[-160.973602,-10.378057],[-160.975586,-10.395555]]],[[[-161.084442,-10.041945],[-161.090576,-10.018333],[-161.072266,-10.008059],[-161.084442,-10.041945]]],[[[-157.941681,-8.982502],[-157.97226,-8.981943],[-158.008362,-8.951389],[-157.941681,-8.982502]]]]}},{"type":"Feature","properties":{"name":"Cyprus","iso2":"CY","iso3":"CYP"},"geometry":{"type":"MultiPolygon","coordinates":[[[[33.652618,35.354103],[34.590271,35.690277],[33.921387,35.272774],[34.083328,34.959442],[33.030838,34.56255],[32.274162,35.043884],[33.652618,35.354103]]]]}},{"type":"Feature","properties":{"name":"Denmark","iso2":"DK","iso3":"DNK"},"geometry":{"type":"MultiPolygon","coordinates":[[[[11.513887,54.829720000000165],[11.85611,54.683327000000176],[10.98989100000017,54.790848],[11.513887,54.829720000000165]]],[[[12.038055,54.892494],[11.964443,54.561661],[11.708611,54.936661000000115],[12.038055,54.892494]]],[[[10.432777000000101,54.84166],[10.248333000000173,54.90416],[10.184166,54.97361],[10.432777000000101,54.84166]]],[[[12.557499,54.96416500000011],[12.11583300000018,54.90416],[12.311943,55.03527100000015],[12.557499,54.96416500000011]]],[[[10.615000000000123,54.950272],[10.49861,55.006386],[10.631943,55.043327],[10.615000000000123,54.950272]]],[[[9.79250000000016,55.074997000000124],[10.071110000000147,54.87471000000012],[9.630554000000103,55.04943800000011],[9.79250000000016,55.074997000000124]]],[[[10.756943000000149,54.777222],[10.681944,54.908607],[10.949165,55.16111],[10.756943000000149,54.777222]]],[[[15.051666,54.994995000000145],[14.679722,55.099716],[14.746387,55.295555000000135],[15.051666,54.994995000000145]]],[[[8.46361,55.33416],[8.360277,55.457771],[8.458332,55.426384],[8.46361,55.33416]]],[[[10.745277000000101,55.482216],[10.782776,55.122498],[10.497776,55.028885],[10.152777,55.084442],[10.11861,55.178886],[10.005833,55.193329],[9.896944,55.279716],[9.810833,55.436661],[9.675554,55.499161000000115],[9.74861,55.540276000000105],[9.813055,55.547493],[9.904999,55.505829000000105],[10.309721000000138,55.616943],[10.478611,55.438049000000106],[10.619165000000123,55.619164],[10.745277000000101,55.482216]]],[[[12.579443,55.551384],[12.606110000000115,55.696106],[12.67861,55.590553],[12.579443,55.551384]]],[[[10.630554,55.865555],[10.527498,55.765831],[10.523611,55.981384],[10.630554,55.865555]]],[[[12.567221,55.992218],[12.190832,55.478607],[12.461666,55.286385],[12.071943,54.968605000000125],[11.246666,55.199715],[10.873610000000156,55.732498],[11.763887,55.964722],[12.057220000000143,55.653328000000116],[11.859444,55.96666000000012],[12.567221,55.992218]]],[[[11.565832,56.67083000000012],[11.503332000000114,56.707771],[11.648054000000116,56.72332800000011],[11.565832,56.67083000000012]]],[[[8.924721,56.91861],[8.766943,56.692215000000104],[8.509722,56.74166100000015],[8.924721,56.91861]]],[[[9.974274,57.071732000000125],[10.311891,56.981304],[10.305277,56.748055],[9.866388000000171,56.650276],[10.963055,56.439438],[10.24679,56.17855100000013],[9.992777,55.704994],[9.549999,55.7058260000001],[9.81916600000011,55.604721],[9.704166,55.53110500000015],[9.588333,55.421661],[9.68861,55.196938],[9.459166,55.123886],[9.768055,54.89110600000011],[9.445358,54.825401],[8.664545,54.913094],[8.623888,55.427498],[8.087221,55.548882],[8.127222,55.98555],[8.397221,55.897499],[8.108332,56.017776000000126],[8.165277,56.653328],[8.728333,56.482216],[9.075567,56.807449],[9.321665,56.525551000000135],[9.178200000000118,56.916031],[9.309444000000155,57.001938],[9.974274,57.071732000000125]]],[[[11.195833,57.31082900000017],[10.997499000000118,57.223328],[10.854443000000117,57.263054],[11.195833,57.31082900000017]]],[[[10.43249900000012,57.592216],[10.336616,56.991665],[10.006666,57.0899890000001],[9.24388900000011,56.995552],[9.115549,57.05277300000013],[8.670832000000132,56.945274],[8.415797,56.67812700000012],[8.591389,56.686104],[8.554998,56.582497],[8.240276,56.70722200000013],[8.617222,57.121666],[10.645953000000134,57.736267],[10.43249900000012,57.592216]]]]}},{"type":"Feature","properties":{"name":"Djibouti","iso2":"DJ","iso3":"DJI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[42.866806,11.585428],[43.249222,11.469534],[42.944092,11.002438],[41.789719,11.008055],[41.828606,11.74],[42.399719,12.469721],[43.12138400000018,12.708332],[43.413887,12.056944],[42.508606,11.567221],[42.866806,11.585428]]]]}},{"type":"Feature","properties":{"name":"Dominica","iso2":"DM","iso3":"DMA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-61.363617,15.198055],[-61.452225,15.631943],[-61.253334,15.461388],[-61.363617,15.198055]]]]}},{"type":"Feature","properties":{"name":"Dominican Republic","iso2":"DO","iso3":"DOM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-71.532227,17.540276],[-71.522232,17.615276],[-71.46305799999988,17.581944],[-71.532227,17.540276]]],[[[-68.574448,18.129444],[-68.731949,18.119999],[-68.78389,18.195],[-68.574448,18.129444]]],[[[-70.783615,19.846664],[-69.936401,19.67110800000013],[-69.75361599999985,19.289444000000103],[-69.22167999999988,19.362221],[-69.631668,19.101665],[-68.729172,18.952774],[-68.32556199999988,18.616665],[-68.4497219999999,18.35583100000015],[-69.881668,18.469444],[-70.510834,18.194721],[-70.690002,18.433887],[-71.079727,18.301109],[-71.4225009999999,17.601944],[-71.767868,18.038502],[-72.003067,18.60083],[-71.715836,18.749722],[-71.754181,19.70583000000012],[-70.783615,19.846664]]]]}},{"type":"Feature","properties":{"name":"Ecuador","iso2":"EC","iso3":"ECU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-80.19334411621094,-3.034721374511719],[-80.20668029785156,-2.724166870117188],[-79.90306091308594,-2.719720840454102],[-80.19334411621094,-3.034721374511719]]],[[[-79.838623046875,-2.641944885253906],[-79.88694763183594,-2.626943588256836],[-79.85667419433594,-2.466667175292969],[-79.838623046875,-2.641944885253906]]],[[[-89.62112426757812,-1.406665802001953],[-89.751953125,-1.360832214355469],[-89.64834594726562,-1.343889236450195],[-89.62112426757812,-1.406665802001953]]],[[[-90.4344482421875,-1.355278015136719],[-90.48167419433594,-1.219165802001953],[-90.3658447265625,-1.269166946411133],[-90.4344482421875,-1.355278015136719]]],[[[-90.0433349609375,-0.838888168334961],[-90.08222961425781,-0.801111221313477],[-90.03973388671875,-0.809444427490234],[-90.0433349609375,-0.838888168334961]]],[[[-89.44361877441406,-0.936666488647461],[-89.62945556640625,-0.927221298217773],[-89.25862121582031,-0.6875],[-89.44361877441406,-0.936666488647461]]],[[[-90.26055908203125,-0.751110076904297],[-90.5352783203125,-0.583889007568359],[-90.19056701660156,-0.542778015136719],[-90.26055908203125,-0.751110076904297]]],[[[-91.4989013671875,-0.496110916137695],[-91.66389465332031,-0.316110610961914],[-91.47111511230469,-0.248056411743164],[-91.4989013671875,-0.496110916137695]]],[[[-90.54750061035156,-0.305000305175781],[-90.87445068359375,-0.270000457763672],[-90.7933349609375,-0.149442672729492],[-90.54750061035156,-0.305000305175781]]],[[[-91.21890258789062,-0.011110305786133],[-90.81083679199219,-0.732500076293945],[-91.37611389160156,-1.026666641235352],[-91.08056640625,-0.587221145629883],[-91.6058349609375,-0.004999160766602],[-91.21890258789062,-0.011110305786133]]],[[[-90.45916557312012,0.266389846801758],[-90.53250122070312,0.34666633605957],[-90.40834045410156,0.326944351196289],[-90.45916557312012,0.266389846801758]]],[[[-90.75111389160156,0.547502517700195],[-90.79972839355469,0.563333511352539],[-90.792236328125,0.651666641235352],[-90.75111389160156,0.547502517700195]]],[[[-78.5916748046875,1.24305534362793],[-77.37945556640625,0.384721755981445],[-76.24305725097656,0.39555549621582],[-75.28584289550781,-0.119722366333008],[-75.62796020507812,-0.108858108520508],[-75.21607971191406,-0.965335845947266],[-75.55917358398438,-1.53416633605957],[-76.66062927246094,-2.572134017944336],[-78.33750915527344,-3.42277717590332],[-78.70903015136719,-4.584787368774414],[-79.05482482910156,-5.009132385253906],[-79.64973258972168,-4.432777404785156],[-80.46778869628906,-4.43889045715332],[-80.46722412109375,-3.986944198608398],[-80.15333557128906,-3.884227752685547],[-80.34042358398438,-3.380516052246094],[-79.94805908203125,-3.198333740234375],[-79.72750854492188,-2.602777481079102],[-79.84584045410156,-2.376388549804688],[-79.76362609863281,-2.009166717529297],[-80.25639343261719,-2.73638916015625],[-80.8900146484375,-2.320554733276367],[-80.91111755371094,-1.031110763549805],[-80.26472473144531,-0.627222061157227],[-80.501953125,-0.367500305175781],[-80.06834411621094,0.062780380249023],[-80.05972290039062,0.828611373901367],[-78.80972290039062,1.437780380249023],[-78.5916748046875,1.24305534362793]],[[-78.9122314453125,1.239168167114258],[-78.90333557128906,1.367780685424805],[-78.9989013671875,1.274999618530273],[-78.9122314453125,1.239168167114258]]]]}},{"type":"Feature","properties":{"name":"Egypt","iso2":"EG","iso3":"EGY"},"geometry":{"type":"MultiPolygon","coordinates":[[[[34.026384353637695,27.498334884643555],[34.041940689086914,27.44222068786621],[33.917497634887695,27.52638816833496],[34.026384353637695,27.498334884643555]]],[[[32.04722023010254,31.14333152770996],[32.04277229309082,31.158056259155273],[32.049997329711914,31.15333366394043],[32.04722023010254,31.14333152770996]]],[[[33.47666358947754,31.13749885559082],[33.26666450500488,31.21527671813965],[33.40055274963379,31.181665420532227],[33.47666358947754,31.13749885559082]]],[[[33.19527626037598,31.232778549194336],[33.26138496398926,31.214998245239258],[33.10166358947754,31.22722053527832],[32.97666358947754,31.168333053588867],[33.09610939025879,31.232500076293945],[33.19527626037598,31.232778549194336]]],[[[25.316667556762695,31.50111198425293],[27.33111000061035,31.374998092651367],[29.06944465637207,30.821664810180664],[31.02777671813965,31.600557327270508],[31.921480178833008,31.52988624572754],[32.20499610900879,31.28999900817871],[31.899999618530273,31.531110763549805],[31.773889541625977,31.271665573120117],[32.14306831359863,31.074167251586914],[32.21055030822754,31.288057327270508],[32.71721839904785,31.032499313354492],[33.11166572570801,31.193056106567383],[33.14972114562988,31.101667404174805],[33.14361000061035,31.058332443237305],[33.41055488586426,31.154722213745117],[33.53277778625488,31.116945266723633],[33.7438907623291,31.133333206176758],[34.21666145324707,31.323331832885742],[34.26758003234863,31.216543197631836],[34.9038028717041,29.48670768737793],[34.25444221496582,27.728612899780273],[33.24277687072754,28.554445266723633],[32.57499885559082,30.005277633666992],[32.340829849243164,29.59694480895996],[33.55888557434082,27.883054733276367],[35.13861274719238,24.517499923706055],[35.81305122375488,23.916112899780273],[35.48305702209473,23.93833351135254],[35.67055702209473,22.96583366394043],[36.88846778869629,22.000112533569336],[31.453889846801758,21.998334884643555],[31.455556869506836,22.232221603393555],[31.2711124420166,21.998334884643555],[25.00142478942871,21.999696731567383],[24.997777938842773,29.24888801574707],[24.706666946411133,30.168611526489258],[25.15166664123535,31.646944046020508],[25.316667556762695,31.50111198425293]],[[34.00139045715332,26.707223892211914],[33.99472236633301,26.749723434448242],[33.96000099182129,26.788331985473633],[34.00139045715332,26.707223892211914]]]]}},{"type":"Feature","properties":{"name":"Ireland","iso2":"IE","iso3":"IRL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-9.656389236450195,53.22222328186035],[-9.724723815917969,53.26805305480957],[-9.660833358764648,53.28000068664551],[-9.656389236450195,53.22222328186035]]],[[[-9.964168548583984,54.01861000061035],[-9.955001831054688,53.876665115356445],[-10.268611907958984,53.97500038146973],[-9.964168548583984,54.01861000061035]]],[[[-8.518611907958984,54.96416664123535],[-8.546945571899414,55.01194190979004],[-8.490556716918945,54.99472236633301],[-8.518611907958984,54.96416664123535]]],[[[-7.406389236450195,54.95333290100098],[-8.159444808959961,54.44194221496582],[-7.559444427490234,54.12693977355957],[-7.030834197998047,54.41777229309082],[-6.266975402832031,54.09983253479004],[-6.013055801391602,52.94500160217285],[-6.361110687255859,52.177499771118164],[-6.994722366333008,52.28277778625488],[-9.234167098999023,51.48055458068848],[-9.817501068115234,51.4455509185791],[-9.53555679321289,51.75000190734863],[-10.132501602172852,51.593332290649414],[-9.57750129699707,51.87221717834473],[-10.338592529296875,51.78292274475098],[-9.75777816772461,52.14860725402832],[-10.460834503173828,52.18222236633301],[-8.818334579467773,52.66555213928223],[-9.936389923095703,52.55583381652832],[-8.941112518310547,53.26416206359863],[-10.175834655761719,53.40777778625488],[-9.561389923095703,53.85972023010254],[-9.940555572509766,53.86694526672363],[-9.787778854370117,53.94194221496582],[-10.006111145019531,54.218889236450195],[-10.124444961547852,54.096384048461914],[-10.112222671508789,54.229997634887695],[-8.471668243408203,54.27388954162598],[-8.6683349609375,54.349443435668945],[-8.188333511352539,54.63360786437988],[-8.800834655761719,54.691667556762695],[-8.317501068115234,55.10888862609863],[-7.657499313354492,55.27443885803223],[-7.681388854980469,54.94832801818848],[-7.393888473510742,55.37944221496582],[-6.931667327880859,55.2358341217041],[-7.252506256103516,55.07059669494629],[-7.406389236450195,54.95333290100098]],[[-8.436944961547852,54.94444465637207],[-8.43861198425293,54.955278396606445],[-8.453889846801758,54.95499610900879],[-8.436944961547852,54.94444465637207]]]]}},{"type":"Feature","properties":{"name":"Equatorial Guinea","iso2":"GQ","iso3":"GNQ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[5.641388,-1.474722],[5.615277,-1.469167],[5.633888000000184,-1.420556],[5.641388,-1.474722]]],[[[10.02611,2.168056],[11.339764,2.168611],[11.353888,1.001944],[9.803976,1.002608],[9.356943,1.167222],[9.811764000000153,2.343698],[10.02611,2.168056]]],[[[8.856667,3.499444],[8.44611,3.27444400000013],[8.68611,3.741666000000109],[8.958887000000175,3.703888],[8.856667,3.499444]]]]}},{"type":"Feature","properties":{"name":"Estonia","iso2":"EE","iso3":"EST"},"geometry":{"type":"MultiPolygon","coordinates":[[[[23.990829,58.099998],[23.947773,58.147217],[24.022186,58.142746],[23.990829,58.099998]]],[[[22.990829,58.597771],[23.332775,58.441658],[21.994160000000193,57.922768],[22.201385,58.144714],[21.83194,58.5049970000001],[22.990829,58.597771]]],[[[23.364998,58.529991],[23.05777400000011,58.60833000000015],[23.247459,58.671051],[23.364998,58.529991]]],[[[23.27722200000011,58.963051],[23.110828,59.024712],[23.391663,58.998047],[23.27722200000011,58.963051]]],[[[22.7497180000002,59],[23.045277000000112,58.83638],[22.042221,58.939987],[22.7497180000002,59]]],[[[25.780277000000126,59.62887600000012],[28.015831,59.4786],[28.170359,59.30978],[27.426105,58.81360600000012],[27.82305100000019,57.87387800000012],[27.372059,57.535637],[26.511387,57.5261],[25.294998000000106,58.084435],[24.314980000000105,57.871826],[24.555553,58.327217],[23.728607,58.370827],[23.495548,58.694153],[23.874996,58.7686],[23.483051000000103,58.80999],[23.464161,59.206383],[25.780277000000126,59.62887600000012]]]]}},{"type":"Feature","properties":{"name":"Eritrea","iso2":"ER","iso3":"ERI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[40.087219,15.851665],[40.419441,15.573889000000136],[39.977776,15.605],[40.087219,15.851665]]],[[[40.113327,16.05583200000011],[39.979721,16.012218000000118],[40.030273,16.095276],[40.113327,16.05583200000011]]],[[[38.797775,17.653332],[39.7211070000001,15.084166],[39.881386,15.489443],[40.17083,14.973610000000136],[41.170555,14.6325],[43.12138400000018,12.708332],[42.399719,12.469721],[40.228058,14.443506],[39.024021,14.655162000000146],[38.44944000000012,14.4175],[37.91138500000014,14.88361],[37.572212,14.102253],[37.291664,14.451944],[36.5428160000001,14.262053],[36.44328300000021,15.149952],[36.97305300000019,16.269444],[36.995827,17.073887],[37.423286000000104,17.034214],[38.600693,17.994881],[38.797775,17.653332]]]]}},{"type":"Feature","properties":{"name":"El Salvador","iso2":"SV","iso3":"SLV"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-87.686401,13.168333],[-87.72168,13.168055],[-87.723068,13.214722],[-87.686401,13.168333]]],[[[-89.339737,14.416111],[-88.47084,13.855276],[-87.75029,13.864166],[-87.815582,13.405386000000107],[-87.93779,13.156387],[-88.53862,13.194166],[-90.09639,13.745832],[-89.348312,14.431982],[-89.339737,14.416111]]]]}},{"type":"Feature","properties":{"name":"Ethiopia","iso2":"ET","iso3":"ETH"},"geometry":{"type":"MultiPolygon","coordinates":[[[[36.5428160000001,14.262053],[37.291664,14.451944],[37.572212,14.102253],[37.91138500000014,14.88361],[38.44944000000012,14.4175],[39.024021,14.655162000000146],[40.228058,14.443506],[42.399719,12.469721],[41.828606,11.74],[41.789719,11.008055],[42.944092,11.002438],[42.663055,10.6325],[42.848053,10.22361],[44.010551,9.007221],[47.01194,8.00111],[47.988243,8.004107],[44.950829,4.902499],[43.686386,4.891944],[41.905167,3.980322],[41.171387,3.9425],[40.783768,4.287975],[39.524437,3.406389],[38.121109,3.611666],[37.039719,4.375555000000134],[35.940552,4.622499],[35.821663,5.32861],[35.30194100000014,5.378055],[34.70472,6.677777000000106],[33.711388,7.660277],[32.991104,7.924999],[33.252777,8.458611000000118],[34.120552,8.577221000000122],[34.28611,10.554165],[34.594444,10.887777],[34.864441,10.734999],[35.096939000000106,11.826944],[35.70108,12.666115],[36.142693,12.706923000000117],[36.5428160000001,14.262053]]]]}},{"type":"Feature","properties":{"name":"Austria","iso2":"AT","iso3":"AUT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[13.833611,48.773605],[14.70028,48.581379],[15.025833,49.018883],[16.946182,48.619064],[17.166386,48.012497],[17.053886,47.709442],[16.450554,47.698051],[16.713886,47.543884],[16.510555,47.00666],[16.111805,46.86972],[14.544998,46.407494],[13.718655,46.526611],[12.440554000000134,46.69082600000014],[12.127777,47.00166300000011],[10.471235,46.871353],[9.598635,47.063835],[9.533569,47.274544],[9.566724,47.540451],[10.173332,47.274719000000104],[10.478054,47.591942000000145],[11.095554,47.396111],[12.735554,47.684166000000104],[13.016666,47.470276],[12.758333,48.123886],[13.833611,48.773605]]]]}},{"type":"Feature","properties":{"name":"Czech Republic","iso2":"CZ","iso3":"CZE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[14.70028,48.581379],[13.833611,48.773605],[12.674444,49.42499500000015],[12.093704000000116,50.322533],[14.309721,51.05360400000011],[14.828333,50.865829],[16.341942,50.66111],[16.20583,50.423882],[16.641941,50.10833],[17.00222,50.216942],[16.890274,50.439438],[17.722775,50.319717],[17.657776,50.108055],[18.577221,49.914444],[18.851246,49.517357],[16.946182,48.619064],[15.025833,49.018883],[14.70028,48.581379]]]]}},{"type":"Feature","properties":{"name":"French Guiana","iso2":"GF","iso3":"GUF"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-53.494339,5.572342],[-52.285278,4.937499],[-52.040001,4.331388],[-51.850563,4.653333],[-51.684067,4.034163],[-52.909729,2.195833],[-54.603783,2.329195],[-54.001114,3.448333],[-54.477501,4.747777],[-54.166946,5.346944],[-53.939728,5.744721],[-53.494339,5.572342]]]]}},{"type":"Feature","properties":{"name":"Finland","iso2":"FI","iso3":"FIN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[22.8336124420166,59.95638465881348],[23.072500228881836,59.95111274719238],[22.91750144958496,59.898332595825195],[22.8336124420166,59.95638465881348]]],[[[22.438886642456055,59.99582862854004],[22.351945877075195,60.06694221496582],[22.440553665161133,60.07249641418457],[22.438886642456055,59.99582862854004]]],[[[21.598054885864258,60.09805488586426],[21.48527717590332,60.1138858795166],[21.655553817749023,60.15555000305176],[21.598054885864258,60.09805488586426]]],[[[21.74888801574707,60.11138343811035],[21.71555519104004,60.183053970336914],[21.885278701782227,60.17721748352051],[21.74888801574707,60.11138343811035]]],[[[21.396665573120117,60.178606033325195],[21.385278701782227,60.15666389465332],[21.26833152770996,60.18805122375488],[21.396665573120117,60.178606033325195]]],[[[22.00083351135254,60.12944221496582],[21.937498092651367,60.170000076293945],[22.060834884643555,60.20388984680176],[22.00083351135254,60.12944221496582]]],[[[25.84861183166504,60.1955509185791],[25.810556411743164,60.20416450500488],[25.874998092651367,60.21110725402832],[25.84861183166504,60.1955509185791]]],[[[22.824445724487305,60.22722053527832],[22.469465255737305,60.00000190734863],[22.44972038269043,60.218332290649414],[22.587778091430664,60.20250129699707],[22.824445724487305,60.22722053527832]]],[[[22.242223739624023,60.181108474731445],[22.2177791595459,60.21860694885254],[22.294443130493164,60.248605728149414],[22.242223739624023,60.181108474731445]]],[[[22.342222213745117,60.28305244445801],[22.06888771057129,60.26861000061035],[22.09610939025879,60.30777931213379],[22.342222213745117,60.28305244445801]]],[[[22.383333206176758,60.28833198547363],[22.32527732849121,60.33471870422363],[22.476945877075195,60.32361030578613],[22.383333206176758,60.28833198547363]]],[[[21.982778549194336,60.324167251586914],[21.78999900817871,60.37249946594238],[21.8075008392334,60.46555519104004],[21.982778549194336,60.324167251586914]]],[[[21.751665115356445,60.49833106994629],[21.684446334838867,60.452775955200195],[21.73000144958496,60.520273208618164],[21.763334274291992,60.52250099182129],[21.751665115356445,60.49833106994629]]],[[[21.48333168029785,60.520273208618164],[21.4325008392334,60.4697208404541],[21.321943283081055,60.54305458068848],[21.48333168029785,60.520273208618164]]],[[[21.328889846801758,60.48111152648926],[21.275835037231445,60.47805213928223],[21.226945877075195,60.552499771118164],[21.328889846801758,60.48111152648926]]],[[[21.2902774810791,60.61222267150879],[21.289167404174805,60.56138801574707],[21.21416664123535,60.61972236633301],[21.2902774810791,60.61222267150879]]],[[[21.32750129699707,60.87722206115723],[21.254167556762695,60.95888710021973],[21.357221603393555,60.921945571899414],[21.32750129699707,60.87722206115723]]],[[[21.080278396606445,63.281389236450195],[21.427221298217773,63.19693946838379],[21.246946334838867,63.144723892211914],[21.080278396606445,63.281389236450195]]],[[[22.18083381652832,63.265275955200195],[22.040834426879883,63.30694007873535],[22.1924991607666,63.32193946838379],[22.18083381652832,63.265275955200195]]],[[[21.323331832885742,63.28916358947754],[21.231943130493164,63.3255558013916],[21.3811092376709,63.34111213684082],[21.323331832885742,63.28916358947754]]],[[[22.87360954284668,63.799997329711914],[22.671388626098633,63.794443130493164],[22.80611228942871,63.87693977355957],[22.87360954284668,63.799997329711914]]],[[[24.73499870300293,64.94444465637207],[24.551668167114258,65.02499580383301],[25.035001754760742,65.03610420227051],[24.73499870300293,64.94444465637207]]],[[[24.462221145629883,65.76388740539551],[24.43694496154785,65.76971626281738],[24.503053665161133,65.78055000305176],[24.462221145629883,65.76388740539551]]],[[[28.165834426879883,69.91221809387207],[29.176111221313477,69.6352710723877],[28.78416633605957,69.16055488586426],[28.95734214782715,69.05162239074707],[28.431943893432617,68.89694404602051],[28.820554733276367,68.84443855285645],[28.45749855041504,68.53193855285645],[28.693334579467773,68.19749641418457],[30.02861213684082,67.6947193145752],[29.07499885559082,66.89583015441895],[30.134164810180664,65.71916389465332],[29.81888771057129,65.65332221984863],[29.636667251586914,64.92805671691895],[30.578054428100586,64.22137641906738],[29.99333381652832,63.743608474731445],[31.588930130004883,62.91441535949707],[27.807832717895508,60.546403884887695],[26.497220993041992,60.44693946838379],[26.65916633605957,60.64750099182129],[25.920000076293945,60.24166297912598],[22.90972328186035,59.80499458312988],[23.338335037231445,60.01999855041504],[22.87444496154785,60.14555549621582],[23.086942672729492,60.346940994262695],[23.05583381652832,60.35333442687988],[22.662778854370117,60.22222328186035],[22.57499885559082,60.21055030822754],[22.447221755981445,60.24444007873535],[22.63222312927246,60.39193916320801],[21.358610153198242,60.65361213684082],[21.668054580688477,61.546945571899414],[21.064722061157227,62.61222267150879],[21.68610954284668,63.02499580383301],[21.497777938842773,63.21000099182129],[22.337221145629883,63.27360725402832],[22.18805503845215,63.46305274963379],[23.31888771057129,63.89666175842285],[24.343332290649414,64.52360725402832],[24.54222297668457,64.80249214172363],[25.447221755981445,64.95471382141113],[25.310834884643555,65.51111030578613],[24.66916847229004,65.65471076965332],[24.689165115356445,65.89610481262207],[24.167009353637695,65.81402778625488],[23.661943435668945,66.31221199035645],[24.007776260375977,66.8005542755127],[23.571664810180664,67.15666389465332],[23.767778396606445,67.41610908508301],[23.43111228942871,67.46554756164551],[23.666112899780273,67.9416675567627],[21.809167861938477,68.57054328918457],[20.580930709838867,69.06030464172363],[21.320833206176758,69.32611274719238],[22.398332595825195,68.71110725402832],[23.976388931274414,68.83249092102051],[24.934919357299805,68.58081245422363],[25.761110305786133,68.98916816711426],[25.945833206176758,69.67332649230957],[26.44999885559082,69.92721748352051],[28.165834426879883,69.91221809387207]],[[25.677221298217773,60.234994888305664],[25.56110954284668,60.26583290100098],[25.598054885864258,60.207773208618164],[25.677221298217773,60.234994888305664]],[[23.705827713012695,59.92721748352051],[23.538328170776367,59.960275650024414],[23.3700008392334,59.911386489868164],[23.705827713012695,59.92721748352051]]]]}},{"type":"Feature","properties":{"name":"Fiji","iso2":"FJ","iso3":"FJI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-178.707764,-20.674442],[-178.737213,-20.666115],[-178.73056,-20.646114],[-178.707764,-20.674442]]],[[[-178.211426,-19.852505],[-178.209747,-19.826389],[-178.19809,-19.835838],[-178.211426,-19.852505]]],[[[-178.396698,-19.185001],[-178.425049,-19.177502],[-178.398621,-19.129169],[-178.396698,-19.185001]]],[[[179.779694,-19.195278],[179.740234,-19.188053],[179.773041,-19.123333],[179.779694,-19.195278]]],[[[-178.538605,-19.181946],[-178.596954,-19.155834],[-178.585846,-19.113613],[-178.538605,-19.181946]]],[[[178.498291,-18.989998],[177.95108,-19.13139],[178.306915,-18.935555],[178.498291,-18.989998]]],[[[-178.936707,-18.989445],[-178.967224,-18.978336],[-178.949432,-18.925835],[-178.936707,-18.989445]]],[[[-179.78363,-18.946388],[-179.868896,-19.005283],[-179.845001,-18.922504],[-179.78363,-18.946388]]],[[[178.528046,-18.910831],[178.4766240000002,-18.883057],[178.521637,-18.859722],[178.528046,-18.910831]]],[[[-178.498627,-18.674725],[-178.506683,-18.635281],[-178.473053,-18.650558],[-178.498627,-18.674725]]],[[[179.91275,-18.641945],[179.837463,-18.576389],[179.963867,-18.540558],[179.91275,-18.641945]]],[[[177.66330000000013,-18.590279],[177.6191099999999,-18.538334],[177.6307980000001,-18.491943],[177.66330000000013,-18.590279]]],[[[178.13272100000015,-18.4175],[178.109406,-18.407501],[178.13970900000012,-18.351944],[178.13272100000015,-18.4175]]],[[[-178.778351,-18.249725],[-178.828613,-18.190002],[-178.747528,-18.201389],[-178.778351,-18.249725]]],[[[179.351898,-18.121113],[179.245789,-18.036388],[179.266663,-17.936111],[179.351898,-18.121113]]],[[[-179.011719,-17.995277],[-179.068359,-17.932503],[-178.991119,-17.950832],[-179.011719,-17.995277]]],[[[-178.286987,-17.96611],[-178.347809,-17.894165],[-178.244476,-17.917778],[-178.286987,-17.96611]]],[[[179.421906,-17.848335],[179.392761,-17.786388],[179.42108199999987,-17.797222],[179.421906,-17.848335]]],[[[-179.292511,-17.783897],[-179.331146,-17.771954],[-179.319153,-17.727509],[-179.292511,-17.783897]]],[[[178.820251,-17.742775],[178.7477420000001,-17.719719],[178.791931,-17.621113],[178.820251,-17.742775]]],[[[-179.141998,-17.476952],[-179.178894,-17.433064],[-179.143341,-17.431114],[-179.141998,-17.476952]]],[[[178.280823,-17.403053],[178.67804,-18.078335],[177.299133,-18.078613],[177.510254,-17.509445],[178.280823,-17.403053]]],[[[177.112457,-17.314445],[177.10025,-17.271114],[177.1419369999999,-17.247776],[177.112457,-17.314445]]],[[[-179.128632,-17.283611],[-179.162811,-17.250835],[-179.121429,-17.258617],[-179.128632,-17.283611]]],[[[179.399414,-17.394444],[179.357178,-17.259445],[179.4330440000002,-17.242222],[179.399414,-17.394444]]],[[[-178.925293,-17.257225],[-178.98584,-17.318058],[-179.02005,-17.153053],[-178.925293,-17.257225]]],[[[177.263611,-17.123611],[177.177185,-17.163612],[177.281097,-17.051945],[177.263611,-17.123611]]],[[[178.333038,-16.835835],[178.282196,-16.833889],[178.277191,-16.789444],[178.333038,-16.835835]]],[[[179.947479,-17.002781],[179.882446,-16.964165],[180,-16.787395],[179.947479,-17.002781]]],[[[-179.993317,-16.955276],[-179.861633,-16.680321],[-179.821106,-16.781094],[-179.993317,-16.955276]]],[[[177.443024,-16.83778],[177.559967,-16.677498],[177.593018,-16.687778],[177.443024,-16.83778]]],[[[179.929413,-16.659164],[179.914154,-16.661945],[179.88443,-16.657501],[179.916656,-16.625832],[179.947754,-16.613056],[179.929413,-16.659164]]],[[[180,-16.537918],[179.9810790000001,-16.524445],[180,-16.494274],[180,-16.537918]]],[[[-179.976166,-16.535278],[-179.988617,-16.476952],[-179.896423,-16.43111],[-179.976166,-16.535278]]],[[[179.958008,-16.197498],[179.478577,-16.701111],[179.932465,-16.460831],[179.950256,-16.513058],[179.87133800000012,-16.665001],[179.951904,-16.741943],[179.9021910000001,-16.769447],[179.265808,-16.690556],[178.747192,-17.011948],[178.478851,-16.78167],[179.958008,-16.197498]]],[[[-179.968872,-16.16761],[-180,-16.154732],[-179.941132,-16.128345],[-179.968872,-16.16761]]],[[[177.119415,-12.514446],[177.026917,-12.507223],[177.11911000000018,-12.484722],[177.119415,-12.514446]]]]}},{"type":"Feature","properties":{"name":"Falkland Islands (Malvinas)","iso2":"FK","iso3":"FLK"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-59.691673,-52.242783],[-59.761116,-52.273613],[-59.753334,-52.170006],[-59.683891,-52.172783],[-59.691673,-52.242783]]],[[[-58.435005,-52.093895],[-58.53389,-52.024445],[-58.432503,-51.99028],[-58.435005,-52.093895]]],[[[-61.224449,-51.864723],[-61.313896,-51.824722],[-61.215004,-51.797226],[-61.224449,-51.864723]]],[[[-61.034447,-51.869446],[-60.867783,-51.903336],[-61.149445,-51.848892],[-60.940559,-51.800285],[-61.034447,-51.869446]]],[[[-61.195839,-51.699448],[-61.315834,-51.733612],[-61.305,-51.693062],[-61.195839,-51.699448]]],[[[-59.210556,-51.410561],[-60.368057,-52.159172],[-60.980835,-52.061951],[-60.180557,-51.758896],[-60.638335999999896,-51.722229],[-60.163612,-51.661392],[-60.642227,-51.3555599999999],[-60.132225,-51.494728],[-60.019447,-51.380005],[-59.210556,-51.410561]]],[[[-58.69667099999987,-51.33667],[-58.22695199999987,-51.654449],[-58.279449,-51.417503],[-57.911949,-51.376396],[-57.761673,-51.538338],[-58.142784,-51.553894],[-57.731392,-51.692223],[-58.940559,-51.801949],[-58.64695,-52.067223],[-59.289726,-52.004173],[-59.035278,-52.14389],[-59.449173,-52.140839],[-59.348061,-52.343056],[-59.718056,-52.121117],[-58.69667099999987,-51.33667]]],[[[-59.93556199999989,-51.350838],[-60.025284,-51.297783],[-59.906113,-51.303062],[-59.93556199999989,-51.350838]]],[[[-60.110557999999884,-51.405281],[-60.300285,-51.271393],[-60.068062,-51.307503],[-60.110557999999884,-51.405281]]],[[[-59.508339,-51.337502],[-59.81111099999987,-51.26973],[-59.479172,-51.264725],[-59.508339,-51.337502]]]]}},{"type":"Feature","properties":{"name":"Micronesia, Federated States of","iso2":"FM","iso3":"FSM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[153.674408,5.286943],[153.659973,5.291666],[153.711365,5.319721],[153.674408,5.286943]]],[[[163.007477,5.263055000000108],[162.904144,5.307221],[163.016388,5.378332],[163.007477,5.263055000000108]]],[[[143.063599,6.707222000000115],[143.054688,6.714722],[143.063599,6.719443],[143.063599,6.707222000000115]]],[[[149.320251,6.698332],[149.313293,6.702499],[149.324982,6.721944],[149.320251,6.698332]]],[[[157.94220000000016,6.71861],[157.93191500000015,6.721944],[157.95245400000013,6.734444],[157.94220000000016,6.71861]]],[[[157.973572,6.738332],[157.964142,6.74111],[157.99273700000018,6.751944000000108],[157.973572,6.738332]]],[[[158.29776,6.786110000000122],[158.120789,6.929721],[158.318848,6.930277],[158.29776,6.786110000000122]]],[[[158.253876,6.983333000000101],[158.241638,6.992777],[158.259979,7.000278],[158.253876,6.983333000000101]]],[[[151.860504,7.31861],[151.839966,7.370276],[151.866638,7.358610000000112],[151.860504,7.31861]]],[[[149.20163,7.363333],[149.194702,7.361388000000105],[149.203033,7.376388],[149.20163,7.363333]]],[[[149.191345,7.375554],[149.177765,7.382499],[149.188019,7.384444],[149.191345,7.375554]]],[[[143.920258,7.37972100000016],[143.911926,7.382499],[143.914154,7.391388],[143.920258,7.37972100000016]]],[[[151.6391600000002,7.326666000000102],[151.5672000000002,7.34111],[151.608307,7.395277000000121],[151.6391600000002,7.326666000000102]]],[[[151.911652,7.444999],[151.85495,7.423888],[151.866638,7.463888000000139],[151.911652,7.444999]]],[[[146.1932980000001,7.504167],[146.179688,7.510833],[146.187195,7.515555000000106],[146.1932980000001,7.504167]]],[[[149.67498800000013,8.575554],[149.6594240000002,8.590275],[149.688873,8.617496],[149.67498800000013,8.575554]]],[[[150.378021,8.617496],[150.373291,8.612776000000125],[150.366638,8.626387],[150.378021,8.617496]]],[[[150.130249,8.978331],[150.118286,8.976387],[150.128021,8.992496],[150.130249,8.978331]]],[[[138.209137,9.523888000000127],[138.060242,9.41527600000012],[138.133606,9.571943],[138.209137,9.523888000000127]]]]}},{"type":"Feature","properties":{"name":"French Polynesia","iso2":"PF","iso3":"PYF"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-143.482483,-27.914448],[-143.508911,-27.890839],[-143.483917,-27.900276],[-143.482483,-27.914448]]],[[[-144.307526,-27.642776],[-144.324738,-27.553333],[-144.285553,-27.577499],[-144.307526,-27.642776]]],[[[-147.689758,-23.881668],[-147.720306,-23.865276],[-147.648621,-23.853336],[-147.689758,-23.881668]]],[[[-149.483337,-23.401943],[-149.52533,-23.373894],[-149.457214,-23.361671],[-149.483337,-23.401943]]],[[[-135.051941,-23.163887],[-135.06308,-23.156113],[-135.031708,-23.143333],[-135.051941,-23.163887]]],[[[-134.985535,-23.139442],[-135.015564,-23.12167],[-134.941406,-23.085838],[-134.985535,-23.139442]]],[[[-152.860016,-22.656387],[-152.845551,-22.605003],[-152.826416,-22.634171],[-152.860016,-22.656387]]],[[[-151.36557,-22.518616],[-151.387817,-22.425835],[-151.350281,-22.464725],[-151.36557,-22.518616]]],[[[-138.714722,-22.271667],[-138.796661,-22.22028],[-138.743591,-22.204449],[-138.714722,-22.271667]]],[[[-140.609467,-21.71917],[-140.66864,-21.708332],[-140.666687,-21.655834],[-140.609467,-21.71917]]],[[[-144.956146,-19.923332],[-144.965027,-19.929169],[-144.958344,-19.895283],[-144.956146,-19.923332]]],[[[-150.648071,-17.662498],[-150.669464,-17.645283],[-150.645294,-17.642498],[-150.648071,-17.662498]]],[[[-149.211426,-17.733891],[-149.179199,-17.870834],[-149.632507,-17.549999],[-149.211426,-17.733891]]],[[[-149.848602,-17.573612],[-149.937256,-17.484165],[-149.786133,-17.46917],[-149.848602,-17.573612]]],[[[-149.532257,-16.974445],[-149.54306,-16.974998],[-149.544189,-16.964443],[-149.532257,-16.974445]]],[[[-149.572266,-16.969723],[-149.59198,-16.980003],[-149.586121,-16.956108],[-149.572266,-16.969723]]],[[[-150.998322,-16.824169],[-151.040039,-16.786118],[-150.994476,-16.762505],[-150.998322,-16.824169]]],[[[-151.40033,-16.888332],[-151.476654,-16.895283],[-151.475037,-16.740276],[-151.40033,-16.888332]]],[[[-151.03833,-16.769726],[-151.037537,-16.693054],[-151.007233,-16.74472],[-151.03833,-16.769726]]],[[[-151.458344,-16.673332],[-151.532257,-16.589443],[-151.441101,-16.599171],[-151.458344,-16.673332]]],[[[-151.748627,-16.534451],[-151.775879,-16.473331],[-151.742249,-16.490833],[-151.748627,-16.534451]]],[[[-146.335846,-16.164722],[-146.38446,-16.110279],[-146.334991,-16.113056],[-146.335846,-16.164722]]],[[[-148.23526,-15.848612],[-148.26532,-15.846947],[-148.28363,-15.800835],[-148.23526,-15.848612]]],[[[-144.621948,-15.74861],[-144.646393,-15.73889],[-144.633667,-15.708055],[-144.621948,-15.74861]]],[[[-138.656708,-10.549725],[-138.695587,-10.431112],[-138.618347,-10.465555],[-138.656708,-10.549725]]],[[[-139.107483,-9.978058],[-139.125824,-9.906113],[-139.047791,-9.914167],[-139.107483,-9.978058]]],[[[-138.9552609999999,-9.743055],[-138.809479,-9.744999],[-139.1725459999999,-9.780281],[-138.9552609999999,-9.743055]]],[[[-140.07724,-9.450556],[-140.147827,-9.380556],[-140.086121,-9.324724],[-140.07724,-9.450556]]],[[[-139.58252,-8.87361],[-139.504181,-8.917225],[-139.611969,-8.95639],[-139.58252,-8.87361]]],[[[-140.026428,-8.901112],[-140.189453,-8.954166],[-140.249756,-8.802778],[-140.026428,-8.901112]]],[[[-140.704712,-8.044168],[-140.709747,-7.965556],[-140.637817,-7.959446],[-140.704712,-8.044168]]],[[[-140.584991,-7.92389],[-140.60614,-7.913611],[-140.56308,-7.888333],[-140.584991,-7.92389]]]]}},{"type":"Feature","properties":{"name":"France","iso2":"FR","iso3":"FRA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[9.485832000000187,42.61527300000013],[9.49472,42.60360700000014],[9.457777,42.643326],[9.485832000000187,42.61527300000013]]],[[[9.44666500000011,42.678886],[9.553333000000123,42.1155550000001],[9.18083200000018,41.364716000000115],[8.78916500000011,41.558052],[8.575832,42.383606],[9.293888,42.675552],[9.353054000000128,43.003883],[9.44666500000011,42.678886]]],[[[-1.194445,45.8224950000001],[-1.401667,46.05055200000011],[-1.233056,45.964722],[-1.194445,45.8224950000001]]],[[[-1.260834,46.156387],[-1.553056,46.24499500000012],[-1.474445,46.255829],[-1.260834,46.156387]]],[[[-2.270832999999868,46.69332900000013],[-2.363889,46.698051],[-2.384999999999877,46.725555],[-2.270832999999868,46.69332900000013]]],[[[-2.196945,47.017220000000165],[-2.145,46.90583],[-2.284722,47.02055400000013],[-2.196945,47.017220000000165]]],[[[-3.066666999999882,47.306664],[-3.215834,47.302498000000114],[-3.258610999999888,47.376106],[-3.066666999999882,47.306664]]],[[[-5.055,48.454163],[-5.134723,48.458328],[-5.064723,48.48305500000011],[-5.055,48.454163]]],[[[-3.576667,48.803886],[-3.575556,48.812492],[-3.563334,48.808609],[-3.576667,48.803886]]],[[[2.541667000000103,51.09111],[4.165,50.283051],[4.149238,49.978371],[4.832503,50.16861],[4.873055000000107,49.797218],[5.80788,49.545044],[6.36217,49.459389],[8.226078,48.964417000000125],[7.578888,48.11972000000016],[7.588268,47.58448],[6.990555000000143,47.497215],[5.966666,46.209442],[6.791389000000152,46.434166],[7.038054,45.93193800000013],[6.798970000000168,45.78067],[7.127777,45.257774],[6.61976,45.110138],[7.031666000000115,44.831383000000116],[6.976388,44.284164],[7.662222,44.17083000000012],[7.528055,43.788605],[7.439293000000106,43.75752300000015],[7.416111,43.770554],[7.387777,43.748604],[7.391609,43.727547],[6.165277000000117,43.050552],[5.031388,43.556664],[3.964722,43.540833],[3.081388,43.069443],[3.177655000000158,42.436806],[1.723611,42.509438],[1.78172,42.569962],[1.445833,42.601944],[-0.562222,42.781387],[-1.780876999999862,43.359924],[-1.036110999999892,44.675278],[-1.250278,44.662498],[-1.083888999999886,45.564438],[-0.536667,44.89555400000013],[-0.776667,45.461105],[-1.240834,45.70166],[-1.067778,45.908882000000105],[-1.114635,46.316582],[-2.130834,46.838333000000105],[-1.984167,47.034439],[-2.170834,47.126663],[-2.134167,47.278053],[-1.728610999999887,47.210831],[-2.003334,47.31916000000011],[-2.289167,47.238884],[-2.540278,47.296661],[-2.361111,47.504166],[-2.698056,47.637215],[-3.106388999999865,47.472221],[-4.366389,47.80416100000012],[-4.726142,48.040581],[-4.186111,48.29999500000012],[-4.777779,48.509438],[-3.220834,48.8705520000001],[-2.685277999999869,48.501663],[-1.368889,48.643608],[-1.941667,49.723885],[-1.264167,49.684166],[-1.113889,49.365273],[0.424722,49.45166],[0.074167,49.526665],[1.461111,50.124161],[1.625000000000114,50.87777700000011],[2.541667000000103,51.09111]]]]}},{"type":"Feature","properties":{"name":"Gambia","iso2":"GM","iso3":"GMB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-16.73167,13.44972],[-16.200836,13.251665],[-16.162224,13.425278],[-15.295834,13.491665],[-16.14389,13.454166],[-16.394726,13.330555],[-16.56567,13.589998],[-15.070278,13.826387],[-13.798613,13.406387],[-14.351112,13.237778],[-15.111668,13.595833],[-15.285002,13.374443],[-15.803612,13.347776],[-15.809723,13.159721],[-16.750874,13.059977],[-16.73167,13.44972]]]]}},{"type":"Feature","properties":{"name":"Gabon","iso2":"GA","iso3":"GAB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[9.007776260375977,-0.767778396606445],[8.946664810180664,-0.658332824707031],[9.00666618347168,-0.598888397216797],[9.007776260375977,-0.767778396606445]]],[[[12.523611068725586,2.283334732055664],[13.293889999389648,2.163610458374023],[13.186784744262695,1.222475051879883],[14.18889045715332,1.391389846801758],[14.487222671508789,0.913610458374023],[13.848333358764648,-0.198610305786133],[14.518610000610352,-0.609167098999023],[14.429723739624023,-1.891666412353516],[14.110834121704102,-2.49305534362793],[13.76222038269043,-2.088888168334961],[13.482778549194336,-2.4375],[13.001508712768555,-2.367671966552734],[12.649999618530273,-1.822500228881836],[12.478055953979492,-2.327220916748047],[11.574167251586914,-2.333332061767578],[11.925832748413086,-3.636943817138672],[11.496946334838867,-3.50694465637207],[11.140661239624023,-3.925275802612305],[9.700834274291992,-2.445554733276367],[10.130556106567383,-2.520000457763672],[9.615278244018555,-2.376667022705078],[8.983057022094727,-1.234167098999023],[9.513887405395508,-1.59666633605957],[8.710000991821289,-0.641111373901367],[9.013887405395508,-0.81916618347168],[9.298334121704102,-0.371665954589844],[9.347501754760742,0.363058090209961],[9.921110153198242,0.185277938842773],[9.303609848022461,0.52833366394043],[9.600000381469727,0.481111526489258],[9.564722061157227,0.983057022094727],[9.803976058959961,1.002607345581055],[11.353887557983398,1.001943588256836],[11.339765548706055,2.168611526489258],[12.523611068725586,2.283334732055664]],[[9.554445266723633,0.274446487426758],[9.544443130493164,0.285001754760742],[9.538057327270508,0.270833969116211],[9.554445266723633,0.274446487426758]]]]}},{"type":"Feature","properties":{"name":"Georgia","iso2":"GE","iso3":"GEO"},"geometry":{"type":"MultiPolygon","coordinates":[[[[41.547623,42.405777],[41.428596,42.738045],[40.002968,43.379265],[40.253387,43.582520000000116],[42.849991,43.17915300000011],[43.911934000000116,42.583321],[44.934708,42.76027700000013],[46.451752,41.897057],[46.194427000000104,41.6858220000001],[46.693871,41.312202],[46.520821,41.049988],[45.336655,41.462494],[45.022942,41.29705000000014],[43.46077,41.112961],[42.827492,41.584991],[41.531559,41.523876],[41.776093,41.841927],[41.547623,42.405777]]]]}},{"type":"Feature","properties":{"name":"Ghana","iso2":"GH","iso3":"GHA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[0.63953,5.845486],[0.662222,5.754167],[0.255833,5.757777],[-0.795556,5.208055],[-1.613333,5.020833],[-2.058889,4.730833],[-3.103041,5.085022],[-3.102272,5.109545000000125],[-2.928128,5.100222],[-2.764445,5.579166],[-3.249166999999886,6.611388],[-2.487778,8.197777000000116],[-2.685561,9.481817],[-2.834048,11.002007],[-0.618333,10.911665],[-0.149762,11.13854],[0.368333,10.259443],[0.2175,9.457222],[0.550833,9.411388],[0.382735,8.760756],[0.727222,8.321388],[0.525,6.947778],[1.198891,6.100546],[0.692222,5.748055],[0.634444,5.948055],[0.51209,6.055245],[0.208197,6.089699],[0.488889,6.043611],[0.63953,5.845486]]]]}},{"type":"Feature","properties":{"name":"Grenada","iso2":"GD","iso3":"GRD"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-61.74694799999986,11.997499],[-61.611946,12.23111],[-61.628616,12.048054],[-61.74694799999986,11.997499]]],[[[-61.580002,12.295555],[-61.589172,12.298054],[-61.578896,12.323055],[-61.580002,12.295555]]],[[[-61.428337,12.453609],[-61.496948,12.443609],[-61.434448,12.529165],[-61.428337,12.453609]]]]}},{"type":"Feature","properties":{"name":"Greenland","iso2":"GL","iso3":"GRL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-43.64805603027344,59.847490310668945],[-44.11555480957031,59.82916450500488],[-43.95805358886719,59.97971534729004],[-43.64805603027344,59.847490310668945]]],[[[-43.295005798339844,59.92083168029785],[-43.327781677246094,59.99721717834473],[-43.20417022705078,59.96832466125488],[-43.295005798339844,59.92083168029785]]],[[[-44.31388854980469,59.87193489074707],[-44.244163513183594,60.011667251586914],[-43.992225646972656,60.00833320617676],[-44.31388854980469,59.87193489074707]]],[[[-43.399993896484375,59.926103591918945],[-43.50917053222656,59.912492752075195],[-43.453330993652344,60.03804969787598],[-43.399993896484375,59.926103591918945]]],[[[-43.35417175292969,60.08443641662598],[-43.13111114501953,60.05526924133301],[-44.132774353027344,60.14083290100098],[-43.35417175292969,60.08443641662598]]],[[[-44.40943908691406,59.947771072387695],[-44.49749755859375,60.00860786437988],[-44.43444061279297,60.14138221740723],[-44.20166778564453,60.04610633850098],[-44.40943908691406,59.947771072387695]]],[[[-45.23249816894531,60.143327713012695],[-45.29999542236328,60.145830154418945],[-45.26611328125,60.1874942779541],[-45.23249816894531,60.143327713012695]]],[[[-45.36500358581543,60.18526649475098],[-45.35388946533203,60.38249397277832],[-45.1522216796875,60.37638282775879],[-45.36500358581543,60.18526649475098]]],[[[-45.95471954345703,60.615549087524414],[-45.9969482421875,60.626657485961914],[-45.98277282714844,60.67276954650879],[-45.961387634277344,60.68387794494629],[-45.78333282470703,60.66082191467285],[-45.95471954345703,60.615549087524414]]],[[[-45.88861083984375,60.69582557678223],[-45.98520278930664,60.69222831726074],[-46.091941833496094,60.63555335998535],[-46.20471954345703,60.67276954650879],[-46.00695037841797,60.70638465881348],[-45.88861083984375,60.69582557678223]]],[[[-46.345550537109375,60.66805458068848],[-46.49944305419922,60.69915962219238],[-46.2772216796875,60.77221870422363],[-46.345550537109375,60.66805458068848]]],[[[-47.754173278808594,60.80471229553223],[-47.90277862548828,60.6763858795166],[-48.2388916015625,60.795549392700195],[-47.754173278808594,60.80471229553223]]],[[[-46.98027801513672,60.77276802062988],[-47.04944610595703,60.80526924133301],[-47.01111602783203,60.80804634094238],[-46.98027801513672,60.77276802062988]]],[[[-47.16138458251953,60.798051834106445],[-47.22694396972656,60.81805610656738],[-47.15277862548828,60.816667556762695],[-47.16138458251953,60.798051834106445]]],[[[-47.23138427734375,60.841936111450195],[-47.25861358642578,60.8558292388916],[-47.17833709716797,60.87193489074707],[-47.23138427734375,60.841936111450195]]],[[[-47.10194396972656,60.822771072387695],[-47.19249725341797,60.835824966430664],[-47.08361053466797,60.874711990356445],[-47.10194396972656,60.822771072387695]]],[[[-46.75361633300781,60.75027656555176],[-46.845001220703125,60.76055335998535],[-46.16444396972656,60.922494888305664],[-46.75361633300781,60.75027656555176]]],[[[-47.029441833496094,60.89721870422363],[-47.05027770996094,60.895273208618164],[-46.95805358886719,60.925554275512695],[-47.029441833496094,60.89721870422363]]],[[[-47.140838623046875,60.879159927368164],[-47.171669006347656,60.88360786437988],[-47.073333740234375,60.92666053771973],[-47.140838623046875,60.879159927368164]]],[[[-46.466392517089844,60.92222023010254],[-46.51416778564453,60.930551528930664],[-46.52666473388672,60.9888858795166],[-46.51860809326172,60.993608474731445],[-46.429443359375,60.9758243560791],[-46.466392517089844,60.92222023010254]]],[[[-48.07361602783203,61.05388069152832],[-48.37055206298828,61.0786075592041],[-48.24333190917969,61.09860420227051],[-48.07361602783203,61.05388069152832]]],[[[-48.93444061279297,61.249162673950195],[-48.874168395996094,61.3013858795166],[-48.72416687011719,61.29138374328613],[-48.93444061279297,61.249162673950195]]],[[[-48.58332824707031,61.31276893615723],[-48.83306121826172,61.33499336242676],[-48.52333068847656,61.36110877990723],[-48.58332824707031,61.31276893615723]]],[[[-42.45305633544922,61.44137763977051],[-42.496665954589844,61.45499610900879],[-42.38972473144531,61.4888858795166],[-42.45305633544922,61.44137763977051]]],[[[-49.0897216796875,61.63333320617676],[-49.19444274902344,61.66221046447754],[-49.149444580078125,61.70054817199707],[-49.0897216796875,61.63333320617676]]],[[[-49.39222717285156,61.70694160461426],[-49.48527526855469,61.75139045715332],[-49.349998474121094,61.743051528930664],[-49.39222717285156,61.70694160461426]]],[[[-42.2691650390625,61.75027656555176],[-42.084442138671875,61.8749942779541],[-42.12110900878906,61.77276802062988],[-42.2691650390625,61.75027656555176]]],[[[-49.4405517578125,61.874711990356445],[-49.63417053222656,61.93082618713379],[-49.41944885253906,61.930551528930664],[-49.4405517578125,61.874711990356445]]],[[[-49.663330078125,62.18027687072754],[-49.79833984375,62.213884353637695],[-49.65027618408203,62.23777198791504],[-49.663330078125,62.18027687072754]]],[[[-42.2772216796875,62.577219009399414],[-42.13111114501953,62.564714431762695],[-42.12555694580078,62.49638557434082],[-42.2772216796875,62.577219009399414]]],[[[-41.99610900878906,62.77499580383301],[-41.86194610595703,62.73472023010254],[-42.447776794433594,62.75139045715332],[-41.99610900878906,62.77499580383301]]],[[[-41.56138610839844,62.873605728149414],[-41.58860778808594,63.00249671936035],[-41.458335876464844,63.01638984680176],[-41.56138610839844,62.873605728149414]]],[[[-50.63666534423828,63.07388496398926],[-50.67028045654297,63.02527046203613],[-50.7550048828125,63.06193733215332],[-50.63666534423828,63.07388496398926]]],[[[-41.333885192871094,63.05027198791504],[-41.526390075683594,63.08138465881348],[-41.373329162597656,63.109994888305664],[-41.333885192871094,63.05027198791504]]],[[[-41.209442138671875,63.15777015686035],[-41.18444061279297,63.12276649475098],[-41.466392517089844,63.1713809967041],[-41.209442138671875,63.15777015686035]]],[[[-50.79972839355469,63.08166694641113],[-50.788055419921875,63.186655044555664],[-50.682777404785156,63.11666297912598],[-50.79972839355469,63.08166694641113]]],[[[-50.61805725097656,63.11471748352051],[-50.612220764160156,63.20166206359863],[-50.468605041503906,63.15332221984863],[-50.61805725097656,63.11471748352051]]],[[[-41.09583282470703,63.22110176086426],[-41.43083190917969,63.23137855529785],[-41.87194061279297,63.46666145324707],[-41.09583282470703,63.22110176086426]]],[[[-51.27361297607422,63.476938247680664],[-51.358055114746094,63.48333168029785],[-51.20471954345703,63.499162673950195],[-51.27361297607422,63.476938247680664]]],[[[-52.00083923339844,64.12776374816895],[-52.06361389160156,64.16388130187988],[-51.90583038330078,64.18887519836426],[-52.00083923339844,64.12776374816895]]],[[[-40.674171447753906,64.29136848449707],[-40.679443359375,64.20860481262207],[-41.05278015136719,64.23275947570801],[-40.674171447753906,64.29136848449707]]],[[[-41.12555694580078,64.28831672668457],[-41.374168395996094,64.28499031066895],[-41.29695129394531,64.31721687316895],[-41.12555694580078,64.28831672668457]]],[[[-51.567222595214844,64.25610542297363],[-51.439720153808594,64.36248970031738],[-51.321388244628906,64.32638740539551],[-51.567222595214844,64.25610542297363]]],[[[-51.239723205566406,64.21470832824707],[-51.341941833496094,64.25332832336426],[-51.025001525878906,64.54942512512207],[-50.81916809082031,64.54165840148926],[-51.239723205566406,64.21470832824707]]],[[[-51.32361602783203,64.37359809875488],[-51.42138671875,64.41331672668457],[-51.091941833496094,64.5666675567627],[-51.32361602783203,64.37359809875488]]],[[[-52.08306121826172,64.59137153625488],[-52.141944885253906,64.59776496887207],[-52.149169921875,64.62719917297363],[-52.1199951171875,64.62915229797363],[-52.08306121826172,64.59137153625488]]],[[[-40.18000030517578,64.43109321594238],[-40.864723205566406,64.90860176086426],[-40.54277801513672,64.84414863586426],[-40.18000030517578,64.43109321594238]]],[[[-40.49583435058594,65.0152759552002],[-40.625274658203125,65.0385913848877],[-40.55638885498047,65.07388496398926],[-40.49583435058594,65.0152759552002]]],[[[-52.39666557312012,65.10942268371582],[-52.36138916015625,65.18692207336426],[-52.24500274658203,65.1816577911377],[-52.39666557312012,65.10942268371582]]],[[[-39.49444580078125,65.31999397277832],[-39.564443588256836,65.26582527160645],[-39.804443359375,65.3338794708252],[-39.49444580078125,65.31999397277832]]],[[[-39.27777862548828,65.46138191223145],[-39.38694763183594,65.50193977355957],[-39.2388916015625,65.50860786437988],[-39.27777862548828,65.46138191223145]]],[[[-52.92833709716797,65.42526435852051],[-53.08777618408203,65.49247932434082],[-52.87194061279297,65.51361274719238],[-52.92833709716797,65.42526435852051]]],[[[-38.84916687011719,65.51860237121582],[-38.95861053466797,65.51776313781738],[-38.76111602783203,65.54165840148926],[-38.84916687011719,65.51860237121582]]],[[[-37.037506103515625,65.53276252746582],[-37.19153594970703,65.53262519836426],[-37.21333312988281,65.57805061340332],[-37.037506103515625,65.53276252746582]]],[[[-52.99500274658203,65.54887580871582],[-53.23249816894531,65.59832954406738],[-52.848052978515625,65.64415168762207],[-52.99500274658203,65.54887580871582]]],[[[-36.99555206298828,65.58442878723145],[-37.212501525878906,65.68441963195801],[-36.992225646972656,65.70109748840332],[-36.99555206298828,65.58442878723145]]],[[[-37.3941650390625,65.81360054016113],[-37.48500061035156,65.60721015930176],[-37.989166259765625,65.69832038879395],[-37.3941650390625,65.81360054016113]]],[[[-36.79833984375,65.75055122375488],[-36.942771911621094,65.8197193145752],[-36.776947021484375,65.86387825012207],[-36.79833984375,65.75055122375488]]],[[[-36.319725036621094,65.82193183898926],[-36.37110900878906,65.87747383117676],[-36.18305969238281,65.87803840637207],[-36.319725036621094,65.82193183898926]]],[[[-36.6199951171875,65.79525947570801],[-36.736663818359375,65.8016529083252],[-36.74833679199219,65.90971565246582],[-36.507225036621094,65.95694160461426],[-36.6199951171875,65.79525947570801]]],[[[-53.52527618408203,66.04248237609863],[-53.679725646972656,66.08194160461426],[-53.423057556152344,66.08442878723145],[-53.52527618408203,66.04248237609863]]],[[[-35.499725341796875,66.17415046691895],[-35.537506103515625,66.22554206848145],[-35.38500213623047,66.24081611633301],[-35.499725341796875,66.17415046691895]]],[[[-33.86194610595703,66.79387092590332],[-33.970550537109375,66.83970832824707],[-33.88444519042969,66.87248420715332],[-33.86194610595703,66.79387092590332]]],[[[-53.070838928222656,66.86609077453613],[-52.86823272705078,66.89721870422363],[-53.46416473388672,66.79887580871582],[-53.070838928222656,66.86609077453613]]],[[[-33.431114196777344,67.14221382141113],[-33.476104736328125,67.18054389953613],[-33.34222412109375,67.20471382141113],[-33.431114196777344,67.14221382141113]]],[[[-33.252227783203125,67.29525947570801],[-33.327781677246094,67.33610725402832],[-33.25695037841797,67.37608528137207],[-33.252227783203125,67.29525947570801]]],[[[-53.65888977050781,67.67581367492676],[-53.7630615234375,67.77693367004395],[-53.58777618408203,67.73359870910645],[-53.65888977050781,67.67581367492676]]],[[[-53.34722137451172,68.00999641418457],[-53.473052978515625,68.06915473937988],[-53.22527313232422,68.05859565734863],[-53.34722137451172,68.00999641418457]]],[[[-51.2933349609375,68.10081672668457],[-52.00750732421875,68.07666206359863],[-51.20527458190918,68.12164497375488],[-51.2933349609375,68.10081672668457]]],[[[-29.838054656982422,68.14082527160645],[-30.011669158935547,68.20749092102051],[-29.694721221923828,68.20860481262207],[-29.838054656982422,68.14082527160645]]],[[[-52.070838928222656,68.11526679992676],[-52.315834045410156,68.16887092590332],[-51.45417022705078,68.25776863098145],[-52.070838928222656,68.11526679992676]]],[[[-52.9888916015625,68.35775947570801],[-53.211944580078125,68.4013843536377],[-53.01972198486328,68.49443244934082],[-52.85417175292969,68.43332099914551],[-52.9888916015625,68.35775947570801]]],[[[-52.64167022705078,68.52998542785645],[-52.69471740722656,68.54609870910645],[-52.43943786621094,68.5608081817627],[-52.64167022705078,68.52998542785645]]],[[[-52.749725341796875,68.48471260070801],[-52.88417053222656,68.54887580871582],[-52.80944061279297,68.56860542297363],[-52.749725341796875,68.48471260070801]]],[[[-51.94194030761719,68.59443855285645],[-52.42138671875,68.57138252258301],[-51.80332946777344,68.62719917297363],[-51.94194030761719,68.59443855285645]]],[[[-51.0352783203125,68.63943672180176],[-51.23277282714844,68.66665840148926],[-51.12944030761719,68.6827564239502],[-51.0352783203125,68.63943672180176]]],[[[-52.13472557067871,68.70109748840332],[-53.12055206298828,68.56414985656738],[-52.63417053222656,68.71026802062988],[-52.13472557067871,68.70109748840332]]],[[[-23.286666870117188,69.64109992980957],[-23.593055725097656,69.71304512023926],[-23.289443969726562,69.73831367492676],[-23.286666870117188,69.64109992980957]]],[[[-50.505279541015625,69.81053352355957],[-50.60639190673828,69.85637092590332],[-50.40972137451172,69.8611011505127],[-50.505279541015625,69.81053352355957]]],[[[-50.92333221435547,69.89276313781738],[-50.65388488769531,69.83665657043457],[-50.958335876464844,69.55053901672363],[-51.38805389404297,69.70526313781738],[-50.92333221435547,69.89276313781738]]],[[[-52.69305419921875,69.91748237609863],[-51.83332824707031,69.62608528137207],[-53.57472229003906,69.22943305969238],[-54.2691650390625,69.40220832824707],[-53.347496032714844,69.57971382141113],[-54.99444580078125,69.69470405578613],[-54.389442443847656,69.67526435852051],[-54.93611145019531,69.84553718566895],[-54.22943878173828,69.91304206848145],[-54.82972717285156,70.07832527160645],[-54.429168701171875,70.3097095489502],[-52.69305419921875,69.91748237609863]]],[[[-54.66138458251953,70.37248420715332],[-54.934722900390625,70.37553596496582],[-55.02777862548828,70.4830493927002],[-54.66138458251953,70.37248420715332]]],[[[-51.512779235839844,70.65387153625488],[-51.861671447753906,70.72221565246582],[-51.69249725341797,70.72776985168457],[-51.512779235839844,70.65387153625488]]],[[[-27.68527603149414,70.73387336730957],[-27.736942291259766,70.88220405578613],[-27.276111602783203,70.87498664855957],[-27.68527603149414,70.73387336730957]]],[[[-25.39472198486328,70.91165351867676],[-25.294445037841797,70.65971565246582],[-26.02972412109375,70.52110481262207],[-28.13666534423828,70.45471382141113],[-27.14958953857422,70.87439155578613],[-25.39472198486328,70.91165351867676]]],[[[-51.565834045410156,70.86470222473145],[-52.16221618652344,70.88665962219238],[-52.02305603027344,70.97915840148926],[-51.565834045410156,70.86470222473145]]],[[[-25.30889129638672,71.01443672180176],[-25.579166412353516,71.10220527648926],[-25.460556030273438,71.10415840148926],[-25.30889129638672,71.01443672180176]]],[[[-25.282501220703125,71.13192939758301],[-25.472774505615234,71.15054512023926],[-25.359722137451172,71.20526313781738],[-25.282501220703125,71.13192939758301]]],[[[-53.649169921875,71.02415657043457],[-53.99028015136719,71.1313648223877],[-53.598052978515625,71.31331062316895],[-53.37638854980469,71.11499214172363],[-53.649169921875,71.02415657043457]]],[[[-52.571388244628906,71.34610176086426],[-52.328338623046875,71.28776741027832],[-53.18444061279297,71.32138252258301],[-52.571388244628906,71.34610176086426]]],[[[-53.13361358642578,71.66192817687988],[-52.75611114501953,71.66026496887207],[-53.47444152832031,71.6524829864502],[-53.13361358642578,71.66192817687988]]],[[[-55.559165954589844,71.81915473937988],[-55.80555725097656,71.87886238098145],[-55.409996032714844,71.8902759552002],[-55.559165954589844,71.81915473937988]]],[[[-55.796112060546875,72.07054328918457],[-55.93860626220703,72.07943916320801],[-55.72527313232422,72.12608528137207],[-55.796112060546875,72.07054328918457]]],[[[-55.374168395996094,72.15971565246582],[-55.68888854980469,72.19859504699707],[-55.015281677246094,72.37719917297363],[-55.374168395996094,72.15971565246582]]],[[[-55.06500244140625,72.52527046203613],[-55.383331298828125,72.54525947570801],[-55.030555725097656,72.5888843536377],[-55.06500244140625,72.52527046203613]]],[[[-55.65027618408203,72.58249092102051],[-55.994720458984375,72.55748176574707],[-55.94305419921875,72.59359931945801],[-55.65027618408203,72.58249092102051]]],[[[-55.13194274902344,72.60081672668457],[-55.26222229003906,72.59776496887207],[-54.94666290283203,72.67221260070801],[-55.13194274902344,72.60081672668457]]],[[[-54.83250427246094,72.69552803039551],[-55.0625,72.71832466125488],[-54.87249755859375,72.75694465637207],[-54.83250427246094,72.69552803039551]]],[[[-55.70417022705078,72.71499824523926],[-56.226104736328125,72.70610237121582],[-55.639442443847656,72.77777290344238],[-55.70417022705078,72.71499824523926]]],[[[-55.285560607910156,72.68109321594238],[-55.84944152832031,72.61137580871582],[-54.9647216796875,72.81137275695801],[-55.285560607910156,72.68109321594238]]],[[[-55.94666290283203,72.82361030578613],[-55.801666259765625,72.79248237609863],[-55.992225646972656,72.78665351867676],[-55.94666290283203,72.82361030578613]]],[[[-23.608612060546875,72.83499336242676],[-21.932498931884766,72.39915657043457],[-22.756946563720703,72.44136238098145],[-22.134166717529297,72.27165412902832],[-22.56277847290039,72.13888740539551],[-24.48444366455078,72.8258228302002],[-23.608612060546875,72.83499336242676]]],[[[-55.586387634277344,72.8902759552002],[-55.352500915527344,72.85220527648926],[-55.53666687011719,72.82249641418457],[-55.586387634277344,72.8902759552002]]],[[[-24.896665573120117,72.77777290344238],[-25.210830688476562,72.85165596008301],[-24.77138900756836,72.91081428527832],[-24.896665573120117,72.77777290344238]]],[[[-22.54916763305664,73.0072193145752],[-21.865833282470703,72.7138843536377],[-24.588890075683594,72.95749092102051],[-22.54916763305664,73.0072193145752]]],[[[-55.753334045410156,73.01138496398926],[-55.88972473144531,73.02581977844238],[-55.693885803222656,73.03221321105957],[-55.753334045410156,73.01138496398926]]],[[[-55.0755615234375,72.96554756164551],[-55.68916320800781,72.99359321594238],[-55.51860809326172,73.04582405090332],[-55.0755615234375,72.96554756164551]]],[[[-21.35333251953125,73.09137153625488],[-21.46277618408203,73.11859321594238],[-21.173053741455078,73.13443183898926],[-21.35333251953125,73.09137153625488]]],[[[-56.201942443847656,73.15555000305176],[-56.33167266845703,73.17221260070801],[-56.27333068847656,73.21887397766113],[-56.201942443847656,73.15555000305176]]],[[[-56.0977783203125,73.08638191223145],[-56.01721954345703,73.22859382629395],[-55.8155517578125,73.22470283508301],[-56.0977783203125,73.08638191223145]]],[[[-55.68638610839844,73.28276252746582],[-55.871665954589844,73.3277759552002],[-55.65416717529297,73.35637092590332],[-55.68638610839844,73.28276252746582]]],[[[-55.953887939453125,73.29915046691895],[-56.15332794189453,73.30415534973145],[-55.830833435058594,73.3733081817627],[-55.953887939453125,73.29915046691895]]],[[[-55.53166961669922,73.31805610656738],[-55.59388732910156,73.34414863586426],[-55.328338623046875,73.39499092102051],[-55.53166961669922,73.31805610656738]]],[[[-24.360000610351562,73.41192817687988],[-23.209999084472656,73.23359870910645],[-25.01028060913086,73.30941963195801],[-22.938610076904297,73.13472175598145],[-25.71277618408203,73.18637275695801],[-25.290836334228516,73.3277759552002],[-25.243053436279297,73.40582466125488],[-24.360000610351562,73.41192817687988]]],[[[-55.5897216796875,73.38109016418457],[-56.11583709716797,73.55664253234863],[-55.47083282470703,73.43193244934082],[-55.5897216796875,73.38109016418457]]],[[[-56.4102783203125,73.54193305969238],[-56.55860900878906,73.55636787414551],[-56.18860626220703,73.62747383117676],[-56.4102783203125,73.54193305969238]]],[[[-56.34416198730469,73.67248725891113],[-56.83332824707031,73.61137580871582],[-56.965553283691406,73.65803718566895],[-56.34416198730469,73.67248725891113]]],[[[-56.36860656738281,73.76609992980957],[-56.20555877685547,73.71832466125488],[-56.43694305419922,73.76805305480957],[-56.36860656738281,73.76609992980957]]],[[[-55.9566650390625,73.83471870422363],[-56.323333740234375,73.78332710266113],[-56.7772216796875,73.87581062316895],[-55.9566650390625,73.83471870422363]]],[[[-20.01611328125,73.88443183898926],[-20.234722137451172,73.92637825012207],[-20.11361312866211,73.9327564239502],[-20.01611328125,73.88443183898926]]],[[[-20.926944732666016,74.41998481750488],[-20.123889923095703,74.20109748840332],[-21.990833282470703,74.22720527648926],[-20.926944732666016,74.41998481750488]]],[[[-56.53083038330078,74.53055000305176],[-56.46277618408203,74.5041675567627],[-57.556663513183594,74.48831367492676],[-56.53083038330078,74.53055000305176]]],[[[-56.98277282714844,74.55359077453613],[-57.095550537109375,74.55748176574707],[-56.83860778808594,74.59166145324707],[-56.98277282714844,74.55359077453613]]],[[[-57.185272216796875,74.57609748840332],[-57.281944274902344,74.58166694641113],[-57.08306121826172,74.61303901672363],[-57.185272216796875,74.57609748840332]]],[[[-18.838611602783203,74.53831672668457],[-19.21999740600586,74.58110237121582],[-18.75278091430664,74.65609931945801],[-18.838611602783203,74.53831672668457]]],[[[-18.53000259399414,74.71220588684082],[-18.300556182861328,74.70526313781738],[-18.383056640625,74.6202564239502],[-18.53000259399414,74.71220588684082]]],[[[-57.47638702392578,74.70610237121582],[-57.72721862792969,74.72192573547363],[-57.431114196777344,74.71748542785645],[-57.47638702392578,74.70610237121582]]],[[[-20.166942596435547,74.89749336242676],[-19.729164123535156,74.85859870910645],[-20.08444595336914,74.7027759552002],[-20.68777847290039,74.81164741516113],[-20.493053436279297,75.03082466125488],[-19.960556030273438,74.99247932434082],[-20.166942596435547,74.89749336242676]]],[[[-17.808334350585938,75.30609321594238],[-18.215274810791016,75.22526741027832],[-17.319721221923828,75.13109016418457],[-18.91555404663086,75.0041675567627],[-18.839168548583984,75.32832527160645],[-17.808334350585938,75.30609321594238]]],[[[-65.0494384765625,76.01388740539551],[-65.22111511230469,76.04553413391113],[-64.95556640625,76.05497932434082],[-65.0494384765625,76.01388740539551]]],[[[-64.05555725097656,76.05941963195801],[-64.1461181640625,76.09305000305176],[-64.01472473144531,76.11053657531738],[-64.05555725097656,76.05941963195801]]],[[[-61.899444580078125,76.12970161437988],[-61.96221923828125,76.17859077453613],[-61.88166809082031,76.18664741516113],[-61.899444580078125,76.12970161437988]]],[[[-20.343055725097656,76.26416206359863],[-20.660831451416016,76.3388843536377],[-20.158611297607422,76.3469409942627],[-20.343055725097656,76.26416206359863]]],[[[-69.97610473632812,76.39415168762207],[-70.18832397460938,76.43914985656738],[-69.89445495605469,76.43692207336426],[-69.97610473632812,76.39415168762207]]],[[[-20.38805389404297,76.45166206359863],[-20.496109008789062,76.4749927520752],[-20.267780303955078,76.4952564239502],[-20.38805389404297,76.45166206359863]]],[[[-21.35305404663086,76.47249031066895],[-21.48971939086914,76.48970222473145],[-21.24944305419922,76.49971199035645],[-21.35305404663086,76.47249031066895]]],[[[-20.7933349609375,76.38998603820801],[-21.141109466552734,76.44748115539551],[-20.72083282470703,76.51388740539551],[-20.7933349609375,76.38998603820801]]],[[[-69.66944885253906,76.53055000305176],[-70.03639221191406,76.56331062316895],[-69.4647216796875,76.57943916320801],[-69.66944885253906,76.53055000305176]]],[[[-20.71277618408203,76.5608081817627],[-20.939441680908203,76.52331733703613],[-20.62555694580078,76.57943916320801],[-20.71277618408203,76.5608081817627]]],[[[-21.083057403564453,76.56915473937988],[-21.547500610351562,76.61526679992676],[-20.963886260986328,76.62915229797363],[-21.083057403564453,76.56915473937988]]],[[[-19.648056030273438,76.69832038879395],[-19.857223510742188,76.73193550109863],[-19.605554580688477,76.72638130187988],[-19.648056030273438,76.69832038879395]]],[[[-18.653053283691406,76.60165596008301],[-18.635276794433594,75.88998603820801],[-19.141944885253906,76.5294361114502],[-18.763057708740234,76.58777046203613],[-19.019168853759766,76.75943183898926],[-18.653053283691406,76.60165596008301]]],[[[-19.691944122314453,76.78193855285645],[-19.809165954589844,76.7885913848877],[-19.59000015258789,76.81164741516113],[-19.691944122314453,76.78193855285645]]],[[[-20.19277572631836,76.82249641418457],[-20.389442443847656,76.84721565246582],[-20.210556030273438,76.86859321594238],[-20.19277572631836,76.82249641418457]]],[[[-71.94221496582031,77.30443000793457],[-72.57389831542969,77.41388130187988],[-71.34584045410156,77.37581062316895],[-71.94221496582031,77.30443000793457]]],[[[-70.66777038574219,77.45776557922363],[-70.05638122558594,77.39915657043457],[-71.2994384765625,77.44775581359863],[-70.66777038574219,77.45776557922363]]],[[[-66.19638061523438,77.50444221496582],[-66.66082763671875,77.48858833312988],[-66.73138427734375,77.5072193145752],[-66.19638061523438,77.50444221496582]]],[[[-19.83444595336914,77.50555610656738],[-20.041667938232422,77.5658130645752],[-19.830280303955078,77.5547046661377],[-19.83444595336914,77.50555610656738]]],[[[-66.90055847167969,77.59166145324707],[-66.97084045410156,77.59942817687988],[-66.62582397460938,77.63638496398926],[-66.90055847167969,77.59166145324707]]],[[[-18.03722381591797,77.66609382629395],[-18.24222183227539,77.67997932434082],[-17.584165573120117,77.83777046203613],[-18.03722381591797,77.66609382629395]]],[[[-19.940555572509766,77.96666145324707],[-19.229164123535156,77.82971382141113],[-19.775833129882812,77.83055305480957],[-20.490833282470703,77.95471382141113],[-19.940555572509766,77.96666145324707]]],[[[-19.542224884033203,77.91609382629395],[-19.699722290039062,77.96499824523926],[-19.61361312866211,77.97192573547363],[-19.542224884033203,77.91609382629395]]],[[[-21.310279846191406,77.88554573059082],[-21.428054809570312,77.9236011505127],[-21.11111068725586,78.01220893859863],[-21.310279846191406,77.88554573059082]]],[[[-20.536113739013672,78.01582527160645],[-20.631942749023438,78.0324878692627],[-20.362777709960938,78.0516529083252],[-20.536113739013672,78.01582527160645]]],[[[-19.276668548583984,78.11775398254395],[-19.383331298828125,78.12719917297363],[-19.29888916015625,78.17581367492676],[-19.276668548583984,78.11775398254395]]],[[[-19.0433349609375,78.07693672180176],[-19.191944122314453,78.11775398254395],[-18.829723358154297,78.17637825012207],[-19.0433349609375,78.07693672180176]]],[[[-20.91583251953125,78.14610481262207],[-21.043054580688477,78.18136787414551],[-20.855554580688477,78.16526985168457],[-20.91583251953125,78.14610481262207]]],[[[-20.526668548583984,78.16137886047363],[-20.78333282470703,78.19136238098145],[-20.302223205566406,78.21331977844238],[-20.526668548583984,78.16137886047363]]],[[[-19.490554809570312,78.24136543273926],[-19.595001220703125,78.2472095489502],[-19.422775268554688,78.27665901184082],[-19.490554809570312,78.24136543273926]]],[[[-19.158889770507812,78.24026679992676],[-19.35333251953125,78.28332710266113],[-18.885555267333984,78.29525947570801],[-19.158889770507812,78.24026679992676]]],[[[-19.633331298828125,78.27665901184082],[-19.67749786376953,78.38638496398926],[-19.490554809570312,78.33055305480957],[-19.633331298828125,78.27665901184082]]],[[[-19.288333892822266,78.31387519836426],[-19.40250015258789,78.39444160461426],[-19.08194351196289,78.36303901672363],[-19.288333892822266,78.31387519836426]]],[[[-18.96999740600586,78.39248847961426],[-19.0977783203125,78.42526435852051],[-18.88111114501953,78.42886543273926],[-18.96999740600586,78.39248847961426]]],[[[-19.126110076904297,78.45526313781738],[-19.254169464111328,78.4458179473877],[-18.96416473388672,78.4749927520752],[-19.126110076904297,78.45526313781738]]],[[[-18.571945190429688,78.57805061340332],[-18.738887786865234,78.6060962677002],[-18.31472396850586,78.6736011505127],[-18.571945190429688,78.57805061340332]]],[[[-18.243053436279297,78.75082588195801],[-18.297222137451172,78.8560962677002],[-18.075557708740234,78.8177661895752],[-18.243053436279297,78.75082588195801]]],[[[-19.346946716308594,78.81137275695801],[-19.756668090820312,78.79525947570801],[-19.190834045410156,78.95305061340332],[-19.346946716308594,78.81137275695801]]],[[[-18.03722381591797,78.99275398254395],[-17.849998474121094,79.21554756164551],[-17.55638885498047,79.16415596008301],[-18.03722381591797,78.99275398254395]]],[[[-19.375,79.12637519836426],[-19.496665954589844,79.1958179473877],[-19.314443588256836,79.23137092590332],[-19.375,79.12637519836426]]],[[[-19.90833282470703,80.05914497375488],[-20.01416778564453,80.09665107727051],[-19.756946563720703,80.24136543273926],[-19.018890380859375,80.16360664367676],[-19.90833282470703,80.05914497375488]]],[[[-66.59527587890625,80.60859870910645],[-66.8961181640625,80.67109870910645],[-66.53167724609375,80.61693000793457],[-66.59527587890625,80.60859870910645]]],[[[-20.59722137451172,81.67248725891113],[-20.971111297607422,81.71443367004395],[-20.164443969726562,81.68193244934082],[-20.59722137451172,81.67248725891113]]],[[[-18.585556030273438,81.64665412902832],[-19.245830535888672,81.77777290344238],[-18.304447174072266,81.66220283508301],[-18.585556030273438,81.64665412902832]]],[[[-19.77777862548828,81.8702564239502],[-20.781944274902344,82.13388252258301],[-20.30666732788086,82.13054084777832],[-19.77777862548828,81.8702564239502]]],[[[-18.858333587646484,81.97442817687988],[-19.41388702392578,82.20555305480957],[-18.792224884033203,81.99193000793457],[-18.858333587646484,81.97442817687988]]],[[[-51.46888732910156,81.96832466125488],[-53.357505798339844,82.2249927520752],[-51.19194030761719,81.99359321594238],[-51.46888732910156,81.96832466125488]]],[[[-51.88861083984375,82.2088794708252],[-52.29389190673828,82.2774829864502],[-51.79528045654297,82.21415901184082],[-51.88861083984375,82.2088794708252]]],[[[-48.212501525878906,82.39583015441895],[-48.86444854736328,82.53915596008301],[-48.03472900390625,82.46443367004395],[-48.212501525878906,82.39583015441895]]],[[[-46.00305938720703,82.64444160461426],[-44.41889190673828,82.36609077453613],[-45.067222595214844,82.21666145324707],[-44.737220764160156,82.09582710266113],[-45.07666778564453,82.05581855773926],[-47.749168395996094,82.62498664855957],[-46.00305938720703,82.64444160461426]]],[[[-40.17444610595703,82.66026496887207],[-40.472496032714844,82.68637275695801],[-40.28916931152344,82.69803047180176],[-40.17444610595703,82.66026496887207]]],[[[-49.95471954345703,82.76999092102051],[-50.067222595214844,82.77554512023926],[-49.723052978515625,82.77998542785645],[-49.95471954345703,82.76999092102051]]],[[[-47.56861114501953,82.7824878692627],[-48.415550231933594,82.8480396270752],[-47.44249725341797,82.80386543273926],[-47.56861114501953,82.7824878692627]]],[[[-46.443885803222656,82.83249092102051],[-47.26250457763672,82.93081855773926],[-46.407501220703125,82.83610725402832],[-46.443885803222656,82.83249092102051]]],[[[-39.570556640625,82.99664497375488],[-40.546112060546875,83.15332221984863],[-39.277496337890625,83.08137702941895],[-39.570556640625,82.99664497375488]]],[[[-38.31861114501953,83.13360786437988],[-38.65972137451172,83.16470527648926],[-38.00917053222656,83.1524829864502],[-38.31861114501953,83.13360786437988]]],[[[-39.904998779296875,82.99887275695801],[-41.48277282714844,83.16499519348145],[-40.836944580078125,83.16360664367676],[-39.904998779296875,82.99887275695801]]],[[[-40.15777587890625,83.20332527160645],[-40.57917022705078,83.21971321105957],[-40.086944580078125,83.21165657043457],[-40.15777587890625,83.20332527160645]]],[[[-41.03722381591797,83.20860481262207],[-41.60639190673828,83.22442817687988],[-41.001670837402344,83.21220588684082],[-41.03722381591797,83.20860481262207]]],[[[-42.0977783203125,83.2422046661377],[-42.418060302734375,83.25387763977051],[-41.959442138671875,83.25166511535645],[-42.0977783203125,83.2422046661377]]],[[[-39.64611053466797,83.26220893859863],[-38.63972473144531,83.11581611633301],[-40.67333221435547,83.28027534484863],[-39.64611053466797,83.26220893859863]]],[[[-41.24444580078125,83.28776741027832],[-41.68444061279297,83.31360054016113],[-41.456390380859375,83.32721138000488],[-41.24444580078125,83.28776741027832]]],[[[-38.90277862548828,83.2905445098877],[-39.62194061279297,83.3369312286377],[-39.22388458251953,83.39694404602051],[-38.90277862548828,83.2905445098877]]],[[[-32.30027770996094,83.57026863098145],[-25.650554656982422,83.29165840148926],[-35.617774963378906,82.90109443664551],[-25.142223358154297,83.16276741027832],[-24.751113891601562,83.00082588195801],[-25.901111602783203,82.7774829864502],[-23.992774963378906,82.91165351867676],[-21.314167022705078,82.60803413391113],[-25.068889617919922,82.1524829864502],[-31.61888885498047,82.20749092102051],[-29.904720306396484,82.09332466125488],[-33.09833526611328,81.77388191223145],[-25.202499389648438,81.98942756652832],[-27.63083267211914,81.4861011505127],[-27.32861328125,81.38081550598145],[-24.210556030273438,81.70833015441895],[-24.00222396850586,82.00972175598145],[-22.016944885253906,81.93304634094238],[-22.231109619140625,81.46582221984863],[-24.511669158935547,80.54081916809082],[-19.940834045410156,81.68304634094238],[-20.305557250976562,81.45109748840332],[-18.017223358154297,81.46805000305176],[-17.35388946533203,81.70193672180176],[-17.534725189208984,81.85359382629395],[-16.70055389404297,81.93193244934082],[-12.155000686645508,81.60331916809082],[-16.005001068115234,80.72859382629395],[-21.24749755859375,80.57554817199707],[-16.113887786865234,80.50248908996582],[-17.113887786865234,80.23692512512207],[-19.70083236694336,80.28581428527832],[-20.55472183227539,80.10582160949707],[-20.755001068115234,79.86499214172363],[-20.326946258544922,79.76054573059082],[-19.289443969726562,80.10331916809082],[-17.44916534423828,80.05581855773926],[-19.631389617919922,79.66137886047363],[-19.86888885498047,79.15304756164551],[-19.573612213134766,79.33110237121582],[-19.078887939453125,79.20054817199707],[-19.378334045410156,79.27499580383301],[-20.091110229492188,79.06360054016113],[-19.914722442626953,78.96415901184082],[-20.01805877685547,78.87719917297363],[-21.182498931884766,78.80998420715332],[-20.926387786865234,78.68997383117676],[-21.426944732666016,78.64444160461426],[-20.906387329101562,78.62414741516113],[-22.039443969726562,77.68831062316895],[-21.57833480834961,77.56414985656738],[-20.866390228271484,78.0152759552002],[-20.311946868896484,77.87082099914551],[-19.23999786376953,77.76304817199707],[-18.9566650390625,77.62886238098145],[-21.053611755371094,77.54387092590332],[-18.395832061767578,77.34276008605957],[-18.120555877685547,76.94832038879395],[-18.305278778076172,76.80609321594238],[-20.723052978515625,76.98831367492676],[-21.728885650634766,76.88360786437988],[-20.939441680908203,76.84248542785645],[-21.604999542236328,76.64471626281738],[-22.738887786865234,76.70443916320801],[-21.814443588256836,76.59027290344238],[-22.506946563720703,76.44803047180176],[-21.573055267333984,76.43664741516113],[-21.682220458984375,76.2391529083252],[-19.805835723876953,76.22859382629395],[-21.982219696044922,75.99193000793457],[-19.825000762939453,75.90915107727051],[-19.335556030273438,75.40498542785645],[-19.88277816772461,75.14583015441895],[-22.251113891601562,75.66415596008301],[-21.406387329101562,75.45555305480957],[-22.511390686035156,75.53082466125488],[-20.515003204345703,75.14082527160645],[-22.43555450439453,75.16388130187988],[-20.63888931274414,75.06192207336426],[-20.762779235839844,74.8469409942627],[-20.606109619140625,74.73692512512207],[-21.119720458984375,74.66165351867676],[-18.97777557373047,74.48166084289551],[-19.68499755859375,74.23748970031738],[-22.082778930664062,74.59832954406738],[-21.765003204345703,74.41943550109863],[-22.479164123535156,74.31192207336426],[-22.053054809570312,74.28387641906738],[-22.492494583129883,74.07443428039551],[-21.980552673339844,73.99803352355957],[-21.821666717529297,73.65109443664551],[-21.748607635498047,74.05832099914551],[-20.283058166503906,73.87997627258301],[-20.501113891601562,73.4527759552002],[-22.379165649414062,73.25055122375488],[-24.032222747802734,73.70248603820801],[-22.178333282470703,73.62469673156738],[-24.044166564941406,73.81469917297363],[-24.463054656982422,73.53581428527832],[-25.68694305419922,73.95248603820801],[-24.67416763305664,73.5133228302002],[-25.31500244140625,73.46165657043457],[-25.721385955810547,73.26361274719238],[-26.012500762939453,73.2422046661377],[-27.337501525878906,73.49247932434082],[-26.387500762939453,73.24136543273926],[-27.72861099243164,73.12970161437988],[-27.49749755859375,72.92442512512207],[-26.44916534423828,73.19359016418457],[-25.053890228271484,73.08276557922363],[-27.38833236694336,72.83665657043457],[-26.30472183227539,72.72776985168457],[-26.46277618408203,72.57222175598145],[-24.842498779296875,72.71943855285645],[-24.60944366455078,72.52331733703613],[-25.90833282470703,72.41388130187988],[-25.289169311523438,72.38443183898926],[-25.526668548583984,72.12137031555176],[-24.588333129882812,72.42109870910645],[-22.494441986083984,71.89276313781738],[-23.12555694580078,71.62608528137207],[-21.895832061767578,71.74081611633301],[-22.506389617919922,71.54971504211426],[-22.473331451416016,71.26304817199707],[-21.805557250976562,71.50943183898926],[-21.60361099243164,71.32304573059082],[-21.961666107177734,71.26388740539551],[-21.6875,71.14915657043457],[-22.33388900756836,71.05359077453613],[-21.681110382080078,71.06833076477051],[-21.92916488647461,70.80220222473145],[-21.474720001220703,70.53997993469238],[-22.37722396850586,70.44165229797363],[-22.506946563720703,70.85054206848145],[-22.62277603149414,70.44664192199707],[-23.34583282470703,70.43914985656738],[-24.73999786376953,71.33221626281738],[-28.639720916748047,72.12442207336426],[-27.325000762939453,71.70971870422363],[-28.466941833496094,71.55247688293457],[-25.411388397216797,71.34915351867676],[-26.478885650634766,70.96026802062988],[-28.409164428710938,70.97581672668457],[-27.91416358947754,70.8672046661377],[-29.20694351196289,70.39415168762207],[-26.322223663330078,70.37303352355957],[-28.54277801513672,70.04471015930176],[-27.34194564819336,69.96249580383301],[-25.229164123535156,70.41443061828613],[-22.079166412353516,70.12970161437988],[-23.930553436279297,69.7552661895752],[-23.579166412353516,69.62359809875488],[-24.343334197998047,69.60443305969238],[-24.072776794433594,69.4780445098877],[-26.36333465576172,68.66748237609863],[-29.378055572509766,68.1988697052002],[-29.862220764160156,68.41360664367676],[-30.196945190429688,68.24247932434082],[-30.03028106689453,68.11165046691895],[-31.571666717529297,68.06694221496582],[-31.745830535888672,68.21081733703613],[-31.53583526611328,68.23942756652832],[-32.007225036621094,68.26193428039551],[-32.48500061035156,68.61998176574707],[-32.133331298828125,68.19609260559082],[-32.40027618408203,68.19941902160645],[-31.999164581298828,68.09526252746582],[-32.122772216796875,67.85775947570801],[-33.1986083984375,67.68803596496582],[-33.600555419921875,67.37137031555176],[-33.36583709716797,67.24693489074707],[-33.973052978515625,66.99054145812988],[-34.26721954345703,66.5758228302002],[-34.429725646972656,66.74136543273926],[-34.406944274902344,66.54081916809082],[-34.719993591308594,66.33831977844238],[-35.85166931152344,66.43359565734863],[-35.587501525878906,66.11026191711426],[-36.331947326660156,65.90721321105957],[-36.343055725097656,66.07998847961426],[-36.56666564941406,66.07666206359863],[-36.52111053466797,65.98471260070801],[-36.98027801513672,65.83749580383301],[-37.07749938964844,66.06219673156738],[-37.19305419921875,65.76915168762207],[-37.81138610839844,66.03055000305176],[-37.184722900390625,66.34166145324707],[-38.106109619140625,66.38693428039551],[-37.69166564941406,66.25972175598145],[-38.05194091796875,65.9124927520752],[-38.483612060546875,66.0102710723877],[-38.10083770751953,65.80304145812988],[-38.241943359375,65.62942695617676],[-40.09638977050781,65.56721687316895],[-39.75556182861328,65.24275398254395],[-41.155555725097656,64.96443367004395],[-40.35889434814453,64.34832954406738],[-40.788055419921875,64.38443183898926],[-41.09166717529297,64.30220222473145],[-41.325836181640625,64.34137153625488],[-41.50695037841797,64.3258228302002],[-41.56945037841797,64.26555061340332],[-40.567779541015625,64.1091480255127],[-40.83860778808594,63.94554328918457],[-40.51805877685547,63.697214126586914],[-41.617774963378906,63.79222297668457],[-40.74833679199219,63.509164810180664],[-41.17066955566406,63.51360511779785],[-40.99888610839844,63.40749549865723],[-41.11333465576172,63.385271072387695],[-41.3941650390625,63.55221748352051],[-41.23833465576172,63.404436111450195],[-41.580833435058594,63.48777198791504],[-41.11333465576172,63.30721473693848],[-41.687217712402344,63.52499580383301],[-41.907501220703125,63.4647159576416],[-41.429168701171875,63.12638282775879],[-42.17444610595703,63.20166206359863],[-41.61528015136719,62.987497329711914],[-41.75556182861328,62.839433670043945],[-43.14722442626953,62.75777626037598],[-42.16221618652344,62.38388252258301],[-42.979164123535156,62.515275955200195],[-42.26111602783203,62.24249458312988],[-42.54084014892578,61.94360542297363],[-42.11583709716797,62.006662368774414],[-42.86944580078125,61.77305030822754],[-42.434722900390625,61.55721473693848],[-43.07917022705078,61.59360694885254],[-42.50750732421875,61.35527229309082],[-43.24610900878906,61.33915901184082],[-42.62999725341797,61.09832954406738],[-43.61277770996094,61.12777137756348],[-42.70471954345703,61.05777168273926],[-43.48444366455078,60.93332862854004],[-42.79084014892578,60.801103591918945],[-43.52666473388672,60.83721351623535],[-42.74944305419922,60.683603286743164],[-44.20249938964844,60.59332466125488],[-43.168609619140625,60.39749336242676],[-43.13750457763672,60.07943916320801],[-44.10083770751953,60.384164810180664],[-44.08055877685547,60.286386489868164],[-44.4566650390625,60.148332595825195],[-44.60417175292969,59.982492446899414],[-45.15277862548828,60.074167251586914],[-44.47083282470703,60.55721473693848],[-45.18999481201172,60.129159927368164],[-44.62610626220703,60.73333168029785],[-45.203330993652344,60.43526649475098],[-45.09916687011719,60.645830154418945],[-45.491943359375,60.48999214172363],[-45.313331604003906,60.69999885559082],[-45.97833251953125,60.57388496398926],[-45.671775817871094,60.67632865905762],[-45.84972381591797,60.69748878479004],[-45.25305938720703,60.901933670043945],[-46.22138214111328,60.753610610961914],[-45.19972229003906,61.18998908996582],[-46.0655517578125,60.92110633850098],[-45.65361022949219,61.142221450805664],[-45.76972198486328,61.33360481262207],[-46.00972557067871,61.22304725646973],[-45.839996337890625,61.164995193481445],[-45.915000915527344,61.09027290344238],[-46.22943878173828,60.97471046447754],[-46.406105041503906,61.08416175842285],[-46.380279541015625,61.04110908508301],[-46.442222595214844,60.999162673950195],[-46.52333068847656,61.015275955200195],[-46.58167266845703,60.90582466125488],[-46.83527374267578,60.93027687072754],[-46.70527458190918,60.88138008117676],[-46.85722351074219,60.797494888305664],[-46.95861053466797,60.86332893371582],[-46.91444396972656,60.93332862854004],[-47.02305603027344,60.97609901428223],[-47.80944061279297,60.879159927368164],[-47.31945037841797,60.86776924133301],[-47.447776794433594,60.82027626037598],[-48.2388916015625,60.819719314575195],[-47.68943786621094,61.0049991607666],[-48.40638732910156,60.98832893371582],[-47.83361053466797,61.041940689086914],[-48.21888732910156,61.18499183654785],[-47.91722106933594,61.324167251586914],[-48.4102783203125,61.132211685180664],[-48.63722229003906,61.238046646118164],[-48.37860870361328,61.3638858795166],[-49.06610870361328,61.39805030822754],[-48.34416198730469,61.604997634887695],[-49.29750061035156,61.55749702453613],[-48.599212646484375,61.63633918762207],[-49.148887634277344,61.71859931945801],[-48.7630615234375,61.98472023010254],[-49.440277099609375,61.84221839904785],[-48.840553283691406,62.07694435119629],[-49.66944885253906,61.99554634094238],[-49.29389190673828,62.17222023010254],[-50.317779541015625,62.49527168273926],[-49.94749450683594,62.827219009399414],[-50.28028106689453,62.70471382141113],[-50.317222595214844,62.743051528930664],[-50.15083312988281,62.93082618713379],[-49.701393127441406,63.05749702453613],[-50.19150161743164,62.93366050720215],[-50.37999725341797,62.784440994262695],[-50.149993896484375,63.015275955200195],[-50.60639190673828,63.094438552856445],[-50.059844970703125,63.2287540435791],[-51.10778045654297,63.339433670043945],[-50.27610778808594,63.401384353637695],[-51.22138214111328,63.43943214416504],[-50.504722595214844,63.66721534729004],[-51.55944061279297,63.70916175842285],[-50.924171447753906,63.93249702453613],[-51.443328857421875,63.80499458312988],[-51.60194396972656,64.03471565246582],[-50.04833984375,64.19413948059082],[-51.761390686035156,64.18193244934082],[-50.950836181640625,64.21805000305176],[-50.843055725097656,64.2541675567627],[-51.04194641113281,64.27554512023926],[-50.85639190673828,64.4155445098877],[-50.35222625732422,64.38275337219238],[-50.173057556152344,64.44832038879395],[-50.856666564941406,64.63304328918457],[-49.58429718017578,64.33764839172363],[-50.0655517578125,64.52916145324707],[-49.99888610839844,64.86914253234863],[-50.56055450439453,64.76805305480957],[-50.978607177734375,65.21971321105957],[-50.63666534423828,64.75305366516113],[-51.22416687011719,64.76220893859863],[-52.00695037841797,64.20359992980957],[-52.03916931152344,64.39915657043457],[-52.105560302734375,64.38720893859863],[-52.05750274658203,64.59908485412598],[-52.120277404785156,64.72026252746582],[-51.2469482421875,65.01748847961426],[-52.211387634277344,64.80664253234863],[-52.09972381591797,65.2391529083252],[-52.55889129638672,65.32748603820801],[-51.72083282470703,65.58221626281738],[-51.90110778808594,65.62387275695801],[-51.69444274902344,65.69859504699707],[-51.24388885498047,65.75972175598145],[-50.54583740234375,65.70694160461426],[-51.20916557312012,65.79609870910645],[-51.48472595214844,65.76304817199707],[-51.94805145263672,65.65887641906738],[-51.93444061279297,65.54637336730957],[-52.497779846191406,65.38720893859863],[-52.46916198730469,65.64082527160645],[-52.80194091796875,65.53888130187988],[-52.68888854980469,65.80554389953613],[-53.268333435058594,65.74693489074707],[-51.831947326660156,66.05581855773926],[-53.46221923828125,66.03415107727051],[-51.271385192871094,66.84387397766113],[-50.32917022705078,66.83305549621582],[-50.956390380859375,66.9347095489502],[-49.997779846191406,66.98082160949707],[-50.63221740722656,67.01582527160645],[-50.33472442626953,67.07193183898926],[-51.18943786621094,66.91775703430176],[-53.476661682128906,66.09887886047363],[-53.11833190917969,66.28581428527832],[-53.619720458984375,66.24331855773926],[-53.633331298828125,66.50444221496582],[-52.41638946533203,66.54637336730957],[-53.451942443847656,66.63749885559082],[-52.2288818359375,66.8399829864502],[-53.965553283691406,67.07470893859863],[-53.81666564941406,67.17886543273926],[-53.37999725341797,67.20221138000488],[-53.588890075683594,67.21499824523926],[-53.47721862792969,67.2391529083252],[-52.151390075683594,67.36998176574707],[-51.52471923828125,67.32304573059082],[-51.18943786621094,67.12359809875488],[-50.351112365722656,67.18054389953613],[-51.52583312988281,67.3510913848877],[-51.15166473388672,67.42331123352051],[-53.252227783203125,67.32054328918457],[-53.79833984375,67.2027759552002],[-53.88111114501953,67.26388740539551],[-52.49610900878906,67.76971626281738],[-51.80944061279297,67.62581062316895],[-51.330284118652344,67.67581367492676],[-50.70055389404297,67.49165534973145],[-50.07194519042969,67.50999641418457],[-50.85222625732422,67.59082221984863],[-50.274444580078125,67.7310962677002],[-49.93666076660156,67.6938648223877],[-50.288612365722656,67.74498176574707],[-50.65027618408203,67.65165901184082],[-50.96971893310547,67.6222095489502],[-51.23082733154297,67.69720649719238],[-50.417503356933594,67.84443855285645],[-51.33111572265625,67.86886787414551],[-51.05999755859375,67.97415351867676],[-53.75361633300781,67.6010913848877],[-52.954559326171875,67.97898292541504],[-53.187217712402344,68.04332160949707],[-52.05999755859375,67.97526741027832],[-53.32111358642578,68.18441963195801],[-52.41444396972656,68.0627613067627],[-52.802223205566406,68.16887092590332],[-51.85778045654297,68.04193305969238],[-51.18860626220703,68.06360054016113],[-50.56945037841797,67.90081977844238],[-50.153053283691406,67.93332099914551],[-51.434165954589844,68.19832038879395],[-50.9566650390625,68.1827564239502],[-51.18360900878906,68.39888191223145],[-50.81999969482422,68.50360298156738],[-52.419166564941406,68.18054389953613],[-53.38916778564453,68.3277759552002],[-53.07972717285156,68.32304573059082],[-52.461669921875,68.54498481750488],[-50.86583709716797,68.61470222473145],[-50.65638732910156,68.82554817199707],[-51.292503356933594,68.74832344055176],[-51.069725036621094,69.13109016418457],[-50.209442138671875,68.96081733703613],[-50.687774658203125,69.11775398254395],[-50.13861083984375,69.17747688293457],[-50.380828857421875,69.3388843536377],[-51.122772216796875,69.20138740539551],[-50.20471954345703,69.52192878723145],[-50.883056640625,69.49136543273926],[-50.19166564941406,69.75749397277832],[-50.31361389160156,69.8733081817627],[-50.58916473388672,69.92192268371582],[-50.21416473388672,70.02165412902832],[-52.312774658203125,70.0466480255127],[-54.62638854980469,70.65193367004395],[-54.063331604003906,70.82971382141113],[-52.72222137451172,70.74470710754395],[-50.6763916015625,70.3227710723877],[-50.49055480957031,70.50972175598145],[-51.03722381591797,70.43081855773926],[-50.939720153808594,70.46776008605957],[-51.345001220703125,70.5666675567627],[-50.61888885498047,70.62858772277832],[-51.43860626220703,70.74775886535645],[-50.633056640625,70.74026679992676],[-51.95249938964844,71.02110481262207],[-50.92888641357422,70.98858833312988],[-51.48527526855469,71.06303596496582],[-51.226661682128906,71.14166450500488],[-52.24944305419922,71.1233081817627],[-51.64555358886719,71.36137580871582],[-52.55555725097656,71.17137336730957],[-51.348052978515625,71.4861011505127],[-52.983612060546875,71.41526985168457],[-51.64055633544922,71.71110725402832],[-53.25055694580078,71.7027759552002],[-52.68444061279297,72.00166511535645],[-53.32194519042969,71.82222175598145],[-53.857505798339844,72.32165718078613],[-53.560279846191406,72.35803413391113],[-53.95500183105469,72.32249641418457],[-53.39666557312012,71.85193061828613],[-54.10028076171875,71.70749092102051],[-53.915550231933594,71.44192695617676],[-55.32361602783203,71.38693428039551],[-55.90583038330078,71.67859077453613],[-54.38444519042969,72.22249031066895],[-55.29833984375,71.92859077453613],[-55.58000183105469,71.99887275695801],[-54.682777404785156,72.36638069152832],[-55.62638854980469,72.45749092102051],[-54.29639434814453,72.47998237609863],[-55.016395568847656,72.51999092102051],[-54.627220153808594,72.62164497375488],[-54.87055206298828,72.64248847961426],[-54.60472106933594,72.82805061340332],[-54.850555419921875,73.01443672180176],[-55.697776794433594,73.0666675567627],[-55.08583068847656,73.36276435852051],[-56.075836181640625,73.64860725402832],[-55.60778045654297,73.72026252746582],[-56.40972137451172,74.06608772277832],[-56.12916564941406,74.27832221984863],[-57.32500457763672,74.10775947570801],[-56.309165954589844,74.28720283508301],[-56.71333312988281,74.34082221984863],[-56.13111114501953,74.38388252258301],[-56.79722595214844,74.44331550598145],[-56.19249725341797,74.5516529083252],[-58.697776794433594,75.34637641906738],[-58.208892822265625,75.44192695617676],[-58.408050537109375,75.71527290344238],[-60.87860870361328,76.1524829864502],[-63.440834045410156,76.3733081817627],[-65.47972106933594,76.01860237121582],[-65.88833618164062,76.09832954406738],[-65.55332946777344,76.23387336730957],[-65.76945495605469,76.27554512023926],[-67.30610656738281,76.16748237609863],[-66.4586181640625,75.90971565246582],[-68.50056457519531,76.0869312286377],[-69.63333129882812,76.38081550598145],[-67.98222351074219,76.67943000793457],[-71.37527465820312,77.05609321594238],[-66.4486083984375,77.13388252258301],[-66.17083740234375,77.19331550598145],[-69.10166931152344,77.27192878723145],[-66.23832702636719,77.24859809875488],[-66.65916442871094,77.41443061828613],[-66.05555725097656,77.49136543273926],[-66.725830078125,77.68081855773926],[-68.3447265625,77.49859809875488],[-68.69943237304688,77.66388130187988],[-69.25028991699219,77.45305061340332],[-70.28999328613281,77.56360054016113],[-69.48361206054688,77.75360298156738],[-70.602783203125,77.67804145812988],[-69.96861267089844,77.83360481262207],[-71.32000732421875,77.76361274719238],[-73.05360412597656,78.15721321105957],[-72.4566650390625,78.28637886047363],[-72.84944152832031,78.31414985656738],[-72.55221557617188,78.52110481262207],[-65.97666931152344,79.10165596008301],[-64.82333374023438,79.53360176086426],[-65.06889343261719,80.00915718078613],[-63.78446960449219,80.1483325958252],[-67.04972839355469,80.05748176574707],[-67.4808349609375,80.32554817199707],[-63.68055725097656,81.14387702941895],[-62.79444885253906,80.75110054016113],[-63.371665954589844,81.15582466125488],[-61.056663513183594,81.11970710754395],[-61.313331604003906,81.35582160949707],[-60.770835876464844,81.50055122375488],[-61.45222473144531,81.75305366516113],[-60.806663513183594,81.87997627258301],[-58.899444580078125,81.86470222473145],[-56.47833251953125,81.33249092102051],[-59.466941833496094,81.99693489074707],[-54.505279541015625,82.36554145812988],[-53.559722900390625,82.11609077453613],[-53.82361602783203,81.69359016418457],[-53.63444519042969,81.5133228302002],[-52.899169921875,82.03415107727051],[-49.614723205566406,81.6402759552002],[-51.0655517578125,81.93220710754395],[-49.432220458984375,81.92776679992676],[-51.11888885498047,82.49414253234863],[-50.3175048828125,82.5183277130127],[-44.63999938964844,81.7541675567627],[-44.183326721191406,81.83415412902832],[-44.92527770996094,81.98970222473145],[-44.50250244140625,82.08970832824707],[-44.79528045654297,82.18997383117676],[-44.1905517578125,82.31248664855957],[-42.299171447753906,82.21666145324707],[-45.765838623046875,82.76443672180176],[-42.14277458190918,82.76165962219238],[-41.682777404785156,82.4780445098877],[-41.89805603027344,82.73275947570801],[-41.55027770996094,82.73665046691895],[-39.752784729003906,82.39888191223145],[-40.135276794433594,82.71443367004395],[-46.88999938964844,82.96110725402832],[-43.38666534423828,82.91443061828613],[-45.52471923828125,83.1222095489502],[-42.69499969482422,83.2744312286377],[-38.57444763183594,82.74414253234863],[-39.15027618408203,82.98027229309082],[-36.87749481201172,83.14721870422363],[-38.85639190673828,83.4316577911377],[-32.30027770996094,83.57026863098145]],[[-20.11333465576172,77.65332221984863],[-20.438331604003906,77.62886238098145],[-20.00833511352539,77.60693550109863],[-20.11333465576172,77.65332221984863]]]]}},{"type":"Feature","properties":{"name":"Germany","iso2":"DE","iso3":"DEU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[8.710256576538086,47.69680976867676],[8.678594589233398,47.69334602355957],[8.670557022094727,47.71110725402832],[8.710256576538086,47.69680976867676]]],[[[6.806390762329102,53.60222053527832],[6.746946334838867,53.56027412414551],[6.658334732055664,53.58610725402832],[6.806390762329102,53.60222053527832]]],[[[6.939443588256836,53.669443130493164],[6.87639045715332,53.67027473449707],[7.088335037231445,53.68416786193848],[6.939443588256836,53.669443130493164]]],[[[7.242498397827148,53.70443916320801],[7.135835647583008,53.70611000061035],[7.346944808959961,53.72110939025879],[7.242498397827148,53.70443916320801]]],[[[8.191110610961914,53.72471809387207],[8.120000839233398,53.71305274963379],[8.142778396606445,53.73360633850098],[8.191110610961914,53.72471809387207]]],[[[7.622224807739258,53.75444221496582],[7.467779159545898,53.73305702209473],[7.485834121704102,53.75750160217285],[7.622224807739258,53.75444221496582]]],[[[7.758890151977539,53.76055335998535],[7.664445877075195,53.761667251586914],[7.812780380249023,53.77555274963379],[7.758890151977539,53.76055335998535]]],[[[8.42527961730957,53.928056716918945],[8.411664962768555,53.95555305480957],[8.454999923706055,53.96305274963379],[8.42527961730957,53.928056716918945]]],[[[13.940279006958008,54.02499580383301],[13.925832748413086,54.018327713012695],[13.934446334838867,54.02777290344238],[13.940279006958008,54.02499580383301]]],[[[8.695554733276367,54.04110908508301],[8.671388626098633,54.077775955200195],[8.693334579467773,54.08249855041504],[8.695554733276367,54.04110908508301]]],[[[14.001317977905273,54.06536293029785],[14.225557327270508,53.928606033325195],[14.218889236450195,53.86902046203613],[13.823431015014648,53.85374641418457],[14.056005477905273,53.98486518859863],[13.759164810180664,54.15999794006348],[14.001317977905273,54.06536293029785]]],[[[10.97944450378418,54.38055610656738],[11.017778396606445,54.38027381896973],[11.003053665161133,54.37693977355957],[10.97944450378418,54.38055610656738]]],[[[8.893056869506836,54.46193885803223],[8.815000534057617,54.50083351135254],[8.960554122924805,54.51916694641113],[8.893056869506836,54.46193885803223]]],[[[11.312776565551758,54.40694618225098],[11.006387710571289,54.4616641998291],[11.184167861938477,54.51999855041504],[11.312776565551758,54.40694618225098]]],[[[8.662778854370117,54.49416542053223],[8.59111213684082,54.52777290344238],[8.710832595825195,54.55166816711426],[8.662778854370117,54.49416542053223]]],[[[13.073610305786133,54.48861122131348],[13.09666633605957,54.59055519104004],[13.151388168334961,54.6027774810791],[13.073610305786133,54.48861122131348]]],[[[13.383054733276367,54.63888740539551],[13.730833053588867,54.275835037231445],[13.11833381652832,54.33388710021973],[13.267499923706055,54.38250160217285],[13.146963119506836,54.54560661315918],[13.503091812133789,54.49309730529785],[13.244722366333008,54.55916786193848],[13.383054733276367,54.63888740539551]]],[[[8.364442825317383,54.61332893371582],[8.294443130493164,54.66666603088379],[8.353887557983398,54.7116641998291],[8.364442825317383,54.61332893371582]]],[[[8.567777633666992,54.68527412414551],[8.396944046020508,54.713884353637695],[8.551111221313477,54.75388526916504],[8.567777633666992,54.68527412414551]]],[[[10.97944450378418,54.38055610656738],[10.818536758422852,53.89005470275879],[12.526945114135742,54.47416114807129],[12.924165725708008,54.42694282531738],[12.369722366333008,54.26500129699707],[13.023889541625977,54.39972114562988],[13.455831527709961,54.09610939025879],[13.718332290649414,54.16971778869629],[13.813055038452148,53.84527778625488],[14.275629043579102,53.69906806945801],[14.149168014526367,52.86277961730957],[14.640275955200195,52.57249641418457],[14.599443435668945,51.81860542297363],[15.03639030456543,51.28555488586426],[14.828332901000977,50.86583137512207],[14.309720993041992,51.053606033325195],[12.093706130981445,50.32253456115723],[12.674444198608398,49.424997329711914],[13.833612442016602,48.77360725402832],[12.758333206176758,48.12388801574707],[13.016668319702148,47.47027778625488],[12.735555648803711,47.68416786193848],[11.095556259155273,47.3961124420166],[10.478055953979492,47.59194374084473],[10.173334121704102,47.27472114562988],[9.56672477722168,47.54045295715332],[8.566110610961914,47.80694007873535],[8.576421737670898,47.59137153625488],[7.697225570678711,47.5433292388916],[7.58827018737793,47.584482192993164],[7.578889846801758,48.11972236633301],[8.226079940795898,48.96441841125488],[6.36216926574707,49.45939064025879],[6.524446487426758,49.808610916137695],[6.134416580200195,50.12784767150879],[6.39820671081543,50.32317543029785],[6.011800765991211,50.757272720336914],[5.864721298217773,51.04610633850098],[6.222223281860352,51.465829849243164],[5.962499618530273,51.80777931213379],[6.828889846801758,51.96555519104004],[7.065557479858398,52.38582801818848],[6.68889045715332,52.54916572570801],[7.051668167114258,52.64361000061035],[7.208364486694336,53.242807388305664],[7.015554428100586,53.41472053527832],[7.295835494995117,53.68527412414551],[8.008333206176758,53.71000099182129],[8.503053665161133,53.35416603088379],[8.665555953979492,53.89388465881348],[9.832498550415039,53.536386489868164],[8.899721145629883,53.94082832336426],[8.883611679077148,54.29416847229004],[8.599443435668945,54.33388710021973],[9.016942977905273,54.49833106994629],[8.580549240112305,54.86787986755371],[8.281110763549805,54.7469425201416],[8.393331527709961,55.053056716918945],[8.664545059204102,54.913095474243164],[9.44536018371582,54.82540321350098],[9.972776412963867,54.76111030578613],[9.870279312133789,54.45443916320801],[10.97944450378418,54.38055610656738]],[[11.459165573120117,53.96110725402832],[11.488611221313477,54.02305030822754],[11.37388801574707,53.98861122131348],[11.459165573120117,53.96110725402832]],[[11.544168472290039,54.06138801574707],[11.612421035766602,54.10458564758301],[11.511110305786133,54.04860877990723],[11.544168472290039,54.06138801574707]],[[12.72972297668457,54.41666603088379],[12.702775955200195,54.42833137512207],[12.68610954284668,54.4183292388916],[12.72972297668457,54.41666603088379]]]]}},{"type":"Feature","properties":{"name":"Guam","iso2":"GU","iso3":"GUM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[144.709412,13.234997],[144.655243,13.427776],[144.875244,13.65361],[144.709412,13.234997]]]]}},{"type":"Feature","properties":{"name":"Greece","iso2":"GR","iso3":"GRC"},"geometry":{"type":"MultiPolygon","coordinates":[[[[24.128609,34.856667000000144],[24.128609,34.808884],[24.04472,34.849998],[24.128609,34.856667000000144]]],[[[26.900555,35.358887],[26.89805200000012,35.419998],[27.019997000000103,35.430832],[26.900555,35.358887]]],[[[23.858608,35.52166],[26.290554,35.131104],[24.752777,34.942215],[23.521111,35.288055000000114],[23.606388000000123,35.613327],[23.858608,35.52166]]],[[[27.15749700000012,35.445831000000126],[27.066109,35.60499600000013],[27.228054,35.826385000000144],[27.15749700000012,35.445831000000126]]],[[[23.332222,35.825272],[23.273052,35.899994],[23.325832,35.872215],[23.332222,35.825272]]],[[[23.049442000000113,36.13694],[22.929443,36.37944],[23.107220000000154,36.243889000000124],[23.049442000000113,36.13694]]],[[[25.838882,36.348053],[25.730270000000104,36.369713],[25.771111,36.401932],[25.838882,36.348053]]],[[[25.399162,36.39444],[25.391388,36.408051],[25.406666,36.410553],[25.399162,36.39444]]],[[[27.786663,35.890549],[27.719719,36.1661000000001],[28.225826,36.45304900000012],[27.786663,35.890549]]],[[[27.400272,36.372498],[27.297771,36.464432000000116],[27.445827,36.4086],[27.400272,36.372498]]],[[[25.457771,36.333611],[25.371941,36.472488],[25.486382,36.408051],[25.457771,36.333611]]],[[[26.342216,36.506386],[26.262497,36.59166],[26.460548000000188,36.598053],[26.342216,36.506386]]],[[[27.854717,36.527222],[27.764996,36.574997],[27.859718,36.650269],[27.854717,36.527222]]],[[[24.950275,36.590553],[24.840832,36.658882],[24.938332,36.632774],[24.950275,36.590553]]],[[[25.089722,36.633881],[25.102219,36.693329],[25.187775,36.71666],[25.089722,36.633881]]],[[[21.785831000000115,36.736938],[21.774998,36.697777],[21.75055300000011,36.71249400000012],[21.76055500000018,36.754997],[21.785831000000115,36.736938]]],[[[24.413609000000122,36.66027100000015],[24.349163,36.746109],[24.548054,36.75943800000012],[24.413609000000122,36.66027100000015]]],[[[25.385551,36.651665],[25.275829,36.78138000000017],[25.407219,36.717766],[25.385551,36.651665]]],[[[24.662777000000148,36.747498],[24.609722,36.778328],[24.665276000000148,36.77638200000017],[24.662777000000148,36.747498]]],[[[21.69860800000015,36.739166],[21.704441000000145,36.7966610000001],[21.728333,36.79277],[21.69860800000015,36.739166]]],[[[24.558609000000132,36.775551000000135],[24.521111000000133,36.823883],[24.562496,36.848610000000136],[24.558609000000132,36.775551000000135]]],[[[25.459995000000106,36.822220000000115],[25.420830000000194,36.83194],[25.4741590000001,36.869164],[25.459995000000106,36.822220000000115]]],[[[25.826664,36.779709],[25.73693800000018,36.784431],[25.976662,36.874161],[25.826664,36.779709]]],[[[26.965832,36.681664],[27.064159000000103,36.838875],[27.35277600000012,36.872208],[26.965832,36.681664]]],[[[25.680832,36.878052],[25.609161,36.886658],[25.651939,36.906097],[25.680832,36.878052]]],[[[25.076664000000108,36.951935],[25.023605000000146,36.999146],[25.083881,37.04248000000014],[25.076664000000108,36.951935]]],[[[24.711941,36.903053],[24.641109000000142,37.042221],[24.765274,36.958328],[24.711941,36.903053]]],[[[26.975552,36.924431],[26.890831,37.076378],[27.04832800000014,36.993607],[26.975552,36.924431]]],[[[25.834438,37.09304],[25.782494,37.11998700000011],[25.825554,37.125542],[25.834438,37.09304]]],[[[25.250275,37.008324],[25.09832800000015,37.027489],[25.268604,37.138611],[25.250275,37.008324]]],[[[26.886662,37.09665700000015],[26.769161000000167,37.17638400000011],[26.85833000000011,37.181107],[26.886662,37.09665700000015]]],[[[25.461388,36.91943400000012],[25.341106,37.074997],[25.54472,37.198044],[25.461388,36.91943400000012]]],[[[24.535000000000196,37.182495],[24.509163,37.11277800000012],[24.414719,37.12722000000012],[24.535000000000196,37.182495]]],[[[26.767494,37.186935],[26.772221,37.206657],[26.787495,37.20694],[26.767494,37.186935]]],[[[23.156666,37.240273],[23.09694300000018,37.277496],[23.150555,37.272774000000126],[23.156666,37.240273]]],[[[23.410831,37.300827],[23.373886,37.299721],[23.583332,37.364166],[23.410831,37.300827]]],[[[24.379444,37.30583200000014],[24.442776,37.481667],[24.48333,37.398048000000145],[24.379444,37.30583200000014]]],[[[25.359161,37.407776],[25.313889,37.488045],[25.463608,37.469719],[25.359161,37.407776]]],[[[24.952499000000103,37.38555100000015],[24.884441,37.363609],[24.889721,37.512497],[24.952499000000103,37.38555100000015]]],[[[23.497776,37.504715],[23.432777,37.526665],[23.522499,37.524162],[23.497776,37.504715]]],[[[25.228333,37.534431],[24.97583,37.675552],[25.238888000000145,37.621941],[25.228333,37.534431]]],[[[24.298611,37.526382],[24.298332,37.654999],[24.394165,37.673332],[24.298611,37.526382]]],[[[26.020828,37.514435],[26.06805,37.631943],[26.361111000000108,37.68666100000017],[26.020828,37.514435]]],[[[23.51305400000018,37.691666],[23.425552,37.762497],[23.563889,37.762772],[23.51305400000018,37.691666]]],[[[27.069443,37.711937],[26.57166300000017,37.730553],[26.748608000000104,37.811378],[27.069443,37.711937]]],[[[20.898052,37.80527500000012],[20.831108000000143,37.646385000000166],[20.621944000000155,37.860832],[20.898052,37.80527500000012]]],[[[24.79166400000014,37.99832900000014],[24.96027800000016,37.68555500000012],[24.713333,37.872772],[24.79166400000014,37.99832900000014]]],[[[23.462498,37.878609],[23.437496,37.985832000000144],[23.538887,37.985832000000144],[23.462498,37.878609]]],[[[20.612499,38.394165],[20.792500000000103,38.060272],[20.341389,38.177216],[20.612499,38.394165]]],[[[20.735554,38.309998],[20.644722000000115,38.39804800000012],[20.648888000000113,38.500275000000116],[20.735554,38.309998]]],[[[26.025555,38.176941],[25.861664000000133,38.583611],[26.159443,38.544434],[26.025555,38.176941]]],[[[20.903053,38.545555],[20.899166,38.566383],[20.93888900000013,38.605270000000175],[20.903053,38.545555]]],[[[25.59999500000012,38.531937],[25.52916,38.59970900000012],[25.613331,38.589989],[25.59999500000012,38.531937]]],[[[20.643608000000114,38.5811080000001],[20.557777,38.683884],[20.701385,38.834717],[20.643608000000114,38.5811080000001]]],[[[24.683052000000117,38.79805],[24.553333,38.768326],[24.458332,38.962776],[24.683052000000117,38.79805]]],[[[23.461941,38.853333],[24.153889000000106,38.64666],[24.564163,37.987221],[22.829998,38.829163],[23.461941,38.853333]]],[[[23.736664,39.074715],[23.590832,39.204437],[23.786663,39.124161],[23.736664,39.074715]]],[[[23.50861,39.159721],[23.392498000000103,39.152222],[23.461388000000113,39.208328],[23.50861,39.159721]]],[[[20.198330000000112,39.174438],[20.136665,39.200554],[20.123608000000104,39.23638200000012],[20.198330000000112,39.174438]]],[[[23.862499,39.13666500000012],[23.953609000000142,39.289719],[23.978054000000157,39.2602770000001],[23.862499,39.13666500000012]]],[[[26.377216,39.273598],[26.614441,39.012497],[25.832222,39.183601],[26.377216,39.273598]]],[[[24.99249600000013,39.466385],[25.006386,39.563309],[25.05360800000014,39.530823],[24.99249600000013,39.466385]]],[[[19.926109,39.794441],[19.846664,39.649162],[20.111664000000133,39.363052],[19.641388,39.744438],[19.926109,39.794441]]],[[[19.404163,39.843605],[19.378887,39.868607000000125],[19.430553,39.86749300000015],[19.404163,39.843605]]],[[[25.441666,40.004715],[25.355827,39.78638500000015],[25.05444,39.86055],[25.441666,40.004715]]],[[[25.601662,40.398041],[25.443886,40.475822],[25.694717000000168,40.4661030000001],[25.601662,40.398041]]],[[[24.773331,40.63166000000014],[24.509441,40.658051],[24.64527500000011,40.797775],[24.773331,40.63166000000014]]],[[[26.294167,41.708054],[26.361095,41.711052],[26.63388400000011,41.35443900000014],[26.044720000000154,40.735825],[25.138054000000125,41.011375],[23.735275000000115,40.7549970000001],[24.398331,40.151939],[23.72777600000012,40.350555],[23.93222000000017,39.943054],[23.353611,40.245277000000115],[23.709999,39.91194200000011],[22.94138700000019,40.63055400000012],[22.59111,40.476662],[22.594997,40.012215],[23.344997,39.17805500000013],[22.9377750000001,39.358604],[23.072777000000144,39.036942],[22.523331,38.857216],[24.073887000000127,38.196938],[24.034443,37.651665],[23.515553000000182,38.040550000000124],[22.991386,37.88055400000012],[23.513611,37.429443],[22.72583,37.568329],[23.19833,36.431938],[22.634163,36.804443],[22.488888,36.386108],[22.152775,37.02166],[21.704441000000145,36.81527700000011],[21.649719000000175,37.44194],[21.106388,37.85443900000011],[21.85833,38.340828],[22.868053,37.938049],[23.226109,38.153053],[22.403332,38.448051],[21.147778,38.304161],[20.989441,38.669998],[20.73222,38.801109],[21.149998,39.00193800000012],[20.731941,38.95249900000012],[20.010029,39.6912],[20.671944,40.09805300000012],[20.98349,40.855888],[22.935604,41.342125],[24.263885,41.570549],[25.28500000000014,41.24305],[26.139996,41.354713],[26.066109,41.69749500000013],[26.294167,41.708054]]]]}},{"type":"Feature","properties":{"name":"Guatemala","iso2":"GT","iso3":"GTM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-90.627625,13.930555],[-91.384735,13.978888],[-92.24677999999989,14.550547],[-91.729172,16.074997],[-90.441956,16.088333],[-90.406403,16.416386],[-91.43749999999989,17.241108],[-90.98390199999989,17.256107],[-90.982422,17.820652],[-89.141953,17.818886],[-89.216171,15.88985100000015],[-88.910568,15.893610000000123],[-88.214737,15.724443],[-89.150375,15.073481],[-89.348312,14.431982],[-90.09639,13.745832],[-90.627625,13.930555]]]]}},{"type":"Feature","properties":{"name":"Guinea","iso2":"GN","iso3":"GIN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-13.602783,9.734441],[-14.664446,10.476665],[-14.693056,11.035276],[-15.016847999999868,10.956451000000143],[-14.686944999999895,11.509722],[-13.709167,11.715277],[-13.971035,12.154758],[-13.713139,12.677221],[-12.345404,12.301748],[-11.373058,12.407774],[-11.315556,12.022774],[-10.92889,12.224442],[-10.652748,11.892609],[-10.323893,12.224997],[-9.701946,12.029163],[-9.155556,12.486111],[-8.53388,11.49391],[-8.357779,11.305555],[-8.680557,10.966389],[-8.289722,11.007776],[-7.973984,10.165611],[-8.143612,9.533888000000104],[-7.732779,9.088055],[-7.957778,8.813332],[-7.646536,8.378416],[-8.198056999999892,8.496666],[-7.946838,8.018505],[-8.469749,7.561325],[-8.660557,7.695],[-9.106945,7.198889],[-9.485161,7.361989],[-9.48365,8.346931],[-10.266651,8.488377],[-10.695835,8.298611],[-10.571526,9.059532],[-11.214444999999898,9.997499],[-12.456112,9.888332],[-13.29561,9.032143],[-13.602783,9.734441]]]]}},{"type":"Feature","properties":{"name":"Guyana","iso2":"GY","iso3":"GUY"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-58.450562,6.896944000000119],[-58.4133379999999,6.969166],[-58.328056,6.956666],[-58.450562,6.896944000000119]]],[[[-59.789169,8.34111],[-58.472778,7.349999000000139],[-58.646118,6.42611],[-58.314728,6.894722000000129],[-57.199722,6.147499],[-57.248505,5.486111],[-57.327225,5.026111],[-57.92333999999988,4.821944],[-58.047226,4.008333000000107],[-57.642227,3.356389000000107],[-57.301392,3.3775],[-56.470634,1.944499000000135],[-57.324721999999895,1.975278],[-58.806946,1.185555000000107],[-59.642784,1.731111],[-59.989448999999865,2.693611],[-59.568611,3.899444],[-59.675835,4.388888],[-60.147507,4.5175],[-60.098335,5.217222],[-60.73037,5.204799],[-61.389725,5.940000000000126],[-61.134026,6.711042],[-60.288612,7.057221000000112],[-60.71917,7.535555],[-59.825562,8.236111],[-59.9902799999999,8.535276],[-59.789169,8.34111]]]]}},{"type":"Feature","properties":{"name":"Haiti","iso2":"HT","iso3":"HTI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-73.58473205566406,18.056943893432617],[-73.66751098632812,18.057222366333008],[-73.70611572265625,18.101388931274414],[-73.58473205566406,18.056943893432617]]],[[[-72.81556701660156,18.698888778686523],[-73.30000305175781,18.927221298217773],[-72.85722351074219,18.83500099182129],[-72.81556701660156,18.698888778686523]]],[[[-72.67361450195312,19.91666603088379],[-71.75418090820312,19.70583152770996],[-71.71583557128906,18.749723434448242],[-72.00306701660156,18.600831985473633],[-71.76786804199219,18.038503646850586],[-73.38639831542969,18.261945724487305],[-73.88166809082031,18.02277946472168],[-74.44667053222656,18.34193992614746],[-74.26806640625,18.665834426879883],[-72.35000610351562,18.5302791595459],[-72.80029296875,19.033056259155273],[-72.72334289550781,19.454999923706055],[-73.46528625488281,19.687776565551758],[-72.67361450195312,19.91666603088379]],[[-73.73945617675781,18.584165573120117],[-73.71528625488281,18.62444496154785],[-73.79806518554688,18.624723434448242],[-73.73945617675781,18.584165573120117]]],[[[-72.62834167480469,19.9869441986084],[-72.95639038085938,20.056665420532227],[-72.81195068359375,20.092222213745117],[-72.62834167480469,19.9869441986084]]]]}},{"type":"Feature","properties":{"name":"Honduras","iso2":"HN","iso3":"HND"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-87.622513,13.246387000000169],[-87.66972399999986,13.278332],[-87.614731,13.28611],[-87.622513,13.246387000000169]]],[[[-87.571945,13.36861],[-87.58168,13.30361000000012],[-87.65834,13.335833],[-87.571945,13.36861]]],[[[-85.841949,16.010555],[-84.26472499999988,15.828609],[-83.85555999999985,15.459999],[-84.208618,15.549999],[-84.07751499999989,15.351387],[-83.131851,14.992979000000105],[-83.239731,14.98249800000012],[-84.482788,14.617777],[-84.906677,14.808611],[-85.732315,13.829235],[-86.015839,14.065832000000114],[-86.763016,13.751621],[-86.695007,13.296944000000124],[-87.301392,12.986599],[-87.396393,13.410831],[-87.815582,13.405386000000107],[-87.75029,13.864166],[-88.47084,13.855276],[-89.339737,14.416111],[-89.348312,14.431982],[-89.150375,15.073481],[-88.214737,15.724443],[-85.841949,16.010555]]],[[[-86.883621,16.086666000000108],[-86.991669,16.087219],[-86.876114,16.121666],[-86.883621,16.086666000000108]]],[[[-86.599731,16.296108],[-86.410278,16.421665000000147],[-86.263336,16.423332],[-86.599731,16.296108]]],[[[-85.944733,16.409721],[-85.900284,16.494720000000157],[-85.83555599999988,16.498886],[-85.944733,16.409721]]],[[[-83.946671,17.405277],[-83.955292,17.417774],[-83.944458,17.414165],[-83.946671,17.405277]]],[[[-83.910568,17.409721],[-83.926392,17.416664],[-83.910004,17.41861000000013],[-83.910568,17.409721]]]]}},{"type":"Feature","properties":{"name":"Croatia","iso2":"HR","iso3":"HRV"},"geometry":{"type":"MultiPolygon","coordinates":[[[[16.90389060974121,42.72610664367676],[16.81389045715332,42.76805305480957],[16.939722061157227,42.768327713012695],[16.90389060974121,42.72610664367676]]],[[[17.7450008392334,42.69194221496582],[17.321664810180664,42.78805732727051],[17.399442672729492,42.79777717590332],[17.7450008392334,42.69194221496582]]],[[[16.820554733276367,42.96000099182129],[17.183610916137695,42.91861152648926],[16.633054733276367,42.98111152648926],[16.820554733276367,42.96000099182129]]],[[[17.298887252807617,43.00694465637207],[17.649843215942383,42.88907814025879],[18.455556869506836,42.56582832336426],[18.503198623657227,42.44944190979004],[17.004167556762695,43.04666328430176],[17.298887252807617,43.00694465637207]]],[[[16.20833396911621,43.02221870422363],[16.050554275512695,43.06305122375488],[16.251943588256836,43.07249641418457],[16.20833396911621,43.02221870422363]]],[[[16.562036514282227,43.230852127075195],[17.19008445739746,43.126054763793945],[16.373056411743164,43.194162368774414],[16.562036514282227,43.230852127075195]]],[[[16.851667404174805,43.26916694641113],[16.404722213745117,43.329721450805664],[16.753053665161133,43.36277961730957],[16.851667404174805,43.26916694641113]]],[[[16.390554428100586,43.332773208618164],[16.198331832885742,43.41166114807129],[16.326387405395508,43.39416694641113],[16.390554428100586,43.332773208618164]]],[[[15.687498092651367,43.63083076477051],[15.606668472290039,43.674997329711914],[15.662221908569336,43.66583442687988],[15.687498092651367,43.63083076477051]]],[[[15.34638786315918,43.80888557434082],[15.376668930053711,43.77592658996582],[15.225000381469727,43.873056411743164],[15.34638786315918,43.80888557434082]]],[[[15.446664810180664,43.887216567993164],[15.260831832885742,44.006662368774414],[15.376943588256836,43.96805000305176],[15.446664810180664,43.887216567993164]]],[[[15.250555038452148,44.01666450500488],[15.062498092651367,44.1572208404541],[15.24305534362793,44.053056716918945],[15.250555038452148,44.01666450500488]]],[[[14.855276107788086,44.17527961730957],[15.226388931274414,43.90110969543457],[15.13749885559082,43.89638710021973],[14.855276107788086,44.17527961730957]]],[[[14.838655471801758,44.6095027923584],[14.732778549194336,44.69805335998535],[15.24888801574707,44.327775955200195],[14.838655471801758,44.6095027923584]]],[[[14.521944046020508,44.47416114807129],[14.367498397827148,44.59027290344238],[14.337499618530273,44.710275650024414],[14.521944046020508,44.47416114807129]]],[[[14.75731086730957,44.803754806518555],[14.865278244018555,44.70666694641113],[14.65925407409668,44.79473686218262],[14.75731086730957,44.803754806518555]]],[[[14.455076217651367,44.90970039367676],[14.49333381652832,44.60638618469238],[14.294137954711914,44.90724754333496],[14.400278091430664,44.9152774810791],[14.315279006958008,45.174997329711914],[14.455076217651367,44.90970039367676]]],[[[14.755834579467773,44.94138526916504],[14.428888320922852,45.07833290100098],[14.539167404174805,45.23944282531738],[14.755834579467773,44.94138526916504]]],[[[16.572500228881836,46.47527503967285],[16.607873916625977,46.47623634338379],[17.669443130493164,45.83500099182129],[18.8170223236084,45.91296577453613],[18.98032569885254,45.37862586975098],[19.423887252807617,45.22583198547363],[19.03972053527832,44.86138343811035],[18.251943588256836,45.13888740539551],[15.786664962768555,45.171945571899414],[16.143056869506836,44.19944190979004],[17.578527450561523,42.94382667541504],[16.884443283081055,43.40305519104004],[15.988332748413086,43.50444221496582],[14.482778549194336,45.311105728149414],[14.292776107788086,45.32499885559082],[13.899168014526367,44.77443885803223],[13.591741561889648,45.481698989868164],[14.601388931274414,45.67527961730957],[15.174459457397461,45.42582130432129],[15.697778701782227,45.84416389465332],[15.654722213745117,46.21944618225098],[16.572500228881836,46.47527503967285]]]]}},{"type":"Feature","properties":{"name":"Hungary","iso2":"HU","iso3":"HUN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[18.81702,45.912964],[17.669441,45.834999],[16.607872,46.476234],[16.111805,46.86972],[16.510555,47.00666],[16.713886,47.543884],[16.450554,47.698051],[17.053886,47.709442],[17.166386,48.012497],[17.251656,48.024994],[18.655277,47.758606],[20.660553,48.563332],[22.151442,48.411919],[22.894804,47.95454],[22.032497,47.530273],[21.176666,46.295555],[20.726955,46.17556],[20.261024,46.114853],[18.81702,45.912964]]]]}},{"type":"Feature","properties":{"name":"Iceland","iso2":"IS","iso3":"ISL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-15.070835,66.1436],[-14.618891,65.994431],[-14.848333,65.731384],[-14.336668,65.783051],[-14.563612,65.494995],[-13.611389,65.509995],[-13.570278,65.25943],[-14.034723,65.193054],[-13.499445,65.069153],[-14.511112,64.797485],[-14.539167,64.406097],[-14.925001,64.26416],[-15.383335,64.371933],[-18.710003,63.391106],[-21.053612,63.945],[-22.689167,63.80555],[-22.703335,64.080826],[-21.36278,64.384987],[-22.102501,64.314438],[-21.508057,64.645554],[-22.170834,64.453888],[-22.407223,64.812485],[-24.059532,64.890884],[-21.835835,65.030273],[-22.56139,65.171097],[-21.698612,65.449158],[-24.542225,65.497772],[-23.805557,65.530548],[-24.105835,65.806656],[-23.226391,65.741653],[-23.873058,65.866653],[-23.213337,65.837494],[-23.81889,66.013321],[-23.371113,65.986664],[-23.665558,66.111099],[-23.473614,66.199158],[-22.424725,65.847488],[-22.972225,66.221375],[-22.43417,66.267776],[-23.188614,66.349716],[-22.9375,66.466385],[-21.399445,66.027222],[-21.603058,65.953323],[-21.33778,65.733322],[-21.777779,65.765823],[-21.084446,65.159164],[-20.927223,65.588882],[-20.446667,65.494995],[-20.424446,66.083054],[-20.179169,66.12944],[-19.451668,65.72583],[-19.453056,66.056381],[-18.784168,66.191101],[-18.069447,65.643326],[-18.299446,66.174713],[-16.594723,66.09111],[-16.527779,66.508041],[-15.381945,66.142776],[-14.710835,66.367218],[-15.070835,66.1436]]]]}},{"type":"Feature","properties":{"name":"India","iso2":"IN","iso3":"IND"},"geometry":{"type":"MultiPolygon","coordinates":[[[[93.91276741027832,7.02861213684082],[93.8238697052002,6.745553970336914],[93.67109870910645,7.181943893432617],[93.91276741027832,7.02861213684082]]],[[[93.66220283508301,7.405832290649414],[93.6544361114502,7.417501449584961],[93.66415596008301,7.41472053527832],[93.66220283508301,7.405832290649414]]],[[[93.63943672180176,7.247220993041992],[93.69359016418457,7.43889045715332],[93.72831916809082,7.32472038269043],[93.63943672180176,7.247220993041992]]],[[[93.45471382141113,7.868890762329102],[93.34942817687988,7.879999160766602],[93.31749153137207,7.997499465942383],[93.45471382141113,7.868890762329102]]],[[[93.57361030578613,7.927778244018555],[93.50277900695801,7.97722053527832],[93.5405445098877,8.015554428100586],[93.57361030578613,7.927778244018555]]],[[[93.48803901672363,7.988889694213867],[93.44304084777832,8.15361213684082],[93.5133228302002,8.226388931274414],[93.48803901672363,7.988889694213867]]],[[[73.03221321105957,8.246664047241211],[73.02083015441895,8.268610000610352],[73.0788745880127,8.310277938842773],[73.03221321105957,8.246664047241211]]],[[[93.16914558410645,8.201387405395508],[93.05998420715332,8.271665573120117],[93.07388496398926,8.348054885864258],[93.16914558410645,8.201387405395508]]],[[[93.60942268371582,8.429998397827148],[93.60193061828613,8.565275192260742],[93.62608528137207,8.508054733276367],[93.60942268371582,8.429998397827148]]],[[[92.7744312286377,9.124719619750977],[92.7088794708252,9.163610458374023],[92.76165962219238,9.263612747192383],[92.7744312286377,9.124719619750977]]],[[[73.63749885559082,10.052778244018555],[73.6302661895752,10.071111679077148],[73.64554023742676,10.097497940063477],[73.63749885559082,10.052778244018555]]],[[[72.63360786437988,10.550832748413086],[72.62469673156738,10.552778244018555],[72.65054512023926,10.577497482299805],[72.63360786437988,10.550832748413086]]],[[[73.68414497375488,10.823053359985352],[73.66220283508301,10.827775955200195],[73.68525886535645,10.829999923706055],[73.68414497375488,10.823053359985352]]],[[[72.17997932434082,10.817499160766602],[72.17053413391113,10.809720993041992],[72.19748115539551,10.872774124145508],[72.17997932434082,10.817499160766602]]],[[[92.49275398254395,10.518331527709961],[92.34665107727051,10.69416618347168],[92.49498176574707,10.90110969543457],[92.49275398254395,10.518331527709961]]],[[[72.29915046691895,10.938055038452148],[72.28943061828613,10.942777633666992],[72.30137825012207,10.954164505004883],[72.29915046691895,10.938055038452148]]],[[[72.74942207336426,11.108888626098633],[72.73665046691895,11.107221603393555],[72.7472095489502,11.120553970336914],[72.74942207336426,11.108888626098633]]],[[[72.10748481750488,11.202775955200195],[72.09971809387207,11.201108932495117],[72.10803413391113,11.215555191040039],[72.10748481750488,11.202775955200195]]],[[[72.77832221984863,11.188886642456055],[72.77083015441895,11.201108932495117],[72.78915596008301,11.25694465637207],[72.77832221984863,11.188886642456055]]],[[[73.00694465637207,11.476663589477539],[73.00444221496582,11.507501602172852],[73.0133228302002,11.502222061157227],[73.00694465637207,11.476663589477539]]],[[[92.63304328918457,11.354166030883789],[92.64360237121582,11.514165878295898],[92.70332527160645,11.385557174682617],[92.63304328918457,11.354166030883789]]],[[[92.2713794708252,11.524442672729492],[92.2169361114502,11.594720840454102],[92.27581977844238,11.582220077514648],[92.2713794708252,11.524442672729492]]],[[[72.71249580383301,11.68861198425293],[72.7008228302002,11.68638801574707],[72.71527290344238,11.69999885559082],[72.71249580383301,11.68861198425293]]],[[[93.05832099914551,11.888612747192383],[92.94331550598145,11.98277473449707],[92.97859382629395,12.033609390258789],[93.05832099914551,11.888612747192383]]],[[[93.13611030578613,12.131940841674805],[93.12553596496582,12.133890151977539],[93.1313648223877,12.149168014526367],[93.13611030578613,12.131940841674805]]],[[[92.7170581817627,12.182806015014648],[92.71859931945801,11.491109848022461],[92.5244312286377,11.854166030883789],[92.7170581817627,12.182806015014648]]],[[[93.09387397766113,12.088052749633789],[93.0608081817627,12.143888473510742],[93.08665657043457,12.207220077514648],[93.09387397766113,12.088052749633789]]],[[[93.86554145812988,12.259164810180664],[93.84860420227051,12.27583122253418],[93.8733081817627,12.277498245239258],[93.86554145812988,12.259164810180664]]],[[[92.78253364562988,12.287679672241211],[92.77415657043457,12.290555953979492],[92.78332710266113,12.293889999389648],[92.78253364562988,12.287679672241211]]],[[[92.83161354064941,12.316526412963867],[92.90165901184082,12.265832901000977],[92.75427436828613,12.07133674621582],[92.83161354064941,12.316526412963867]]],[[[92.90498542785645,12.380830764770508],[92.87275886535645,12.405832290649414],[92.91081428527832,12.404165267944336],[92.90498542785645,12.380830764770508]]],[[[92.92859077453613,12.90916633605957],[92.98748970031738,12.508611679077148],[92.75888252258301,12.304998397827148],[92.92859077453613,12.90916633605957]]],[[[92.69108772277832,12.796110153198242],[92.66887092590332,12.855276107788086],[92.71443367004395,12.989999771118164],[92.69108772277832,12.796110153198242]]],[[[92.87581062316895,13.391389846801758],[92.86665534973145,13.400556564331055],[92.87608528137207,13.403886795043945],[92.87581062316895,13.391389846801758]]],[[[94.27693367004395,13.413610458374023],[94.26388740539551,13.430276870727539],[94.28415107727051,13.44416618347168],[94.27693367004395,13.413610458374023]]],[[[93.06442451477051,13.237497329711914],[92.81341743469238,12.897920608520508],[93.00387763977051,13.571111679077148],[93.06442451477051,13.237497329711914]]],[[[93.04942512512207,13.639444351196289],[92.99304389953613,13.661664962768555],[93.03637886047363,13.679998397827148],[93.04942512512207,13.639444351196289]]],[[[80.94803047180176,15.736665725708008],[80.87858772277832,15.843332290649414],[80.99193000793457,15.765832901000977],[80.94803047180176,15.736665725708008]]],[[[82.3708667755127,16.86777687072754],[82.37082099914551,16.85833168029785],[82.36886787414551,16.871110916137695],[82.3708667755127,16.86777687072754]]],[[[88.89721870422363,21.524999618530273],[88.8449878692627,21.526945114135742],[88.82554817199707,21.5594425201416],[88.83638191223145,21.605833053588867],[88.90860176086426,21.5686092376709],[88.89721870422363,21.524999618530273]]],[[[72.71805000305176,21.606386184692383],[72.60331916809082,21.64361000061035],[72.76609992980957,21.655275344848633],[72.71805000305176,21.606386184692383]]],[[[88.13472175598145,21.619997024536133],[88.04498481750488,21.660829544067383],[88.13247871398926,21.876108169555664],[88.13472175598145,21.619997024536133]]],[[[88.6463794708252,21.8255558013916],[88.64499092102051,21.78472328186035],[88.59359931945801,21.79777717590332],[88.57916450500488,21.82694435119629],[88.64193916320801,21.921663284301758],[88.6463794708252,21.8255558013916]]],[[[88.08859443664551,21.849443435668945],[88.11303901672363,21.948606491088867],[88.1352710723877,21.907499313354492],[88.08859443664551,21.849443435668945]]],[[[78.07554817199707,35.44582557678223],[78.30914497375488,34.64249610900879],[78.98535346984863,34.35001564025879],[78.81164741516113,33.525827407836914],[79.53027534484863,32.754167556762695],[78.97110176086426,32.35083198547363],[78.76054573059082,32.63555335998535],[78.39776802062988,32.54860877990723],[78.76721382141113,31.309999465942383],[79.09248542785645,31.437498092651367],[81.02536201477051,30.204355239868164],[80.37692451477051,29.748605728149414],[80.05581855773926,28.836111068725586],[82.0664005279541,27.914155960083008],[83.29136848449707,27.337778091430664],[84.14721870422363,27.511388778686523],[85.85554695129395,26.570276260375977],[88.01471138000488,26.364721298217773],[88.14279365539551,27.866056442260742],[88.83166694641113,28.013334274291992],[88.91772651672363,27.32032585144043],[88.89387702941895,26.975553512573242],[89.64305305480957,26.715272903442383],[92.06999397277832,26.8619441986084],[92.11360359191895,27.29749870300293],[91.65776252746582,27.76472282409668],[92.54498481750488,27.861940383911133],[94.64750862121582,29.333459854125977],[95.38777351379395,29.035276412963867],[96.07748603820801,29.46860694885254],[96.39526557922363,29.255277633666992],[96.16914558410645,28.903608322143555],[96.47082710266113,29.056665420532227],[96.61581611633301,28.7902774810791],[96.40193367004395,28.351110458374023],[97.34887886047363,28.2227725982666],[96.88665962219238,27.606107711791992],[97.13665962219238,27.085832595825195],[96.19413948059082,27.27083396911621],[95.1413745880127,26.612497329711914],[95.17804145812988,26.058889389038086],[94.62553596496582,25.397775650024414],[94.73442268371582,25.024721145629883],[94.15109443664551,23.855276107788086],[93.33873176574707,24.077917098999023],[93.19664192199707,22.25638771057129],[92.60081672668457,21.98221778869629],[92.28332710266113,23.70527458190918],[91.94999885559082,23.73221778869629],[91.61360359191895,22.943052291870117],[91.15942573547363,23.640554428100586],[91.37329292297363,24.10194206237793],[92.12137031555176,24.39333152770996],[92.40637397766113,25.030553817749023],[89.84526252746582,25.288610458374023],[89.7391529083252,26.15638542175293],[89.34277534484863,26.017030715942383],[88.43304634094238,26.551389694213867],[88.11053657531738,25.835554122924805],[89.00943183898926,25.288331985473633],[88.4508228302002,25.187776565551758],[88.04332160949707,24.68416404724121],[88.75053596496582,24.220983505249023],[88.56387519836426,23.652219772338867],[88.9861011505127,23.208330154418945],[89.0630054473877,22.115476608276367],[89.00555610656738,21.903608322143555],[89.0888843536377,21.628053665161133],[89.00749397277832,21.600000381469727],[88.85554695129395,21.632776260375977],[88.78442573547363,21.556943893432617],[88.70721626281738,21.566389083862305],[88.66775703430176,22.202219009399414],[88.55693244934082,21.81333351135254],[88.62858772277832,21.749162673950195],[88.57222175598145,21.559999465942383],[88.49609565734863,21.950273513793945],[88.2541675567627,21.548608779907227],[88.19941902160645,22.155275344848633],[87.90776252746582,22.421663284301758],[88.16804695129395,22.091665267944336],[87.79637336730957,21.698884963989258],[86.96331977844238,21.381940841674805],[87.02556037902832,20.674829483032227],[86.42025947570801,19.98277473449707],[85.45138740539551,19.660276412963867],[85.43488502502441,19.88701057434082],[84.10637092590332,18.29222297668457],[82.36442756652832,17.100831985473633],[82.30169868469238,16.58305549621582],[81.3133716583252,16.363332748413086],[81.01727485656738,15.775556564331055],[80.89193916320801,16.02610969543457],[80.82527351379395,15.751943588256836],[80.2794361114502,15.699167251586914],[80.04887580871582,15.048887252807617],[80.31303596496582,13.439165115356445],[80.04942512512207,13.617776870727539],[80.34971809387207,13.334165573120117],[79.76304817199707,11.648889541625977],[79.85971260070801,10.288888931274414],[79.32499885559082,10.280832290649414],[78.90803718566895,9.479719161987305],[79.45138740539551,9.149999618530273],[78.39665412902832,9.089719772338867],[78.06053352355957,8.364164352416992],[77.53610420227051,8.071943283081055],[76.5758228302002,8.876943588256836],[75.68887519836426,11.435277938842773],[74.81025886535645,12.864721298217773],[74.41192817687988,14.483331680297852],[73.44775581359863,16.05583381652832],[72.85386848449707,18.660554885864258],[73.05554389953613,19.011945724487305],[72.76999092102051,18.943052291870117],[72.78055000305176,19.312498092651367],[73.04722785949707,19.217256546020508],[72.66415596008301,19.870832443237305],[72.93441963195801,20.774721145629883],[72.56414985656738,21.378053665161133],[73.13081550598145,21.753610610961914],[72.54165840148926,21.66388511657715],[72.73442268371582,21.98638343811035],[72.50082588195801,21.97666358947754],[72.91914558410645,22.267778396606445],[72.15193367004395,22.28388786315918],[72.11053657531738,21.201940536499023],[70.81888008117676,20.69749641418457],[68.94442939758301,22.294164657592773],[70.1655445098877,22.5483341217041],[70.50694465637207,23.10222053527832],[69.21582221984863,22.84027671813965],[68.43304634094238,23.42999839782715],[68.74136543273926,23.84416389465332],[68.32138252258301,23.58083152770996],[68.19780158996582,23.766687393188477],[68.7472095489502,23.969995498657227],[68.78305244445801,24.33277702331543],[70.01471138000488,24.16971778869629],[71.10582160949707,24.4163875579834],[70.66638374328613,25.698331832885742],[70.08804512023926,25.98277473449707],[70.18359565734863,26.53611183166504],[69.50610542297363,26.754446029663086],[69.58027839660645,27.173330307006836],[70.36831855773926,28.02083396911621],[70.82943916320801,27.706384658813477],[71.89694404602051,27.961942672729492],[73.39749336242676,29.942773818969727],[73.93340492248535,30.136003494262695],[73.87249946594238,30.390100479125977],[74.69458961486816,31.0539608001709],[74.60532569885254,31.877119064331055],[75.38128852844238,32.214242935180664],[74.01638984680176,33.18860054016113],[73.99054145812988,33.74388313293457],[74.29582405090332,33.977487564086914],[73.91331672668457,34.06860542297363],[73.94165229797363,34.64638710021973],[76.86998176574707,34.658884048461914],[77.04248237609863,35.09916114807129],[77.82393074035645,35.50132942199707],[78.07554817199707,35.44582557678223]],[[86.28360176086426,20.038053512573242],[86.27609443664551,20.05000114440918],[86.25139045715332,20.045000076293945],[86.28360176086426,20.038053512573242]]]]}},{"type":"Feature","properties":{"name":"Iran (Islamic Republic of)","iso2":"IR","iso3":"IRN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[54.034439000000106,26.484718],[53.903603,26.536110000000107],[54.0188830000001,26.554165],[54.034439000000106,26.484718]]],[[[53.31805400000016,26.79777500000013],[53.203323,26.802498000000114],[53.151657,26.846386],[53.31805400000016,26.79777500000013]]],[[[56.346657,26.822220000000144],[56.34388,26.884163],[56.4086,26.885551],[56.346657,26.822220000000144]]],[[[55.734993,26.838051000000135],[55.63276700000014,26.794720000000112],[55.688599,26.929161],[55.734993,26.838051000000135]]],[[[56.24527000000015,26.927494],[55.283607,26.558609],[55.769989,26.792774],[55.75222000000011,26.951939],[56.24527000000015,26.927494]]],[[[56.470825,27.037777],[56.434715,27.086941],[56.469986,27.108608000000103],[56.509163,27.071663],[56.470825,27.037777]]],[[[50.32888000000017,29.20805],[50.291382,29.278053],[50.338326,29.268887],[50.32888000000017,29.20805]]],[[[45.004433,39.416382],[46.1782460000002,38.841148],[46.54037500000018,38.875587],[47.976662,39.719231],[48.359787,39.385216],[48.020821,38.835541],[48.88828300000014,38.442406],[49.10248600000014,37.64304400000013],[50.191376,37.38916000000016],[51.10110500000022,36.728874],[53.943321,36.799995],[53.90564,37.35085300000016],[54.681107,37.443604],[55.442764,38.08610500000013],[57.21221200000011,38.28193700000013],[57.45027200000018,37.939156000000125],[59.338882,37.539162],[60.333054000000146,36.656097000000116],[61.1572110000001,36.649994],[61.27655800000011,35.60724600000013],[60.721657,34.522217],[60.87887600000013,34.319717],[60.50833100000014,34.140274],[60.527771,33.64415700000011],[60.94304700000012,33.51944],[60.582497,33.06610100000013],[60.84388,31.498329],[61.713608,31.383331],[61.8511050000001,31.021111],[60.86859900000016,29.863884],[61.90554800000015,28.554996],[62.78138,28.266941],[62.782494000000185,27.260555],[63.34193400000012,27.122498],[63.17638400000013,26.631107],[61.858047,26.234718],[61.61103100000017,25.197647],[57.3180540000001,25.770832],[56.690544,27.148331],[56.132767,27.160275],[54.794716000000136,26.489994],[53.7477720000002,26.70916],[52.440269,27.640831],[51.430275,27.937775000000116],[50.048607,30.207222],[49.551384,30.0075],[48.98499300000017,30.513054000000167],[48.92054700000014,30.043053000000114],[48.545555,29.96303],[48.032494,30.491383],[48.036385,30.997494000000117],[47.693878,31.00111],[47.864441,31.798607000000104],[47.434158,32.397774000000126],[46.107216,32.967491],[46.181938,33.260277],[45.401054,33.9795680000001],[45.797733,34.91404],[46.171364,35.113411],[45.979988,35.584717],[46.346939000000106,35.817215],[45.405823,35.99082900000012],[44.787338,37.149712],[44.61805,37.727768],[44.223969,37.899151],[44.484154,38.345543],[44.034157,39.3849950000001],[44.4161,39.425262],[44.605820000000136,39.78054],[44.813042,39.630814],[45.004433,39.416382]]]]}},{"type":"Feature","properties":{"name":"Israel","iso2":"IL","iso3":"ISR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[35.25972000000016,31.78722000000012],[35.251663,31.788055000000114],[35.24888600000011,31.808887000000155],[35.25972000000016,31.78722000000012]]],[[[35.623634,33.245728],[35.648888,32.685272],[35.552567,32.394196],[35.282494,32.516937],[34.884995,31.391388],[35.47819500000011,31.497322],[34.97998,29.545753000000147],[34.903801,29.486706],[34.26757800000021,31.216541],[34.33416,31.25972],[34.490547,31.596096000000117],[35.10083,33.093605000000125],[35.623634,33.245728]]]]}},{"type":"Feature","properties":{"name":"Italy","iso2":"IT","iso3":"ITA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[12.127777,47.00166300000011],[12.440554000000134,46.69082600000014],[13.718655,46.526611],[13.383055,46.297218],[13.669167,46.177498],[13.480000000000103,46.011108],[13.919167,45.637497],[13.716944,45.596107],[13.193333,45.778053],[12.281387000000166,45.46804800000017],[12.16111,45.263885],[12.539165,44.961105],[12.245554,44.715828000000116],[12.368332000000123,44.246666],[13.621666,43.553886],[14.016666,42.66999800000015],[14.739721,42.085548000000145],[16.141941,41.914162],[15.932499000000178,41.47805],[18.011665,40.6444400000001],[18.512218,40.13666500000012],[18.349442,39.79193900000014],[17.859165000000132,40.283607],[16.913609000000122,40.44554900000013],[16.486664000000133,39.767494],[17.151108000000193,39.389999],[17.16916700000013,38.963333],[16.59499700000015,38.800827000000154],[16.062496,37.92416400000012],[15.631666000000166,38.011665],[16.2225,38.910828],[15.666666,40.03083],[11.098888,42.39305100000011],[10.107498,44.00750000000015],[8.748888000000136,44.42916100000018],[7.528055,43.788605],[7.662222,44.17083000000012],[6.976388,44.284164],[7.031666000000115,44.831383000000116],[6.61976,45.110138],[7.127777,45.257774],[6.798970000000168,45.78067],[7.038054,45.93193800000013],[7.855742,45.91905200000012],[8.436388000000136,46.463333000000105],[9.036665,45.837776],[9.281944000000124,46.49582700000015],[10.129999000000112,46.22721900000015],[10.050278000000105,46.539993],[10.465277000000128,46.546387],[10.471235,46.871353],[12.127777,47.00166300000011]],[[12.459166,43.896111],[12.509998,43.986938],[12.415798,43.957954],[12.459166,43.896111]],[[12.445090330888661,41.90311752178489],[12.456660170953796,41.901426024699205],[12.45165333958056,41.907989033391274],[12.445090330888661,41.90311752178489]]],[[[12.422777,45.420555],[12.323610000000144,45.343887],[12.373333,45.42805500000013],[12.422777,45.420555]]],[[[9.844166,43.03443900000012],[9.80694400000013,43.00972],[9.804165,43.063889],[9.8316650000001,43.07555400000011],[9.844166,43.03443900000012]]],[[[10.441111,42.84444400000011],[10.423054000000121,42.708885],[10.101944000000174,42.772499],[10.441111,42.84444400000011]]],[[[10.088333,42.57222],[10.081944000000135,42.618889],[10.101665,42.593605],[10.088333,42.57222]]],[[[10.915833000000134,42.325272],[10.866388,42.35860400000011],[10.877777000000123,42.388054],[10.915833000000134,42.325272]]],[[[10.316666000000112,42.3174970000001],[10.293055,42.349998],[10.326111,42.34333],[10.316666000000112,42.3174970000001]]],[[[9.513332,41.14666],[9.825832000000105,40.526108],[9.569166000000166,39.15055100000011],[9.018332,39.266388],[8.859165000000132,38.879166],[8.406944,38.958611],[8.556665,39.86610400000016],[8.192499,40.913605],[9.513332,41.14666]]],[[[8.339167,41.06249200000012],[8.215277,40.992493],[8.321110000000147,41.121384],[8.339167,41.06249200000012]]],[[[12.964167000000145,40.883888],[12.950277000000199,40.91777],[12.988054,40.931389000000124],[12.964167000000145,40.883888]]],[[[13.951387000000182,40.701385000000144],[13.853888,40.734718],[13.948055000000181,40.742493],[13.951387000000182,40.701385000000144]]],[[[14.210554,40.560555],[14.261944,40.55555],[14.197222000000124,40.536659000000114],[14.210554,40.560555]]],[[[8.292221,39.09360500000018],[8.223888,39.164719],[8.302776,39.189995],[8.292221,39.09360500000018]]],[[[15.21361,38.770554],[15.190277,38.79055],[15.239166,38.806107],[15.21361,38.770554]]],[[[13.17333200000013,38.690277],[13.162222,38.714439],[13.198332000000136,38.711388],[13.17333200000013,38.690277]]],[[[14.868332000000152,38.531387],[14.794722,38.567772],[14.86861,38.57804900000012],[14.868332000000152,38.531387]]],[[[14.955276,38.445549000000184],[14.912222,38.516663],[14.96388800000011,38.517494],[14.955276,38.445549000000184]]],[[[14.988888,38.36416600000014],[14.941111,38.399437000000106],[14.958887,38.431107],[14.988888,38.36416600000014]]],[[[15.528889,38.13694],[15.086666,37.47943900000011],[15.316666,37.008888],[15.081388000000118,36.649162],[12.422222,37.796104],[13.316666,38.21833],[13.768888,37.970551],[15.528889,38.13694]]],[[[12.073889000000179,37.953606],[12.029999,37.986938],[12.059166,37.98916600000014],[12.073889000000179,37.953606]]],[[[12.354166,37.906105],[12.271387000000175,37.936386],[12.339167,37.934441],[12.354166,37.906105]]],[[[12.015833,36.738327],[11.93083200000018,36.82972],[12.048332,36.796944],[12.015833,36.738327]]]]}},{"type":"Feature","properties":{"name":"Cote d'Ivoire","iso2":"CI","iso3":"CIV"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-3.102272,5.109545000000125],[-3.103041,5.085022],[-3.168334,5.117222],[-3.102272,5.109545000000125]]],[[[-4.787278,5.1683120000001],[-4.146389,5.277222],[-4.004445,5.231667],[-4.787278,5.1683120000001]]],[[[-4.787278,5.1683120000001],[-5.319723,5.230833],[-5.002929,5.129237],[-7.525402,4.352806000000101],[-7.423334,5.839444],[-8.606383999999878,6.507815],[-8.308334,6.860833000000113],[-8.469749,7.561325],[-7.946838,8.018505],[-8.198056999999892,8.496666],[-7.646536,8.378416],[-7.957778,8.813332],[-7.732779,9.088055],[-8.143612,9.533888000000104],[-7.973984,10.165611],[-7.635555999999895,10.448332000000107],[-6.988056,10.147499],[-6.243402,10.735256],[-6.111389,10.197777],[-5.51985,10.436272],[-4.704445,9.698055],[-3.633611,9.954443000000111],[-2.685561,9.481817],[-2.487778,8.197777000000116],[-3.249166999999886,6.611388],[-2.764445,5.579166],[-2.928128,5.100222],[-3.1425,5.367777],[-3.29722299999986,5.118055],[-4.004168,5.253611],[-3.807778,5.375555000000119],[-4.787278,5.1683120000001]]]]}},{"type":"Feature","properties":{"name":"Iraq","iso2":"IQ","iso3":"IRQ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[45.797733,34.91404],[45.401054,33.9795680000001],[46.181938,33.260277],[46.107216,32.967491],[47.434158,32.397774000000126],[47.864441,31.798607000000104],[47.693878,31.00111],[48.036385,30.997494000000117],[48.032494,30.491383],[48.545555,29.96303],[48.54332,29.926662],[48.443047,29.927498],[48.158875,30.038052],[47.943474,30.017555],[47.9310990000001,30.018887],[47.169991,30.015270000000115],[46.546944,29.104198],[44.72166100000018,29.198330000000126],[42.084999,31.11166000000013],[40.41333,31.94833],[39.196743,32.154942],[38.794701,33.377594],[41.003876,34.419434],[41.290276,36.355553],[42.355614,37.106926],[42.790825000000126,37.384720000000144],[44.116379,37.316376],[44.317215,36.970543],[44.787338,37.149712],[45.405823,35.99082900000012],[46.346939000000106,35.817215],[45.979988,35.584717],[46.171364,35.113411],[45.797733,34.91404]]]]}},{"type":"Feature","properties":{"name":"Japan","iso2":"JP","iso3":"JPN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[153.958589553833,24.295000076293945],[153.93969917297363,24.300832748413086],[153.95276069641113,24.321386337280273],[153.958589553833,24.295000076293945]]],[[[123.87082099914551,24.252500534057617],[123.67886543273926,24.316110610961914],[123.92192268371582,24.371110916137695],[123.87082099914551,24.252500534057617]]],[[[122.99693489074707,24.438886642456055],[122.93525886535645,24.458051681518555],[123.00943183898926,24.46693992614746],[122.99693489074707,24.438886642456055]]],[[[131.26416206359863,24.45499610900879],[131.243013381958,24.48444175720215],[131.27359199523926,24.475828170776367],[131.26416206359863,24.45499610900879]]],[[[124.26165962219238,24.45749855041504],[124.21914863586426,24.335275650024414],[124.0758228302002,24.424718856811523],[124.32443428039551,24.587499618530273],[124.26165962219238,24.45749855041504]]],[[[141.30914497375488,24.7480525970459],[141.2902545928955,24.77805519104004],[141.35745429992676,24.788888931274414],[141.30914497375488,24.7480525970459]]],[[[125.35637092590332,24.77666664123535],[125.45110511779785,24.739717483520508],[125.2572193145752,24.729162216186523],[125.2633228302002,24.884164810180664],[125.35637092590332,24.77666664123535]]],[[[141.29358100891113,25.4183292388916],[141.26831245422363,25.445276260375977],[141.29358100891113,25.451387405395508],[141.29358100891113,25.4183292388916]]],[[[131.24383735656738,25.816667556762695],[131.20800971984863,25.83333396911621],[131.250825881958,25.872220993041992],[131.24383735656738,25.816667556762695]]],[[[126.76193428039551,26.38694190979004],[126.78720283508301,26.296945571899414],[126.69220161437988,26.36055564880371],[126.76193428039551,26.38694190979004]]],[[[142.17776679992676,26.622499465942383],[142.11136054992676,26.715272903442383],[142.1530475616455,26.687219619750977],[142.17776679992676,26.622499465942383]]],[[[128.252779006958,26.638887405395508],[127.65277290344238,26.08305549621582],[127.88388252258301,26.667497634887695],[128.287202835083,26.854997634887695],[128.252779006958,26.638887405395508]]],[[[142.23245429992676,27.033334732055664],[142.178316116333,27.07527732849121],[142.23330879211426,27.08916664123535],[142.23245429992676,27.033334732055664]]],[[[142.19470405578613,27.148332595825195],[142.17859077453613,27.15666389465332],[142.19412422180176,27.19110679626465],[142.19470405578613,27.148332595825195]]],[[[140.878023147583,27.225828170776367],[140.86413764953613,27.21944236755371],[140.87219429016113,27.243051528930664],[140.878023147583,27.225828170776367]]],[[[128.60913276672363,27.358888626098633],[128.52359199523926,27.413610458374023],[128.70190620422363,27.445829391479492],[128.60913276672363,27.358888626098633]]],[[[142.1955280303955,27.599164962768555],[142.16998481750488,27.624719619750977],[142.19330024719238,27.61777687072754],[142.1955280303955,27.599164962768555]]],[[[142.08914375305176,27.717775344848633],[142.06884956359863,27.72666358947754],[142.08691596984863,27.73221778869629],[142.08914375305176,27.717775344848633]]],[[[128.95108222961426,27.67582893371582],[128.9474811553955,27.907499313354492],[129.02997016906738,27.774442672729492],[128.95108222961426,27.67582893371582]]],[[[129.33609199523926,28.07527732849121],[129.21911811828613,28.097776412963867],[129.19107246398926,28.188608169555664],[129.33609199523926,28.07527732849121]]],[[[129.99218940734863,28.281667709350586],[129.91497993469238,28.296110153198242],[130.02746772766113,28.36638832092285],[129.99218940734863,28.281667709350586]]],[[[129.71551704406738,28.451108932495117],[129.37552070617676,28.11527442932129],[129.14358711242676,28.250276565551758],[129.71551704406738,28.451108932495117]]],[[[129.73303413391113,29.60972023010254],[129.70608711242676,29.647497177124023],[129.74133491516113,29.663331985473633],[129.73303413391113,29.60972023010254]]],[[[129.89636421203613,29.87416648864746],[129.92190742492676,29.819719314575195],[129.851900100708,29.85222053527832],[129.89636421203613,29.87416648864746]]],[[[129.96301460266113,29.95722007751465],[129.9274616241455,29.97443962097168],[129.92859077453613,30.000001907348633],[129.96301460266113,29.95722007751465]]],[[[130.55859565734863,30.23638343811035],[130.38272285461426,30.393888473510742],[130.66638374328613,30.381940841674805],[130.55859565734863,30.23638343811035]]],[[[140.33026313781738,30.462495803833008],[140.30304145812988,30.47527503967285],[140.32913398742676,30.479162216186523],[140.33026313781738,30.462495803833008]]],[[[130.906099319458,30.354719161987305],[130.86941719055176,30.469717025756836],[131.05359077453613,30.84027671813965],[130.906099319458,30.354719161987305]]],[[[129.72134590148926,31.632219314575195],[129.67053413391113,31.6583309173584],[129.78274726867676,31.793333053588867],[129.72134590148926,31.632219314575195]]],[[[140.02554512023926,31.933053970336914],[139.99939155578613,31.942495346069336],[140.00970649719238,31.946664810180664],[140.02554512023926,31.933053970336914]]],[[[130.15774726867676,32.10888862609863],[130.11636543273926,32.21666145324707],[130.1955280303955,32.17694282531738],[130.15774726867676,32.10888862609863]]],[[[130.36941719055176,32.374711990356445],[130.20941352844238,32.44304847717285],[130.44803047180176,32.50527381896973],[130.36941719055176,32.374711990356445]]],[[[130.02997016906738,32.19499397277832],[130.1571979522705,32.54361152648926],[130.208589553833,32.33499336242676],[130.02997016906738,32.19499397277832]]],[[[128.90081977844238,32.64305305480957],[128.60107612609863,32.618600845336914],[128.66079902648926,32.781938552856445],[128.90081977844238,32.64305305480957]]],[[[139.841646194458,33.03499794006348],[139.74356269836426,33.13804817199707],[139.86413764953613,33.10166358947754],[139.841646194458,33.03499794006348]]],[[[129.10052680969238,32.97860145568848],[129.05554389953613,32.81638526916504],[129.11773872375488,33.14554786682129],[129.10052680969238,32.97860145568848]]],[[[129.39221382141113,33.16471290588379],[129.45413398742676,33.33166694641113],[129.56469917297363,33.38694190979004],[129.39221382141113,33.16471290588379]]],[[[132.2760944366455,33.75943946838379],[132.1855182647705,33.783334732055664],[132.23053169250488,33.79527473449707],[132.2760944366455,33.75943946838379]]],[[[129.75470161437988,33.726938247680664],[129.65887641906738,33.74499702453613],[129.7016315460205,33.856943130493164],[129.75470161437988,33.726938247680664]]],[[[139.61828804016113,33.83221626281738],[139.5827350616455,33.84360694885254],[139.60107612609863,33.887773513793945],[139.61828804016113,33.83221626281738]]],[[[132.32608222961426,33.89471626281738],[132.184419631958,33.90749549865723],[132.4516315460205,33.92276954650879],[132.32608222961426,33.89471626281738]]],[[[131.21414375305176,33.59554481506348],[131.66971015930176,33.64749336242676],[131.51638984680176,33.26555061340332],[131.90277290344238,33.25694465637207],[131.98941230773926,32.83055305480957],[131.34301948547363,31.37388801574707],[130.66638374328613,30.99666404724121],[130.80859565734863,31.68416404724121],[130.53442573547363,31.528886795043945],[130.63553047180176,31.178884506225586],[130.22802925109863,31.248884201049805],[130.16247749328613,32.00694465637207],[130.56970405578613,32.44249153137207],[130.58746528625488,32.63193702697754],[130.44607734680176,32.62054634094238],[130.60553169250488,32.79138374328613],[130.21109199523926,33.17083168029785],[130.34607124328613,32.664438247680664],[129.7460651397705,32.561105728149414],[129.67553901672363,33.06999397277832],[129.94412422180176,32.99249458312988],[129.57885932922363,33.35360908508301],[130.69079780578613,33.93582344055176],[131.21414375305176,33.59554481506348]],[[129.83331489562988,33.34110450744629],[129.86108589172363,33.37555122375488],[129.81360054016113,33.397775650024414],[129.83331489562988,33.34110450744629]]],[[[139.5260944366455,34.03249549865723],[139.48217964172363,34.06999397277832],[139.5605182647705,34.10610389709473],[139.5260944366455,34.03249549865723]]],[[[132.54553413391113,34.11110877990723],[132.557466506958,34.061105728149414],[132.456636428833,34.08693885803223],[132.52887153625488,34.18249702453613],[132.54553413391113,34.11110877990723]]],[[[132.44885444641113,34.115549087524414],[132.38553047180176,34.243608474731445],[132.4819049835205,34.27916145324707],[132.44885444641113,34.115549087524414]]],[[[132.97107124328613,34.18582344055176],[133.02969551086426,34.29110908508301],[133.05053901672363,34.20971870422363],[132.97107124328613,34.18582344055176]]],[[[129.236909866333,34.08221626281738],[129.21747016906738,34.32193946838379],[129.34939765930176,34.27999305725098],[129.236909866333,34.08221626281738]]],[[[134.22357368469238,34.344438552856445],[134.75305366516113,33.82610511779785],[134.18774604797363,33.23832893371582],[133.5988483428955,33.50139045715332],[132.80304145812988,32.735551834106445],[132.37246894836426,33.466386795043945],[132.01581001281738,33.33721351623535],[132.8991413116455,34.10777473449707],[133.5241413116455,33.961381912231445],[134.22357368469238,34.344438552856445]]],[[[139.27887153625488,34.32110786437988],[139.24856758117676,34.35083198547363],[139.29608345031738,34.41971778869629],[139.27887153625488,34.32110786437988]]],[[[134.3508014678955,34.43443489074707],[134.19275093078613,34.50999641418457],[134.36856269836426,34.55027198791504],[134.3508014678955,34.43443489074707]]],[[[134.7902545928955,34.19332313537598],[134.66693305969238,34.296945571899414],[135.0180377960205,34.5927677154541],[134.7902545928955,34.19332313537598]]],[[[129.33996772766113,34.29471778869629],[129.3002643585205,34.55694007873535],[129.46386909484863,34.68943214416504],[129.33996772766113,34.29471778869629]]],[[[139.45331001281738,34.672494888305664],[139.369966506958,34.69249153137207],[139.37161445617676,34.78166389465332],[139.45331001281738,34.672494888305664]]],[[[133.0705280303955,35.99027442932129],[133.02221870422363,35.99138069152832],[133.01080513000488,36.01444435119629],[133.0705280303955,35.99027442932129]]],[[[133.0988483428955,36.02999305725098],[133.0746784210205,36.07999610900879],[133.13189888000488,36.10000038146973],[133.0988483428955,36.02999305725098]]],[[[133.00219917297363,36.03305244445801],[132.95303535461426,36.06638526916504],[133.0866413116455,36.12388038635254],[133.00219917297363,36.03305244445801]]],[[[133.29193305969238,36.32499885559082],[133.37857246398926,36.20054817199707],[133.25247383117676,36.15249061584473],[133.29193305969238,36.32499885559082]]],[[[137.057466506958,37.14305305480957],[136.95413398742676,37.089433670043945],[136.9111042022705,37.143327713012695],[137.057466506958,37.14305305480957]]],[[[138.43524360656738,38.047494888305664],[138.21829414367676,37.80082893371582],[138.51638984680176,38.32027626037598],[138.43524360656738,38.047494888305664]]],[[[141.27081489562988,41.34249305725098],[142.06970405578613,39.54666328430176],[141.52581977844238,38.26638984680176],[140.9535846710205,38.14805030822754],[140.97552680969238,36.98777198791504],[140.565523147583,36.24749183654785],[140.83719062805176,35.74332618713379],[140.3346881866455,35.13138008117676],[139.77026557922363,34.953325271606445],[139.96856880187988,35.66082191467285],[139.67663764953613,35.135271072387695],[139.17108345031738,35.23610877990723],[138.84747505187988,34.59249305725098],[138.744966506958,35.12276649475098],[138.21414375305176,34.59916114807129],[137.0361042022705,34.564714431762695],[137.34747505187988,34.72221565246582],[136.87774848937988,34.72027015686035],[136.84692573547363,35.07833290100098],[136.51944160461426,34.69249153137207],[136.8991413116455,34.26693916320801],[136.343843460083,34.189714431762695],[135.77221870422363,33.45499610900879],[135.06329536437988,33.87777137756348],[135.333589553833,34.71832466125488],[132.36773872375488,34.35860633850098],[132.05053901672363,33.77249336242676],[131.74579048156738,34.053606033325195],[130.89331245422363,33.92166328430176],[130.94635200500488,34.41638374328613],[131.40555000305176,34.419443130493164],[133.08801460266113,35.58166694641113],[136.07275581359863,35.64860725402832],[135.95941352844238,35.97332191467285],[136.71246528625488,36.75139045715332],[136.78692817687988,37.36221504211426],[137.35635566711426,37.504716873168945],[137.35522651672363,37.43138313293457],[137.03747749328613,37.18194007873535],[136.9213581085205,37.197214126586914],[136.86328315734863,37.08777046203613],[137.3024616241455,36.74638557434082],[138.5805377960205,37.39860725402832],[139.424409866333,38.15165901184082],[140.02276802062988,39.37860298156738],[140.0383014678955,39.803049087524414],[139.70245552062988,39.93194007873535],[140.02054023742676,40.23082160949707],[139.8527545928955,40.60110664367676],[140.26886177062988,40.806657791137695],[140.34857368469238,41.24804878234863],[140.72497749328613,40.82916450500488],[141.14941596984863,40.86221504211426],[141.228853225708,41.229990005493164],[140.763032913208,41.17276954650879],[140.91885566711426,41.53027534484863],[141.27081489562988,41.34249305725098]]],[[[139.56302070617676,42.22860145568848],[139.428316116333,42.061662673950195],[139.4333209991455,42.20193672180176],[139.56302070617676,42.22860145568848]]],[[[145.290864944458,43.53866004943848],[145.22000312805176,43.60255241394043],[145.36108589172363,43.555551528930664],[145.290864944458,43.53866004943848]]],[[[143.97024726867676,44.1411075592041],[143.87774848937988,44.147775650024414],[143.81192207336426,44.16805458068848],[143.97024726867676,44.1411075592041]]],[[[141.25943183898926,45.09804725646973],[141.13470649719238,45.213884353637695],[141.3083209991455,45.18888282775879],[141.25943183898926,45.09804725646973]]],[[[142.0483112335205,45.40471076965332],[143.77221870422363,44.09415626525879],[144.77942085266113,43.9133243560791],[145.34247016906738,44.34415626525879],[145.06997871398926,43.77471351623535],[145.25610542297363,43.31499671936035],[145.82220649719238,43.36944007873535],[143.98968696594238,42.90665626525879],[143.2399616241455,41.92416572570801],[141.79052925109863,42.60638618469238],[140.98608589172363,42.295000076293945],[140.4616413116455,42.56777381896973],[140.28497505187988,42.25305366516113],[141.19912910461426,41.7983341217041],[140.06970405578613,41.41916084289551],[139.83636665344238,42.61527442932129],[140.52887153625488,43.00055122375488],[140.4677448272705,43.36721229553223],[141.4071979522705,43.29138374328613],[141.797212600708,44.6249942779541],[141.57803535461426,45.232492446899414],[142.0483112335205,45.40471076965332]]],[[[141.03943061828613,45.26693916320801],[140.97357368469238,45.46527290344238],[141.07440376281738,45.41415596008301],[141.03943061828613,45.26693916320801]]]]}},{"type":"Feature","properties":{"name":"Jamaica","iso2":"JM","iso3":"JAM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-77.131958,17.878887],[-77.733337,17.84861],[-78.339737,18.362499],[-76.945282,18.394444],[-76.221115,17.904163],[-77.131958,17.878887]]]]}},{"type":"Feature","properties":{"name":"Jordan","iso2":"JO","iso3":"JOR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[34.961388,29.360832],[34.97998,29.545753000000147],[35.47819500000011,31.497322],[35.552567,32.394196],[35.648888,32.685272],[36.837776,32.313606],[38.794701,33.377594],[39.196743,32.154942],[37.005272,31.505554],[38.001389,30.504166],[37.502777,30.00222],[36.743607,29.864719],[36.07,29.188889],[34.961388,29.360832]]]]}},{"type":"Feature","properties":{"name":"Kenya","iso2":"KE","iso3":"KEN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[41.13805400000015,-2.124444],[40.950272,-2.173611],[41.0638890000001,-2.044167],[41.13805400000015,-2.124444]]],[[[35.940552,4.622499],[37.039719,4.375555000000134],[38.121109,3.611666],[39.524437,3.406389],[40.783768,4.287975],[41.171387,3.9425],[41.905167,3.980322],[40.98659500000011,2.829956],[40.998329,-0.866111],[41.558159,-1.674868],[41.31527700000018,-1.958056],[40.891663,-2.019167],[40.96360800000011,-2.298889],[40.854996000000114,-2.236111],[40.638054,-2.55],[40.236664000000104,-2.663333],[39.20302600000011,-4.669618],[37.613609,-3.504167],[37.602776,-2.995833],[33.920273,-1.001111],[33.907219,0.103056],[35.0097200000001,1.895278],[34.463333,3.671389],[33.996666,4.222777000000136],[34.388191,4.609682],[35.940552,4.622499]]]]}},{"type":"Feature","properties":{"name":"Kyrgyzstan","iso2":"KG","iso3":"KGZ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[80.23402400000012,42.19622],[78.080826,41.04078700000015],[76.873871,41.014107],[76.345825,40.35022],[75.69720500000014,40.29911],[75.5780490000001,40.647995],[74.86026000000018,40.519386],[73.9944310000001,40.046043],[73.655685,39.454826],[72.248596,39.191856],[71.473038,39.6213],[70.997757,39.40094],[69.306091,39.539436],[69.540817,40.131378],[70.498032,39.90683],[70.98204,40.244843],[71.710541,40.145767],[73.173035,40.822998],[72.19548,41.006592],[71.69136,41.556335],[71.418045,41.118553],[70.187195,41.52829],[71.276382,42.195511],[70.97081,42.254669],[71.17109700000012,42.69135300000015],[71.747208,42.823586],[73.5197140000001,42.408005],[73.583878,43.038574],[74.293594,43.216904],[75.664429,42.807457],[79.194702,42.795792],[80.23402400000012,42.19622]]]]}},{"type":"Feature","properties":{"name":"Korea, Democratic People's Republic of","iso2":"KP","iso3":"PRK"},"geometry":{"type":"MultiPolygon","coordinates":[[[[124.8461,39.497215],[124.8891600000002,39.605553000000114],[124.934143,39.60833],[124.8461,39.497215]]],[[[130.6388850000001,42.406937],[130.697418,42.292206],[129.699402,41.648605],[129.70941200000013,40.829994],[127.506943,39.724709000000175],[127.393051,39.200829],[128.3635560000001,38.62524400000011],[128.07995600000018,38.311935],[127.106087,38.287498000000156],[126.688492,37.83390800000011],[125.589157,38.027214],[125.724426,37.91082],[125.342758,37.67137900000013],[125.512207,37.88694],[124.980553,37.924438],[125.268051,38.072769],[124.66470300000017,38.121101],[124.993591,38.58832600000012],[125.65332000000015,38.62721300000011],[125.139977,38.79638700000014],[125.44831800000011,39.576385],[125.12303200000011,39.557213],[124.744431,39.776939],[124.624153,39.594994],[124.3735960000001,40.09362],[126.016937,40.899994],[126.91304000000022,41.796104],[128.155823,41.382492],[128.05886800000016,42.00332600000014],[128.925812,42.024437],[129.71191400000012,42.444153],[129.907532,43.005821],[130.6043700000001,42.42186],[130.6388850000001,42.406937]]]]}},{"type":"Feature","properties":{"name":"Kiribati","iso2":"KI","iso3":"KIR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-151.78363,-11.466391],[-151.808044,-11.449722],[-151.814453,-11.392502],[-151.78363,-11.466391]]],[[[-152.391418,-10.105278],[-152.406708,-10.097221],[-152.395599,-10.095835],[-152.391418,-10.105278]]],[[[-150.224152,-9.954166],[-150.233063,-9.938614],[-150.220551,-9.923891],[-150.224152,-9.954166]]],[[[-150.225281,-9.915834],[-150.228882,-9.890835],[-150.219177,-9.901392],[-150.225281,-9.915834]]],[[[-155.878052,-5.64],[-155.92807,-5.61889],[-155.85614,-5.619445],[-155.878052,-5.64]]],[[[-172.1875,-4.531668],[-172.231384,-4.504446],[-172.196381,-4.491944],[-172.1875,-4.531668]]],[[[-171.231689,-4.46139],[-171.264496,-4.446388],[-171.235535,-4.438055],[-171.231689,-4.46139]]],[[[-154.939209,-4.045555],[-154.95639,-4.102501],[-155.016113,-4.060834],[-154.939209,-4.045555]]],[[[-171.078064,-3.141667],[-171.089722,-3.137501],[-171.086426,-3.108889],[-171.078064,-3.141667]]],[[[-171.627808,-2.8325],[-171.626373,-2.869445],[-171.725586,-2.772778],[-171.627808,-2.8325]]],[[[176.848297,-2.669445],[176.774139,-2.607778],[176.833313,-2.633889],[176.848297,-2.669445]]],[[[175.971893,-2.505],[175.960236,-2.505834],[175.964417,-2.481111],[175.971893,-2.505]]],[[[175.58609,-1.919722],[175.54776,-1.821667],[175.592743,-1.883333],[175.58609,-1.919722]]],[[[175.53137200000012,-1.806111],[175.493561,-1.769722],[175.519714,-1.777778],[175.53137200000012,-1.806111]]],[[[175.041931,-1.5525],[175.001648,-1.528611],[175.046082,-1.434722],[175.041931,-1.5525]]],[[[174.873291,-1.408056],[174.85745199999988,-1.408611],[174.8535769999999,-1.399167],[174.873291,-1.408056]]],[[[176.46469100000022,-1.435278],[176.390533,-1.324445],[176.421356,-1.348333],[176.46469100000022,-1.435278]]],[[[175.954681,-1.279167],[176.018311,-1.389444],[175.934143,-1.3025],[175.954681,-1.279167]]],[[[174.767761,-1.255833],[174.71637,-1.14],[174.767212,-1.207222],[174.767761,-1.255833]]],[[[174.489685,-0.816667],[174.458008,-0.653611],[174.495789,-0.770278],[174.489685,-0.816667]]],[[[174.458862,-0.651667],[174.377167,-0.5975],[174.392487,-0.594722],[174.458862,-0.651667]]],[[[173.618011,0.133611],[173.604126,0.2125],[173.631622,0.216667],[173.618011,0.133611]]],[[[173.40969800000013,0.203611],[173.402191,0.233056],[173.425537,0.215278],[173.40969800000013,0.203611]]],[[[173.38497900000013,0.244167],[173.371338,0.250278],[173.376617,0.266111000000123],[173.38497900000013,0.244167]]],[[[173.931915,0.298055],[173.923584,0.302222],[173.93942300000012,0.320833],[173.931915,0.298055]]],[[[173.830536,0.448333],[173.921631,0.379722],[173.804962,0.431111],[173.830536,0.448333]]],[[[173.021912,1.006667],[173.084137,0.951944000000125],[172.981354,0.821667],[173.021912,1.006667]]],[[[172.93969700000017,1.336111000000116],[172.914154,1.346389],[172.943573,1.345833],[172.93969700000017,1.336111000000116]]],[[[173.126617,1.349166],[173.09857200000013,1.351389],[173.11911,1.373333],[173.126617,1.349166]]],[[[173.062195,1.410278000000119],[173.039703,1.417778],[173.0346980000002,1.444444],[173.062195,1.410278000000119]]],[[[173.012756,1.472500000000153],[173.016388,1.465],[172.99719200000013,1.500556],[173.012756,1.472500000000153]]],[[[172.981903,1.529444000000112],[172.960785,1.553333000000137],[172.955231,1.619166],[172.981903,1.529444000000112]]],[[[172.88470500000014,1.838333],[172.834137,1.863611],[172.85800200000014,1.861666],[172.88470500000014,1.838333]]],[[[173.014984,1.706111000000135],[172.929962,1.936111],[173.027191,1.821111],[173.014984,1.706111000000135]]],[[[172.891663,1.93],[172.8827210000002,1.932777],[172.8855290000001,1.943889000000112],[172.891663,1.93]]],[[[173.328857,1.940278],[173.311096,1.958055],[173.349396,1.965833],[173.328857,1.940278]]],[[[173.343018,1.982777],[173.313599,1.973889],[173.325256,2.015833],[173.343018,1.982777]]],[[[-157.431671,2.021388000000115],[-157.179443,1.714444],[-157.571381,1.858888],[-157.431671,2.021388000000115]]],[[[172.870239,3.064444],[172.774994,3.002222],[172.749115,3.024166],[172.870239,3.064444]]],[[[172.9682920000001,3.24861],[172.95745800000012,3.281388],[172.97662400000016,3.296389],[172.9682920000001,3.24861]]],[[[-159.340027,3.920833],[-159.271698,3.789722],[-159.40448,3.864166],[-159.340027,3.920833]]],[[[-160.394745,4.685554],[-160.405609,4.725276],[-160.37973,4.718332],[-160.394745,4.685554]]]]}},{"type":"Feature","properties":{"name":"Korea, Republic of","iso2":"KR","iso3":"KOR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[126.622208,33.23999],[126.158333,33.314713],[126.898041,33.52332300000013],[126.622208,33.23999]]],[[[126.7655490000001,34.280823],[126.651382,34.316101],[126.701393,34.38694],[126.7655490000001,34.280823]]],[[[127.213608,34.418884],[127.111366,34.460274],[127.222717,34.48362700000011],[127.213608,34.418884]]],[[[127.790817,34.47637900000011],[127.711929,34.5266570000001],[127.77082800000014,34.5383300000001],[127.790817,34.47637900000011]]],[[[126.186653,34.351387],[126.243317,34.573326],[126.380257,34.494713],[126.186653,34.351387]]],[[[127.803864,34.575554],[127.734421,34.613327],[127.76805100000016,34.66415400000015],[127.803864,34.575554]]],[[[125.991364,34.668053],[125.91499300000012,34.692215],[125.981369,34.716934],[125.991364,34.668053]]],[[[125.993042,34.791939],[126.009163,34.759995],[125.890549,34.728043],[125.993042,34.791939]]],[[[128.085785,34.830276],[127.974152,34.85833],[128.024139,34.913879],[128.085785,34.830276]]],[[[126.063599,34.854439],[125.983597,34.864998],[126.06275900000011,34.928329],[126.063599,34.854439]]],[[[127.9561,34.800827],[128.060791,34.701103],[127.857208,34.723877],[127.879967,34.92943600000011],[127.9561,34.800827]]],[[[128.754425,34.87693800000015],[128.594116,34.697769],[128.488556,34.856384],[128.754425,34.87693800000015]]],[[[126.10608700000014,35.046944],[126.05998200000013,35.090828],[126.162201,35.14332600000016],[126.10608700000014,35.046944]]],[[[126.428307,36.399719],[126.33582300000015,36.438599],[126.346939,36.591103],[126.428307,36.399719]]],[[[126.16943400000017,36.82582900000013],[126.16110200000011,36.838043],[126.172447,36.8368380000001],[126.16943400000017,36.82582900000013]]],[[[130.887482,37.453323],[130.807465,37.51832600000013],[130.919434,37.545273],[130.887482,37.453323]]],[[[126.501389,37.594437],[126.373032,37.621658],[126.400543,37.818886],[126.501389,37.594437]]],[[[124.695534,37.9161000000001],[124.615257,37.968597],[124.72554000000011,37.981659],[124.695534,37.9161000000001]]],[[[128.532471,38.330551],[129.433594,37.058884000000106],[129.43942300000018,35.475822],[129.136932,35.11221300000015],[127.593323,34.941658],[127.640823,34.616936],[127.49387400000015,34.851662000000104],[127.389427,34.4711],[127.124687,34.53721600000013],[127.328598,34.74305],[126.889427,34.412491],[126.772491,34.58277100000011],[126.556374,34.300545],[126.266937,34.683327],[126.659714,34.812767000000136],[126.249153,35.11666100000012],[126.431374,35.023323],[126.68775900000017,35.533333],[126.474701,35.635826000000165],[126.872993,36.054718],[126.544418,36.136406],[126.49720800000014,36.723877000000144],[126.1235960000001,36.709160000000125],[126.50248700000012,37.052773],[126.9922030000001,36.91082],[126.661102,37.156097],[126.865807,37.266937],[126.688492,37.83390800000011],[127.106087,38.287498000000156],[128.07995600000018,38.311935],[128.3635560000001,38.62524400000011],[128.532471,38.330551]]]]}},{"type":"Feature","properties":{"name":"Kuwait","iso2":"KW","iso3":"KWT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[48.362488,29.450272],[48.38832900000014,29.395554],[48.266930000000144,29.441109],[48.362488,29.450272]]],[[[48.224709,29.594719],[48.152222,29.991940000000156],[48.359444,29.744999],[48.224709,29.594719]]],[[[48.032219,29.968052],[48.00860600000013,29.973885],[48.037766,30.011105000000114],[48.11166400000016,30.023048],[48.032219,29.968052]]],[[[47.9310990000001,30.018887],[47.943474,30.017555],[48.167213,29.553055],[47.707222,29.37583200000013],[48.028603,29.344994],[48.416588,28.545277],[47.688880999999895,28.538883],[47.4599910000002,28.999439],[46.546944,29.104198],[47.169991,30.015270000000115],[47.9310990000001,30.018887]]]]}},{"type":"Feature","properties":{"name":"Kazakhstan","iso2":"KZ","iso3":"KAZ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[50.116104,44.838043],[49.978867,44.956383],[50.11277,45.077492],[50.116104,44.838043]]],[[[50.291664,44.949997],[50.26554900000022,45.036659],[50.342766,45.08305400000013],[50.291664,44.949997]]],[[[53.024994,46.2286],[52.96027400000011,46.266388],[53.046387,46.367493],[53.097488,46.296661],[53.024994,46.2286]]],[[[69.185532,55.34388000000014],[70.843323,55.301933],[71.27887,54.690269],[70.99693300000015,54.339157],[71.185532,54.10332500000011],[72.19609100000017,54.137497],[72.05165100000013,54.387772],[72.468597,53.908882000000105],[72.61331200000015,54.145271],[73.763885,54.065544000000116],[73.238586,53.64444000000019],[73.437195,53.43610400000016],[74.42915300000018,53.47860000000016],[76.811646,54.447769],[76.521652,53.993881],[77.908035,53.271103],[80.077957,50.75808700000012],[80.687836,51.31472],[81.468048,50.742218],[83.456375,51.00249500000011],[84.363037,50.212212],[85.014435,50.075829000000155],[85.258606,49.591377],[86.19108600000018,49.472488],[86.77499400000013,49.788887],[86.616653,49.587212],[87.348206,49.092621],[86.874695,49.110825000000105],[86.5961,48.53611],[85.75915500000022,48.387772],[85.529312,47.060165],[84.75943,46.826385],[83.040543,47.212212],[82.317764,45.570534],[82.649429,45.43026],[82.561646,45.129417],[81.688309,45.350815],[79.87109400000011,44.904976],[80.520828,44.73247500000012],[80.362762,44.125244],[80.817215,43.156067],[80.37664800000019,43.025238],[80.578598,42.89107500000013],[80.171921,42.660507],[80.23402400000012,42.19622],[79.194702,42.795792],[75.664429,42.807457],[74.293594,43.216904],[73.583878,43.038574],[73.5197140000001,42.408005],[71.747208,42.823586],[71.17109700000012,42.69135300000015],[70.97081,42.254669],[69.05636600000011,41.379433000000105],[68.455261,40.59777100000012],[67.935532,41.183327],[66.7199860000002,41.174995],[66.526382,42.003052],[66.02916,42.003052],[66.123871,42.99694100000012],[65.82193,42.877213],[64.931366,43.73777],[62.025108,43.484787],[58.569717,45.571106],[55.99749,45.001106],[56.000961,41.32845300000015],[55.45694000000017,41.28665900000014],[54.17305,42.337212],[53.014999,42.138885],[52.440071,41.740936],[52.73832700000011,42.710274000000155],[51.26554900000016,43.153046],[50.839989,44.193047],[50.239433,44.576385],[51.57027400000018,44.513885],[50.953049,44.86193800000014],[51.405266,45.37054400000015],[53.228043000000156,45.33776900000011],[52.733047,45.549438],[53.08582300000015,46.007217],[53.164154,46.317215],[52.99665800000017,46.488045],[53.194153,46.714996],[51.189987,47.114716],[49.222527,46.346306000000155],[48.560547,46.564995],[49.027206,46.776093],[48.20443,47.704987000000116],[47.383324,47.688881],[47.122765,48.27166],[46.499161000000214,48.417496],[47.062767,49.142769000000115],[46.79583,49.339714],[46.929436,49.863609],[47.520828,50.436378],[48.251663,49.86971300000012],[48.796944,49.941933000000134],[48.697487,50.591934],[50.77330000000015,51.76918],[51.303047,51.4797130000001],[52.338326,51.782211],[52.603325,51.45694],[53.428604,51.49166100000015],[54.506386,50.856941000000106],[54.523933,50.528839],[54.647217,51.03694200000011],[55.692490000000106,50.532494],[56.510826,51.08332800000012],[57.481934,50.864716],[58.337769,51.156097],[59.542496,50.478325],[60.04361,50.863327],[61.381378,50.783607],[61.685822,51.265831],[60.00222,51.958328],[61.061935000000204,52.342491],[60.694153000000114,52.680824],[61.09915900000013,52.981659],[62.118324000000115,53.004166000000126],[61.184715,53.3066560000001],[61.57749200000015,53.513329],[60.90554800000021,53.62027],[61.226936,53.811935],[61.01416,53.947487],[62.547493,53.879433000000105],[63.172218,54.18637800000012],[65.216385,54.318886],[65.483322,54.6380460000001],[69.185532,55.34388000000014]]]]}},{"type":"Feature","properties":{"name":"Lao People's Democratic Republic","iso2":"LA","iso3":"LAO"},"geometry":{"type":"MultiPolygon","coordinates":[[[[107.5466,14.708618],[106.853592,14.303053],[106.540741,14.598724000000132],[106.004707,14.373053],[106.056641,13.929998],[105.210602,14.349648],[105.536102,14.563332000000116],[105.637772,15.659721],[104.747208,16.528332],[104.71832300000014,17.50333],[103.985527,18.321663],[103.397217,18.434994],[102.683594,17.819996],[102.089394,18.214983000000146],[101.162773,17.459995],[100.921371,17.56721900000015],[101.281097,19.562218],[100.50360100000015,19.526665],[100.58046,20.157768000000104],[100.09137,20.348606],[101.14823900000013,21.572636],[101.281937,21.180275],[101.78720100000012,21.144161],[101.57443200000014,22.20916],[101.738037,22.49694100000012],[102.14074700000012,22.396286],[102.676651,21.65583],[102.976089,21.739437],[103.170532,20.846664],[103.693588,20.657219],[104.109154,20.977219],[104.6436,20.660275000000112],[104.3819270000001,20.444717],[104.979156,20.004997],[104.640266,19.611942],[104.03724700000012,19.69294400000011],[103.87943300000015,19.29361],[105.193863,18.642494],[105.183319,18.334442],[106.561096,16.996941],[106.685532,16.45805],[107.464706,16.078609000000128],[107.1755370000001,15.784164],[107.695251,15.270832],[107.5466,14.708618]]]]}},{"type":"Feature","properties":{"name":"Lebanon","iso2":"LB","iso3":"LBN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[35.623634,33.245728],[35.10083,33.093605000000125],[35.972771,34.647499],[36.459999,34.635277],[36.623741,34.204994],[35.623634,33.245728]]]]}},{"type":"Feature","properties":{"name":"Latvia","iso2":"LV","iso3":"LVA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[21.068607,56.435547],[21.053608,56.83638],[21.73333,57.576942],[22.610275,57.756386],[23.785831,56.970268],[24.407497,57.25666],[24.314980000000105,57.871826],[25.294998000000106,58.084435],[26.511387,57.5261],[27.372059,57.535637],[27.861107,57.302216],[27.70166,56.914711],[28.168011,56.150154],[26.613209,55.674835],[25,56.295547],[22.139439,56.4236070000001],[21.051685,56.077309],[21.068607,56.435547]]]]}},{"type":"Feature","properties":{"name":"Belarus","iso2":"BY","iso3":"BLR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[26.613209,55.674835],[28.168011,56.150154],[30.926247,55.60257],[31.02972,55.043327],[30.781387,54.79361],[31.844162,54.064438],[31.764225,53.80262],[32.741104,53.463051],[31.266941,53.02471200000015],[31.783886,52.108047],[30.94309600000011,52.073792000000125],[30.551414000000108,51.251846],[25.775829000000158,51.939156],[24.396664,51.886658],[23.604633,51.527695],[23.638607,52.079437],[23.1654,52.282276],[23.94083,52.732208],[23.50404,53.947044],[25.785275000000127,54.160545],[25.547497,54.33277100000011],[25.788887,54.870270000000104],[26.81971700000014,55.281105],[26.45583,55.341377],[26.613209,55.674835]]]]}},{"type":"Feature","properties":{"name":"Lithuania","iso2":"LT","iso3":"LTU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[21.044441,55.32638500000017],[20.984814,55.27655],[20.942833,55.287201],[21.089996,55.719986],[21.044441,55.32638500000017]]],[[[25,56.295547],[26.613209,55.674835],[26.45583,55.341377],[26.81971700000014,55.281105],[25.788887,54.870270000000104],[25.547497,54.33277100000011],[25.785275000000127,54.160545],[23.50404,53.947044],[22.785885,54.363838],[22.842495,54.896942],[21.431385,55.251938],[21.263935000000146,55.248985],[21.051685,56.077309],[22.139439,56.4236070000001],[25,56.295547]]]]}},{"type":"Feature","properties":{"name":"Liberia","iso2":"LR","iso3":"LBR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-10.806074,6.403],[-11.492331,6.927091000000132],[-10.266651,8.488377],[-9.48365,8.346931],[-9.485161,7.361989],[-9.106945,7.198889],[-8.660557,7.695],[-8.469749,7.561325],[-8.308334,6.860833000000113],[-8.606383999999878,6.507815],[-7.423334,5.839444],[-7.525402,4.352806000000101],[-9.142778,5.055555],[-10.806074,6.403]]]]}},{"type":"Feature","properties":{"name":"Slovakia","iso2":"SK","iso3":"SVK"},"geometry":{"type":"MultiPolygon","coordinates":[[[[17.251656,48.024994],[17.166386,48.012497],[16.946182,48.619064],[18.851246,49.517357],[19.475555,49.599998],[20.074444,49.175278],[21.618889,49.436386],[22.558052,49.079437],[22.151442,48.411919],[20.660553,48.563332],[18.655277,47.758606],[17.251656,48.024994]]]]}},{"type":"Feature","properties":{"name":"Liechtenstein","iso2":"LI","iso3":"LIE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[9.533569,47.274544],[9.598635,47.063835],[9.474637,47.057457],[9.533569,47.274544]]]]}},{"type":"Feature","properties":{"name":"Libyan Arab Jamahiriya","iso2":"LY","iso3":"LBY"},"geometry":{"type":"MultiPolygon","coordinates":[[[[9.948332,27.824444],[9.766388,29.427776],[9.303888,30.122498],[9.537113,30.23439],[10.21361,30.730831],[10.287222,31.694164],[11.567499,32.442215],[11.526081,33.171135],[15.165833,32.398605],[15.761665,31.385555],[17.370831,31.081665],[19.001389,30.266941],[20.060555,30.855274],[20.084442,32.184715],[21.621387,32.933609],[23.112499,32.6325],[23.247196,32.216225],[24.973888,31.969997],[25.151665,31.646942],[24.706665,30.16861],[24.997776,29.248886],[25.001423,21.999695],[25.000832,19.999119],[24.000832000000116,20.001942],[24.002747,19.499065],[16.000832,23.450554],[14.997889,23.000591],[14.234999,22.614166],[13.543888,23.16861],[11.986475,23.522305],[11.558887,24.302498],[10.252222,24.605831],[9.398333,26.153332],[9.871666,26.514164],[9.948332,27.824444]]]]}},{"type":"Feature","properties":{"name":"Madagascar","iso2":"MG","iso3":"MDG"},"geometry":{"type":"MultiPolygon","coordinates":[[[[49.8336124420166,-17.089723587036133],[49.860551834106445,-16.913890838623047],[50.01055335998535,-16.72555923461914],[49.8336124420166,-17.089723587036133]]],[[[47.2197208404541,-15.436668395996094],[47.207773208618164,-15.434446334838867],[47.2005558013916,-15.427501678466797],[47.20666694641113,-15.420557022094727],[47.21944618225098,-15.420833587646484],[47.2197208404541,-15.436668395996094]]],[[[48.34250068664551,-13.418054580688477],[48.20555305480957,-13.391389846801758],[48.281389236450195,-13.196666717529297],[48.34250068664551,-13.418054580688477]]],[[[49.356943130493164,-12.09083366394043],[49.94333076477051,-13.039445877075195],[50.433610916137695,-15.580001831054688],[50.17277717590332,-15.97972297668457],[49.866106033325195,-15.432500839233398],[49.63360786437988,-15.557500839233398],[49.78860664367676,-16.830280303955078],[47.1330509185791,-24.928058624267578],[45.21472358703613,-25.588336944580078],[44.017221450805664,-24.985279083251953],[43.2388858795166,-22.282501220703125],[43.50055122375488,-21.33388900756836],[44.48221778869629,-19.970279693603516],[43.93721961975098,-17.479446411132812],[44.45916175842285,-16.1844482421875],[46.151384353637695,-15.703611373901367],[46.47722053527832,-15.96611213684082],[46.338335037231445,-15.624723434448242],[46.947221755981445,-15.198890686035156],[46.95944404602051,-15.558055877685547],[47.22361946105957,-15.448465347290039],[47.235647201538086,-15.412919998168945],[47.11194038391113,-15.305557250976562],[47.05832862854004,-15.185001373291016],[47.45499610900879,-14.665279388427734],[47.42721748352051,-15.110555648803711],[47.81127738952637,-14.603889465332031],[48.001665115356445,-14.765556335449219],[47.69944190979004,-14.420557022094727],[48.0483341217041,-14.155555725097656],[47.90527534484863,-13.596389770507812],[48.28721809387207,-13.808055877685547],[48.73971748352051,-13.427223205566406],[48.95944404602051,-12.822223663330078],[48.7308292388916,-12.434167861938477],[49.356943130493164,-12.09083366394043]],[[49.604440689086914,-12.62639045715332],[49.595834732055664,-12.610000610351562],[49.59444618225098,-12.623611450195312],[49.604440689086914,-12.62639045715332]]]]}},{"type":"Feature","properties":{"name":"Martinique","iso2":"MQ","iso3":"MTQ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-60.86084,14.402777],[-61.174728,14.876944],[-60.940834,14.740833],[-60.86084,14.402777]]]]}},{"type":"Feature","properties":{"name":"Mongolia","iso2":"MN","iso3":"MNG"},"geometry":{"type":"MultiPolygon","coordinates":[[[[91.020248,46.600109],[90.074432,47.886383],[88.65332,48.18277000000013],[87.9733120000001,48.57694200000016],[87.840698,49.172951],[92.322769,50.81499500000011],[94.274994,50.569443],[94.63526900000014,50.024437],[97.34082,49.734436],[98.28970300000012,50.293884],[97.82777400000012,51.00110600000012],[98.930267,52.143608],[102.218872,51.333603],[102.327766,50.569717],[102.918587,50.315269],[106.66304,50.3386],[107.977127,49.943626],[107.9491420000002,49.678047],[108.57222,49.33360300000011],[110.788589,49.149437000000106],[113.09082,49.59860200000013],[114.313026,50.284164000000104],[116.7113800000001,49.830467],[115.592194,47.919441000000106],[117.372192,47.653595],[117.80108600000014,48.010551],[118.539337,47.994751],[119.72998,47.16415400000015],[119.89749100000014,46.675552],[117.421097,46.578331],[116.585541,46.29583000000015],[115.701927,45.458603],[114.545258,45.389435],[113.638046,44.74527],[111.98082,45.09166],[111.42137100000011,44.382492],[111.958328,43.692215],[110.440536,42.777771],[109.313599,42.429993000000124],[107.471916,42.466103],[105.012207,41.581383],[100.835541,42.678047],[96.38304100000013,42.731102],[95.336105,44.02082800000015],[95.416656,44.29388400000012],[93.5547030000001,44.957214],[90.896942,45.253052],[90.681931,45.57972],[91.020248,46.600109]]]]}},{"type":"Feature","properties":{"name":"Montserrat","iso2":"MS","iso3":"MSR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-62.171394,16.671387],[-62.236671,16.711941],[-62.20195,16.81361],[-62.171394,16.671387]]]]}},{"type":"Feature","properties":{"name":"The former Yugoslav Republic of Macedonia","iso2":"MK","iso3":"MKD"},"geometry":{"type":"MultiPolygon","coordinates":[[[[20.82111,40.908882],[20.492775,41.331108],[20.589642,41.882187],[22.365276,42.323883],[23.014721,41.762215],[22.935604,41.342125],[20.98349,40.855888],[20.82111,40.908882]]]]}},{"type":"Feature","properties":{"name":"Mali","iso2":"ML","iso3":"MLI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-8.53388,11.49391],[-9.155556,12.486111],[-9.701946,12.029163],[-10.323893,12.224997],[-10.652748,11.892609],[-10.92889,12.224442],[-11.315556,12.022774],[-11.373058,12.407774],[-11.378056,12.988054],[-12.057222,13.664721],[-12.244833,14.764385],[-11.841391,14.863054],[-11.494167,15.646387],[-10.899637,15.106874],[-10.716387,15.438902000000112],[-9.411112,15.443888],[-9.338057,15.704721000000106],[-9.333612,15.499722000000148],[-5.49505,15.498371],[-5.335,16.328053],[-5.601389,16.507774],[-6.577223,24.999165000000133],[-4.806111,25.000275],[1.169662,21.102543],[1.1675,20.741108],[1.795833,20.308331],[3.233055,19.820274],[3.331944,18.976387],[4.245277,19.146664],[4.245,18.645275],[4.200833,16.393887],[3.523981,15.358152],[1.3125,15.286665],[0.235048,14.915068],[-0.725278,15.082777],[-1.980834,14.474722],[-2.006945,14.187777],[-2.474722,14.287498],[-2.879167,13.655554],[-3.2575,13.696665],[-3.437675,13.166498],[-3.964253,13.50383],[-4.337223,13.121666],[-4.4175,12.300831],[-5.273056,11.843887],[-5.51985,10.436272],[-6.111389,10.197777],[-6.243402,10.735256],[-6.988056,10.147499],[-7.635555999999895,10.448332000000107],[-7.973984,10.165611],[-8.289722,11.007776],[-8.680557,10.966389],[-8.357779,11.305555],[-8.53388,11.49391]]]]}},{"type":"Feature","properties":{"name":"Morocco","iso2":"MA","iso3":"MAR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-9.053169,32.734802],[-6.843056,34.018608],[-5.918744,35.790649],[-5.395557,35.91633600000013],[-5.345834,35.84166000000012],[-4.695834,35.208885],[-2.946945,35.329163],[-2.925278,35.266663],[-2.91472199999987,35.273605],[-2.209445,35.085831],[-1.747222,34.747215],[-1.668056,33.261108],[-1.010278,32.508331],[-1.180556,32.11055],[-2.853889,32.088333],[-3.818334,31.695553],[-3.626667,30.970554],[-4.920556,30.508053],[-5.538334,29.902496],[-7.123889,29.636944],[-8.667223,28.709442],[-8.666668,27.666664],[-13.174961,27.666958],[-11.458057,28.334442],[-10.138056,29.428055],[-9.640278,30.168053],[-9.809168,31.446663],[-9.053169,32.734802]]]]}},{"type":"Feature","properties":{"name":"Mauritius","iso2":"MU","iso3":"MUS"},"geometry":{"type":"MultiPolygon","coordinates":[[[[57.572495000000146,-20.514168],[57.304718,-20.449169],[57.624443,-19.986389],[57.572495000000146,-20.514168]]],[[[63.466385,-19.735836],[63.32860600000012,-19.738056],[63.461105,-19.673058],[63.466385,-19.735836]]],[[[56.564438,-10.397223],[56.511665,-10.346668],[56.51361100000011,-10.316668],[56.564438,-10.397223]]]]}},{"type":"Feature","properties":{"name":"Mauritania","iso2":"MR","iso3":"MRT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-16.42750199999989,19.603611],[-16.460003,19.699718000000146],[-16.344448,19.866386000000105],[-16.42750199999989,19.603611]]],[[[-6.662778,26.129166],[-4.806111,25.000275],[-6.577223,24.999165000000133],[-5.601389,16.507774],[-5.335,16.328053],[-5.49505,15.498371],[-9.333612,15.499722000000148],[-9.338057,15.704721000000106],[-9.411112,15.443888],[-10.716387,15.438902000000112],[-10.899637,15.106874],[-11.494167,15.646387],[-11.841391,14.863054],[-12.244833,14.764385],[-14.345278,16.638611],[-16.280834,16.519722],[-16.527679,16.060249],[-16.039448,17.728054000000114],[-16.51166899999987,19.352219],[-16.19639199999989,20.223053],[-16.919724,21.161663000000104],[-17.05233,20.764095000000125],[-16.953056,21.338333],[-15.741997,21.338284],[-12.999723,21.338055000000125],[-13.105278,22.893055],[-12.000278,23.454441000000102],[-12.000557,26],[-8.666944999999885,26.000275000000116],[-8.66679,27.290459],[-6.662778,26.129166]]]]}},{"type":"Feature","properties":{"name":"Malta","iso2":"MT","iso3":"MLT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[14.562222,35.820274],[14.374998,35.847496],[14.326387000000182,35.978882],[14.562222,35.820274]]],[[[14.2675,36.011383],[14.18111000000016,36.06082900000011],[14.34111,36.033882],[14.2675,36.011383]]]]}},{"type":"Feature","properties":{"name":"Oman","iso2":"OM","iso3":"OMN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[55.874718,17.490833],[55.829163,17.493610000000118],[55.859718,17.516666],[55.874718,17.490833]]],[[[56.024162,17.484165],[55.957497,17.519165],[56.09360500000011,17.514721],[56.024162,17.484165]]],[[[58.84277300000011,20.441109],[58.649719,20.168888],[58.899719,20.693054000000117],[58.84277300000011,20.441109]]],[[[56.037498,24.938889],[56.104164,24.734722000000104],[56.373528,24.979382],[57.16499300000012,23.937775],[58.609444000000195,23.633053000000118],[59.811386,22.226665],[58.515831,20.411663],[58.210831,20.612499],[57.829437,20.218887],[57.803886,18.969444000000138],[56.814484,18.747684],[56.353333000000106,17.934166],[55.436943,17.828888000000134],[55.03999300000012,17.018608],[53.114441,16.642778],[51.99929,18.999344000000136],[55,20],[55.666107,21.999722],[55.199165000000136,22.699718],[55.510277000000116,23.97277500000014],[56.024719,24.076111],[55.7794420000001,24.563889000000145],[56.037498,24.938889]]],[[[56.365368,26.382389],[56.269722,25.636015],[56.183331,25.654989],[56.079941,26.065559],[56.365368,26.382389]]]]}},{"type":"Feature","properties":{"name":"Maldives","iso2":"MV","iso3":"MDV"},"geometry":{"type":"MultiPolygon","coordinates":[[[[73.17637600000015,-0.689722],[73.15637200000012,-0.683889],[73.17192100000014,-0.681667],[73.17637600000015,-0.689722]]],[[[73.201385,-0.680833],[73.188309,-0.684722],[73.20193500000013,-0.667222],[73.201385,-0.680833]]],[[[73.12915000000012,-0.668889],[73.12525900000011,-0.668889],[73.121368,-0.653333],[73.12915000000012,-0.668889]]],[[[73.23082,-0.648056],[73.226089,-0.6325],[73.2422030000001,-0.617778],[73.23082,-0.648056]]],[[[73.1163790000002,-0.635833],[73.09082,-0.606667],[73.09137,-0.5825],[73.1163790000002,-0.635833]]],[[[73.248032,-0.605278],[73.23580900000016,-0.585556],[73.249146,-0.576111],[73.248032,-0.605278]]],[[[73.44693,-0.299444],[73.428314,-0.286389],[73.442474,-0.285278],[73.44693,-0.299444]]],[[[73.106934,0.211944],[73.095535,0.228056],[73.10331700000015,0.228889],[73.106934,0.211944]]],[[[73.214706,0.230833000000118],[73.209152,0.24],[73.22026100000014,0.239167],[73.214706,0.230833000000118]]],[[[73.04498300000014,0.259444],[73.034424,0.261389],[73.033051,0.272778],[73.04498300000014,0.259444]]],[[[73.375809,0.28],[73.367203,0.281389],[73.3797,0.291944],[73.375809,0.28]]],[[[73.51304600000012,0.378333],[73.50471500000012,0.383889],[73.508881,0.3925],[73.51304600000012,0.378333]]],[[[72.943039,0.488611],[72.938034,0.485555],[72.937195,0.499722000000105],[72.943039,0.488611]]],[[[73.498032,0.499722000000105],[73.493042,0.496944000000113],[73.487762,0.508055],[73.498032,0.499722000000105]]],[[[73.374695,1.781667000000141],[73.361374,1.788611],[73.374695,1.79527800000011],[73.374695,1.781667000000141]]],[[[73.399155,1.793889000000107],[73.397766,1.806389],[73.40776100000014,1.805833],[73.399155,1.793889000000107]]],[[[73.28720100000012,1.831944],[73.297211,1.819166],[73.284424,1.823055000000139],[73.28720100000012,1.831944]]],[[[73.50694300000012,1.826667],[73.49498,1.823055000000139],[73.516663,1.847222],[73.50694300000012,1.826667]]],[[[73.25054900000012,1.889166],[73.24192800000012,1.886111],[73.247757,1.898333],[73.25054900000012,1.889166]]],[[[73.549988,1.896389000000141],[73.53997800000016,1.891944],[73.549713,1.937222],[73.549988,1.896389000000141]]],[[[73.55304,1.965],[73.548325,1.964166],[73.54721100000015,1.978333],[73.55304,1.965]]],[[[73.323044,1.985000000000113],[73.3138730000002,1.986388],[73.322495,1.995555],[73.323044,1.985000000000113]]],[[[73.588882,2.1075],[73.559143,2.09611],[73.567764,2.11],[73.588882,2.1075]]],[[[73.123871,2.190555],[73.11026000000012,2.196944],[73.12191800000019,2.196944],[73.123871,2.190555]]],[[[72.930817,2.314444],[72.919983,2.322500000000119],[72.92276000000012,2.328888],[72.930817,2.314444]]],[[[73.366653,2.384444],[73.350266,2.440833000000111],[73.3685909999999,2.409721],[73.366653,2.384444]]],[[[73.319717,2.492499],[73.313599,2.491944],[73.311096,2.504722],[73.319717,2.492499]]],[[[72.876083,2.681388],[72.866379,2.684999],[72.866379,2.69611],[72.876083,2.681388]]],[[[73.025269,2.734444],[73.018875,2.736944],[73.034988,2.747499000000118],[73.025269,2.734444]]],[[[73.356644,2.771666],[73.348877,2.770833],[73.349426,2.781944000000124],[73.356644,2.771666]]],[[[73.0177610000002,2.946944],[73.005829,2.946944],[73.012207,2.954722],[73.0177610000002,2.946944]]],[[[73.5799870000001,2.948888],[73.574432,2.950555],[73.585541,2.967499],[73.5799870000001,2.948888]]],[[[72.98220800000016,3.101944],[72.973877,3.108055],[72.982758,3.110833000000156],[72.98220800000016,3.101944]]],[[[73.587204,3.367777],[73.581665,3.372221],[73.59082,3.376944],[73.587204,3.367777]]],[[[73.753326,3.446388],[73.74775700000012,3.451111000000154],[73.751389,3.452499],[73.753326,3.446388]]],[[[72.80276500000011,3.510278],[72.78804000000011,3.511111],[72.798599,3.516944],[72.80276500000011,3.510278]]],[[[72.92276000000012,3.544167],[72.908035,3.537777000000133],[72.9272,3.559721],[72.92276000000012,3.544167]]],[[[72.69747900000013,3.714166],[72.687759,3.724721],[72.699417,3.724166],[72.69747900000013,3.714166]]],[[[73.47387700000016,3.933055],[73.465546,3.932222],[73.4802700000001,3.940555],[73.47387700000016,3.933055]]],[[[72.70971700000021,3.995555000000138],[72.69775400000017,4.000833],[72.707764,4.003611],[72.70971700000021,3.995555000000138]]],[[[73.512207,4.093611],[73.501938,4.096388],[73.50305200000011,4.106943],[73.512207,4.093611]]],[[[73.503601,4.164165],[73.491089,4.174999],[73.505264,4.17861],[73.503601,4.164165]]],[[[73.5186,4.191387000000134],[73.51915,4.176388],[73.51138300000011,4.182221],[73.5186,4.191387000000134]]],[[[72.959717,4.26861],[72.977768,4.261666],[72.962494,4.262221],[72.959717,4.26861]]],[[[72.96971100000016,4.877776],[72.970261,4.898055],[72.9802700000001,4.901111000000157],[72.96971100000016,4.877776]]],[[[73.589706,5.27361],[73.56694,5.277499],[73.589706,5.286943],[73.589706,5.27361]]],[[[73.320267,5.36111],[73.314987,5.365276],[73.333603,5.366666],[73.320267,5.36111]]],[[[73.635269,5.385555],[73.62025500000013,5.420833000000101],[73.63749700000014,5.412777],[73.635269,5.385555]]],[[[73.3841550000001,5.709722],[73.387772,5.741943],[73.3927610000002,5.72861],[73.3841550000001,5.709722]]],[[[72.99136400000012,5.76111],[72.981659,5.758888],[72.981659,5.771666],[72.99136400000012,5.76111]]],[[[73.436371,5.827222],[73.4297030000001,5.827222],[73.45109600000015,5.849166],[73.436371,5.827222]]],[[[72.96887200000012,5.850832],[72.96499600000013,5.847499],[72.961105,5.867777],[72.96887200000012,5.850832]]],[[[73.433044,5.902222],[73.423599,5.903610000000128],[73.422211,5.911666],[73.433044,5.902222]]],[[[73.398331,5.955277],[73.379425,5.971388],[73.393326,5.96861],[73.398331,5.955277]]],[[[72.933319,5.960833],[72.92831400000014,5.954999],[72.9260860000002,5.97194400000015],[72.933319,5.960833]]],[[[73.270538,6.185276],[73.2686,6.175277000000122],[73.269989,6.193054],[73.270538,6.185276]]],[[[73.248032,6.231943],[73.2397,6.227499],[73.234711,6.23611],[73.248032,6.231943]]],[[[73.204437,6.317499],[73.190811,6.324721000000125],[73.20166,6.327499000000117],[73.204437,6.317499]]],[[[73.05026200000012,6.429166000000151],[73.040817,6.429999000000151],[73.041367,6.444165],[73.05026200000012,6.429166000000151]]],[[[73.0674900000001,6.661388],[73.059982,6.657499],[73.068054,6.672776],[73.0674900000001,6.661388]]],[[[73.101089,6.696943],[73.093323,6.697221],[73.1024780000001,6.715555],[73.101089,6.696943]]],[[[73.136932,6.726388],[73.12915000000012,6.733888],[73.161926,6.784165],[73.136932,6.726388]]],[[[73.18136600000011,6.8325],[73.20166,6.828888],[73.184143,6.81861],[73.18136600000011,6.8325]]],[[[73.2052610000002,6.883611],[73.19552600000011,6.889443000000142],[73.209991,6.926388],[73.2052610000002,6.883611]]],[[[73.198868,6.947498],[73.19165,6.951111],[73.193588,6.978610000000117],[73.198868,6.947498]]],[[[72.985535,7.012221],[72.97998000000021,7.011666000000119],[72.974991,7.029444],[72.985535,7.012221]]],[[[72.91609200000019,7.081666],[72.90277100000012,7.093055000000106],[72.911926,7.094999],[72.91609200000019,7.081666]]]]}},{"type":"Feature","properties":{"name":"Mexico","iso2":"MX","iso3":"MEX"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-114.74278259277344,18.322778701782227],[-114.80307006835938,18.33277702331543],[-114.72389221191406,18.353334426879883],[-114.74278259277344,18.322778701782227]]],[[[-87.37278747558594,18.400278091430664],[-87.33168029785156,18.503053665161133],[-87.32695007324219,18.453332901000977],[-87.37278747558594,18.400278091430664]]],[[[-87.25167846679688,18.641389846801758],[-87.25944519042969,18.627779006958008],[-87.2650146484375,18.733888626098633],[-87.25167846679688,18.641389846801758]]],[[[-91.82861328125,18.6391658782959],[-91.6461181640625,18.753610610961914],[-91.52389526367188,18.77055549621582],[-91.82861328125,18.6391658782959]]],[[[-110.92611694335938,18.72110939025879],[-111.07140350341797,18.76833152770996],[-111.00334167480469,18.864999771118164],[-110.92611694335938,18.72110939025879]]],[[[-110.78861999511719,19.308053970336914],[-110.83585357666016,19.271387100219727],[-110.81333923339844,19.341665267944336],[-110.78861999511719,19.308053970336914]]],[[[-86.7327880859375,20.585554122924805],[-87,20.25638771057129],[-86.93890380859375,20.539445877075195],[-86.7327880859375,20.585554122924805]]],[[[-86.70140075683594,21.197221755981445],[-86.7388916015625,21.239999771118164],[-86.74917602539062,21.28639030456543],[-86.70140075683594,21.197221755981445]]],[[[-106.195556640625,21.255277633666992],[-106.26500701904297,21.336668014526367],[-106.197509765625,21.33860969543457],[-106.195556640625,21.255277633666992]]],[[[-106.38667297363281,21.42083168029785],[-106.51139831542969,21.45027732849121],[-106.33556365966797,21.49888801574707],[-106.38667297363281,21.42083168029785]]],[[[-106.51500701904297,21.5130558013916],[-106.64584350585938,21.68833351135254],[-106.5300064086914,21.690832138061523],[-106.51500701904297,21.5130558013916]]],[[[-106.65640258789062,21.752500534057617],[-106.67529296875,21.74138832092285],[-106.67056274414062,21.816389083862305],[-106.65640258789062,21.752500534057617]]],[[[-97.81889343261719,22.6825008392334],[-97.83084106445312,22.697221755981445],[-97.7841796875,22.774168014526367],[-97.81889343261719,22.6825008392334]]],[[[-97.77305603027344,22.7913875579834],[-97.78140258789062,22.80499839782715],[-97.76028442382812,22.834165573120117],[-97.77305603027344,22.7913875579834]]],[[[-109.7844467163086,24.135000228881836],[-109.87139892578125,24.187498092651367],[-109.91555786132812,24.3688907623291],[-109.7844467163086,24.135000228881836]]],[[[-111.53250122070312,24.378053665161133],[-111.49474334716797,24.351388931274414],[-111.6702880859375,24.371946334838867],[-111.53250122070312,24.378053665161133]]],[[[-111.70584106445312,24.331666946411133],[-112.01667785644531,24.532499313354492],[-111.8369369506836,24.541112899780273],[-111.70584106445312,24.331666946411133]]],[[[-110.32805633544922,24.400835037231445],[-110.40194702148438,24.579999923706055],[-110.30000305175781,24.484445571899414],[-110.32805633544922,24.400835037231445]]],[[[-110.53695678710938,24.88222312927246],[-110.70500183105469,25.093889236450195],[-110.57890319824219,25.03388786315918],[-110.53695678710938,24.88222312927246]]],[[[-112.04611206054688,24.519166946411133],[-112.25279235839844,24.809999465942383],[-112.13362121582031,25.281110763549805],[-112.20250701904297,24.844999313354492],[-112.04611206054688,24.519166946411133]]],[[[-108.84278869628906,25.42860984802246],[-108.78916931152344,25.372220993041992],[-109.01112365722656,25.43833351135254],[-108.84278869628906,25.42860984802246]]],[[[-110.79695129394531,25.594999313354492],[-110.82528686523438,25.642499923706055],[-110.8083267211914,25.695833206176758],[-110.79695129394531,25.594999313354492]]],[[[-111.197509765625,25.844999313354492],[-111.19139099121094,26.038888931274414],[-111.086669921875,26.074445724487305],[-111.197509765625,25.844999313354492]]],[[[-110.54611206054688,27.309999465942383],[-110.59750366210938,27.336111068725586],[-110.59028625488281,27.4152774810791],[-110.54611206054688,27.309999465942383]]],[[[-114.22000122070312,27.738332748413086],[-114.32389831542969,27.816667556762695],[-114.24501037597656,27.814443588256836],[-114.22000122070312,27.738332748413086]]],[[[-115.17388916015625,28.027498245239258],[-115.3266830444336,28.138334274291992],[-115.24083709716797,28.370553970336914],[-115.17388916015625,28.027498245239258]]],[[[-112.760009765625,28.593610763549805],[-112.88583374023438,28.683889389038086],[-112.79640197753906,28.644166946411133],[-112.760009765625,28.593610763549805]]],[[[-112.58168029785156,28.670278549194336],[-112.60362243652344,28.72722053527832],[-112.54084777832031,28.7358341217041],[-112.58168029785156,28.670278549194336]]],[[[-118.28916931152344,28.88166618347168],[-118.40416717529297,29.14777946472168],[-118.31001281738281,29.195276260375977],[-118.28916931152344,28.88166618347168]]],[[[-112.26194763183594,28.773332595825195],[-112.56417846679688,28.878332138061523],[-112.34584045410156,29.233610153198242],[-112.26194763183594,28.773332595825195]]],[[[-113.13555908203125,29.019723892211914],[-113.59221458435059,29.425832748413086],[-113.588623046875,29.5836124420166],[-113.13555908203125,29.019723892211914]]],[[[-114.65084838867188,31.690553665161133],[-114.76363372802734,31.712499618530273],[-114.790283203125,31.7994441986084],[-114.65084838867188,31.690553665161133]]],[[[-113.05288696289062,31.971071243286133],[-111.04583740234375,31.33305549621582],[-108.20834350585938,31.33305549621582],[-108.2086181640625,31.783334732055664],[-106.40084838867188,31.750276565551758],[-104.90055847167969,30.572778701782227],[-104.54000854492188,29.671110153198242],[-103.375,29.023611068725586],[-102.30584716796875,29.88944435119629],[-101.40501403808594,29.77277946472168],[-99.5050048828125,27.570276260375977],[-99.104736328125,26.434999465942383],[-97.14073944091797,25.966428756713867],[-97.88972473144531,22.600831985473633],[-97.17611694335938,20.684999465942383],[-95.91139221191406,18.82527732849121],[-94.80223083496094,18.52250099182129],[-94.47889709472656,18.146665573120117],[-91.99501037597656,18.7277774810791],[-91.81472778320312,18.383054733276367],[-91.47500610351562,18.439443588256836],[-90.45472717285156,19.975278854370117],[-90.3275146484375,21.031389236450195],[-88.45140075683594,21.56888771057129],[-87.02778625488281,21.59027671813965],[-86.77278137207031,21.15138816833496],[-87.7388916015625,19.67472267150879],[-87.41166687011719,19.578889846801758],[-87.84750366210938,18.190832138061523],[-88.03750610351562,18.869443893432617],[-88.29949951171875,18.48293113708496],[-88.37779235839844,18.482778549194336],[-89.14195251464844,17.81888771057129],[-90.982421875,17.820653915405273],[-90.98390197753906,17.2561092376709],[-91.4375,17.24110984802246],[-90.40640258789062,16.4163875579834],[-90.44195556640625,16.088335037231445],[-91.72917175292969,16.07499885559082],[-92.24678039550781,14.550546646118164],[-92.77278137207031,15.174444198608398],[-94.36805725097656,16.294443130493164],[-94.05778503417969,16.040834426879883],[-94.7247314453125,16.196664810180664],[-94.57806396484375,16.318334579467773],[-94.78973388671875,16.257776260375977],[-94.86195373535156,16.427499771118164],[-96.47611999511719,15.643610000610352],[-97.78500366210938,15.968610763549805],[-101.01112365722656,17.265275955200195],[-101.95001220703125,17.97749900817871],[-103.45001220703125,18.31361198425293],[-104.98361206054688,19.339445114135742],[-105.68000793457031,20.386388778686523],[-105.24417114257812,20.574167251586914],[-105.54444885253906,20.785001754760742],[-105.189453125,21.437498092651367],[-105.81696319580078,22.660276412963867],[-107.99918365478516,24.652498245239258],[-108.04251098632812,25.073610305786133],[-108.39418029785156,25.141111373901367],[-108.76779174804688,25.54222297668457],[-109.10890197753906,25.52610969543457],[-108.82805633544922,25.7983341217041],[-109.3880615234375,25.7561092376709],[-109.10389709472656,26.28360939025879],[-110.52971458435059,27.371110916137695],[-110.5097427368164,27.86638832092285],[-111.10556030273438,27.93833351135254],[-112.16472625732422,28.972501754760742],[-113.086669921875,31.22722053527832],[-115.03167724609375,31.968053817749023],[-114.5452880859375,30.00111198425293],[-112.86279296875,28.433332443237305],[-111.85861206054688,26.661943435668945],[-111.84221458435059,26.90305519104004],[-111.56083679199219,26.72361183166504],[-110.66056823730469,24.337778091430664],[-110.35417175292969,24.115835189819336],[-110.213623046875,24.351945877075195],[-109.41084289550781,23.468332290649414],[-110.00499725341797,22.886110305786133],[-110.31668090820312,23.5674991607666],[-112.08750915527344,24.7561092376709],[-112.07084655761719,25.613054275512695],[-112.10611724853516,25.51833152770996],[-112.39666557312012,26.27277946472168],[-113.22029113769531,26.705556869506836],[-113.12834167480469,26.958887100219727],[-113.59750366210938,26.7369441986084],[-114.9888916015625,27.72110939025879],[-113.98306274414062,27.70250129699707],[-114.31056213378906,27.865556716918945],[-114.06360626220703,28.527223587036133],[-115.69389343261719,29.76833152770996],[-117.12237358093262,32.53533363342285],[-114.7190933227539,32.71845817565918],[-114.80982971191406,32.50699043273926],[-113.05288696289062,31.971071243286133]],[[-109.94889831542969,27.024442672729492],[-109.98139953613281,27.076387405395508],[-110.0344467163086,27.09139060974121],[-109.94889831542969,27.024442672729492]],[[-97.6077880859375,21.736665725708008],[-97.68556213378906,21.85999870300293],[-97.67417907714844,21.7902774810791],[-97.6077880859375,21.736665725708008]]]]}},{"type":"Feature","properties":{"name":"Malaysia","iso2":"MY","iso3":"MYS"},"geometry":{"type":"MultiPolygon","coordinates":[[[[104.12024116516113,2.318891525268555],[104.15497016906738,2.287778854370117],[104.1010684967041,2.294168472290039],[104.12024116516113,2.318891525268555]]],[[[111.37082099914551,2.36027717590332],[111.30359077453613,2.448057174682617],[111.32747840881348,2.781389236450195],[111.38388252258301,2.680002212524414],[111.37692451477051,2.495279312133789],[111.41388130187988,2.37611198425293],[111.37082099914551,2.36027717590332]]],[[[104.17108345031738,2.705278396606445],[104.17191505432129,2.895002365112305],[104.22162818908691,2.72972297668457],[104.17108345031738,2.705278396606445]]],[[[117.72664833068848,4.169721603393555],[117.9035587310791,4.174043655395508],[117.68692207336426,4.168336868286133],[117.72664833068848,4.169721603393555]]],[[[118.68193244934082,4.499723434448242],[118.76277351379395,4.463613510131836],[118.68942451477051,4.441110610961914],[118.68193244934082,4.499723434448242]]],[[[118.50972175598145,4.554445266723633],[118.51748847961426,4.536111831665039],[118.49942207336426,4.529165267944336],[118.50972175598145,4.554445266723633]]],[[[118.57026863098145,4.600831985473633],[118.34387397766113,4.670553207397461],[118.47886848449707,4.689165115356445],[118.57026863098145,4.600831985473633]]],[[[115.2330493927002,5.259721755981445],[115.15833473205566,5.257776260375977],[115.24193000793457,5.384721755981445],[115.2330493927002,5.259721755981445]]],[[[100.28885841369629,5.256109237670898],[100.1838550567627,5.462499618530273],[100.32025337219238,5.427778244018555],[100.28885841369629,5.256109237670898]]],[[[115.67221260070801,5.707223892211914],[115.62776374816895,5.728334426879883],[115.65442848205566,5.735834121704102],[115.67221260070801,5.707223892211914]]],[[[118.17192268371582,5.812223434448242],[118.17886543273926,5.84889030456543],[118.2330493927002,5.848333358764648],[118.17192268371582,5.812223434448242]]],[[[116.05941963195801,6.003057479858398],[116.01693916320801,6.035833358764648],[116.05664253234863,6.039999008178711],[116.05941963195801,6.003057479858398]]],[[[115.60915565490723,6.195276260375977],[115.59274482727051,6.204721450805664],[115.60775947570801,6.221109390258789],[115.60915565490723,6.195276260375977]]],[[[99.87329292297363,6.416109085083008],[99.81302070617676,6.156667709350586],[99.64082527160645,6.419721603393555],[99.87329292297363,6.416109085083008]]],[[[100.65497016906738,6.448331832885742],[101.11551856994629,6.24888801574707],[101.13968849182129,5.63194465637207],[101.56997871398926,5.916666030883789],[101.83386421203613,5.74333381652832],[102.0952320098877,6.236139297485352],[103.40997505187988,4.858053207397461],[103.43579292297363,2.933889389038086],[104.27580451965332,1.365556716918945],[103.95941352844238,1.646944046020508],[103.51214027404785,1.269529342651367],[101.28497505187988,2.84111213684082],[101.29442024230957,3.268888473510742],[100.69719123840332,3.903890609741211],[100.12711524963379,6.424947738647461],[100.2149829864502,6.711111068725586],[100.65497016906738,6.448331832885742]]],[[[117.49359321594238,6.742498397827148],[117.46692848205566,6.642499923706055],[117.33719825744629,6.651388168334961],[117.49359321594238,6.742498397827148]]],[[[116.78914833068848,6.579168319702148],[117.17830848693848,6.990278244018555],[117.29081916809082,6.635835647583008],[117.73887825012207,6.39000129699707],[117.50305366516113,5.896112442016602],[118.00888252258301,6.061666488647461],[117.96027565002441,5.681390762329102],[118.37359809875488,5.807500839233398],[119.27581977844238,5.344999313354492],[118.14055061340332,4.888334274291992],[118.55220222473145,4.351667404174805],[117.5920581817627,4.169820785522461],[116.04942512512207,4.279443740844727],[115.68525886535645,4.171945571899414],[115.49553108215332,3.040002822875977],[115.13971138000488,2.906110763549805],[115.2371997833252,2.522500991821289],[114.8047046661377,2.24888801574707],[114.5627613067627,1.433610916137695],[113.65833473205566,1.224721908569336],[112.47276496887207,1.568056106567383],[111.82721138000488,0.998613357543945],[110.55525398254395,0.853891372680664],[109.66998481750488,1.613054275512695],[109.64856910705566,2.073408126831055],[109.92830848693848,1.689165115356445],[110.33333015441895,1.802221298217773],[111.37692451477051,1.343889236450195],[111.00000190734863,1.575555801391602],[111.37275886535645,2.150835037231445],[111.16858863830566,2.152223587036133],[111.22331428527832,2.421110153198242],[111.36811256408691,2.339094161987305],[111.45027351379395,2.368612289428711],[111.44470405578613,2.691667556762695],[113.01053810119629,3.160554885864258],[114.09507942199707,4.590539932250977],[114.64109992980957,4.018888473510742],[115.01843452453613,4.895795822143555],[115.02913093566895,4.820211410522461],[115.34332466125488,4.311944961547852],[115.2230396270752,4.804998397827148],[115.14578437805176,4.903242111206055],[115.54609870910645,5.053056716918945],[115.37886238098145,5.398889541625977],[115.84887886047363,5.56389045715332],[116.76249885559082,7.023611068725586],[116.78914833068848,6.579168319702148]]],[[[117.28333473205566,7.314722061157227],[117.06667518615723,7.10194206237793],[117.07415962219238,7.287500381469727],[117.28333473205566,7.314722061157227]]],[[[116.87248420715332,7.219999313354492],[117.00332832336426,7.353334426879883],[117.01888465881348,7.266389846801758],[116.87248420715332,7.219999313354492]]]]}},{"type":"Feature","properties":{"name":"Mozambique","iso2":"MZ","iso3":"MOZ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[32.954437,-26.058613],[32.89527100000012,-26.040836],[32.980553,-25.972778],[32.954437,-26.058613]]],[[[35.48832700000011,-21.685001],[35.435555,-21.783337],[35.47943900000021,-21.523891],[35.48832700000011,-21.685001]]],[[[39.901382,-16.413334],[39.810829000000155,-16.363056],[39.861382,-16.278057],[39.901382,-16.413334]]],[[[40.5008320000002,-11.031946],[40.64694200000022,-12.760834],[40.409996,-12.961945],[40.846107,-14.697779],[40.587776000000105,-15.479723],[39.09444400000021,-16.986389],[36.841385,-17.877224],[36.943886,-18.108612],[36.25277700000012,-18.891392],[34.899162,-19.857224],[34.619164,-19.617779],[35.312492,-22.418056],[35.545273,-22.232502],[35.497215,-24.105278],[35.012215,-24.654167],[32.81388900000016,-25.60778],[32.576111,-25.975559],[32.837494,-26.293056],[32.95249900000013,-26.083889],[32.890427,-26.847145],[32.1334,-26.839626],[31.96851,-25.95784],[32.016106,-24.459446],[31.297504000000146,-22.414764],[32.488876,-21.344448],[32.50222000000011,-20.598614],[33.0188830000001,-19.943336],[32.699165,-18.944447],[33.073051000000106,-18.348892],[32.987808,-17.265003],[32.98114,-16.709053],[31.276665,-16.018612],[30.422775,-16.009167],[30.415756,-15.631872],[30.21301700000018,-14.981716],[33.222229,-14.012566],[33.633331,-14.539722],[34.522217,-14.571667],[34.589722,-15.282778],[34.2555540000001,-15.899168],[35.2900540000002,-17.134266],[35.135300000000115,-16.553375],[35.814438,-16.019447],[35.924164000000104,-14.885557],[34.566383000000116,-13.342224],[34.375275,-12.155834],[34.626106000000135,-11.575834],[34.966728,-11.572111],[35.838333,-11.414722],[36.18972,-11.706667],[37.462044,-11.727329],[37.941383,-11.285002],[39.268051000000156,-11.168056],[40.43681300000017,-10.478174],[40.5008320000002,-11.031946]],[[34.602776000000205,-12.011946],[34.623886,-12.036667],[34.629997,-12.012501],[34.602776000000205,-12.011946]],[[34.723885,-12.032778],[34.732216,-12.095556],[34.754715,-12.044168],[34.723885,-12.032778]]]]}},{"type":"Feature","properties":{"name":"Malawi","iso2":"MW","iso3":"MWI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[34.732216,-12.095556],[34.723885,-12.032778],[34.754715,-12.044168],[34.732216,-12.095556]]],[[[34.623886,-12.036667],[34.602776000000205,-12.011946],[34.629997,-12.012501],[34.623886,-12.036667]]],[[[33.13472000000016,-9.494167],[34.325272,-9.732779],[34.966728,-11.572111],[34.626106000000135,-11.575834],[34.375275,-12.155834],[34.566383000000116,-13.342224],[35.924164000000104,-14.885557],[35.814438,-16.019447],[35.135300000000115,-16.553375],[35.2900540000002,-17.134266],[34.2555540000001,-15.899168],[34.589722,-15.282778],[34.522217,-14.571667],[33.633331,-14.539722],[33.222229,-14.012566],[32.678886,-13.60639],[33.046387,-12.603889],[33.54583,-12.359446],[33.273331,-12.144445],[33.250549,-10.886667],[33.702278,-10.561857],[32.940399,-9.405077],[33.13472000000016,-9.494167]]]]}},{"type":"Feature","properties":{"name":"New Caledonia","iso2":"NC","iso3":"NCL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[167.534424,-22.69389],[167.508026,-22.688332],[167.53137200000018,-22.651112],[167.534424,-22.69389]]],[[[167.5016480000002,-22.672222],[167.434692,-22.543056],[167.553864,-22.612499],[167.5016480000002,-22.672222]]],[[[166.816071,-22.463333],[166.7724910000002,-22.456108],[166.811646,-22.395],[166.816071,-22.463333]]],[[[171.313873,-22.33139],[171.300812,-22.334999],[171.304962,-22.327778],[171.313873,-22.33139]]],[[[166.0505370000001,-22.079445],[166.027191,-22.054722],[166.0505370000001,-22.036667],[166.0505370000001,-22.079445]]],[[[166.450256,-21.704445],[166.415527,-21.691387],[166.440796,-21.68861],[166.450256,-21.704445]]],[[[168.0021970000001,-21.451942],[168.1202390000001,-21.631111],[167.808868,-21.385834],[168.0021970000001,-21.451942]]],[[[167.842743,-21.14389],[167.80136100000013,-21.119446],[167.80246,-21.100277],[167.842743,-21.14389]]],[[[166.4480290000001,-20.734165],[166.38858,-20.72583],[166.459137,-20.719719],[166.4480290000001,-20.734165]]],[[[167.287201,-20.75639],[167.39804100000012,-21.177776],[167.059692,-20.988609],[167.287201,-20.75639]]],[[[166.62466400000014,-20.406109],[166.62579300000013,-20.601665],[166.499115,-20.717777],[166.62466400000014,-20.406109]]],[[[164.288025,-20.255558],[164.275269,-20.248886],[164.27026400000014,-20.219719],[164.288025,-20.255558]]],[[[163.943848,-20.170555],[163.922485,-20.16972],[163.906921,-20.14389],[163.943848,-20.170555]]],[[[164.31665000000012,-20.327225],[167.01470900000012,-22.321388],[166.451904,-22.316666],[166.116364,-21.946388],[165.2599790000002,-21.558056],[163.98941,-20.087223],[164.31665000000012,-20.327225]]],[[[164.234131,-20.161945],[164.161102,-20.113335],[164.16330000000013,-20.065277],[164.234131,-20.161945]]],[[[163.821625,-20.082779],[163.796936,-20.040836],[163.817749,-20.040836],[163.821625,-20.082779]]],[[[163.97717300000014,-20.081669],[163.939972,-20.068058],[163.949402,-20.002224],[163.97717300000014,-20.081669]]],[[[163.671906,-19.785835],[163.61969,-19.625832],[163.700806,-19.766392],[163.671906,-19.785835]]],[[[163.6074520000001,-19.604168],[163.568024,-19.573055],[163.5766300000001,-19.549446],[163.6074520000001,-19.604168]]],[[[159.949402,-19.343334],[159.95108,-19.114445],[159.978851,-19.171665],[159.949402,-19.343334]]]]}},{"type":"Feature","properties":{"name":"Niue","iso2":"NU","iso3":"NIU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-169.89389,-19.145557],[-169.931671,-19.016666],[-169.817505,-18.96833],[-169.89389,-19.145557]]]]}},{"type":"Feature","properties":{"name":"Niger","iso2":"NE","iso3":"NER"},"geometry":{"type":"MultiPolygon","coordinates":[[[[4.245,18.645275],[4.245277,19.146664],[5.812499,19.44611],[7.450807,20.852863],[11.986475,23.522305],[13.543888,23.16861],[14.234999,22.614166],[14.997889,23.000591],[15.202499,21.495831],[15.996666,20.353054],[15.489166,16.914165],[13.468887,14.461111],[13.62512,13.718338],[12.459166,13.066111],[10.724165,13.386389],[9.634932,12.802435],[7.815,13.352777],[6.933332,12.997221000000124],[6.423055,13.605276000000131],[5.874722,13.749443],[4.1425,13.476944],[3.604459,11.693274],[2.83862,12.396658],[2.378054,12.240274],[2.397925,11.896152],[2.1425,12.694443],[1.578333,12.629999],[0.989167,13.047222],[0.991667,13.371666],[1.285306,13.349957],[0.602222,13.703888],[0.235048,14.915068],[1.3125,15.286665],[3.523981,15.358152],[4.200833,16.393887],[4.245,18.645275]]]]}},{"type":"Feature","properties":{"name":"Aruba","iso2":"AW","iso3":"ABW"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-69.882233,12.41111],[-70.059448,12.538055],[-70.063065,12.628611],[-69.882233,12.41111]]]]}},{"type":"Feature","properties":{"name":"Anguilla","iso2":"AI","iso3":"AIA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-63.167778,18.164444],[-62.970001,18.272221],[-62.993057,18.227219],[-63.167778,18.164444]]]]}},{"type":"Feature","properties":{"name":"Belgium","iso2":"BE","iso3":"BEL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[4.302375,51.263184],[4.252368,51.375145],[5.041389000000152,51.486664],[5.849171,51.15638],[5.640833,50.839722],[6.011798000000113,50.7572710000001],[6.398204,50.323174],[6.134414,50.127846],[6.026256,50.181252],[5.80788,49.545044],[4.873055000000107,49.797218],[4.832503,50.16861],[4.149238,49.978371],[4.165,50.283051],[2.541667000000103,51.09111],[3.370866,51.373856000000146],[4.238898,51.350426],[4.302375,51.263184]]]]}},{"type":"Feature","properties":{"name":"Hong Kong","iso2":"HK","iso3":"HKG"},"geometry":{"type":"MultiPolygon","coordinates":[[[[114.24609400000011,22.203327],[114.124977,22.279999],[114.201103,22.290554],[114.24609400000011,22.203327]]],[[[113.8966520000001,22.195827000000108],[113.82527200000013,22.232216],[114.04776000000012,22.339996000000113],[113.8966520000001,22.195827000000108]]],[[[114.31414800000013,22.342773],[114.295258,22.34582900000011],[114.296097,22.368053],[114.31414800000013,22.342773]]],[[[114.219437,22.474438],[114.296104,22.260561],[114.03333040044393,22.50913814917469],[114.2225957829825,22.550548246897094],[114.219437,22.474438]]]]}},{"type":"Feature","properties":{"name":"Northern Mariana Islands","iso2":"MP","iso3":"MNP"},"geometry":{"type":"MultiPolygon","coordinates":[[[[145.2816470000001,14.158333],[145.11996500000012,14.122498],[145.237183,14.194998],[145.2816470000001,14.158333]]],[[[145.5352480000001,14.82833100000012],[145.529694,14.848331],[145.570251,14.844997],[145.5352480000001,14.82833100000012]]],[[[145.624115,14.908054000000106],[145.5722050000002,15.009998],[145.633026,15.083887],[145.624115,14.908054000000106]]],[[[145.73608400000015,15.133610000000118],[145.679138,15.105276],[145.818024,15.265833],[145.73608400000015,15.133610000000118]]],[[[145.655823,16.334721],[145.63443,16.376106],[145.714691,16.355831],[145.655823,16.334721]]],[[[145.798309,16.680275],[145.774994,16.705273000000105],[145.80163600000012,16.70055000000012],[145.798309,16.680275]]],[[[145.860779,17.28722],[145.84024,17.317219],[145.8674620000002,17.30416500000011],[145.860779,17.28722]]],[[[145.860779,17.567776],[145.824402,17.577496000000124],[145.833862,17.604996000000156],[145.860779,17.567776]]],[[[145.73608400000015,18.043888],[145.77914400000012,18.17083000000015],[145.824402,18.163052],[145.73608400000015,18.043888]]],[[[145.679138,18.721382000000133],[145.6633000000002,18.810276],[145.71051000000014,18.76833],[145.679138,18.721382000000133]]],[[[145.405823,19.652775],[145.3891600000002,19.688885],[145.415253,19.677219],[145.405823,19.652775]]],[[[145.256927,20.010830000000126],[145.242188,20.052219],[145.27359,20.036385],[145.256927,20.010830000000126]]],[[[144.921082,20.51833],[144.899139,20.526108],[144.913605,20.556385],[144.921082,20.51833]]]]}},{"type":"Feature","properties":{"name":"Faroe Islands","iso2":"FO","iso3":"FRO"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-6.655277252197266,61.38944435119629],[-6.962778091430664,61.61916542053223],[-6.724445343017578,61.57332801818848],[-6.655277252197266,61.38944435119629]]],[[[-6.604166030883789,61.821664810180664],[-6.6522216796875,61.74277687072754],[-6.908332824707031,61.90471839904785],[-6.604166030883789,61.821664810180664]]],[[[-7.049722671508789,62.06777381896973],[-7.201665878295898,62.01861000061035],[-7.434999465942383,62.140275955200195],[-7.049722671508789,62.06777381896973]]],[[[-6.706943511962891,61.9374942779541],[-7.232221603393555,62.172494888305664],[-7.210832595825195,62.28472328186035],[-6.706943511962891,61.9374942779541]]],[[[-6.657499313354492,62.09250068664551],[-7.060277938842773,62.313608169555664],[-6.601110458374023,62.19693946838379],[-6.657499313354492,62.09250068664551]]],[[[-6.620000839233398,62.22972297668457],[-6.685832977294922,62.24499702453613],[-6.720832824707031,62.33138465881348],[-6.620000839233398,62.22972297668457]]],[[[-6.418611526489258,62.18388557434082],[-6.572500228881836,62.2116641998291],[-6.57440185546875,62.34987831115723],[-6.418611526489258,62.18388557434082]]],[[[-6.406110763549805,62.284440994262695],[-6.480278015136719,62.29777717590332],[-6.545278549194336,62.38694190979004],[-6.406110763549805,62.284440994262695]]]]}},{"type":"Feature","properties":{"name":"Andorra","iso2":"AD","iso3":"AND"},"geometry":{"type":"MultiPolygon","coordinates":[[[[1.78172,42.569962],[1.723611,42.509438],[1.445833,42.601944],[1.78172,42.569962]]]]}},{"type":"Feature","properties":{"name":"Gibraltar","iso2":"GI","iso3":"GIB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-5.334508,36.16256000000011],[-5.33823,36.112175],[-5.355799,36.1633070000001],[-5.334508,36.16256000000011]]]]}},{"type":"Feature","properties":{"name":"Isle of Man","iso2":"IM","iso3":"IMN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-4.777779,54.05555],[-4.354167,54.410828],[-4.394444,54.186386],[-4.777779,54.05555]]]]}},{"type":"Feature","properties":{"name":"Luxembourg","iso2":"LU","iso3":"LUX"},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.026256,50.181252],[6.134414,50.127846],[6.524444,49.808609],[6.36217,49.459389],[5.80788,49.545044],[6.026256,50.181252]]]]}},{"type":"Feature","properties":{"name":"Macau","iso2":"MO","iso3":"MAC"},"geometry":{"type":"MultiPolygon","coordinates":[[[[113.531662,22.194736],[113.554428,22.21273000000015],[113.552467,22.183052],[113.531662,22.194736]]]]}},{"type":"Feature","properties":{"name":"Monaco","iso2":"MC","iso3":"MCO"},"geometry":{"type":"MultiPolygon","coordinates":[[[[7.439293000000106,43.75752300000015],[7.391609,43.727547],[7.387777,43.748604],[7.416111,43.770554],[7.439293000000106,43.75752300000015]]]]}},{"type":"Feature","properties":{"name":"Palestine","iso2":"PS","iso3":"PSE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[34.33416,31.25972],[34.26757800000021,31.216541],[34.21666,31.323330000000155],[34.490547,31.596096000000117],[34.33416,31.25972]]],[[[35.282494,32.516937],[35.552567,32.394196],[35.47819500000011,31.497322],[34.884995,31.391388],[35.282494,32.516937]],[[35.251663,31.788055000000114],[35.25972000000016,31.78722000000012],[35.24888600000011,31.808887000000155],[35.251663,31.788055000000114]]]]}},{"type":"Feature","properties":{"name":"Montenegro","iso2":"ME","iso3":"MNE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[18.455555,42.565826],[18.699997,43.255554],[19.228809,43.513214],[20.348888,42.886383],[20.071423,42.560913],[19.645832,42.61805],[19.367771,41.848999],[18.503197,42.44944],[18.455555,42.565826]]]]}},{"type":"Feature","properties":{"name":"Mayotte","iso2":"YT","iso3":"MYT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[45.282494,-12.804167],[45.262497,-12.76889],[45.283051,-12.747501],[45.282494,-12.804167]]],[[[45.2049940000002,-12.849724],[45.097496,-12.985834],[45.078888,-12.6625],[45.2049940000002,-12.849724]]]]}},{"type":"Feature","properties":{"name":"Åland Islands","iso2":"AX","iso3":"ALA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[20.210831000000155,59.979996000000156],[19.99916500000012,60.055275],[20.205276,60.063606],[20.210831000000155,59.979996000000156]]],[[[20.270554,60.057495000000145],[20.215553,60.13916],[20.292221,60.125275],[20.270554,60.057495000000145]]],[[[19.676666,60.156944],[19.510555,60.17527800000012],[19.601944,60.255829],[19.676666,60.156944]]],[[[20.397221000000144,60.195],[20.36610800000014,60.26554900000012],[20.441109,60.253052000000125],[20.397221000000144,60.195]]],[[[20.084721,60.350273],[20.277496,60.274162],[19.943886,60.04277],[19.648331,60.25666],[20.084721,60.350273]]]]}},{"type":"Feature","properties":{"name":"Norfolk Island","iso2":"NF","iso3":"NFK"},"geometry":{"type":"MultiPolygon","coordinates":[[[[167.964966,-29.081112],[167.912476,-29.00528],[167.997742,-29.025002],[167.964966,-29.081112]]]]}},{"type":"Feature","properties":{"name":"Cocos (Keeling) Islands","iso2":"CC","iso3":"CCK"},"geometry":{"type":"MultiPolygon","coordinates":[[[[96.914154,-12.198055],[96.902481,-12.199999],[96.91470300000012,-12.151945],[96.914154,-12.198055]]],[[[96.86276200000012,-12.196112],[96.819443,-12.178057],[96.826385,-12.128332],[96.86276200000012,-12.196112]]]]}},{"type":"Feature","properties":{"name":"Antarctica","iso2":"AQ","iso3":"ATA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-60.220001220703125,-80.28584289550781],[-60.90861511230469,-80.74833679199219],[-61.843894958496094,-80.83639526367188],[-67.03195190429688,-80.16639709472656],[-62.55000305175781,-80.25889587402344],[-60.69500732421875,-79.61000061035156],[-60.173614501953125,-79.711669921875],[-60.220001220703125,-80.28584289550781]]],[[[162.15973091125488,-79.06167602539062],[161.94778633117676,-79.03083801269531],[161.92584419250488,-78.98167419433594],[162.15973091125488,-79.06167602539062]]],[[[-162.13336181640625,-78.74111938476562],[-158.53250122070312,-79.71389770507812],[-161.08584594726562,-79.83528137207031],[-163.81640625,-79.20750427246094],[-162.13336181640625,-78.74111938476562]]],[[[-39.972503662109375,-78.55473327636719],[-37.459449768066406,-78.64028930664062],[-41.93055725097656,-78.59194946289062],[-39.972503662109375,-78.55473327636719]]],[[[-70.945556640625,-79.65000915527344],[-71.85528564453125,-79.4202880859375],[-70.30416870117188,-78.80528259277344],[-67.31723022460938,-78.50361633300781],[-70.945556640625,-79.65000915527344]]],[[[167.31555366516113,-78.25361633300781],[166.87164497375488,-78.20808410644531],[167.67749214172363,-78.11752319335938],[167.31555366516113,-78.25361633300781]]],[[[166.35220527648926,-78.31362915039062],[166.06555366516113,-78.11474609375],[166.77417182922363,-78.22111511230469],[166.35220527648926,-78.31362915039062]]],[[[-44.11444854736328,-78.69889831542969],[-45.575279235839844,-78.85195922851562],[-43.7933349609375,-79.00361633300781],[-44.583335876464844,-79.33389282226562],[-43.46611785888672,-79.47029113769531],[-43.35444641113281,-79.77972412109375],[-44.57250213623047,-80.09222412109375],[-44.066673278808594,-80.25750732421875],[-44.28639221191406,-80.33973693847656],[-52.05555725097656,-80.90278625488281],[-54.90888977050781,-80.71861267089844],[-50.666114807128906,-79.588623046875],[-50.183616638183594,-78.65055847167969],[-48.27278137207031,-78.05639457702637],[-44.841949462890625,-78.10139465332031],[-43.89111328125,-78.36195373535156],[-44.11444854736328,-78.69889831542969]]],[[[-148.76113891601562,-77.44223022460938],[-149.0352783203125,-77.41694641113281],[-148.8294677734375,-77.40139770507812],[-148.76113891601562,-77.44223022460938]]],[[[-150.20751953125,-77.37001037597656],[-151.19390869140625,-77.27195739746094],[-150.076416015625,-77.34056091308594],[-150.20751953125,-77.37001037597656]]],[[[-148.85861206054688,-77.354736328125],[-149.51947021484375,-77.29084777832031],[-149.16168212890625,-77.25889587402344],[-148.85861206054688,-77.354736328125]]],[[[167.71695137023926,-77.40583801269531],[169.45111274719238,-77.49668884277344],[166.77664375305176,-77.8577880859375],[166.54776191711426,-77.70668029785156],[166.88250923156738,-77.67195129394531],[166.2133502960205,-77.53863525390625],[166.63165473937988,-77.17280578613281],[167.71695137023926,-77.40583801269531]]],[[[-147.25222778320312,-77.16555786132812],[-147.53280639648438,-77.15194702148438],[-147.0625,-77.17388916015625],[-147.25222778320312,-77.16555786132812]]],[[[-147.89697265625,-77.42973327636719],[-148.86419677734375,-77.27084350585938],[-148.46444702148438,-77.070556640625],[-147.70889282226562,-77.189453125],[-147.59085083007812,-77.33168029785156],[-147.89697265625,-77.42973327636719]]],[[[-147.63363647460938,-77.10334777832031],[-147.83529663085938,-77.03472900390625],[-147.65472412109375,-77.04000854492188],[-147.63363647460938,-77.10334777832031]]],[[[-148.51168823242188,-76.90779113769531],[-148.20669555664062,-76.97805786132812],[-149.19473266601562,-76.9505615234375],[-148.51168823242188,-76.90779113769531]]],[[[-149.47836303710938,-76.89834594726562],[-149.072509765625,-77.10084533691406],[-150.73638916015625,-76.95112609863281],[-149.47836303710938,-76.89834594726562]]],[[[-146.71084594726562,-76.97917175292969],[-146.99166870117188,-76.85139465332031],[-146.22335815429688,-76.89750671386719],[-146.71084594726562,-76.97917175292969]]],[[[-148.53390502929688,-76.72250366210938],[-148.1572265625,-76.76528930664062],[-149.169189453125,-76.73222351074219],[-148.53390502929688,-76.72250366210938]]],[[[-149.83197021484375,-76.66445922851562],[-150.32086181640625,-76.78167724609375],[-150.701416015625,-76.71945190429688],[-149.83197021484375,-76.66445922851562]]],[[[-148.40945434570312,-76.689453125],[-148.77474975585938,-76.65278625488281],[-148.61917114257812,-76.61805725097656],[-148.40945434570312,-76.689453125]]],[[[-147.43362426757812,-76.68861389160156],[-147.95419311523438,-76.59112358093262],[-147.59140014648438,-76.59390258789062],[-147.43362426757812,-76.68861389160156]]],[[[-146.77224731445312,-76.71417236328125],[-147.25140380859375,-76.57695007324219],[-146.76083374023438,-76.570556640625],[-146.77224731445312,-76.71417236328125]]],[[[-147.34722900390625,-76.6138916015625],[-147.61807250976562,-76.55694580078125],[-147.4747314453125,-76.55751037597656],[-147.34722900390625,-76.6138916015625]]],[[[168.60333442687988,-76.2327880859375],[168.36108589172363,-76.16250610351562],[168.490816116333,-76.15861511230469],[168.60333442687988,-76.2327880859375]]],[[[-146.5855712890625,-76.30555725097656],[-147.278076171875,-76.11334228515625],[-146.776123046875,-76.08723258972168],[-146.57305908203125,-76.22029113769531],[-146.5855712890625,-76.30555725097656]]],[[[-146.79055786132812,-75.8558349609375],[-147.00363159179688,-75.8194580078125],[-146.85946655273438,-75.80555725097656],[-146.79055786132812,-75.8558349609375]]],[[[-145.15390014648438,-75.73667907714844],[-145.86727905273438,-75.60455322265625],[-145.57168579101562,-75.55278015136719],[-145.15390014648438,-75.73667907714844]]],[[[-143.00140380859375,-75.526123046875],[-143.28085327148438,-75.49166870117188],[-143.08224487304688,-75.46528625488281],[-143.00140380859375,-75.526123046875]]],[[[-132.3719482421875,-74.46417236328125],[-132.66195678710938,-74.41917419433594],[-132.20529174804688,-74.39250183105469],[-132.3719482421875,-74.46417236328125]]],[[[-131.38973999023438,-74.34695434570312],[-130.7447509765625,-74.41500854492188],[-132.00778198242188,-74.42916870117188],[-131.38973999023438,-74.34695434570312]]],[[[-127.39111328125,-74.58029174804688],[-128.16085815429688,-74.25418090820312],[-127.03611755371094,-74.39222717285156],[-127.39111328125,-74.58029174804688]]],[[[-117.11418151855469,-74.33416557312012],[-117.19833374023438,-74.32833862304688],[-116.75167846679688,-74.24722290039062],[-117.11418151855469,-74.33416557312012]]],[[[-20.46750259399414,-74.33029174804688],[-20.11944580078125,-74.85057067871094],[-21.603614807128906,-74.45083618164062],[-20.36944580078125,-74.12167358398438],[-20.46750259399414,-74.33029174804688]]],[[[-115.93028259277344,-73.96194458007812],[-116.27362060546875,-74.15362358093262],[-117.24111938476562,-74.1875],[-115.93028259277344,-73.96194458007812]]],[[[-122.14972686767578,-73.61445617675781],[-118.54945373535156,-73.92889404296875],[-122.13223266601562,-74.36805725097656],[-122.62999725341797,-74.32084655761719],[-122.41445922851562,-73.87055969238281],[-123.15939331054688,-73.73403930664062],[-122.14972686767578,-73.61445617675781]]],[[[169.8244342803955,-73.5955810546875],[169.388032913208,-73.5330810546875],[169.86859321594238,-73.28916931152344],[169.8244342803955,-73.5955810546875]]],[[[-78.04806518554688,-73.44223022460938],[-78.34611511230469,-73.25279235839844],[-77.63639831542969,-73.30000305175781],[-78.04806518554688,-73.44223022460938]]],[[[-126.11834716796875,-73.24722290039062],[-125.13417053222656,-73.71806335449219],[-124.23056030273438,-73.68917846679688],[-123.72416687011719,-74.10057067871094],[-125.25279235839844,-74.06390380859375],[-127.39250183105469,-73.41778564453125],[-126.11834716796875,-73.24722290039062]]],[[[-73.89111328125,-73.42500305175781],[-74.06417846679688,-73.3255615234375],[-73.4989013671875,-73.15362358093262],[-73.89111328125,-73.42500305175781]]],[[[-104.8650131225586,-73.2388916015625],[-105.24111938476562,-73.05473327636719],[-104.55029296875,-73.18667602539062],[-104.8650131225586,-73.2388916015625]]],[[[-89.74501037597656,-72.87556457519531],[-89.45668029785156,-72.91361999511719],[-90.37945556640625,-73.04779052734375],[-89.74501037597656,-72.87556457519531]]],[[[-74.2227783203125,-72.97611999511719],[-74.46556091308594,-73.64834594726562],[-76.09361267089844,-73.20945739746094],[-75.39527893066406,-73.06001281738281],[-75.72029113769531,-72.945556640625],[-75.38612365722656,-72.81806945800781],[-74.2227783203125,-72.97611999511719]]],[[[-93.75944519042969,-72.91166687011719],[-94.1380615234375,-72.83917236328125],[-93.80584716796875,-72.81500244140625],[-93.75944519042969,-72.91166687011719]]],[[[-98.14805603027344,-72.73001098632812],[-98.34361267089844,-72.69944763183594],[-97.82528686523438,-72.66334533691406],[-98.14805603027344,-72.73001098632812]]],[[[-99.7408447265625,-72.62361145019531],[-98.93028259277344,-72.67361450195312],[-100.85861206054688,-72.66555786132812],[-99.7408447265625,-72.62361145019531]]],[[[-95.33139038085938,-72.67195129394531],[-95.51834106445312,-72.64944458007812],[-94.69676208496094,-72.61419677734375],[-95.33139038085938,-72.67195129394531]]],[[[-91.33723258972168,-73.15695190429688],[-91.61723327636719,-72.604736328125],[-90.80639457702637,-72.59278869628906],[-91.33723258972168,-73.15695190429688]]],[[[-93.36528015136719,-72.65444946289062],[-93.46142578125,-72.58451843261719],[-93.1702880859375,-72.5755615234375],[-93.36528015136719,-72.65444946289062]]],[[[-61.038612365722656,-72.55972290039062],[-61.13500213623047,-72.54501342773438],[-60.970001220703125,-72.52751159667969],[-61.038612365722656,-72.55972290039062]]],[[[-78.42001342773438,-72.56777954101562],[-77.43917846679688,-72.588623046875],[-77.59445190429688,-72.91000366210938],[-78.80636596679688,-73.18165588378906],[-79.42167663574219,-72.96000671386719],[-78.8416748046875,-72.77139282226562],[-79.46139526367188,-72.56639099121094],[-79.24751281738281,-72.40251159667969],[-78.42001342773438,-72.56777954101562]]],[[[-68.81611633300781,-72.47445678710938],[-68.97750854492188,-72.46055603027344],[-68.59806823730469,-72.38583374023438],[-68.81611633300781,-72.47445678710938]]],[[[-60.336944580078125,-72.25750732421875],[-60.501943588256836,-72.19972229003906],[-60.34361267089844,-72.19416809082031],[-60.336944580078125,-72.25750732421875]]],[[[68.48201179504395,-72.27778625488281],[68.6931324005127,-72.08891296386719],[68.82002449035645,-72.165283203125],[68.48201179504395,-72.27778625488281]]],[[[69.79756355285645,-72.0330810546875],[69.7730884552002,-71.92362976074219],[69.9572925567627,-71.91864013671875],[69.79756355285645,-72.0330810546875]]],[[[-98.80307006835938,-71.88667297363281],[-98.29750061035156,-71.8719482421875],[-98.56056213378906,-72.13111877441406],[-98.19667053222656,-72.19917297363281],[-98.13630676269531,-71.89289855957031],[-97.6864013671875,-72.18194580078125],[-97.34945678710938,-71.86250305175781],[-96.65055847167969,-71.87333679199219],[-96.34263610839844,-72.002197265625],[-97.258056640625,-72.22222900390625],[-95.99514770507812,-72.08000183105469],[-95.82167053222656,-72.189453125],[-96.59611511230469,-72.28666687011719],[-95.67584228515625,-72.36056518554688],[-98.61611938476562,-72.56889343261719],[-102.56278991699219,-72.12472534179688],[-100.41445922851562,-71.88139343261719],[-100.06166076660156,-71.93513488769531],[-100.51055908203125,-72.02362060546875],[-100.23500061035156,-72.13084411621094],[-98.83306884765625,-72.13139343261719],[-99.30751037597656,-71.94389343261719],[-98.80307006835938,-71.88667297363281]]],[[[0.452028274536133,-71.1005859375],[0.239809036254883,-71.03361511230469],[0.586732864379883,-71.064453125],[0.452028274536133,-71.1005859375]]],[[[-60.53553009033203,-71.05635070800781],[-60.95916557312012,-70.94528198242188],[-60.624725341796875,-70.885009765625],[-60.53553009033203,-71.05635070800781]]],[[[-7.879444122314453,-70.73390197753906],[-8.043611526489258,-70.70001220703125],[-7.725276947021484,-70.71028137207031],[-7.879444122314453,-70.73390197753906]]],[[[-2.389999389648438,-70.751953125],[-1.982776641845703,-70.81639099121094],[-2.796388626098633,-71.03973388671875],[-3.454999923706055,-70.69306945800781],[-2.389999389648438,-70.751953125]]],[[[-73.68528747558594,-70.68028259277344],[-74.30612182617188,-71.01028442382812],[-76.635009765625,-71.06028747558594],[-73.68528747558594,-70.68028259277344]]],[[[2.050657272338867,-70.69972229003906],[1.895933151245117,-70.6461181640625],[2.216733932495117,-70.63639831542969],[2.050657272338867,-70.69972229003906]]],[[[-60.81945037841797,-70.6622314453125],[-61.15917205810547,-70.57583618164062],[-60.63139343261719,-70.54833984375],[-60.81945037841797,-70.6622314453125]]],[[[2.957578659057617,-70.625],[2.613157272338867,-70.50502014160156],[3.327329635620117,-70.46891784667969],[2.957578659057617,-70.625]]],[[[-6.040277481079102,-70.57917785644531],[-6.376682281494141,-70.47607421875],[-5.969852447509766,-70.4179515838623],[-6.040277481079102,-70.57917785644531]]],[[[-3.128055572509766,-70.50418090820312],[-3.329721450805664,-70.48333740234375],[-2.644166946411133,-70.415283203125],[-3.128055572509766,-70.50418090820312]]],[[[163.38614082336426,-70.38056945800781],[163.30529975891113,-70.34918212890625],[163.48333930969238,-70.35389709472656],[163.38614082336426,-70.38056945800781]]],[[[72.22700691223145,-70.61308288574219],[71.6881275177002,-70.33834838867188],[71.9300708770752,-70.29417419433594],[72.22700691223145,-70.61308288574219]]],[[[-1.790277481079102,-70.23194885253906],[-1.973054885864258,-70.18167114257812],[-1.897220611572266,-70.16889953613281],[-1.790277481079102,-70.23194885253906]]],[[[13.109552383422852,-70.0572509765625],[13.221185684204102,-70.13751220703125],[12.481744766235352,-70.11056518554688],[13.109552383422852,-70.0572509765625]]],[[[15.992849349975586,-70.1722412109375],[15.360345840454102,-70.02890014648438],[16.3620548248291,-70.01751708984375],[15.992849349975586,-70.1722412109375]]],[[[-61.38500213623047,-70.01528930664062],[-61.52806091308594,-69.96528625488281],[-61.292503356933594,-69.93417358398438],[-61.38500213623047,-70.01528930664062]]],[[[-74.84222412109375,-69.81584167480469],[-74.4525146484375,-70.02166557312012],[-75.86138916015625,-70.05528259277344],[-74.84222412109375,-69.81584167480469]]],[[[38.23148536682129,-69.67807006835938],[38.05619239807129,-69.63668823242188],[38.23148536682129,-69.64666557312012],[38.23148536682129,-69.67807006835938]]],[[[-72.35528564453125,-69.75750732421875],[-72.94528198242188,-69.60084533691406],[-72.04444885253906,-69.69306945800781],[-72.35528564453125,-69.75750732421875]]],[[[-62.04222869873047,-69.72000122070312],[-62.32722473144531,-69.10751342773438],[-61.71556091308594,-69.46861267089844],[-62.04222869873047,-69.72000122070312]]],[[[155.873628616333,-69.151123046875],[155.5258502960205,-69.00057983398438],[155.88369941711426,-69.05897521972656],[155.873628616333,-69.151123046875]]],[[[155.20083808898926,-69.04611206054688],[154.95392036437988,-69.01722717285156],[155.30890083312988,-68.98114013671875],[155.20083808898926,-69.04611206054688]]],[[[-70.15695190429688,-68.84861755371094],[-70.08416557312012,-69.26362609863281],[-68.37722778320312,-70.64944458007812],[-68.07139587402344,-71.63833618164062],[-68.39167785644531,-72.23390197753906],[-69.260009765625,-72.56417846679688],[-72.37611389160156,-72.727783203125],[-73.1944580078125,-72.43139457702637],[-70.52195739746094,-72.20777893066406],[-72.04501342773438,-72.1944580078125],[-70.94723510742188,-72.03889465332031],[-72.26750183105469,-71.6461181640625],[-72.86666870117188,-71.93417358398438],[-73.87918090820312,-71.820556640625],[-73.58111572265625,-72.04722595214844],[-74.0433349609375,-72.20889282226562],[-75.46612358093262,-71.85111999511719],[-75.14195251464844,-71.57778930664062],[-74.43583679199219,-71.69306945800781],[-74.38917541503906,-71.43417358398438],[-73.5291748046875,-71.64334106445312],[-73.67916870117188,-71.35806274414062],[-72.41195678710938,-71.33639526367188],[-73.15972900390625,-71.18501281738281],[-72.9263916015625,-71.1158447265625],[-70.6138916015625,-71.16639709472656],[-71.02084350585938,-70.8033447265625],[-72.46084594726562,-70.60195922851562],[-71.38917541503906,-70.23001098632812],[-71.81500244140625,-69.98417663574219],[-71.64584350585938,-69.51750183105469],[-72.25334167480469,-69.20722961425781],[-70.15695190429688,-68.84861755371094]]],[[[-90.59445190429688,-68.92584228515625],[-90.75140380859375,-68.79917907714844],[-90.48695373535156,-68.82778930664062],[-90.59445190429688,-68.92584228515625]]],[[[-63.44694519042969,-68.85139465332031],[-63.627784729003906,-68.79695129394531],[-63.41333770751953,-68.83723258972168],[-63.44694519042969,-68.85139465332031]]],[[[-60.718055725097656,-68.75473022460938],[-61.08167266845703,-68.67945861816406],[-60.82972717285156,-68.66111755371094],[-60.718055725097656,-68.75473022460938]]],[[[-67.50750732421875,-67.81001281738281],[-67.81529235839844,-67.68917846679688],[-67.08416557312012,-67.63139343261719],[-67.50750732421875,-67.81001281738281]]],[[[47.67118263244629,-67.58668518066406],[47.89804267883301,-67.59428405761719],[47.40786933898926,-67.62472534179688],[47.67118263244629,-67.58668518066406]]],[[[59.35531044006348,-67.33168029785156],[59.26925849914551,-67.290283203125],[59.41646766662598,-67.32057189941406],[59.35531044006348,-67.33168029785156]]],[[[164.78723335266113,-67.59529113769531],[164.56167793273926,-67.27166557312012],[164.84002876281738,-67.42362976074219],[164.78723335266113,-67.59529113769531]]],[[[58.64254951477051,-67.12641906738281],[58.52865028381348,-67.1177978515625],[58.67147254943848,-67.12001037597656],[58.64254951477051,-67.12641906738281]]],[[[58.86062049865723,-67.1219482421875],[58.77419471740723,-67.10861206054688],[58.82480049133301,-67.10224914550781],[58.86062049865723,-67.1219482421875]]],[[[50.34646797180176,-67.11639404296875],[50.13064765930176,-67.07418823242188],[50.25009346008301,-67.06779479980469],[50.34646797180176,-67.11639404296875]]],[[[48.79397773742676,-66.75613403320312],[48.39731788635254,-66.89028930664062],[48.29147529602051,-66.82000732421875],[48.79397773742676,-66.75613403320312]]],[[[86.0653247833252,-67.00112915039062],[85.3728199005127,-66.74668884277344],[85.8719654083252,-66.77389526367188],[86.18390083312988,-66.92251586914062],[86.0653247833252,-67.00112915039062]]],[[[86.49279975891113,-66.77473258972168],[86.30169868469238,-66.71113586425781],[86.73201179504395,-66.71223258972168],[86.49279975891113,-66.77473258972168]]],[[[-67.24417114257812,-66.74778747558594],[-67.54194641113281,-66.86973571777344],[-67.45973205566406,-66.69723510742188],[-67.24417114257812,-66.74778747558594]]],[[[-68.10028076171875,-67.39334106445312],[-68.56500244140625,-67.74806213378906],[-69.22889709472656,-67.54139709472656],[-67.58555603027344,-66.6138916015625],[-67.91084289550781,-66.84889221191406],[-67.67472839355469,-67.1591796875],[-68.10028076171875,-67.39334106445312]]],[[[99.29449653625488,-66.74861145019531],[99.21588325500488,-66.72306823730469],[99.52087593078613,-66.59002685546875],[99.29449653625488,-66.74861145019531]]],[[[163.10696601867676,-66.75613403320312],[162.9491901397705,-66.57223510742188],[163.11834907531738,-66.62306213378906],[163.10696601867676,-66.75613403320312]]],[[[85.33284187316895,-66.62861633300781],[85.1519947052002,-66.59028625488281],[85.2841968536377,-66.52029418945312],[85.33284187316895,-66.62861633300781]]],[[[98.77197456359863,-66.49197387695312],[98.60199165344238,-66.43333435058594],[98.86279487609863,-66.4544677734375],[98.77197456359863,-66.49197387695312]]],[[[97.22918891906738,-66.46640014648438],[97.08838081359863,-66.415283203125],[97.35310554504395,-66.42388916015625],[97.22918891906738,-66.46640014648438]]],[[[162.5680866241455,-66.43502807617188],[162.30029487609863,-66.18891906738281],[162.601411819458,-66.3505859375],[162.5680866241455,-66.43502807617188]]],[[[100.27307319641113,-66.19279479980469],[100.22973823547363,-66.14889526367188],[100.3516788482666,-66.14363098144531],[100.27307319641113,-66.19279479980469]]],[[[96.76751899719238,-66.25973510742188],[96.26001167297363,-66.18891906738281],[96.8477954864502,-66.12168884277344],[96.76751899719238,-66.25973510742188]]],[[[-66.73222351074219,-66.31056213378906],[-66.74305725097656,-66.11778259277344],[-66.5755615234375,-66.08805847167969],[-66.73222351074219,-66.31056213378906]]],[[[100.55475044250488,-66.14723205566406],[100.61865425109863,-66.04695129394531],[100.75641059875488,-66.07919311523438],[100.55475044250488,-66.14723205566406]]],[[[100.82141304016113,-66.02694702148438],[100.77282905578613,-66.01333618164062],[100.81726264953613,-65.99752807617188],[100.82141304016113,-66.02694702148438]]],[[[100.92755317687988,-66.00556945800781],[100.84362983703613,-65.98307800292969],[100.95892524719238,-65.96833801269531],[100.92755317687988,-66.00556945800781]]],[[[100.77057075500488,-65.86138916015625],[100.70807075500488,-65.83279418945312],[100.99810981750488,-65.80891418457031],[100.77057075500488,-65.86138916015625]]],[[[92.69893074035645,-65.79835510253906],[92.26892280578613,-65.76417541503906],[92.49505805969238,-65.6722412109375],[92.69893074035645,-65.79835510253906]]],[[[-65.66694641113281,-65.68722534179688],[-66.16111755371094,-65.86889457702637],[-65.9183349609375,-65.52972412109375],[-65.66694641113281,-65.68722534179688]]],[[[100.7549991607666,-65.67861938476562],[100.24695014953613,-65.5836181640625],[101.25665473937988,-65.50376892089844],[100.7549991607666,-65.67861938476562]]],[[[103.24279975891113,-65.29583740234375],[103.4725284576416,-65.45001220703125],[102.77393531799316,-65.14028930664062],[103.24279975891113,-65.29583740234375]]],[[[-59.43611145019531,-65.25584411621094],[-59.81305694580078,-65.10722351074219],[-59.533058166503906,-65.10945129394531],[-59.43611145019531,-65.25584411621094]]],[[[-63.14417266845703,-64.78140258789062],[-63.32444763183594,-64.91195678710938],[-63.55500030517578,-64.89306640625],[-63.14417266845703,-64.78140258789062]]],[[[-57.27916717529297,-64.55250358581543],[-57.488616943359375,-64.49639892578125],[-56.855003356933594,-64.338623046875],[-57.27916717529297,-64.55250358581543]]],[[[-63.306671142578125,-64.42861938476562],[-62.760284423828125,-64.56028747558594],[-63.64000701904297,-64.83389282226562],[-64.22056579589844,-64.67333984375],[-63.089447021484375,-64.29667663574219],[-63.306671142578125,-64.42861938476562]]],[[[-56.81500244140625,-64.31695556640625],[-56.758338928222656,-64.23779296875],[-56.5755615234375,-64.2197265625],[-56.81500244140625,-64.31695556640625]]],[[[-62.30000305175781,-64.4344482421875],[-62.70472717285156,-64.46612358093262],[-62.480560302734375,-64.0433349609375],[-62.01167297363281,-64.21417236328125],[-62.30000305175781,-64.4344482421875]]],[[[-57.815834045410156,-63.961395263671875],[-57.03334045410156,-64.17250061035156],[-57.91278076171875,-64.44528198242188],[-58.23944854736328,-64.32501220703125],[-58.080833435058594,-64.08473205566406],[-58.428611755371094,-64.11334228515625],[-57.815834045410156,-63.961395263671875]]],[[[-57.570556640625,-63.78778076171875],[-57.045562744140625,-63.822784423828125],[-57.694725036621094,-63.81639099121094],[-57.570556640625,-63.78778076171875]]],[[[-60.73833465576172,-63.86833953857422],[-60.76416778564453,-63.660560607910156],[-60.531394958496094,-63.65167236328125],[-60.73833465576172,-63.86833953857422]]],[[[-55.97666931152344,-63.581390380859375],[-56.20555877685547,-63.452781677246094],[-55.70777893066406,-63.45250701904297],[-55.97666931152344,-63.581390380859375]]],[[[-62.15416717529297,-63.32417297363281],[-62.260284423828125,-63.25389099121094],[-61.94333457946777,-63.28166961669922],[-62.15416717529297,-63.32417297363281]]],[[[-56.94639587402344,-63.4505615234375],[-56.72138977050781,-63.5947265625],[-57.3800048828125,-63.46055603027344],[-58.60083770751953,-63.948890686035156],[-58.77864074707031,-64.53581237792969],[-59.49305725097656,-64.31611633300781],[-59.505279541015625,-64.5372314453125],[-59.91889190673828,-64.4122314453125],[-61.959449768066406,-65.18028259277344],[-62.08972930908203,-65.44029235839844],[-61.68305969238281,-65.53861999511719],[-62.45972442626953,-65.90472412109375],[-61.872779846191406,-66.17195129394531],[-60.55750274658203,-65.94528198242188],[-60.93695068359375,-66.260009765625],[-61.41667175292969,-66.12528991699219],[-61.713890075683594,-66.46917724609375],[-62.18139457702637,-66.18028259277344],[-62.885284423828125,-66.26278686523438],[-62.44361114501953,-66.43028259277344],[-62.60889434814453,-66.72834777832031],[-63.675559997558594,-66.21833801269531],[-64.19667053222656,-66.72029113769531],[-63.743614196777344,-66.89167785644531],[-64.83778381347656,-66.95140075683594],[-64.77056884765625,-67.31723022460938],[-65.6138916015625,-67.55917358398438],[-65.290283203125,-67.67333984375],[-65.61778259277344,-67.8800048828125],[-65.32917785644531,-67.9747314453125],[-65.72361755371094,-68.14805603027344],[-64.76834106445312,-68.12278747558594],[-65.5966796875,-68.34750366210938],[-65.0916748046875,-68.44195556640625],[-65.31333923339844,-68.71139526367188],[-63.85778045654297,-68.84278869628906],[-64.3900146484375,-68.51333618164062],[-62.72834014892578,-68.41000366210938],[-63.97416687011719,-68.53639221191406],[-63.21055603027344,-68.78695678710938],[-63.70667266845703,-68.74250793457031],[-63.36805725097656,-69.05000305175781],[-63.638893127441406,-69.22723388671875],[-62.47583770751953,-69.45306396484375],[-62.63500213623047,-69.85334777832031],[-61.940834045410156,-70.22917175292969],[-62.49083709716797,-70.38056945800781],[-61.48445129394531,-70.52027893066406],[-62.12889099121094,-70.86557006835938],[-61.380279541015625,-70.81529235839844],[-60.9425048828125,-71.15834045410156],[-61.929725646972656,-71.65640258789062],[-60.90416717529297,-71.73638916015625],[-62.55250358581543,-72.04750061035156],[-60.86583709716797,-72.00306701660156],[-61.07472229003906,-72.16361999511719],[-60.852500915527344,-72.38890075683594],[-61.54972839355469,-72.42279052734375],[-61.270835876464844,-72.70028686523438],[-60.616111755371094,-72.64334106445312],[-60.617225646972656,-73.02862358093262],[-59.774169921875,-72.90028381347656],[-59.849449157714844,-73.23306274414062],[-60.59972381591797,-73.36029052734375],[-61.91944885253906,-73.14306640625],[-61.43639373779297,-73.34361267089844],[-61.836669921875,-73.36639404296875],[-61.609169006347656,-73.54611206054688],[-60.58778381347656,-73.70611572265625],[-61.76250457763672,-73.91389465332031],[-61.03639221191406,-74.09834289550781],[-61.755279541015625,-74.30639457702637],[-61.88750457763672,-74.83222961425781],[-62.531394958496094,-74.98251342773438],[-63.24583435058594,-74.60417175292969],[-63.0513916015625,-74.89527893066406],[-63.98944854736328,-75.008056640625],[-63.09584045410156,-75.13084411621094],[-64.44778442382812,-75.29779052734375],[-63.0947265625,-75.3255615234375],[-63.429168701171875,-75.4505615234375],[-69.38528442382812,-76.29611206054688],[-70.47639465332031,-76.70777893066406],[-75.4444580078125,-76.54640197753906],[-76.38056945800781,-76.06500244140625],[-77.77166557312012,-75.91889953613281],[-78.47666931152344,-76.4072265625],[-75.63278198242188,-77.50862121582031],[-72.83973693847656,-77.6400146484375],[-74.85334777832031,-78.14111328125],[-81.4969482421875,-77.65779113769531],[-80.60556030273438,-77.88639831542969],[-81.47000122070312,-77.89723205566406],[-77.48750305175781,-78.52667236328125],[-78.95750427246094,-78.81333923339844],[-84.1077880859375,-78.36083984375],[-80.63555908203125,-79.61917114257812],[-80.20278930664062,-79.22889709472656],[-77.02944946289062,-79.27944946289062],[-76.0836181640625,-79.64584350585938],[-77.32194519042969,-80.01139831542969],[-79.84945678710938,-79.95445251464844],[-76.08944702148438,-80.19723510742188],[-74.69389343261719,-80.69723510742188],[-59.64805603027344,-82.43389892578125],[-58.783058166503906,-82.64500427246094],[-59.07972717285156,-82.96583557128906],[-58.210838317871094,-83.03334045410156],[-53.72583770751953,-82.15028381347656],[-43.084449768066406,-81.85139465332031],[-41.4888916015625,-81.38334655761719],[-28.319446563720703,-80.27694702148438],[-28.0625,-80.00473022460938],[-30.210556030273438,-79.66667175292969],[-27.085556030273438,-79.01333618164062],[-33.00111389160156,-79.45390319824219],[-36.30278015136719,-78.7791748046875],[-33.88611602783203,-77.66056823730469],[-28.305278778076172,-76.56529235839844],[-17.758056640625,-75.729736328125],[-18.256389617919922,-75.49583435058594],[-17.14722442626953,-74.78472900390625],[-13.704723358154297,-73.94195556640625],[-16.326114654541016,-74.06390380859375],[-16.919170379638672,-73.97611999511719],[-16.069168090820312,-73.74751281738281],[-16.89889144897461,-73.77305603027344],[-16.02361297607422,-73.32028198242188],[-13.731111526489258,-73.02084350585938],[-14.469167709350586,-72.79667663574219],[-13.406112670898438,-72.82305908203125],[-11.657777786254883,-72.32695007324219],[-11.325834274291992,-71.96501159667969],[-12.276945114135742,-71.37750244140625],[-11.556507110595703,-71.27882385253906],[-11.592779159545898,-71.56195068359375],[-11.019445419311523,-71.6572265625],[-10.048612594604492,-71.11138916015625],[-10.430000305175781,-70.98695373535156],[-9.878713607788086,-70.90097045898438],[-8.93083381652832,-71.23361206054688],[-8.366945266723633,-71.82583618164062],[-7.337778091430664,-71.69195556640625],[-7.723333358764648,-71.42916870117188],[-6.021110534667969,-70.69972229003906],[-5.441110610961914,-70.88250732421875],[-6.103889465332031,-71.14445495605469],[-6.009166717529297,-71.41889953613281],[-2.261667251586914,-71.17083740234375],[-2.093889236450195,-71.48611450195312],[-1.053333282470703,-71.27667236328125],[-0.7772216796875,-71.38917541503906],[-0.923055648803711,-71.58917236328125],[-0.29749870300293,-71.65888977050781],[2.803159713745117,-70.84695434570312],[6.699522018432617,-70.58639526367188],[7.557310104370117,-70.16835021972656],[8.480646133422852,-70.47724914550781],[9.090387344360352,-70.31834411621094],[8.682855606079102,-70.074462890625],[11.270624160766602,-70.71028137207031],[12.046747207641602,-70.71751403808594],[12.740350723266602,-70.2811279296875],[14.165643692016602,-70.15890502929688],[15.705926895141602,-70.27862358093262],[18.036489486694336,-69.96917724609375],[23.246755599975586,-70.54641723632812],[31.08342170715332,-69.77389526367188],[32.90232276916504,-69.27694702148438],[33.44504737854004,-68.95724487304688],[33.42423439025879,-68.65141296386719],[34.14035987854004,-68.4827880859375],[36.41452980041504,-69.314453125],[36.12644386291504,-69.53361511230469],[36.72257423400879,-69.72807312011719],[37.91617774963379,-69.25141906738281],[37.85093116760254,-69.53390502929688],[37.14505958557129,-69.66474914550781],[38.23923683166504,-69.9927978515625],[38.56449317932129,-69.50057983398438],[38.65036964416504,-69.98863220214844],[39.70176124572754,-69.64863586425781],[39.76035499572754,-68.9544677734375],[41.10312843322754,-68.52389526367188],[46.30893135070801,-67.64169311523438],[46.24643135070801,-67.35751342773438],[46.55143165588379,-67.27725219726562],[47.44895362854004,-67.41780090332031],[47.00950050354004,-67.55030822753906],[47.39560890197754,-67.72251892089844],[48.21701240539551,-67.63444519042969],[49.16726875305176,-67.38336181640625],[48.26285743713379,-67.16752624511719],[49.16397285461426,-66.86280822753906],[49.15170478820801,-67.088623046875],[50.68948554992676,-67.18139457702637],[50.16977119445801,-66.74305725097656],[50.41311836242676,-66.44197082519531],[53.77896308898926,-65.84002685546875],[55.61923408508301,-66.0069580078125],[57.31197547912598,-66.56333923339844],[56.72952461242676,-66.901123046875],[59.11062049865723,-67.4122314453125],[69.6447925567627,-67.75390625],[70.10200691223145,-68.52389526367188],[69.2920093536377,-69.102783203125],[69.74312019348145,-69.36308288574219],[68.87117195129395,-69.37947082519531],[69.34004402160645,-69.63862609863281],[69.2053394317627,-69.86390686035156],[68.0947437286377,-69.87947082519531],[67.6461353302002,-70.38639831542969],[68.59395027160645,-70.77058410644531],[68.85029792785645,-70.53224182128906],[68.66169929504395,-70.3677978515625],[69.1447925567627,-70.33139038085938],[69.2439136505127,-70.67057800292969],[67.60530281066895,-71.58308410644531],[67.9011402130127,-71.64447021484375],[67.33755683898926,-72.06333923339844],[68.9364185333252,-72.42500305175781],[70.86494636535645,-71.93014526367188],[71.44978523254395,-71.54611206054688],[71.24812507629395,-71.38945007324219],[71.50447273254395,-70.95390319824219],[72.86311531066895,-70.43278503417969],[72.6156177520752,-70.20361328125],[72.9011402130127,-70.02195739746094],[77.74727058410645,-69.11697387695312],[78.11641120910645,-68.45973205566406],[82.0572681427002,-67.6722412109375],[81.4697437286377,-67.50529479980469],[82.01448249816895,-67.25167846679688],[82.66504096984863,-67.39389038085938],[83.40339851379395,-67.15667724609375],[85.79168891906738,-67.17778015136719],[87.50251960754395,-66.89474487304688],[88.10949897766113,-66.65252685546875],[88.22723579406738,-66.03639221191406],[88.96722602844238,-66.76139831542969],[92.00531196594238,-66.53390502929688],[97.56445503234863,-66.74057006835938],[98.26196479797363,-66.51611328125],[99.28308296203613,-66.88084411621094],[100.95392036437988,-66.08084106445312],[102.62616157531738,-65.901123046875],[107.80478096008301,-66.39836120605469],[108.82422065734863,-66.83113098144531],[110.62976264953613,-66.48667907714844],[110.89172554016113,-66.06362915039062],[113.31534004211426,-65.71334838867188],[114.43142890930176,-66.17947387695312],[114.51835823059082,-66.4727783203125],[116.18004035949707,-66.36668395996094],[117.76700019836426,-66.98974609375],[122.18335914611816,-66.54780578613281],[125.19001960754395,-66.73419189453125],[126.35616493225098,-66.27972412109375],[126.98835945129395,-66.45358276367188],[126.92865180969238,-66.83445739746094],[128.83477973937988,-67.14251708984375],[130.35199165344238,-66.22584533691406],[134.24530220031738,-66.20112609863281],[134.43640327453613,-66.00141906738281],[134.10061836242676,-65.12306213378906],[134.437837600708,-64.92613220214844],[135.27224922180176,-65.4364013671875],[134.94778633117676,-66.09306335449219],[142.56640815734863,-66.99417114257812],[143.40002632141113,-66.85113525390625],[144.58557319641113,-67.24528503417969],[145.40445137023926,-67.01722717285156],[145.87530708312988,-67.19586181640625],[145.31500434875488,-67.61334228515625],[146.6427936553955,-67.70945739746094],[147.1508502960205,-67.99085998535156],[146.9533405303955,-68.14169311523438],[148.02945137023926,-67.84446716308594],[148.64807319641113,-67.98919677734375],[148.21722602844238,-68.12724304199219],[148.81335639953613,-68.33528137207031],[150.992525100708,-68.39085388183594],[151.1850299835205,-68.98002624511719],[153.76861763000488,-68.9222412109375],[153.77835273742676,-68.3436279296875],[154.68585395812988,-68.61500358581543],[154.28668403625488,-68.86308288574219],[154.85669136047363,-69.10252380371094],[156.33612251281738,-69.24057006835938],[157.23639106750488,-68.94252014160156],[160.96890449523926,-70.25556945800781],[162.75390815734863,-70.28030395507812],[163.520845413208,-70.67500305175781],[163.78528022766113,-70.62806701660156],[163.55389595031738,-70.46528625488281],[166.77166938781738,-70.61167907714844],[166.46304512023926,-70.70195007324219],[167.76751899719238,-70.78083801269531],[170.27224922180176,-71.66001892089844],[170.21527290344238,-71.28279113769531],[170.45303535461426,-71.35166931152344],[170.99444770812988,-71.86419677734375],[170.129976272583,-72.05140686035156],[169.87164497375488,-72.37919616699219],[170.3041706085205,-72.30084228515625],[170.3222370147705,-72.58030700683594],[169.26642036437988,-73.08390808105469],[169.07916450500488,-73.52752685546875],[167.56167793273926,-73.40335083007812],[165.54858589172363,-73.93251037597656],[166.12915229797363,-74.12724304199219],[164.780855178833,-74.136962890625],[165.33331489562988,-74.67280578613281],[164.14251899719238,-74.61611938476562],[163.65667915344238,-74.77445983886719],[163.871675491333,-74.95335388183594],[162.53973579406738,-75.10891723632812],[163.13696479797363,-75.93667602539062],[162.33780097961426,-76.167236328125],[162.875581741333,-76.24778747558594],[162.93225288391113,-76.58308410644531],[162.623628616333,-76.61946105957031],[163.06973457336426,-76.73085021972656],[162.33279609680176,-76.951416015625],[163.23834419250488,-77.04139709472656],[163.89697456359863,-77.46669006347656],[163.61084175109863,-77.69612121582031],[164.56500434875488,-77.73638916015625],[164.20669746398926,-78.14389038085938],[165.5400104522705,-78.00335693359375],[165.68359565734863,-78.39169311523438],[167.26944160461426,-78.65583801269531],[164.49444770812988,-78.56974792480469],[160.49417304992676,-79.02085876464844],[160.04055976867676,-79.15583801269531],[160.73806953430176,-79.45307922363281],[159.09280586242676,-79.97111511230469],[160.52444648742676,-80.04139709472656],[158.05725288391113,-80.28056335449219],[160.89196968078613,-80.37750244140625],[159.75695991516113,-80.56974792480469],[161.17447090148926,-80.63555908203125],[160.01556587219238,-80.78030395507812],[160.84390449523926,-80.89306640625],[160.50308418273926,-80.95278930664062],[160.839448928833,-81.07807922363281],[160.62613105773926,-81.20501708984375],[162.19391059875488,-81.29780578613281],[160.39111518859863,-81.52140808105469],[162.2758502960205,-81.6622314453125],[163.859468460083,-82.17417907714844],[163.446138381958,-82.26502990722656],[168.692476272583,-83.14640808105469],[167.46972846984863,-83.43917846679688],[169.250825881958,-83.33001708984375],[172.31860542297363,-83.59722900390625],[171.90503120422363,-83.80169677734375],[180.00000190734863,-84.30224609375],[180.00000190734863,-90],[-180,-90],[-180,-84.30534362792969],[-157.48333740234375,-85.44862365722656],[-150.23947143554688,-85.463623046875],[-148.13833618164062,-85.09083557128906],[-139.66140747070312,-85.24501037597656],[-138.58944702148438,-84.98472595214844],[-149.29473876953125,-84.56195068359375],[-153.05307006835938,-84.01278686523438],[-153.00750732421875,-83.08750915527344],[-151.794189453125,-82.57778930664062],[-154.89141845703125,-81.90501403808594],[-153.98919677734375,-81.62918090820312],[-154.20501708984375,-81.55223083496094],[-156.96002197265625,-81.25167846679688],[-154.92169189453125,-81.001953125],[-148.41336059570312,-81.35751342773438],[-145.524169921875,-80.46055603027344],[-146.81195068359375,-79.88751220703125],[-155.90640258789062,-78.7197265625],[-153.75030517578125,-78.30833435058594],[-157.9102783203125,-78.001953125],[-158.17584228515625,-77.85972595214844],[-157.69696044921875,-77.57139587402344],[-157.75308227539062,-77.10806274414062],[-156.48333740234375,-77.35861206054688],[-155.86138916015625,-77.08445739746094],[-153.790283203125,-77.17472839355469],[-153.0836181640625,-77.28666687011719],[-153.10641479492188,-77.49722290039062],[-152.06112670898438,-77.32528686523438],[-149.6622314453125,-77.76112365722656],[-149.08724975585938,-77.69612121582031],[-149.4141845703125,-77.57084655761719],[-148.7327880859375,-77.62556457519531],[-148.5855712890625,-77.59445190429688],[-148.58111572265625,-77.50445556640625],[-147.59140014648438,-77.42222595214844],[-147.49307250976562,-77.29695129394531],[-147.07168579101562,-77.37278747558594],[-147.0322265625,-77.22084045410156],[-146.26861572265625,-77.46640014648438],[-145.87890625,-77.30639457702637],[-146.22750854492188,-77.16500854492188],[-145.84280395507812,-77.11418151855469],[-146.3013916015625,-76.99917602539062],[-145.29888916015625,-77.0291748046875],[-146.10223388671875,-76.84001159667969],[-145.45639038085938,-76.76028442382812],[-146.9322509765625,-76.45195007324219],[-149.50613403320312,-76.38751220703125],[-148.10128784179688,-76.09565734863281],[-146.49166870117188,-76.36750793457031],[-145.47946166992188,-76.44334411621094],[-146.2952880859375,-76.03973388671875],[-134.30389404296875,-74.53279113769531],[-133.26251220703125,-74.84722900390625],[-121.47834777832031,-74.74250793457031],[-118.53167724609375,-74.61361694335938],[-117.74305725097656,-74.30862426757812],[-117.39695739746094,-74.53083801269531],[-114.6977767944336,-74.46917724609375],[-114.81001281738281,-74.104736328125],[-114.00361633300781,-73.88917541503906],[-113.1864013671875,-74.16889953613281],[-113.4336166381836,-74.47222900390625],[-112.93028259277344,-74.45500183105469],[-113.55555725097656,-74.63444519042969],[-112.65416717529297,-74.85861206054688],[-111.34306335449219,-74.75944519042969],[-111.72445678710938,-74.58723258972168],[-111.38583374023438,-74.46223258972168],[-111.50389099121094,-74.19168090820312],[-110.15471458435059,-74.2841796875],[-109.92888641357422,-74.76139831542969],[-110.961669921875,-75.15779113769531],[-110.383056640625,-75.30612182617188],[-99.51028442382812,-75.09251403808594],[-100.85166931152344,-74.81472778320312],[-100.151123046875,-74.76083374023438],[-100.51555633544922,-74.67111206054688],[-100.24806213378906,-74.4908447265625],[-101.33194732666016,-74.48056030273438],[-101.65834045410156,-73.9989013671875],[-102.90139770507812,-73.87583923339844],[-103.01334381103516,-73.62918090820312],[-99.17556762695312,-73.61917114257812],[-103.03611755371094,-73.32640075683594],[-103.60334777832031,-72.89195251464844],[-103.17611694335938,-72.73333740234375],[-102.09916687011719,-73.08473205566406],[-90.86111450195312,-73.32667541503906],[-89.32112121582031,-73.05416870117188],[-89.5372314453125,-72.63362121582031],[-89.26112365722656,-72.63945007324219],[-88.33584594726562,-72.81611633300781],[-88.70916557312012,-73.17945861816406],[-86.84083557128906,-73.33639526367188],[-85.9666748046875,-73.04139709472656],[-85.47084045410156,-73.3497314453125],[-85.5997314453125,-73.55833435058594],[-82.13417053222656,-73.94334411621094],[-81.04139709472656,-73.71556091308594],[-81.27528381347656,-73.36944580078125],[-80.51918029785156,-73.44639587402344],[-80.695556640625,-73.05056762695312],[-78.95889282226562,-73.39250183105469],[-78.78973388671875,-73.69306945800781],[-76.61834716796875,-73.57667541503906],[-76.96278381347656,-73.87306213378906],[-69.4283447265625,-73.19723510742188],[-66.79722595214844,-72.40779113769531],[-66.85917663574219,-71.89556884765625],[-67.5372314453125,-71.45472717285156],[-67.40028381347656,-71.04000854492188],[-67.70390319824219,-70.59306335449219],[-68.83805847167969,-69.417236328125],[-66.65779113769531,-69.01779174804688],[-67.49444580078125,-68.81556701660156],[-66.93223571777344,-68.77389526367188],[-67.16555786132812,-68.2933349609375],[-66.58973693847656,-68.23806762695312],[-67.1572265625,-68.01055908203125],[-66.42723083496094,-67.53334045410156],[-67.6239013671875,-67.55361938476562],[-67.48583984375,-67.07722473144531],[-66.40472412109375,-66.88555908203125],[-66.49722290039062,-66.62251281738281],[-65.68972778320312,-66.125],[-64.45333862304688,-65.98167419433594],[-64.65972900390625,-65.74028015136719],[-63.71278381347656,-65.50250244140625],[-64.05307006835938,-65.42195129394531],[-63.87944793701172,-65.01834106445312],[-63.09056091308594,-65.13389587402344],[-62.93805694580078,-64.79750061035156],[-62.31945037841797,-64.85890197753906],[-62.61778259277344,-64.7550048828125],[-62.45361328125,-64.58917236328125],[-61.935279846191406,-64.69056701660156],[-60.94194793701172,-64.27751159667969],[-60.991668701171875,-64.03584289550781],[-59.445838928222656,-63.89305877685547],[-58.91083526611328,-63.533058166503906],[-57.20500183105469,-63.20555877685547],[-56.94639587402344,-63.4505615234375]]],[[[-55.470001220703125,-63.143333435058594],[-55.002784729003906,-63.28388977050781],[-56.5433349609375,-63.36444854736328],[-55.470001220703125,-63.143333435058594]]],[[[-56.26500701904297,-63.16944885253906],[-56.58472442626953,-63.035003662109375],[-55.97084045410156,-63.05445098876953],[-56.26500701904297,-63.16944885253906]]],[[[-60.471839904785156,-62.90089797973633],[-60.58000183105469,-63.008056640625],[-60.74248123168945,-62.97399139404297],[-60.471839904785156,-62.90089797973633]]],[[[-62.69139099121094,-63.095001220703125],[-62.48944854736328,-62.921112060546875],[-62.26055908203125,-62.88166809082031],[-62.69139099121094,-63.095001220703125]]],[[[-61.358612060546875,-62.81361389160156],[-61.47917175292969,-62.75389099121094],[-61.15055847167969,-62.7086181640625],[-61.358612060546875,-62.81361389160156]]],[[[-60.51667022705078,-62.55389404296875],[-59.81694793701172,-62.614173889160156],[-61.17250061035156,-62.57500457763672],[-60.51667022705078,-62.55389404296875]]],[[[-59.665557861328125,-62.55694580078125],[-59.97917175292969,-62.450836181640625],[-59.54222869873047,-62.49861145019531],[-59.665557861328125,-62.55694580078125]]],[[[-59.439170837402344,-62.44722557067871],[-59.67833709716797,-62.3638916015625],[-59.32750701904297,-62.37139129638672],[-59.439170837402344,-62.44722557067871]]],[[[-58.99250030517578,-62.3477783203125],[-59.208892822265625,-62.285560607910156],[-58.81639099121094,-62.298057556152344],[-58.99250030517578,-62.3477783203125]]],[[[-57.6219482421875,-61.90972900390625],[-58.98638916015625,-62.214447021484375],[-58.40028381347656,-61.93861389160156],[-57.6219482421875,-61.90972900390625]]],[[[-55.09222412109375,-61.098060607910156],[-54.646392822265625,-61.09278106689453],[-55.49444580078125,-61.126670837402344],[-55.09222412109375,-61.098060607910156]]],[[[-54.04695129394531,-61.269447326660156],[-54.2005615234375,-61.236114501953125],[-54.0322265625,-61.08805847167969],[-54.04695129394531,-61.269447326660156]]],[[[-44.428062438964844,-60.72333526611328],[-44.78472900390625,-60.73445129394531],[-44.531394958496094,-60.675559997558594],[-44.428062438964844,-60.72333526611328]]],[[[-45.005279541015625,-60.72528076171875],[-45.07111358642578,-60.63111114501953],[-45.025840759277344,-60.641944885253906],[-45.005279541015625,-60.72528076171875]]],[[[-45.55083465576172,-60.54722595214844],[-45.14527893066406,-60.76611328125],[-46.02361297607422,-60.61083984375],[-45.55083465576172,-60.54722595214844]]]]}},{"type":"Feature","properties":{"name":"Bouvet Island","iso2":"BV","iso3":"BVT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[3.361389,-54.462784],[3.366944,-54.399727],[3.483611,-54.402229],[3.361389,-54.462784]]]]}},{"type":"Feature","properties":{"name":"French Southern and Antarctic Lands","iso2":"TF","iso3":"ATF"},"geometry":{"type":"MultiPolygon","coordinates":[[[[69.81277656555176,-49.678062438964844],[69.76193428039551,-49.65888977050781],[69.79500007629395,-49.64722442626953],[69.81277656555176,-49.678062438964844]]],[[[68.78915596008301,-49.361671447753906],[68.64444160461426,-49.34361267089844],[68.80166816711426,-49.328338623046875],[68.78915596008301,-49.361671447753906]]],[[[69.60666084289551,-49.20777893066406],[69.53305244445801,-49.19667053222656],[69.67833137512207,-49.15306091308594],[69.60666084289551,-49.20777893066406]]],[[[69.26471138000488,-49.09111785888672],[69.21638679504395,-48.96722412109375],[69.36888313293457,-48.886390686035156],[69.26471138000488,-49.09111785888672]]],[[[69.15222358703613,-48.988059997558594],[69.22221565246582,-48.856117248535156],[69.24249458312988,-48.89250183105469],[69.15222358703613,-48.988059997558594]]],[[[69.4911060333252,-48.882781982421875],[69.40193367004395,-48.834449768066406],[69.51721382141113,-48.86028289794922],[69.4911060333252,-48.882781982421875]]],[[[69.00110054016113,-48.79750061035156],[69.06305122375488,-49.119728088378906],[69.10388374328613,-48.99583435058594],[69.21721076965332,-49.12555694580078],[69.62193489074707,-48.978057861328125],[69.2824878692627,-49.18639373779297],[69.58276557922363,-49.30445098876953],[70.32388496398926,-49.05083465576172],[70.5666675567627,-49.24500274658203],[69.77472114562988,-49.39417266845703],[70.25360298156738,-49.69111633300781],[69.6433277130127,-49.50139617919922],[68.79777717590332,-49.721946716308594],[69.00110054016113,-48.79750061035156]],[[69.9044361114502,-49.47722625732422],[69.82527351379395,-49.42583465576172],[69.84305000305176,-49.459449768066406],[69.9044361114502,-49.47722625732422]],[[70.01193428039551,-49.57194519042969],[69.92109870910645,-49.5130615234375],[69.83554267883301,-49.508056640625],[70.01193428039551,-49.57194519042969]]],[[[68.6755542755127,-48.643890380859375],[68.60611152648926,-48.63972473144531],[68.66861152648926,-48.62805938720703],[68.6755542755127,-48.643890380859375]]],[[[68.79777717590332,-48.61500358581543],[68.78721809387207,-48.57722473144531],[68.82470893859863,-48.570556640625],[68.79777717590332,-48.61500358581543]]],[[[52.25444221496582,-46.45750427246094],[52.088335037231445,-46.41111755371094],[52.257219314575195,-46.37805938720703],[52.25444221496582,-46.45750427246094]]],[[[51.81944465637207,-46.45361328125],[51.65194129943848,-46.374168395996094],[51.78000068664551,-46.34111785888672],[51.81944465637207,-46.45361328125]]],[[[50.27221870422363,-46.13139343261719],[50.17694282531738,-46.0625],[50.27388954162598,-46.05083465576172],[50.27221870422363,-46.13139343261719]]],[[[77.5294361114502,-38.73778533935547],[77.49971199035645,-38.731117248535156],[77.50610542297363,-38.703895568847656],[77.5294361114502,-38.73778533935547]]],[[[77.55415534973145,-37.90277862548828],[77.48388862609863,-37.83528137207031],[77.55444526672363,-37.82250213623047],[77.55415534973145,-37.90277862548828]]],[[[42.75777626037598,-17.075000762939453],[42.72110939025879,-17.055557250976562],[42.75694465637207,-17.059722900390625],[42.75777626037598,-17.075000762939453]]]]}},{"type":"Feature","properties":{"name":"Heard Island and McDonald Islands","iso2":"HM","iso3":"HMD"},"geometry":{"type":"MultiPolygon","coordinates":[[[[73.77388,-53.125031],[73.474442,-53.194168],[73.234436,-52.987785],[73.77388,-53.125031]]]]}},{"type":"Feature","properties":{"name":"British Indian Ocean Territory","iso2":"IO","iso3":"IOT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[72.48719800000012,-7.381944],[72.35914600000015,-7.265278],[72.4488680000002,-7.234445],[72.48719800000012,-7.381944]]],[[[71.3483279999999,-6.658889],[71.343323,-6.656667],[71.36526500000011,-6.651667],[71.3483279999999,-6.658889]]],[[[71.266388,-6.391945],[71.25860600000013,-6.382222],[71.266098,-6.366666],[71.266388,-6.391945]]],[[[71.347763,-6.206944],[71.338593,-6.195833],[71.360809,-6.174167],[71.347763,-6.206944]]],[[[71.7824860000002,-5.440277],[71.759995,-5.431389],[71.766388,-5.429722],[71.7824860000002,-5.440277]]],[[[72.216385,-5.362222],[72.207764,-5.354445],[72.20860300000012,-5.348056],[72.216385,-5.362222]]],[[[72.23248300000014,-5.319722],[72.2211,-5.335556],[72.228043,-5.315833],[72.23248300000014,-5.319722]]],[[[71.74220300000016,-5.291111],[71.74054,-5.271111],[71.748596,-5.265556],[71.74220300000016,-5.291111]]],[[[71.86943100000016,-5.257778],[71.87025500000013,-5.249722],[71.882202,-5.256111],[71.86943100000016,-5.257778]]]]}},{"type":"Feature","properties":{"name":"Christmas Island","iso2":"CX","iso3":"CXR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[105.701401,-10.51097],[105.628998,-10.43731],[105.736603,-10.38408],[105.701401,-10.51097]]]]}},{"type":"Feature","properties":{"name":"United States Minor Outlying Islands","iso2":"UM","iso3":"UMI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-160.021149,-0.398056],[-160.048615,-0.383611],[-160.017792,-0.374722],[-160.021149,-0.398056]]],[[[-176.456146,0.215833],[-176.468323,0.222222],[-176.453918,0.226111],[-176.456146,0.215833]]],[[[-176.632202,0.793055],[-176.64447,0.795555],[-176.643097,0.812778],[-176.632202,0.793055]]],[[[-169.522522,16.728882],[-169.543884,16.726379000000108],[-169.531708,16.732491],[-169.522522,16.728882]]],[[[166.646362,19.279442000000145],[166.607452,19.304996],[166.627594,19.324577],[166.646362,19.279442000000145]]],[[[-177.334442,28.194157],[-177.321686,28.213608],[-177.317505,28.200829000000155],[-177.334442,28.194157]]],[[[-177.388062,28.18637800000012],[-177.389771,28.212769],[-177.358032,28.219162],[-177.388062,28.18637800000012]]]]}},{"type":"Feature","properties":{"name":"Vanuatu","iso2":"VU","iso3":"VUT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[169.846069,-20.252224],[169.745514,-20.149445],[169.886658,-20.170555],[169.846069,-20.252224]]],[[[170.217468,-19.559444],[170.205231,-19.525002],[170.2324520000001,-19.52417],[170.217468,-19.559444]]],[[[169.498291,-19.545002],[169.349701,-19.636944],[169.232452,-19.350277],[169.498291,-19.545002]]],[[[169.594971,-19.273613],[169.578583,-19.262501],[169.594971,-19.231388],[169.594971,-19.273613]]],[[[169.30523700000018,-18.978886],[168.989136,-18.880833],[169.018585,-18.639999],[169.30523700000018,-18.978886]]],[[[168.574677,-17.692776],[168.148041,-17.719719],[168.3110960000001,-17.531391],[168.574677,-17.692776]]],[[[168.399139,-16.78278],[168.168579,-16.805279],[168.14831500000017,-16.580555],[168.399139,-16.78278]]],[[[168.231079,-16.516113],[168.20135500000012,-16.500557],[168.242462,-16.429165],[168.231079,-16.516113]]],[[[168.21524000000014,-16.174168],[168.304138,-16.339443],[167.9177550000002,-16.260281],[168.21524000000014,-16.174168]]],[[[167.41665600000013,-16.110001],[167.7724910000002,-16.535],[167.41748,-16.532223],[167.177765,-15.899168],[167.41665600000013,-16.110001]]],[[[167.209137,-15.755556],[167.077454,-15.640278],[167.227173,-15.637779],[167.209137,-15.755556]]],[[[167.258606,-15.588055],[167.239136,-15.574444],[167.2769170000001,-15.546112],[167.258606,-15.588055]]],[[[167.202454,-15.60861],[167.110229,-15.59],[167.16275,-15.535833],[167.190521,-15.529167],[167.21051000000014,-15.580278],[167.202454,-15.60861]]],[[[168.21078500000013,-15.998055],[168.15332,-15.492222],[168.266663,-15.870832],[168.21078500000013,-15.998055]]],[[[167.85580400000012,-15.485832],[167.66830400000012,-15.446945],[168.0021970000001,-15.290001],[167.85580400000012,-15.485832]]],[[[167.17526200000012,-15.266666],[167.163605,-15.254168],[167.179413,-15.256668],[167.17526200000012,-15.266666]]],[[[167.14444000000012,-14.971388],[167.096344,-14.932501],[167.1510930000002,-14.957777],[167.14444000000012,-14.971388]]],[[[168.169128,-15.395834],[168.10580400000018,-14.92],[168.190247,-15.214722],[168.169128,-15.395834]]],[[[166.802765,-15.157501],[167.058868,-14.945],[167.237717,-15.524258],[167.151154,-15.520343],[167.071625,-15.598055],[166.90277100000017,-15.582777],[166.8146970000001,-15.663055],[166.761932,-15.642778],[166.59274300000018,-14.624443],[166.802765,-15.157501]]],[[[167.527466,-14.326666],[167.413605,-14.178888],[167.58828700000012,-14.172777],[167.527466,-14.326666]]],[[[167.479126,-13.948334],[167.4766240000001,-13.706667],[167.577759,-13.847221],[167.479126,-13.948334]]],[[[167.70553600000014,-13.675001],[167.62356600000012,-13.691944],[167.687744,-13.621666],[167.70553600000014,-13.675001]]],[[[167.34719800000013,-13.56139],[167.29330400000018,-13.52639],[167.322205,-13.486944],[167.34719800000013,-13.56139]]],[[[166.67746,-13.452499],[166.6508180000001,-13.409723],[166.694122,-13.415834],[166.67746,-13.452499]]],[[[166.631622,-13.381388],[166.5960690000002,-13.334166],[166.6413570000001,-13.356943],[166.631622,-13.381388]]],[[[166.620239,-13.271389],[166.587463,-13.223055],[166.638306,-13.221666],[166.620239,-13.271389]]],[[[166.55969200000013,-13.186388],[166.521362,-13.070555],[166.564972,-13.091944],[166.55969200000013,-13.186388]]]]}},{"type":"Feature","properties":{"name":"Nigeria","iso2":"NG","iso3":"NGA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[7.466389,4.445277],[7.335833,4.443055],[7.411944,4.488055],[7.466389,4.445277]]],[[[7.20361,4.380555000000129],[7.22611,4.52],[7.316667,4.4725],[7.20361,4.380555000000129]]],[[[5.874722,13.749443],[6.423055,13.605276000000131],[6.933332,12.997221000000124],[7.815,13.352777],[9.634932,12.802435],[10.724165,13.386389],[12.459166,13.066111],[13.62512,13.718338],[14.07472,13.0816650000001],[14.174444,12.396666],[14.645277,12.188332000000145],[14.646387,11.575832],[13.80722,11.055832],[12.79694400000011,8.769722],[12.253887000000134,8.408054],[11.864166,7.084722],[11.340277,6.440833],[10.615000000000123,7.06861],[9.795555,6.801666],[8.865276,5.841944],[8.591738000000134,4.810932000000122],[7.676944,4.496388],[7.071666,4.753888],[7.073055,4.434722],[6.962222000000111,4.725277000000119],[7.005555,4.369444],[6.768055,4.774722],[6.848611000000119,4.348332000000113],[6.727221,4.605],[6.694166000000109,4.33],[6.104166,4.272778000000102],[5.451944,4.923055],[5.345277,5.33],[5.639722,5.536111],[5.257222000000183,5.43555500000015],[5.501111,5.620555],[5.175278000000105,5.575555],[4.525833,6.304999],[3.388611,6.443333000000109],[3.807222000000166,6.612778],[2.719606,6.365505],[2.789444,9.043888],[3.095,9.090555],[3.855,10.584999],[3.604459,11.693274],[4.1425,13.476944],[5.874722,13.749443]]]]}},{"type":"Feature","properties":{"name":"Netherlands","iso2":"NL","iso3":"NLD"},"geometry":{"type":"MultiPolygon","coordinates":[[[[3.764165878295898,51.34527778625488],[3.370866775512695,51.373857498168945],[4.238897323608398,51.35042762756348],[3.764165878295898,51.34527778625488]]],[[[5.763887405395508,52.4152774810791],[5.573057174682617,52.368051528930664],[5.53416633605957,52.283334732055664],[5.428613662719727,52.26416206359863],[5.135557174682617,52.38027381896973],[5.643613815307617,52.60110664367676],[5.855558395385742,52.54416847229004],[5.855558395385742,52.49249458312988],[5.763887405395508,52.4152774810791]]],[[[5.423334121704102,52.63638496398926],[5.051794052124023,52.39411735534668],[5.039495468139648,52.63365364074707],[5.423334121704102,52.63638496398926]]],[[[4.76472282409668,52.99027442932129],[4.713888168334961,53.056108474731445],[4.883333206176758,53.18416786193848],[4.76472282409668,52.99027442932129]]],[[[4.957223892211914,53.23777961730957],[4.879999160766602,53.21444129943848],[5.106389999389648,53.30333137512207],[4.957223892211914,53.23777961730957]]],[[[6.871667861938477,53.41610908508301],[7.208364486694336,53.242807388305664],[7.051668167114258,52.64361000061035],[6.68889045715332,52.54916572570801],[7.065557479858398,52.38582801818848],[6.828889846801758,51.96555519104004],[5.962499618530273,51.80777931213379],[6.222223281860352,51.465829849243164],[5.864721298217773,51.04610633850098],[6.011800765991211,50.757272720336914],[5.640832901000977,50.83972358703613],[5.849172592163086,51.156381607055664],[5.041391372680664,51.48666572570801],[4.252370834350586,51.37514686584473],[3.440832138061523,51.53582954406738],[4.286111831665039,51.44861030578613],[3.687501907348633,51.70971870422363],[4.167753219604492,51.68557167053223],[3.865556716918945,51.81499671936035],[4.584432601928711,52.461503982543945],[5.424444198608398,52.248605728149414],[5.533609390258789,52.267221450805664],[5.624723434448242,52.35416603088379],[5.774168014526367,52.40527534484863],[5.878057479858398,52.50943946838379],[5.855001449584961,52.60691261291504],[5.599443435668945,52.65860939025879],[5.59916877746582,52.75777626037598],[5.718351364135742,52.838022232055664],[5.368612289428711,52.87777900695801],[5.420557022094727,52.96444129943848],[5.364168167114258,53.07027626037598],[5.100278854370117,52.94805335998535],[5.304166793823242,52.70694160461426],[5.033334732055664,52.634164810180664],[5.02833366394043,52.37583351135254],[4.579999923706055,52.47166633605957],[4.734167098999023,52.95555305480957],[6.871667861938477,53.41610908508301]]],[[[5.213056564331055,53.35000038146973],[5.168889999389648,53.37388801574707],[5.581945419311523,53.44777870178223],[5.213056564331055,53.35000038146973]]],[[[5.699167251586914,53.462778091430664],[5.956113815307617,53.462778091430664],[5.633054733276367,53.441667556762695],[5.699167251586914,53.462778091430664]]],[[[6.135000228881836,53.4536075592041],[6.148889541625977,53.49749946594238],[6.34111213684082,53.50277900695801],[6.135000228881836,53.4536075592041]]]]}},{"type":"Feature","properties":{"name":"Norway","iso2":"NO","iso3":"NOR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[8.743612289428711,58.40972328186035],[8.726945877075195,58.41277503967285],[8.73750114440918,58.43499946594238],[8.761388778686523,58.436662673950195],[8.761388778686523,58.42138862609863],[8.743612289428711,58.40972328186035]]],[[[5.961946487426758,58.97222328186035],[5.945001602172852,58.977495193481445],[5.958887100219727,58.98388862609863],[5.961946487426758,58.97222328186035]]],[[[5.726388931274414,59.07805061340332],[5.548334121704102,59.13055610656738],[5.68889045715332,59.129167556762695],[5.726388931274414,59.07805061340332]]],[[[5.952779769897461,59.22833442687988],[5.909723281860352,59.2741641998291],[6.059167861938477,59.26082801818848],[5.952779769897461,59.22833442687988]]],[[[5.287778854370117,59.218889236450195],[5.155279159545898,59.14694404602051],[5.183610916137695,59.411943435668945],[5.287778854370117,59.218889236450195]]],[[[5.263334274291992,59.79860877990723],[5.148889541625977,59.58111000061035],[5.107500076293945,59.86444282531738],[5.263334274291992,59.79860877990723]]],[[[5.413057327270508,59.751665115356445],[5.276388168334961,59.96694374084473],[5.468332290649414,59.88638496398926],[5.413057327270508,59.751665115356445]]],[[[5.524999618530273,59.893327713012695],[5.360834121704102,59.99221992492676],[5.658056259155273,60.075273513793945],[5.524999618530273,59.893327713012695]]],[[[5.268056869506836,60.0049991607666],[5.168058395385742,60.031389236450195],[5.17277717590332,60.12166786193848],[5.268056869506836,60.0049991607666]]],[[[5.954721450805664,60.08944129943848],[5.924165725708008,60.145273208618164],[6.016946792602539,60.14666175842285],[5.954721450805664,60.08944129943848]]],[[[5.216943740844727,60.24194526672363],[5.19972038269043,60.251108169555664],[5.233335494995117,60.254716873168945],[5.216943740844727,60.24194526672363]]],[[[5.111944198608398,60.18583106994629],[4.946943283081055,60.249162673950195],[4.942499160766602,60.427499771118164],[5.111944198608398,60.18583106994629]]],[[[5.195276260375977,60.408884048461914],[5.000833511352539,60.53110694885254],[5.179445266723633,60.48277473449707],[5.195276260375977,60.408884048461914]]],[[[5.185277938842773,60.50610542297363],[4.926946640014648,60.60527229309082],[5.121667861938477,60.57805061340332],[5.185277938842773,60.50610542297363]]],[[[5.55000114440918,60.4313907623291],[5.360002517700195,60.52388954162598],[5.675832748413086,60.683053970336914],[5.55000114440918,60.4313907623291]]],[[[5.158334732055664,60.58166694641113],[4.85444450378418,60.732500076293945],[4.980001449584961,60.71472358703613],[5.158334732055664,60.58166694641113]]],[[[4.696390151977539,60.98722267150879],[4.630834579467773,61.006662368774414],[4.628057479858398,61.06443977355957],[4.696390151977539,60.98722267150879]]],[[[4.986387252807617,61.104440689086914],[4.804723739624023,61.044443130493164],[4.788057327270508,61.14638710021973],[4.986387252807617,61.104440689086914]]],[[[4.934167861938477,61.7741641998291],[4.804166793823242,61.84055519104004],[5.221944808959961,61.84555244445801],[4.934167861938477,61.7741641998291]]],[[[5.068056106567383,61.923051834106445],[5.009721755981445,62.01361274719238],[5.127222061157227,61.99249458312988],[5.068056106567383,61.923051834106445]]],[[[5.64777946472168,62.1874942779541],[5.506109237670898,62.224443435668945],[5.80805778503418,62.27305030822754],[5.64777946472168,62.1874942779541]]],[[[5.840555191040039,62.239999771118164],[5.804998397827148,62.36694526672363],[5.977502822875977,62.41111183166504],[5.840555191040039,62.239999771118164]]],[[[6.253889083862305,62.39166450500488],[6.023054122924805,62.435556411743164],[6.333612442016602,62.41333198547363],[6.253889083862305,62.39166450500488]]],[[[6.736665725708008,62.66722297668457],[6.649721145629883,62.6813907623291],[6.919443130493164,62.70916175842285],[6.736665725708008,62.66722297668457]]],[[[6.886388778686523,62.77694129943848],[6.775835037231445,62.84555244445801],[6.940557479858398,62.84444618225098],[6.886388778686523,62.77694129943848]]],[[[7.548334121704102,62.94832801818848],[7.365556716918945,62.99638557434082],[7.711946487426758,63.00249671936035],[7.548334121704102,62.94832801818848]]],[[[7.809724807739258,63.023332595825195],[7.679445266723633,63.056108474731445],[7.915277481079102,63.07916450500488],[7.809724807739258,63.023332595825195]]],[[[8.060277938842773,63.14166450500488],[7.926389694213867,63.171945571899414],[8.18638801574707,63.15305519104004],[8.060277938842773,63.14166450500488]]],[[[8.391111373901367,63.15916633605957],[8.269723892211914,63.2661075592041],[8.437498092651367,63.283884048461914],[8.576112747192383,63.18943977355957],[8.391111373901367,63.15916633605957]]],[[[8.511945724487305,63.319162368774414],[8.431112289428711,63.33194160461426],[8.675832748413086,63.34666633605957],[8.511945724487305,63.319162368774414]]],[[[8.162221908569336,63.36138343811035],[7.77833366394043,63.405832290649414],[8.091665267944336,63.46666145324707],[8.162221908569336,63.36138343811035]]],[[[8.494165420532227,63.42833137512207],[8.280000686645508,63.46472358703613],[9.176389694213867,63.56472206115723],[8.494165420532227,63.42833137512207]]],[[[8.808332443237305,63.81027412414551],[8.794443130493164,63.69749641418457],[8.269998550415039,63.67888832092285],[8.808332443237305,63.81027412414551]]],[[[11.453611373901367,64.51416206359863],[11.175554275512695,64.50694465637207],[11.038610458374023,64.62887763977051],[11.453611373901367,64.51416206359863]]],[[[11.351388931274414,64.64999580383301],[11.310834884643555,64.59666633605957],[11.176111221313477,64.64444160461426],[11.351388931274414,64.64999580383301]]],[[[11.261667251586914,64.88472175598145],[10.82499885559082,64.8449878692627],[11.106111526489258,64.95027351379395],[11.261667251586914,64.88472175598145]]],[[[11.110834121704102,64.96582221984863],[10.731389999389648,64.86027717590332],[10.777776718139648,64.91888618469238],[11.110834121704102,64.96582221984863]]],[[[11.636667251586914,65.06527900695801],[11.531389236450195,65.06082344055176],[11.77277946472168,65.11360359191895],[11.636667251586914,65.06527900695801]]],[[[12.156389236450195,65.05137825012207],[11.981668472290039,65.07638740539551],[12.183610916137695,65.20833015441895],[12.315279006958008,65.10998725891113],[12.285001754760742,65.08444404602051],[12.156389236450195,65.05137825012207]]],[[[12.075277328491211,65.21138191223145],[12.258054733276367,65.57611274719238],[12.502779006958008,65.39193916320801],[12.075277328491211,65.21138191223145]]],[[[11.974164962768555,65.62693977355957],[11.758611679077148,65.61694526672363],[11.894445419311523,65.70443916320801],[11.974164962768555,65.62693977355957]]],[[[12.542501449584961,65.89694404602051],[12.414999008178711,65.89360237121582],[12.573888778686523,66.01054573059082],[12.90361213684082,66.00860786437988],[12.542501449584961,65.89694404602051]]],[[[12.352499008178711,66.02249336242676],[12.563333511352539,66.21777534484863],[12.657220840454102,66.10472297668457],[12.352499008178711,66.02249336242676]]],[[[12.796667098999023,66.21443367004395],[12.71583366394043,66.24749946594238],[12.870832443237305,66.27749824523926],[12.796667098999023,66.21443367004395]]],[[[12.986665725708008,66.22833442687988],[12.93083381652832,66.22638130187988],[13.158334732055664,66.27749824523926],[12.986665725708008,66.22833442687988]]],[[[14.257776260375977,67.13304328918457],[14.191946029663086,66.99943733215332],[13.991109848022461,67.07859992980957],[14.257776260375977,67.13304328918457]]],[[[14.253053665161133,67.35859870910645],[14.216665267944336,67.35832405090332],[14.374998092651367,67.42221260070801],[14.253053665161133,67.35859870910645]]],[[[15.20222282409668,67.90027046203613],[14.931665420532227,67.92387580871582],[15.303609848022461,67.92027473449707],[15.20222282409668,67.90027046203613]]],[[[15.90333366394043,67.97888374328613],[15.49888801574707,67.98777961730957],[15.851110458374023,68.01361274719238],[15.90333366394043,67.97888374328613]]],[[[12.841943740844727,67.8086109161377],[13.155832290649414,68.08110237121582],[13.134443283081055,67.95250129699707],[12.841943740844727,67.8086109161377]]],[[[13.438055038452148,68.11277961730957],[13.163057327270508,68.01138496398926],[13.299165725708008,68.14972114562988],[13.438055038452148,68.11277961730957]]],[[[13.968332290649414,68.23832893371582],[14.135831832885742,68.23944282531738],[13.44972038269043,68.06749153137207],[13.968332290649414,68.23832893371582]]],[[[14.870553970336914,68.21165657043457],[14.826112747192383,68.25444221496582],[14.940553665161133,68.26805305480957],[14.870553970336914,68.21165657043457]]],[[[14.203611373901367,68.23916816711426],[14.049444198608398,68.30333137512207],[14.214166641235352,68.30110359191895],[14.203611373901367,68.23916816711426]]],[[[13.973333358764648,68.25332832336426],[13.883333206176758,68.30221748352051],[13.990556716918945,68.30999946594238],[13.973333358764648,68.25332832336426]]],[[[15.026388168334961,68.3549976348877],[14.19972038269043,68.15222358703613],[15.168889999389648,68.45054817199707],[15.026388168334961,68.3549976348877]]],[[[16.405553817749023,68.41110420227051],[16.094446182250977,68.39665412902832],[16.32694435119629,68.53360176086426],[16.405553817749023,68.41110420227051]]],[[[17.11638832092285,68.75248908996582],[16.81305503845215,68.72833442687988],[17.00055503845215,68.85443305969238],[17.11638832092285,68.75248908996582]]],[[[17.241666793823242,68.78860664367676],[17.0836124420166,68.91026496887207],[17.437776565551758,68.86526679992676],[17.241666793823242,68.78860664367676]]],[[[14.954442977905273,68.87277412414551],[14.839166641235352,68.88194465637207],[14.885278701782227,68.93332099914551],[14.954442977905273,68.87277412414551]]],[[[15.988054275512695,68.75193977355957],[15.739442825317383,68.52610969543457],[16.17888832092285,68.85165596008301],[16.565000534057617,68.65193367004395],[14.986665725708008,68.24749946594238],[15.71360969543457,68.69861030578613],[15.451665878295898,68.76220893859863],[15.636110305786133,68.94665718078613],[15.988054275512695,68.75193977355957]]],[[[16.537221908569336,68.87971687316895],[16.261110305786133,68.96666145324707],[16.601667404174805,68.94554328918457],[16.537221908569336,68.87971687316895]]],[[[15.382776260375977,68.84527778625488],[15.059167861938477,68.57249641418457],[14.371110916137695,68.6836109161377],[15.148611068725586,68.81221199035645],[15.087778091430664,69.00804328918457],[15.382776260375977,68.84527778625488]]],[[[17.41694450378418,68.99582099914551],[17.3527774810791,69.02415657043457],[17.56138801574707,69.0949878692627],[17.41694450378418,68.99582099914551]]],[[[15.522500991821289,68.90609931945801],[15.560277938842773,69.09471321105957],[16.148054122924805,69.28637886047363],[15.522500991821289,68.90609931945801]]],[[[17.63661003112793,69.51604652404785],[18.074167251586914,69.43083381652832],[18.003610610961914,69.19027900695801],[16.775278091430664,69.06443977355957],[17.173887252807617,69.19583320617676],[16.93083381652832,69.39248847961426],[17.63661003112793,69.51604652404785]]],[[[30.155553817749023,69.78166389465332],[30.11055564880371,69.78721809387207],[30.12611198425293,69.79748725891113],[30.155553817749023,69.78166389465332]]],[[[18.89000129699707,69.69194221496582],[17.996946334838867,69.58833503723145],[18.75139045715332,69.68277168273926],[18.693056106567383,69.88443183898926],[18.89000129699707,69.69194221496582]]],[[[20.68027687072754,69.8086109161377],[20.5563907623291,69.85110664367676],[20.739168167114258,69.90527534484863],[20.68027687072754,69.8086109161377]]],[[[29.8266658782959,69.75694465637207],[29.841943740844727,69.91026496887207],[30.04805564880371,69.82750129699707],[29.8266658782959,69.75694465637207]]],[[[21.730276107788086,69.93110847473145],[21.668611526489258,69.94194221496582],[21.717222213745117,69.94970893859863],[21.730276107788086,69.93110847473145]]],[[[19.56722068786621,69.85165596008301],[19.459444046020508,69.84250068664551],[19.89777946472168,69.97221565246582],[19.56722068786621,69.85165596008301]]],[[[19.959165573120117,70.00555610656738],[19.899168014526367,70.01609992980957],[19.996110916137695,70.01277351379395],[19.959165573120117,70.00555610656738]]],[[[19.300554275512695,70.02610969543457],[19.691946029663086,69.99472236633301],[18.72110939025879,69.93416023254395],[19.300554275512695,70.02610969543457]]],[[[20.892568588256836,70.03081703186035],[21.10249900817871,70.00471687316895],[20.757776260375977,69.98999214172363],[20.892568588256836,70.03081703186035]]],[[[21.00083351135254,70.01971626281738],[20.95194435119629,70.02583503723145],[21.049165725708008,70.04971504211426],[21.00083351135254,70.01971626281738]]],[[[18.785001754760742,70.11137580871582],[19.002779006958008,70.08415412902832],[18.684446334838867,69.99666023254395],[18.785001754760742,70.11137580871582]]],[[[20.919721603393555,70.07943916320801],[20.814722061157227,70.1161060333252],[20.861387252807617,70.14915657043457],[20.919721603393555,70.07943916320801]]],[[[19.607500076293945,70.1019458770752],[19.349721908569336,70.13138008117676],[19.4313907623291,70.17776679992676],[19.607500076293945,70.1019458770752]]],[[[20.831945419311523,70.19388008117676],[20.78388786315918,70.05638313293457],[20.385278701782227,70.09887886047363],[20.831945419311523,70.19388008117676]]],[[[20.11277961730957,70.10472297668457],[19.76999855041504,70.06527900695801],[19.53611183166504,70.24832344055176],[20.11277961730957,70.10472297668457]]],[[[19.185277938842773,70.12249946594238],[19.03360939025879,70.16110420227051],[19.233610153198242,70.25444221496582],[19.185277938842773,70.12249946594238]]],[[[22.8347225189209,70.33221626281738],[23.02277946472168,70.25943183898926],[22.36861228942871,70.33444404602051],[22.8347225189209,70.33221626281738]]],[[[21.77277946472168,70.26666450500488],[21.697778701782227,70.38194465637207],[21.84139060974121,70.35026741027832],[21.77277946472168,70.26666450500488]]],[[[23.595834732055664,70.57805061340332],[23.230554580688477,70.27832221984863],[22.851110458374023,70.40582466125488],[23.595834732055664,70.57805061340332]]],[[[23.871110916137695,70.51220893859863],[23.634164810180664,70.69638252258301],[24.12583351135254,70.61526679992676],[23.871110916137695,70.51220893859863]]],[[[23.4516658782959,70.78360176086426],[22.78416633605957,70.51971626281738],[21.94972038269043,70.64610481262207],[23.4516658782959,70.78360176086426]]],[[[24.06194496154785,70.90887641906738],[23.880834579467773,70.99360847473145],[24.2438907623291,70.95193672180176],[24.06194496154785,70.90887641906738]]],[[[24.7994441986084,71.02388191223145],[24.63944435119629,71.06082344055176],[24.853612899780273,71.0899829864502],[24.7994441986084,71.02388191223145]]],[[[25.828054428100586,71.09860420227051],[26.2197208404541,71.03360176086426],[25.28611183166504,71.02083015441895],[25.828054428100586,71.09860420227051]]],[[[5.336946487426758,61.59277534484863],[5.276834487915039,61.58799934387207],[5.345335006713867,61.58633232116699],[5.336946487426758,61.59277534484863],[4.938055038452148,61.6763858795166],[6.763612747192383,61.868051528930664],[5.148054122924805,61.892221450805664],[5.40361213684082,62.0161075592041],[5.150278091430664,62.21193885803223],[6.357221603393555,62.05527687072754],[5.918058395385742,62.215829849243164],[6.306665420532227,62.37166786193848],[6.538057327270508,62.10472297668457],[6.388334274291992,62.36972236633301],[6.87611198425293,62.414995193481445],[7.043058395385742,62.08638954162598],[7.415555953979492,62.232500076293945],[6.781389236450195,62.47833442687988],[6.257223129272461,62.44888496398926],[6.649835586547852,62.49838447570801],[6.246946334838867,62.574716567993164],[8.14527702331543,62.68999671936035],[6.958887100219727,62.72249794006348],[7.03639030456543,62.96750068664551],[8.548334121704102,62.653886795043945],[7.879167556762695,63.01055335998535],[8.530832290649414,62.841386795043945],[8.15916633605957,63.12027931213379],[8.938333511352539,63.20666694641113],[8.477777481079102,63.29361152648926],[8.763612747192383,63.34527778625488],[8.652776718139648,63.40916633605957],[9.004999160766602,63.46750068664551],[9.427778244018555,63.37693977355957],[9.149721145629883,63.48416328430176],[9.647500991821289,63.62388801574707],[10.25666618347168,63.26111030578613],[10.047224044799805,63.40610694885254],[10.910276412963867,63.45111274719238],[10.65888786315918,63.549997329711914],[11.455831527709961,63.78721809387207],[11.090555191040039,63.87832832336426],[11.492776870727539,64.01944160461426],[11.318887710571289,64.03221321105957],[11.358331680297852,64.11055183410645],[11.30583381652832,64.11638069152832],[11.180276870727539,64.00804328918457],[10.574167251586914,63.80499458312988],[10.904165267944336,63.89416694641113],[11.07722282409668,63.83749580383301],[10.941946029663086,63.738054275512695],[10.04777717590332,63.496110916137695],[9.789167404174805,63.66250038146973],[10.098333358764648,63.76194190979004],[9.543889999389648,63.76361274719238],[10.189722061157227,63.930551528930664],[9.982221603393555,63.990556716918945],[10.495290756225586,64.42381477355957],[10.972223281860352,64.60138130187988],[11.22166633605957,64.31610298156738],[11.728055953979492,64.57971382141113],[11.438333511352539,64.71110725402832],[12.224443435668945,64.93721199035645],[11.297224044799805,64.88360786437988],[11.975000381469727,65.06582832336426],[12.019445419311523,65.02610969543457],[12.04749870300293,65.05583381652832],[12.148889541625977,65.03915596008301],[12.624723434448242,65.13360786437988],[12.939722061157227,65.30832099914551],[12.24888801574707,65.22860908508301],[12.638055801391602,65.41888618469238],[12.360834121704102,65.64776802062988],[12.788610458374023,65.63638496398926],[12.667501449584961,65.91693305969238],[13.17500114440918,65.84915351867676],[13.121946334838867,65.94027900695801],[12.931943893432617,65.9749927520752],[12.959444046020508,66.04222297668457],[12.673887252807617,66.06694221496582],[14.146665573120117,66.32165718078613],[13.027223587036133,66.18609809875488],[13.53639030456543,66.3036060333252],[12.969999313354492,66.5183277130127],[13.725557327270508,66.6019458770752],[13.228055953979492,66.71249580383301],[13.990835189819336,66.78360176086426],[13.546945571899414,66.92666816711426],[15.739721298217773,67.17248725891113],[14.361665725708008,67.23388862609863],[15.035833358764648,67.57054328918457],[15.64000129699707,67.26638984680176],[15.541112899780273,67.4769458770752],[15.899168014526367,67.55888557434082],[14.758054733276367,67.80526924133301],[15.871110916137695,67.92332649230957],[15.961111068725586,68.01304817199707],[15.283056259155273,68.03555488586426],[15.972223281860352,68.24554634094238],[16.217222213745117,67.88804817199707],[16.495832443237305,67.79416084289551],[16.20749855041504,68.00166511535645],[16.71527671813965,68.0666675567627],[16.103334426879883,68.27693367004395],[16.80583381652832,68.13138008117676],[16.31722068786621,68.36694526672363],[17.35472297668457,68.17387580871582],[17.200834274291992,68.36694526672363],[17.552778244018555,68.52388191223145],[16.459444046020508,68.50804328918457],[17.68027687072754,68.6544361114502],[17.236112594604492,68.75471687316895],[17.79250144958496,68.75694465637207],[17.425832748413086,68.90500068664551],[18.152223587036133,69.15222358703613],[18.25694465637207,69.48637580871582],[19.440553665161133,69.22583198547363],[18.94416618347168,69.6130542755127],[19.75889015197754,69.81027412414551],[19.679166793823242,69.42944526672363],[20.304166793823242,69.96832466125488],[19.946943283081055,69.25610542297363],[20.853055953979492,69.48916816711426],[20.48138999938965,69.63888740539551],[21.307222366333008,70.01971626281738],[22.101667404174805,69.74083137512207],[21.797224044799805,70.03360176086426],[22.09666633605957,70.11332893371582],[21.30000114440918,70.24693489074707],[22.9505558013916,70.20555305480957],[22.287778854370117,70.03888130187988],[23.31194496154785,69.94082832336426],[23.660001754760742,70.42000007629395],[24.72916603088379,70.62193489074707],[24.245553970336914,70.77722358703613],[24.591943740844727,70.96304512023926],[25.907777786254883,70.88665962219238],[25.073610305786133,70.50000190734863],[25.273054122924805,70.39888191223145],[24.9424991607666,70.08777046203613],[25.234724044799805,70.08972358703613],[26.570276260375977,70.93889045715332],[26.5049991607666,70.3630542755127],[27.029443740844727,70.47415351867676],[27.565553665161133,70.80471992492676],[27.136110305786133,70.95833015441895],[27.65166664123535,71.1130542755127],[28.550832748413086,70.96832466125488],[27.64750099182129,70.60527229309082],[28.295000076293945,70.71277046203613],[27.851667404174805,70.47888374328613],[28.335554122924805,70.50555610656738],[28.038888931274414,70.06193733215332],[28.527498245239258,70.72665596008301],[29.03611183166504,70.8741626739502],[31.078054428100586,70.28915596008301],[28.61250114440918,70.10777473449707],[29.671667098999023,69.96750068664551],[29.365556716918945,69.85527229309082],[29.73750114440918,69.90527534484863],[29.486665725708008,69.65555000305176],[30.854841232299805,69.79231452941895],[30.910001754760742,69.54887580871582],[30.103334426879883,69.66305732727051],[28.95734214782715,69.05162239074707],[28.78416633605957,69.16055488586426],[29.176111221313477,69.6352710723877],[28.165834426879883,69.91221809387207],[26.44999885559082,69.92721748352051],[25.945833206176758,69.67332649230957],[25.761110305786133,68.98916816711426],[24.934919357299805,68.58081245422363],[23.976388931274414,68.83249092102051],[22.398332595825195,68.71110725402832],[21.320833206176758,69.32611274719238],[20.580930709838867,69.06030464172363],[20.09694480895996,69.04222297668457],[20.350278854370117,68.78665351867676],[19.937776565551758,68.33749580383301],[18.09083366394043,68.50776863098145],[17.884164810180664,67.94554328918457],[16.726945877075195,67.89915657043457],[16.085832595825195,67.41165351867676],[16.3538875579834,67.01777839660645],[15.36277961730957,66.4799976348877],[15.468053817749023,66.28387641906738],[14.504999160766602,66.13249397277832],[14.49305534362793,65.31360054016113],[13.662500381469727,64.58276557922363],[14.116388320922852,64.47055244445801],[13.988332748413086,64.01805305480957],[12.938055038452148,64.05333137512207],[12.139444351196289,63.58416175842285],[11.93638801574707,63.27221870422363],[12.295831680297852,62.261667251586914],[12.124444961547852,61.72860908508301],[12.856111526489258,61.362497329711914],[12.210000991821289,61.00249671936035],[12.594446182250977,60.51693916320801],[12.494165420532227,60.11110877990723],[11.815961837768555,59.84610176086426],[11.75111198425293,59.09027290344238],[11.429193496704102,58.98764228820801],[10.79749870300293,59.18638801574707],[10.557779312133789,59.72860908508301],[10.748334884643555,59.88694190979004],[10.527498245239258,59.87527656555176],[10.558053970336914,59.54305458068848],[10.222223281860352,59.727495193481445],[10.516389846801758,59.31083106994629],[10.231111526489258,59.03860664367676],[9.540834426879883,59.11471748352051],[9.693056106567383,58.98305702209473],[9.409444808959961,58.841386795043945],[9.191110610961914,58.658334732055664],[8.995832443237305,58.59832954406738],[8.712644577026367,58.441938400268555],[8.691946029663086,58.37722206115723],[8.510278701782227,58.270273208618164],[8.248056411743164,58.20194435119629],[8.211111068725586,58.115556716918945],[6.597776412963867,58.07027626037598],[6.767221450805664,58.23832893371582],[5.45777702331543,58.74444007873535],[5.552778244018555,59.03277778625488],[6.168611526489258,58.832223892211914],[6.623334884643555,59.05166816711426],[5.866388320922852,59.072221755981445],[6.468889236450195,59.55527687072754],[5.511110305786133,59.27499580383301],[5.178056716918945,59.50833320617676],[6.306390762329102,59.843332290649414],[5.698335647583008,59.832773208618164],[6.204721450805664,60.29555702209473],[6.640554428100586,60.4102725982666],[6.521112442016602,60.07666206359863],[7.108057022094727,60.49416542053223],[6.220834732055664,60.41250038146973],[5.747224807739258,59.98666572570801],[5.734445571899414,60.38694190979004],[5.411111831665039,60.129716873168945],[5.142221450805664,60.346384048461914],[5.70250129699707,60.45443916320801],[5.700834274291992,60.694162368774414],[5.261388778686523,60.553056716918945],[4.928888320922852,60.79888343811035],[5.433610916137695,60.62722206115723],[5.236387252807617,60.77388954162598],[5.533609390258789,60.87249946594238],[5.007776260375977,61.03721809387207],[5.419443130493164,61.02555274963379],[5.920835494995117,61.123056411743164],[6.372224807739258,61.06194496154785],[6.590555191040039,61.151384353637695],[7.113889694213867,60.86027717590332],[7.000833511352539,61.09610939025879],[7.428613662719727,61.1813907623291],[7.303888320922852,61.294443130493164],[7.574445724487305,61.479440689086914],[7.309167861938477,61.362497329711914],[7.273054122924805,61.278886795043945],[7.353891372680664,61.18999671936035],[7.278055191040039,61.15860939025879],[6.955556869506836,61.109994888305664],[6.564165115356445,61.218332290649414],[6.703611373901367,61.401384353637695],[6.520406723022461,61.24620246887207],[6.498334884643555,61.13027381896973],[5.749166488647461,61.15277290344238],[5.397222518920898,61.06860542297363],[4.953332901000977,61.25860786437988],[5.63416862487793,61.360551834106445],[4.948888778686523,61.41277503967285],[5.804998397827148,61.452775955200195],[5.130834579467773,61.52666664123535],[5.273889541625977,61.55777549743652],[5.148611068725586,61.59305000305176],[5.336946487426758,61.59277534484863]],[[5.77833366394043,58.94749641418457],[5.754999160766602,58.95638465881348],[5.760835647583008,58.94583320617676],[5.77833366394043,58.94749641418457]]]]}},{"type":"Feature","properties":{"name":"Nepal","iso2":"NP","iso3":"NPL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[82.06639900000013,27.914154],[80.055817,28.836109],[80.37692300000012,29.748604],[81.02536,30.204353],[81.22360200000011,30.010277],[81.421097,30.385273],[82.10054,30.342220000000125],[83.55276500000011,29.185829],[84.119141,29.259998],[84.481094,28.736660000000157],[85.189972,28.603329],[85.1066440000001,28.309441],[85.721375,28.279163],[86.014435,27.882774],[86.183594,28.163883],[86.444977,27.90805100000013],[86.686371,28.112217],[87.192749,27.82305100000015],[88.142792,27.866055],[88.014709,26.364719],[85.855545,26.57027400000011],[84.147217,27.51138700000014],[83.29136700000018,27.337776],[82.06639900000013,27.914154]]]]}},{"type":"Feature","properties":{"name":"Nauru","iso2":"NR","iso3":"NRU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[166.929138,-0.552222],[166.930542,-0.493333],[166.958588,-0.506389],[166.929138,-0.552222]]]]}},{"type":"Feature","properties":{"name":"Suriname","iso2":"SR","iso3":"SUR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-55.127968,5.822173],[-54.030006,5.821111],[-54.166946,5.346944],[-54.477501,4.747777],[-54.001114,3.448333],[-54.603783,2.329195],[-55.965836,2.532777],[-55.904167,1.893055],[-56.470634,1.944499000000135],[-57.301392,3.3775],[-57.642227,3.356389000000107],[-58.047226,4.008333000000107],[-57.92333999999988,4.821944],[-57.327225,5.026111],[-57.248505,5.486111],[-56.972504,5.996944],[-55.899559,5.671908],[-55.836395,5.956666],[-55.127968,5.822173]]]]}},{"type":"Feature","properties":{"name":"Nicaragua","iso2":"NI","iso3":"NIC"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-83.712509,11.868332],[-83.73194899999987,11.903332],[-83.714447,11.988054],[-83.712509,11.868332]]],[[[-83.048889,12.145555],[-83.05751,12.183611],[-83.021393,12.184166],[-83.048889,12.145555]]],[[[-82.964737,12.286943],[-82.983337,12.313055],[-82.97139,12.312498000000119],[-82.964737,12.286943]]],[[[-82.750839,14.353888],[-82.7897339999999,14.374998],[-82.733612,14.418888],[-82.750839,14.353888]]],[[[-83.239731,14.98249800000012],[-83.131851,14.992979000000105],[-83.421402,14.80611],[-83.186951,14.323889],[-83.551117,13.450554],[-83.482788,12.403889],[-83.604446,12.819443],[-83.83168,11.874722],[-83.645798,10.924847],[-83.915558,10.708611],[-85.087784,11.009998],[-85.692383,11.076061],[-87.69250499999987,12.912222],[-87.301392,12.986599],[-86.695007,13.296944000000124],[-86.763016,13.751621],[-86.015839,14.065832000000114],[-85.732315,13.829235],[-84.906677,14.808611],[-84.482788,14.617777],[-83.239731,14.98249800000012]]]]}},{"type":"Feature","properties":{"name":"New Zealand","iso2":"NZ","iso3":"NZL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[169.185516,-52.57695],[169.000824,-52.507225],[169.205231,-52.441383],[169.185516,-52.57695]]],[[[166.09661900000017,-50.923058],[165.923584,-50.856392],[166.22052,-50.887505],[166.09661900000017,-50.923058]]],[[[165.995544,-50.603638],[165.969421,-50.605003],[166.003601,-50.595001],[165.995544,-50.603638]]],[[[166.2508240000001,-50.82695],[165.886932,-50.804443],[166.199402,-50.527222],[166.2508240000001,-50.82695]]],[[[166.321899,-50.50695],[166.284973,-50.50528],[166.331909,-50.49472],[166.321899,-50.50695]]],[[[178.816376,-49.723885],[178.71524,-49.685272],[178.814972,-49.613617],[178.816376,-49.723885]]],[[[166.632172,-48.04084],[166.563873,-48.039444],[166.622192,-47.995552],[166.632172,-48.04084]]],[[[179.076904,-47.680595],[179.049133,-47.67556],[179.0697020000002,-47.661667],[179.076904,-47.680595]]],[[[167.434967,-47.248611],[167.426636,-47.222496],[167.486908,-47.214165],[167.434967,-47.248611]]],[[[167.685791,-46.796669],[167.663605,-46.760002],[167.718842,-46.771385],[167.685791,-46.796669]]],[[[168.191925,-46.905273],[167.519135,-47.27417],[167.775818,-46.700279],[168.191925,-46.905273]]],[[[166.71637000000013,-45.741669],[166.50497400000015,-45.719162],[166.710785,-45.61528],[166.71637000000013,-45.741669]]],[[[167.0099790000002,-45.31028],[166.891357,-45.250282],[166.962189,-45.153328],[167.0099790000002,-45.31028]]],[[[-176.162231,-44.324722],[-176.23584,-44.234734],[-176.115814,-44.263336],[-176.162231,-44.324722]]],[[[-176.45224,-43.736122],[-176.60556,-44.119171],[-176.53421,-43.870277],[-176.848053,-43.812225],[-176.45224,-43.736122]]],[[[174.399414,-41.115837],[174.37439,-41.203056],[174.193298,-41.232498],[174.344421,-41.18306],[174.3718870000001,-41.148613],[174.322754,-41.1325],[174.399414,-41.115837]]],[[[173.80581700000013,-40.92778],[173.823303,-40.762505],[173.963867,-40.710556],[173.80581700000013,-40.92778]]],[[[172.861359,-40.507782],[172.656921,-40.653328],[173.013306,-40.796669],[173.10553,-41.313332],[174.323853,-41.003334],[174.026642,-41.236115],[174.20636,-41.269447],[174.326904,-41.222771],[174.04443400000022,-41.442497],[174.289154,-41.748337],[172.760803,-43.239166],[173.091644,-43.856392],[172.424988,-43.733612],[171.293579,-44.343613],[170.554413,-45.888054],[170.783051,-45.878334],[169.008026,-46.680832],[166.48440600000018,-46.01445],[166.987183,-45.709724],[166.775818,-45.662773],[167.0413510000001,-45.501396],[166.704407,-45.574448],[166.82162500000013,-45.320557],[167.21191400000012,-45.475273],[166.996918,-45.145836],[167.507202,-45.001396],[168.374969,-44.037781],[170.794128,-42.90139],[172.064972,-41.40361],[172.108856,-40.885559],[172.861359,-40.507782]]],[[[177.001373,-37.870552],[176.964691,-37.863617],[176.97995,-37.848053],[177.001373,-37.870552]]],[[[176.43856800000012,-37.650276],[176.44693,-37.604721],[176.459412,-37.622772],[176.43856800000012,-37.650276]]],[[[175.166077,-36.833885],[175.002472,-36.792778],[175.193848,-36.727493],[175.166077,-36.833885]]],[[[175.827179,-36.630829],[175.770264,-36.580833],[175.80246,-36.576111],[175.827179,-36.630829]]],[[[174.86386100000013,-36.459724],[174.869965,-36.388893],[174.907196,-36.451668],[174.86386100000013,-36.459724]]],[[[175.1494139999999,-36.213333],[175.07968100000014,-36.200836],[175.121887,-36.170555],[175.1494139999999,-36.213333]]],[[[175.5447080000002,-36.347778],[175.358856,-36.229439],[175.3718870000001,-36.070557],[175.5447080000002,-36.347778]]],[[[173.038879,-34.436943],[173.2691350000002,-35.019722],[173.450806,-34.807777],[174.319977,-35.232773],[174.85440099999985,-36.847778],[175.579132,-37.244446],[175.353577,-36.481941],[175.84079,-36.754173],[175.994415,-37.638893],[177.15942400000014,-38.013336],[178.0180050000001,-37.550831],[178.565521,-37.713333],[177.90997300000012,-39.25695],[177.05496200000013,-39.204445],[176.834137,-40.181671],[175.323029,-41.614449],[174.591919,-41.27861],[175.127747,-40.713615],[175.155548,-40.095833],[173.75192300000012,-39.288612],[174.594421,-38.815834],[174.974976,-37.75],[174.549713,-37.073616],[174.887482,-37.059166],[174.502472,-37.037506],[174.187744,-36.496948],[174.453033,-36.651108],[174.268585,-36.342224],[174.505249,-36.231384],[173.913879,-35.86972],[174.080811,-36.409439],[173.398865,-35.573891],[173.655548,-35.313332],[173.38052400000012,-35.528053],[173.087463,-35.211388],[172.722473,-34.495277],[173.038879,-34.436943]]],[[[172.157196,-34.173889],[172.133331,-34.153328],[172.18692,-34.152496],[172.157196,-34.173889]]],[[[-178.605286,-30.581116],[-178.613068,-30.587223],[-178.612518,-30.574448],[-178.605286,-30.581116]]],[[[-177.84613,-29.278614],[-177.923615,-29.284725],[-177.952484,-29.226112],[-177.84613,-29.278614]]]]}},{"type":"Feature","properties":{"name":"Paraguay","iso2":"PY","iso3":"PRY"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-54.330559,-24.679449],[-54.59891499999989,-25.573223],[-54.698334,-26.438335],[-55.736115,-27.439445],[-58.604622,-27.316921],[-57.576668,-25.549446],[-57.75611099999986,-25.176945],[-61.007782,-23.813335],[-62.643768,-22.238903],[-61.7425,-19.645],[-59.09584,-19.348892],[-58.15139,-19.828056],[-58.15889,-20.168056],[-57.814445,-20.971947],[-57.985107,-22.091827],[-55.849724,-22.288891],[-55.411667,-23.95639],[-54.407227,-23.916668],[-54.330559,-24.679449]]]]}},{"type":"Feature","properties":{"name":"Peru","iso2":"PE","iso3":"PER"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-78.70903,-4.584787],[-78.3375089999999,-3.422778],[-76.66062899999986,-2.572135],[-75.559174,-1.534167],[-75.21608,-0.965336],[-75.62796,-0.108859],[-75.285843,-0.119722],[-74.776947,-0.204167],[-74.227234,-1.027778],[-73.556396,-1.370833],[-72.88195799999988,-2.506389],[-71.698059,-2.146945],[-70.288345,-2.505],[-70.067505,-2.755556],[-70.724167,-3.779723],[-69.956924,-4.236874],[-70.765839,-4.146389],[-72.85195899999985,-5.124722],[-73.123901,-6.447223],[-73.74417099999988,-6.876945],[-74.01055899999989,-7.541389],[-72.964172,-8.983334],[-73.205292,-9.407223],[-72.366394,-9.494446],[-72.14389,-10.004723],[-71.298889,-9.996389],[-70.5146639999999,-9.428001],[-70.631393,-11.009167],[-69.568436,-10.951092],[-68.673904,-12.50115],[-68.974457,-12.869722],[-68.853058,-14.199167],[-69.366394,-14.802502],[-69.136948,-15.245834],[-69.421951,-15.618057],[-68.82251,-16.339725],[-69.618896,-17.214725],[-69.499725,-17.50528],[-69.951126,-18.242779],[-70.405487,-18.348545],[-71.497513,-17.296947],[-75.047501,-15.469168],[-75.933334,-14.658056],[-76.39389,-13.898056],[-76.196945,-13.418335],[-77.652512,-11.292223],[-78.989731,-8.226946],[-79.982788,-6.764445],[-81.174728,-6.086667],[-80.871399,-5.652223],[-81.289734,-4.31],[-80.340424,-3.380517],[-80.153336,-3.884228],[-80.467224,-3.986945],[-80.467789,-4.43889],[-79.649734,-4.432778],[-79.054825,-5.009132],[-78.70903,-4.584787]]]]}},{"type":"Feature","properties":{"name":"Pakistan","iso2":"PK","iso3":"PAK"},"geometry":{"type":"MultiPolygon","coordinates":[[[[67.449417,24.002777],[67.41192600000014,24.005833000000123],[67.379425,24.051662],[67.45887800000011,24.05694200000012],[67.481659,24.042774],[67.45887800000011,24.007221],[67.449417,24.002777]]],[[[74.8174900000001,37.021767],[75.864426,36.65967600000015],[76.166382,35.819717],[77.8239290000001,35.501328],[77.04248,35.099159],[76.8699800000002,34.658882],[73.94165,34.646385],[73.913315,34.068604],[74.295822,33.977486],[73.99054000000015,33.743881000000115],[74.016388,33.18859900000011],[75.381287,32.214241],[74.605324,31.877119],[74.69458800000021,31.053961],[73.872498,30.390099],[73.933403,30.136002],[73.397491,29.942772],[71.896942,27.961941000000152],[70.829437,27.706383],[70.368317,28.020832000000112],[69.580276,27.173328],[69.506104,26.754444000000106],[70.183594,26.536110000000107],[70.088043,25.982773],[70.666382,25.69833],[71.10582,24.416386],[70.01470900000012,24.169716],[68.78305100000014,24.332775],[68.747208,23.969994],[68.1978,23.766685000000123],[67.493591,23.890831],[67.53804000000017,23.938129],[67.50067100000015,23.974043],[67.486649,24.045277],[67.461197,24.065355],[67.338043,24.089718],[67.2738800000001,24.425827],[67.15165700000014,24.610554],[67.2541660000002,24.746105000000128],[66.645538,24.829163],[66.732758,25.197495],[66.359421,25.613609000000125],[66.141602,25.503941000000125],[66.506378,25.402496],[64.65193200000013,25.162773],[64.113876,25.453327],[61.61103100000017,25.197647],[61.858047,26.234718],[63.17638400000013,26.631107],[63.34193400000012,27.122498],[62.782494000000185,27.260555],[62.78138,28.266941],[61.90554800000015,28.554996],[60.86859900000016,29.863884],[62.4844360000001,29.406105],[66.256653,29.851940000000113],[66.395538,30.94083],[66.72303800000012,31.212215],[67.778046,31.33221800000014],[67.575546,31.53194000000012],[68.166092,31.833054000000104],[68.833054,31.603886],[69.32824700000012,31.940365000000114],[69.505264,33.034164],[70.326935,33.33194],[69.90637200000018,34.035271],[71.08194000000012,34.05582400000013],[70.987488,34.551102000000114],[71.64942900000014,35.424995],[71.2435760000001,36.129715],[72.556641,36.821266],[74.56543,37.027817],[74.8174900000001,37.021767]]]]}},{"type":"Feature","properties":{"name":"Poland","iso2":"PL","iso3":"POL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[18.851246,49.517357],[18.577221,49.914444],[17.657776,50.108055],[17.722775,50.319717],[16.890274,50.439438],[17.00222,50.216942],[16.641941,50.10833],[16.20583,50.423882],[16.341942,50.66111],[14.828333,50.865829],[15.036388,51.285553],[14.599443,51.818604],[14.640276,52.572495],[14.14916600000015,52.862778],[14.275627,53.699066],[14.614166,53.816383],[14.218887,53.869019],[14.225555000000156,53.928604],[17.918888,54.82666],[18.334999,54.836662],[18.739998,54.685272],[18.405277,54.74305],[18.582775,54.435272],[18.836388,54.353333],[19.627258,54.463272],[19.651108,54.455826],[19.226662,54.32888],[19.797007,54.43755],[22.785885,54.363838],[23.50404,53.947044],[23.94083,52.732208],[23.1654,52.282276],[23.638607,52.079437],[23.604633,51.527695],[24.111385,50.56694],[22.680828000000105,49.572495],[22.886074,49.002914],[22.558052,49.079437],[21.618889,49.436386],[20.074444,49.175278],[19.475555,49.599998],[18.851246,49.517357]]]]}},{"type":"Feature","properties":{"name":"Panama","iso2":"PA","iso3":"PAN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-81.77862358093262,7.276388168334961],[-81.79750061035156,7.225835800170898],[-81.81861877441406,7.290002822875977],[-81.77862358093262,7.276388168334961]]],[[[-81.20584106445312,7.486665725708008],[-81.24972534179688,7.488332748413086],[-81.03361511230469,7.570833206176758],[-81.20584106445312,7.486665725708008]]],[[[-81.64944458007812,7.38416862487793],[-81.87417602539062,7.491113662719727],[-81.75862121582031,7.63416862487793],[-81.64944458007812,7.38416862487793]]],[[[-81.10389709472656,7.717779159545898],[-81.149169921875,7.741666793823242],[-81.12417602539062,7.758890151977539],[-81.10389709472656,7.717779159545898]]],[[[-81.165283203125,7.822778701782227],[-81.17361450195312,7.818056106567383],[-81.16139221191406,7.841665267944336],[-81.165283203125,7.822778701782227]]],[[[-82.34056091308594,8.087499618530273],[-82.36639404296875,8.088888168334961],[-82.31973266601562,8.136667251586914],[-82.34056091308594,8.087499618530273]]],[[[-82.21334838867188,8.197500228881836],[-82.2952880859375,8.193609237670898],[-82.31333923339844,8.218889236450195],[-82.21334838867188,8.197500228881836]]],[[[-82.33250427246094,8.233610153198242],[-82.40362358093262,8.253053665161133],[-82.33612060546875,8.292501449584961],[-82.31417846679688,8.271665573120117],[-82.33250427246094,8.233610153198242]]],[[[-79.10694885253906,8.201112747192383],[-79.09750366210938,8.309167861938477],[-79.05584716796875,8.25139045715332],[-79.10694885253906,8.201112747192383]]],[[[-79.07640075683594,8.369722366333008],[-79.11445617675781,8.415277481079102],[-79.07583618164062,8.408609390258789],[-79.07640075683594,8.369722366333008]]],[[[-78.85139465332031,8.288610458374023],[-78.95916557312012,8.29222297668457],[-78.96028137207031,8.447221755981445],[-78.85139465332031,8.288610458374023]]],[[[-82.0150146484375,9.12639045715332],[-82.04917907714844,9.144166946411133],[-82.04583740234375,9.176389694213867],[-82.0150146484375,9.12639045715332]]],[[[-82.07917785644531,9.284444808959961],[-82.12445068359375,9.271944046020508],[-82.20639038085938,9.348333358764648],[-82.07917785644531,9.284444808959961]]],[[[-82.22445678710938,9.335000991821289],[-82.22944641113281,9.337499618530273],[-82.2247314453125,9.352499008178711],[-82.22445678710938,9.335000991821289]]],[[[-82.23918151855469,9.330278396606445],[-82.314453125,9.424722671508789],[-82.25834655761719,9.429166793823242],[-82.23918151855469,9.330278396606445]]],[[[-79.46305847167969,9.568056106567383],[-78.03556823730469,9.230001449584961],[-77.36666870117188,8.67500114440918],[-77.21556091308594,7.937223434448242],[-77.57389831542969,7.525278091430664],[-77.74667358398438,7.722223281860352],[-77.88972473144531,7.228891372680664],[-78.43305969238281,8.051942825317383],[-78.25723266601562,8.101945877075195],[-78.13917541503906,8.403890609741211],[-77.7791748046875,8.155000686645508],[-78.10751342773438,8.455831527709961],[-78.41416931152344,8.344167709350586],[-78.97862243652344,9.142778396606445],[-80.47361755371094,8.212778091430664],[-79.98973083496094,7.516111373901367],[-80.43333435058594,7.244443893432617],[-80.92529296875,7.250001907348633],[-81.05805969238281,7.873334884643555],[-81.17886352539062,7.85499382019043],[-81.21778869628906,7.607221603393555],[-81.4969482421875,7.698610305786133],[-81.73861694335938,8.162500381469727],[-82.19195556640625,8.19444465637207],[-82.2872314453125,8.313333511352539],[-82.7216796875,8.317220687866211],[-82.89884757995605,8.025671005249023],[-82.71084594726562,8.931112289428711],[-82.93472290039062,9.47166633605957],[-82.56356811523438,9.562875747680664],[-82.23695373535156,8.997777938842773],[-81.81639099121094,8.945276260375977],[-81.88389587402344,9.174444198608398],[-81.19612121582031,8.780279159545898],[-79.46305847167969,9.568056106567383]],[[-77.98695373535156,8.242223739624023],[-77.99223327636719,8.250555038452148],[-78.00306701660156,8.25111198425293],[-77.98695373535156,8.242223739624023]]]]}},{"type":"Feature","properties":{"name":"Portugal","iso2":"PT","iso3":"PRT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-17.102500915527344,32.82332801818848],[-16.715557098388672,32.75889015197754],[-16.94361114501953,32.63749885559082],[-17.102500915527344,32.82332801818848]]],[[[-16.28583526611328,33.09416389465332],[-16.400558471679688,33.03860664367676],[-16.325557708740234,33.10805702209473],[-16.28583526611328,33.09416389465332]]],[[[-25.01639175415039,36.9697208404541],[-25.200557708740234,36.9858341217041],[-25.08639144897461,37.02360725402832],[-25.01639175415039,36.9697208404541]]],[[[-25.585002899169922,37.82666206359863],[-25.864723205566406,37.85055732727051],[-25.130279541015625,37.811662673950195],[-25.585002899169922,37.82666206359863]]],[[[-28.14111328125,38.44988441467285],[-28.03778076171875,38.40694618225098],[-28.54944610595703,38.52722358703613],[-28.14111328125,38.44988441467285]]],[[[-27.086944580078125,38.63138771057129],[-27.38500213623047,38.76333045959473],[-27.065834045410156,38.76416206359863],[-27.086944580078125,38.63138771057129]]],[[[-31.215557098388672,39.35333442687988],[-31.213890075683594,39.52194404602051],[-31.123058319091797,39.44888496398926],[-31.215557098388672,39.35333442687988]]],[[[-8.204723358154297,41.87471961975098],[-6.594165802001953,41.9536075592041],[-6.187221527099609,41.579721450805664],[-6.931667327880859,41.01805305480957],[-7.017221450805664,39.674997329711914],[-7.532505035400391,39.66942024230957],[-6.954792022705078,39.026384353637695],[-7.321111679077148,38.44944190979004],[-6.939167022705078,38.178056716918945],[-7.446945190429688,37.69944190979004],[-7.431854248046875,37.253190994262695],[-8.990278244018555,37.02305030822754],[-8.673334121704102,38.413888931274414],[-9.183889389038086,38.41971778869629],[-8.984445571899414,38.94777870178223],[-9.484445571899414,38.71000099182129],[-8.660833358764648,40.68721961975098],[-8.74500846862793,41.95250129699707],[-8.201223373413086,42.15274238586426],[-8.204723358154297,41.87471961975098]]]]}},{"type":"Feature","properties":{"name":"Papua New Guinea","iso2":"PG","iso3":"PNG"},"geometry":{"type":"MultiPolygon","coordinates":[[[[153.77081489562988,-11.616388320922852],[153.376070022583,-11.567222595214844],[153.19803047180176,-11.324167251586914],[153.77081489562988,-11.616388320922852]]],[[[154.29776191711426,-11.391944885253906],[154.00332832336426,-11.383890151977539],[154.15387153625488,-11.314167022705078],[154.29776191711426,-11.391944885253906]]],[[[153.241060256958,-11.268890380859375],[153.21051216125488,-11.285833358764648],[153.09106636047363,-11.197221755981445],[153.241060256958,-11.268890380859375]]],[[[152.87329292297363,-10.662221908569336],[152.74441719055176,-10.716665267944336],[152.54080390930176,-10.63055419921875],[152.87329292297363,-10.662221908569336]]],[[[151.06970405578613,-10.61111068725586],[151.0422077178955,-10.676944732666016],[150.90997505187988,-10.654722213745117],[151.06970405578613,-10.61111068725586]]],[[[150.89221382141113,-10.650833129882812],[150.79080390930176,-10.54222297668457],[150.90027046203613,-10.553054809570312],[150.89221382141113,-10.650833129882812]]],[[[151.116060256958,-10.046667098999023],[151.28137397766113,-9.923334121704102],[151.22912788391113,-10.20111083984375],[150.958589553833,-10.11027717590332],[150.7599811553955,-9.70777702331543],[151.116060256958,-10.046667098999023]]],[[[150.66665840148926,-9.438333511352539],[150.92163276672363,-9.670833587646484],[150.42190742492676,-9.389444351196289],[150.66665840148926,-9.438333511352539]]],[[[150.33914375305176,-9.524723052978516],[150.10830879211426,-9.368610382080078],[150.18914985656738,-9.211111068725586],[150.33914375305176,-9.524723052978516]]],[[[152.81497383117676,-8.972776412963867],[152.99719429016113,-9.173055648803711],[152.49774360656738,-9.021665573120117],[152.81497383117676,-8.972776412963867]]],[[[151.1249713897705,-8.425556182861328],[151.14444160461426,-8.830554962158203],[150.996919631958,-8.52861213684082],[151.1249713897705,-8.425556182861328]]],[[[143.638032913208,-8.733055114746094],[143.18359565734863,-8.420000076293945],[143.46719551086426,-8.527778625488281],[143.638032913208,-8.733055114746094]]],[[[143.57275581359863,-8.493888854980469],[143.3144245147705,-8.376665115356445],[143.57831001281738,-8.37388801574707],[143.57275581359863,-8.493888854980469]]],[[[143.68719673156738,-8.439722061157227],[143.60717964172363,-8.33277702331543],[143.672212600708,-8.35444450378418],[143.68719673156738,-8.439722061157227]]],[[[143.6974811553955,-8.245277404785156],[143.65164375305176,-8.199722290039062],[143.73330879211426,-8.174722671508789],[143.6974811553955,-8.245277404785156]]],[[[143.67776679992676,-8.174722671508789],[143.6049518585205,-8.108888626098633],[143.70025825500488,-8.106109619140625],[143.67776679992676,-8.174722671508789]]],[[[143.73108100891113,-8.071666717529297],[143.58856391906738,-8.071666717529297],[143.56524848937988,-8.020000457763672],[143.73108100891113,-8.071666717529297]]],[[[145.1935749053955,-7.867221832275391],[145.18054389953613,-7.861110687255859],[145.182466506958,-7.827777862548828],[145.1935749053955,-7.867221832275391]]],[[[143.99969673156738,-7.824443817138672],[143.8771686553955,-7.709722518920898],[143.96692085266113,-7.748332977294922],[143.99969673156738,-7.824443817138672]]],[[[154.88244819641113,-5.543333053588867],[155.91858100891113,-6.807777404785156],[155.2399616241455,-6.622499465942383],[154.74438667297363,-5.939779281616211],[154.88244819641113,-5.543333053588867]]],[[[148.0614948272705,-5.777116775512695],[147.86511421203613,-5.747753143310547],[147.78027534484863,-5.494165420532227],[148.0614948272705,-5.777116775512695]]],[[[148.12079048156738,-5.468332290649414],[148.071626663208,-5.424444198608398],[148.099702835083,-5.377498626708984],[148.12079048156738,-5.468332290649414]]],[[[147.60217475891113,-5.361944198608398],[147.5605182647705,-5.318889617919922],[147.60913276672363,-5.288055419921875],[147.60217475891113,-5.361944198608398]]],[[[147.15332221984863,-5.44972038269043],[147.0080280303955,-5.350276947021484],[147.1210651397705,-5.191110610961914],[147.15332221984863,-5.44972038269043]]],[[[154.67553901672363,-5.440832138061523],[154.53027534484863,-5.133888244628906],[154.63916206359863,-5.016387939453125],[154.67553901672363,-5.440832138061523]]],[[[149.15692329406738,-4.923055648803711],[149.118013381958,-4.889444351196289],[149.16192817687988,-4.866388320922852],[149.15692329406738,-4.923055648803711]]],[[[146.24661445617676,-4.857500076293945],[146.19940376281738,-4.833610534667969],[146.21997261047363,-4.788331985473633],[146.24661445617676,-4.857500076293945]]],[[[149.55719184875488,-4.718889236450195],[149.45581245422363,-4.679166793823242],[149.5402545928955,-4.653888702392578],[149.55719184875488,-4.718889236450195]]],[[[159.516939163208,-4.578056335449219],[159.51138496398926,-4.576665878295898],[159.51886177062988,-4.536388397216797],[159.516939163208,-4.578056335449219]]],[[[145.95135688781738,-4.764444351196289],[145.87246894836426,-4.67249870300293],[145.98163032531738,-4.527500152587891],[145.95135688781738,-4.764444351196289]]],[[[154.1552448272705,-4.438055038452148],[154.13272285461426,-4.371665954589844],[154.15277290344238,-4.379444122314453],[154.1552448272705,-4.438055038452148]]],[[[152.23523139953613,-4.207221984863281],[152.40582466125488,-4.688888549804688],[151.970796585083,-4.993331909179688],[152.09607124328613,-5.457221984863281],[151.45941352844238,-5.535833358764648],[150.46856880187988,-6.276111602783203],[149.05691719055176,-6.164165496826172],[148.323091506958,-5.675376892089844],[148.42859077453613,-5.45111083984375],[149.88080024719238,-5.534999847412109],[150.08886909484863,-5.007778167724609],[150.16443061828613,-5.551387786865234],[150.924409866333,-5.487220764160156],[151.67608833312988,-4.908054351806641],[151.51165962219238,-4.204444885253906],[152.23523139953613,-4.207221984863281]],[[149.05359077453613,-6.094165802001953],[149.05414009094238,-6.083889007568359],[149.04385566711426,-6.088611602783203],[149.05359077453613,-6.094165802001953]]],[[[145.05774116516113,-4.135276794433594],[145.06884956359863,-4.045000076293945],[145.109956741333,-4.098333358764648],[145.05774116516113,-4.135276794433594]]],[[[153.64554023742676,-4.140277862548828],[153.58441352844238,-4.095832824707031],[153.65860176086426,-4.019166946411133],[153.64554023742676,-4.140277862548828]]],[[[153.25833320617676,-3.49888801574707],[153.19384956359863,-3.468610763549805],[153.23358345031738,-3.446666717529297],[153.25833320617676,-3.49888801574707]]],[[[154.83304023742676,-3.510276794433594],[154.8185749053955,-3.530277252197266],[154.799409866333,-3.424999237060547],[154.83304023742676,-3.510276794433594]]],[[[153.34524726867676,-3.411943435668945],[153.26248359680176,-3.404443740844727],[153.333589553833,-3.371389389038086],[153.34524726867676,-3.411943435668945]]],[[[152.64636421203613,-3.228610992431641],[152.53888130187988,-3.106109619140625],[152.599702835083,-3.048055648803711],[152.64636421203613,-3.228610992431641]]],[[[150.94134712219238,-2.921943664550781],[151.02163887023926,-2.971942901611328],[150.7660846710205,-2.979442596435547],[150.94134712219238,-2.921943664550781]]],[[[152.06997871398926,-3.001388549804688],[151.97357368469238,-2.848054885864258],[152.07885932922363,-2.928333282470703],[152.06997871398926,-3.001388549804688]]],[[[152.00219917297363,-2.828887939453125],[151.93164253234863,-2.832500457763672],[151.932466506958,-2.708332061767578],[152.00219917297363,-2.828887939453125]]],[[[150.90652656555176,-2.635944366455078],[152.05581855773926,-3.247777938842773],[152.98968696594238,-4.075832366943359],[152.97467231750488,-4.766666412353516],[152.73550605773926,-4.660833358764648],[152.69165229797363,-4.18055534362793],[152.28247261047363,-3.572776794433594],[150.72967720031738,-2.740554809570313],[150.90652656555176,-2.635944366455078]]],[[[141.889986038208,-2.969999313354492],[144.51165962219238,-3.820833206176758],[145.73550605773926,-4.802776336669922],[145.76638984680176,-5.48527717590332],[147.47686958312988,-5.974191665649414],[147.86941719055176,-6.660833358764648],[146.96136665344238,-6.747220993041992],[147.17859077453613,-7.463888168334961],[148.13525581359863,-8.066110610961914],[148.60412788391113,-9.082500457763672],[149.31469917297363,-9.018890380859375],[149.21997261047363,-9.474721908569336],[150.008882522583,-9.631387710571289],[149.71747016906738,-9.826665878295898],[149.914155960083,-10.04888916015625],[150.87829780578613,-10.231666564941406],[150.3691120147705,-10.321945190429688],[150.69134712219238,-10.561111450195312],[150.2096881866455,-10.700555801391602],[149.74774360656738,-10.342777252197266],[147.95245552062988,-10.145833969116211],[147.05523872375488,-9.466665267944336],[146.97247505187988,-9.029167175292969],[146.5866413116455,-8.999164581298828],[146.089693069458,-8.091110229492188],[144.52054023742676,-7.501943588256836],[144.21301460266113,-7.795276641845703],[143.66482734680176,-7.467649459838867],[143.95800971984863,-7.978622436523438],[143.35830879211426,-7.902500152587891],[143.611909866333,-8.243888854980469],[142.13720893859863,-8.225555419921875],[143.11023139953613,-8.470277786254883],[143.331636428833,-9.02833366394043],[142.6388874053955,-9.334722518920898],[141.00702095031738,-9.128467559814453],[141.00247383117676,-2.607084274291992],[141.889986038208,-2.969999313354492]]],[[[152.02221870422363,-2.667499542236328],[151.9577350616455,-2.664722442626953],[151.9838581085205,-2.596111297607422],[152.02221870422363,-2.667499542236328]]],[[[150.45831489562988,-2.653610229492188],[149.948579788208,-2.47166633605957],[150.21637153625488,-2.377777099609375],[150.45831489562988,-2.653610229492188]]],[[[147.8124713897705,-2.349721908569336],[147.81524848937988,-2.243610382080078],[147.8791217803955,-2.293611526489258],[147.8124713897705,-2.349721908569336]]],[[[147.30081367492676,-2.025278091430664],[146.524995803833,-2.190832138061523],[146.63858222961426,-1.978610992431641],[147.30081367492676,-2.025278091430664]]],[[[142.86636543273926,-1.697776794433594],[142.81360054016113,-1.732776641845703],[142.82107734680176,-1.695833206176758],[142.86636543273926,-1.697776794433594]]],[[[149.7196979522705,-1.433332443237305],[149.7319049835205,-1.60333251953125],[149.52777290344238,-1.454442977905273],[149.7196979522705,-1.433332443237305]]],[[[144.52191352844238,-1.395553588867188],[144.50555610656738,-1.380556106567383],[144.51638984680176,-1.381942749023438],[144.52191352844238,-1.395553588867188]]],[[[144.52054023742676,-1.120832443237305],[144.51443672180176,-1.116109848022461],[144.51721382141113,-1.098333358764648],[144.52054023742676,-1.120832443237305]]]]}},{"type":"Feature","properties":{"name":"Guinea-Bissau","iso2":"GW","iso3":"GNB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-15.885834,11.052221],[-15.981111999999882,11.049444000000122],[-15.94639,11.195],[-15.885834,11.052221]]],[[[-16.005836,11.068333],[-16.06139,11.163055],[-15.980556,11.202499000000131],[-16.005836,11.068333]]],[[[-16.088058,11.025555],[-16.24416699999989,11.100555],[-16.0825,11.206944],[-16.088058,11.025555]]],[[[-15.862223,11.199999],[-15.906388999999876,11.224998],[-15.830278,11.300833],[-15.862223,11.199999]]],[[[-15.740002,11.166943],[-15.77639,11.225832000000167],[-15.667501,11.306389],[-15.740002,11.166943]]],[[[-16.17778,11.2152770000001],[-16.264446,11.281666],[-16.160835,11.290277000000103],[-16.17778,11.2152770000001]]],[[[-15.679724,11.439444000000108],[-15.743057,11.458332],[-15.665834,11.502222000000131],[-15.679724,11.439444000000108]]],[[[-16.21278,11.439722],[-16.300556,11.449444],[-16.16444799999988,11.514999],[-16.21278,11.439722]]],[[[-16.250557,11.536665],[-16.419445,11.482777],[-16.393889999999885,11.545832000000132],[-16.250557,11.536665]]],[[[-15.952501,11.423054],[-16.065002,11.44972],[-15.958334,11.594166],[-15.952501,11.423054]]],[[[-15.553057,11.517221],[-15.633612,11.535276],[-15.472223,11.631109000000109],[-15.553057,11.517221]]],[[[-16.031948,11.755833],[-16.162224,11.86861],[-15.978334,11.905832],[-16.031948,11.755833]]],[[[-16.236389,11.836943],[-16.30167,11.971666000000113],[-16.184723,11.876665],[-16.236389,11.836943]]],[[[-14.516945,12.67972200000014],[-13.713139,12.677221],[-13.971035,12.154758],[-13.709167,11.715277],[-14.686944999999895,11.509722],[-15.016847999999868,10.956451000000143],[-15.022779,11.195276],[-15.407223,11.184999],[-15.26528,11.425913],[-15.509167,11.338055],[-15.027223999999876,11.594166],[-15.55666699999989,11.723331],[-14.931946,11.750832],[-15.003889,11.974165000000113],[-15.963335,11.734165000000132],[-15.704445,12.004444],[-15.852779,12.016666],[-16.128056,11.881943],[-16.333893,11.996664],[-16.334446,12.15111],[-16.110558,12.330832],[-16.71777,12.322426],[-14.516945,12.67972200000014]]]]}},{"type":"Feature","properties":{"name":"Qatar","iso2":"QA","iso3":"QAT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[51.51759,25.383415],[51.611664,25.010277],[51.215164,24.620888],[50.830956,24.749966],[51.042496,26.049442],[51.568054,25.908333],[51.51759,25.383415]]]]}},{"type":"Feature","properties":{"name":"Reunion","iso2":"RE","iso3":"REU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[55.709999,-20.998058],[55.674164,-21.37389],[55.219719,-21.027779],[55.709999,-20.998058]]]]}},{"type":"Feature","properties":{"name":"Romania","iso2":"RO","iso3":"ROU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[20.726955,46.17556],[21.176666,46.295555],[22.032497,47.530273],[22.894804,47.95454],[24.91944100000012,47.711662],[26.634995,48.257164],[28.119717,46.854404],[28.21484,45.448647],[29.664331,45.211803],[29.549438,44.820267],[28.868324,44.943047],[28.583244,43.747765],[27.036427,44.147339],[25.430229,43.626778],[24.179996,43.684715],[22.875275,43.842499],[23.044167,44.076111],[22.681435,44.224701],[22.457333,44.474358],[22.764893,44.559006],[22.479164,44.710274],[22.146385,44.479164],[21.400398,44.780823],[21.513611,45.151108],[20.261024,46.114853],[20.726955,46.17556]]]]}},{"type":"Feature","properties":{"name":"Republic of Moldova","iso2":"MD","iso3":"MDA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[28.119717,46.854404],[26.634995,48.257164],[27.755554,48.451385],[29.141937000000155,47.98609200000014],[29.184441,47.443047],[29.949997,46.814156],[30.11694,46.386101],[28.994434,46.47832500000011],[28.971935,46.006653],[28.21484,45.448647],[28.119717,46.854404]]]]}},{"type":"Feature","properties":{"name":"Philippines","iso2":"PH","iso3":"PHL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[119.47221565246582,4.648054122924805],[119.45583534240723,4.90888786315918],[119.51053810119629,4.763887405395508],[119.47221565246582,4.648054122924805]]],[[[120.01915168762207,5.030279159545898],[120.01888465881348,5.02861213684082],[120.01471138000488,5.030832290649414],[120.01915168762207,5.030279159545898]]],[[[119.94719886779785,5.076944351196289],[119.93414497375488,5.075834274291992],[119.94109535217285,5.083612442016602],[119.94719886779785,5.076944351196289]]],[[[120.24414253234863,5.300832748413086],[120.22664833068848,5.306390762329102],[120.23108863830566,5.325002670288086],[120.24414253234863,5.300832748413086]]],[[[120.25360298156738,5.233335494995117],[119.83110237121582,5.059164047241211],[120.17775917053223,5.343610763549805],[120.25360298156738,5.233335494995117]]],[[[125.41470527648926,5.361112594604492],[125.32998847961426,5.38722038269043],[125.40582466125488,5.430276870727539],[125.41470527648926,5.361112594604492]]],[[[125.47831916809082,5.388334274291992],[125.45027351379395,5.421945571899414],[125.47943305969238,5.491945266723633],[125.47831916809082,5.388334274291992]]],[[[120.86971473693848,5.491388320922852],[120.84332466125488,5.585000991821289],[120.90999031066895,5.536111831665039],[120.86971473693848,5.491388320922852]]],[[[121.18387031555176,5.787500381469727],[121.13916206359863,5.785276412963867],[121.1463794708252,5.84889030456543],[121.18387031555176,5.787500381469727]]],[[[121.18525886535645,6.039999008178711],[121.42581367492676,5.95250129699707],[120.87552833557129,5.921110153198242],[121.18525886535645,6.039999008178711]]],[[[121.86303901672363,6.016389846801758],[121.76277351379395,6.09083366394043],[121.95332527160645,6.051111221313477],[121.86303901672363,6.016389846801758]]],[[[120.56833076477051,6.244722366333008],[120.47776985168457,6.264165878295898],[120.59971809387207,6.396112442016602],[120.56833076477051,6.244722366333008]]],[[[122.23027229309082,6.660833358764648],[122.03386878967285,6.411111831665039],[121.79471015930176,6.593610763549805],[122.23027229309082,6.660833358764648]]],[[[118.53360176086426,7.035001754760742],[118.54026985168457,6.965276718139648],[118.41721534729004,7.022222518920898],[118.53360176086426,7.035001754760742]]],[[[125.79498481750488,6.932775497436523],[125.66998481750488,7.075002670288086],[125.69914436340332,7.191667556762695],[125.79498481750488,6.932775497436523]]],[[[117.02221870422363,7.808889389038086],[116.94999885559082,8.032220840454102],[117.06553840637207,8.078611373901367],[117.02221870422363,7.808889389038086]]],[[[117.29886817932129,8.182222366333008],[117.26805305480957,8.306108474731445],[117.31804847717285,8.331110000610352],[117.29886817932129,8.182222366333008]]],[[[126.23665046691895,9.008333206176758],[126.23166084289551,8.998052597045898],[126.22943305969238,9.013055801391602],[126.23665046691895,9.008333206176758]]],[[[126.26361274719238,8.997220993041992],[126.24664497375488,9.013612747192383],[126.26053810119629,9.00666618347168],[126.26361274719238,8.997220993041992]]],[[[123.67498970031738,9.226388931274414],[123.60942268371582,9.092222213745117],[123.45720863342285,9.190553665161133],[123.67498970031738,9.226388931274414]]],[[[124.77858924865723,9.075555801391602],[124.64360237121582,9.155279159545898],[124.67276191711426,9.253053665161133],[124.77858924865723,9.075555801391602]]],[[[123.77361488342285,9.544164657592773],[123.74471473693848,9.595277786254883],[123.84499549865723,9.636110305786133],[123.77361488342285,9.544164657592773]]],[[[125.95247840881348,9.557500839233398],[125.90054512023926,9.616941452026367],[125.93831062316895,9.756387710571289],[125.95247840881348,9.557500839233398]]],[[[126.0486011505127,9.231943130493164],[126.58582496643066,7.285001754760742],[126.16526985168457,6.88166618347168],[126.19165229797363,6.272222518920898],[125.85555458068848,7.349721908569336],[125.65220832824707,7.236665725708008],[125.37719917297363,6.719720840454102],[125.70332527160645,6.027223587036133],[125.40555000305176,5.563333511352539],[125.26361274719238,6.091665267944336],[124.95694160461426,5.851388931274414],[124.1858081817627,6.210554122924805],[123.94859504699707,6.823335647583008],[124.26860237121582,7.374444961547852],[123.6766529083252,7.812498092651367],[123.45471382141113,7.367498397827148],[123.11638069152832,7.72944450378418],[122.83276557922363,7.275278091430664],[122.62387275695801,7.773054122924805],[122.14998817443848,6.905279159545898],[121.92109870910645,6.994165420532227],[122.22331428527832,7.962221145629883],[122.92302894592285,8.15083122253418],[123.37915229797363,8.72722053527832],[123.81804847717285,8.47694206237793],[123.67109870910645,7.953889846801758],[124.43221473693848,8.615274429321289],[124.72747993469238,8.486387252807617],[124.80386543273926,9.001665115356445],[125.51471138000488,9.00666618347168],[125.44026374816895,9.809164047241211],[126.0486011505127,9.231943130493164]]],[[[124.57415962219238,9.854719161987305],[124.56609535217285,9.849443435668945],[124.56553840637207,9.861944198608398],[124.57415962219238,9.863332748413086],[124.57415962219238,9.854719161987305]]],[[[123.38443183898926,9.878885269165039],[123.3722095489502,9.880552291870117],[123.37970161437988,9.888055801391602],[123.38443183898926,9.878885269165039]]],[[[126.11303901672363,9.744443893432617],[125.94553565979004,9.830831527709961],[126.06025886535645,10.054166793823242],[126.11303901672363,9.744443893432617]]],[[[124.48387336730957,10.050832748413086],[124.36554145812988,9.626943588256836],[123.79332160949707,9.72944450378418],[124.14888191223145,10.146944046020508],[124.48387336730957,10.050832748413086]]],[[[125.28692817687988,9.90916633605957],[125.12664985656738,10.155832290649414],[125.21748542785645,10.122220993041992],[125.28692817687988,9.90916633605957]]],[[[125.6594181060791,9.82472038269043],[125.47527503967285,10.131109237670898],[125.64526557922363,10.468889236450195],[125.6594181060791,9.82472038269043]]],[[[119.82721138000488,10.439722061157227],[119.75833320617676,10.556943893432617],[120.00248908996582,10.591386795043945],[119.82721138000488,10.439722061157227]]],[[[124.3672046661377,10.60777473449707],[124.27581977844238,10.587778091430664],[124.32054328918457,10.706941604614258],[124.3672046661377,10.60777473449707]]],[[[124.43747901916504,10.624998092651367],[124.45139503479004,10.714998245239258],[124.51748847961426,10.659444808959961],[124.43747901916504,10.624998092651367]]],[[[122.6352710723877,10.443609237670898],[122.47971534729004,10.487775802612305],[122.6594181060791,10.748331069946289],[122.6352710723877,10.443609237670898]]],[[[125.80246925354004,10.688886642456055],[125.6624927520752,10.750833511352539],[125.69220161437988,10.823610305786133],[125.80246925354004,10.688886642456055]]],[[[123.56387519836426,10.794164657592773],[123.13638496398926,9.836111068725586],[123.29637336730957,9.229719161987305],[123.01471138000488,9.03388786315918],[122.45276832580566,9.973333358764648],[122.85832405090332,10.097497940063477],[122.95247840881348,10.894445419311523],[123.56387519836426,10.794164657592773]]],[[[121.0405445098877,10.79194450378418],[121.00388526916504,10.836111068725586],[121.08110237121582,10.905279159545898],[121.0405445098877,10.79194450378418]]],[[[124.01987648010254,11.11894416809082],[124.02693367004395,10.381940841674805],[123.31025886535645,9.411943435668945],[124.01987648010254,11.11894416809082]]],[[[123.75081825256348,11.147500991821289],[123.69275093078613,11.22138786315918],[123.7330493927002,11.300554275512695],[123.75081825256348,11.147500991821289]]],[[[119.50857734680176,11.335607528686523],[119.71248817443848,10.497499465942383],[117.1858081817627,8.325555801391602],[119.31247901916504,10.582498550415039],[119.21692848205566,10.959997177124023],[119.45610237121582,10.723608016967773],[119.50857734680176,11.335607528686523]]],[[[119.53386878967285,11.362497329711914],[119.52221870422363,11.366666793823242],[119.54026985168457,11.373052597045898],[119.53386878967285,11.362497329711914]]],[[[119.83249092102051,11.376943588256836],[119.71470832824707,11.476110458374023],[119.87137031555176,11.50666618347168],[119.83249092102051,11.376943588256836]]],[[[124.63889503479004,11.293333053588867],[124.94748115539551,11.42500114440918],[125.02998542785645,11.195833206176758],[125.27165412902832,10.29749870300293],[124.98027229309082,10.37916374206543],[125.01471138000488,10.027776718139648],[124.28970527648926,11.541387557983398],[124.63889503479004,11.293333053588867]]],[[[124.58471870422363,11.472497940063477],[124.3388843536377,11.68083381652832],[124.53137397766113,11.679719924926758],[124.58471870422363,11.472497940063477]]],[[[124.83167457580566,11.528886795043945],[124.71805000305176,11.72722053527832],[124.84276008605957,11.591665267944336],[124.83167457580566,11.528886795043945]]],[[[122.22943305969238,11.79777717590332],[122.88081550598145,11.429166793823242],[123.15305519104004,11.600275039672852],[123.12859535217285,11.174444198608398],[121.94331550598145,10.416387557983398],[122.09887886047363,11.69999885559082],[121.8480396270752,11.760000228881836],[122.22943305969238,11.79777717590332]]],[[[119.96527290344238,11.656942367553711],[119.88498878479004,11.976110458374023],[120.07054328918457,11.864999771118164],[119.96527290344238,11.656942367553711]],[[120.04637336730957,11.823331832885742],[120.04609870910645,11.826387405395508],[120.04387092590332,11.824441909790039],[120.04637336730957,11.823331832885742]]],[[[120.26805305480957,11.826944351196289],[120.20276832580566,11.946111679077148],[120.25444221496582,11.982221603393555],[120.26805305480957,11.826944351196289]]],[[[120.08471870422363,11.958608627319336],[120.06553840637207,11.964166641235352],[120.06165504455566,11.992498397827148],[120.08471870422363,11.958608627319336]]],[[[119.95358467102051,12.021665573120117],[119.95025825500488,12.030553817749023],[119.95941352844238,12.036943435668945],[119.95358467102051,12.021665573120117]]],[[[121.13749885559082,12.157499313354492],[121.04276466369629,12.22944450378418],[121.04582405090332,12.290555953979492],[121.13749885559082,12.157499313354492]]],[[[120.16829872131348,12.118330001831055],[120.3399829864502,11.992776870727539],[119.87387275695801,12.314443588256836],[120.16829872131348,12.118330001831055]]],[[[122.68109321594238,12.308053970336914],[122.43248176574707,12.461111068725586],[122.66943550109863,12.483610153198242],[122.68109321594238,12.308053970336914]]],[[[124.4638843536377,12.520833969116211],[125.29694557189941,12.457498550415039],[125.7602710723877,11.011667251586914],[125.26944160461426,11.128053665161133],[124.96999549865723,11.447500228881836],[124.84359931945801,11.466386795043945],[125.04248237609863,11.747220993041992],[124.38693428039551,12.190275192260742],[124.25804328918457,12.55555534362793],[124.4638843536377,12.520833969116211]],[[125.67249488830566,11.089998245239258],[125.68193244934082,11.103609085083008],[125.66470527648926,11.102777481079102],[125.67249488830566,11.089998245239258]]],[[[123.66943550109863,12.346944808959961],[124.07639503479004,11.718332290649414],[123.53027534484863,12.208608627319336],[123.15776252746582,11.908609390258789],[123.24165534973145,12.606943130493164],[123.66943550109863,12.346944808959961]]],[[[122.30693244934082,12.486387252807617],[122.24803352355957,12.56110954284668],[122.28305244445801,12.633333206176758],[122.30693244934082,12.486387252807617]]],[[[123.79221534729004,12.344999313354492],[123.58554267883301,12.660554885864258],[123.72776985168457,12.601663589477539],[123.79221534729004,12.344999313354492]]],[[[122.0486011505127,12.176664352416992],[121.91748237609863,12.304166793823242],[122.12275886535645,12.676942825317383],[122.0486011505127,12.176664352416992]]],[[[123.38247871398926,12.69194221496582],[122.93193244934082,13.10999870300293],[123.0486011505127,13.134721755981445],[123.38247871398926,12.69194221496582]]],[[[124.21805000305176,13.17249870300293],[124.07832527160645,13.211111068725586],[124.16330909729004,13.232221603393555],[124.21805000305176,13.17249870300293]]],[[[124.04609870910645,13.220552444458008],[123.95610237121582,13.232500076293945],[123.91499519348145,13.286386489868164],[124.09887886047363,13.260557174682617],[124.04609870910645,13.220552444458008]]],[[[123.91304206848145,13.24305534362793],[123.87915229797363,13.22944450378418],[123.85386848449707,13.267221450805664],[123.8510913848877,13.35194206237793],[123.93081855773926,13.324441909790039],[123.89048194885254,13.278779983520508],[123.91304206848145,13.24305534362793]]],[[[122.1513843536377,13.39555549621582],[122.13165473937988,13.40083122253418],[122.12608528137207,13.421945571899414],[122.1513843536377,13.39555549621582]]],[[[122.12343788146973,13.404104232788086],[122.00332832336426,13.20222282409668],[121.81331062316895,13.448610305786133],[122.12343788146973,13.404104232788086]]],[[[120.72165107727051,13.477777481079102],[121.5022144317627,13.148889541625977],[121.55832099914551,12.601110458374023],[121.22054481506348,12.230554580688477],[120.30330848693848,13.443609237670898],[120.72165107727051,13.477777481079102]]],[[[120.28193855285645,13.754167556762695],[120.27469825744629,13.668333053588867],[120.07998847961426,13.849164962768555],[120.28193855285645,13.754167556762695]]],[[[124.28736305236816,13.946176528930664],[124.20804023742676,13.515275955200195],[124.03055000305176,13.663888931274414],[124.28736305236816,13.946176528930664]]],[[[124.30108833312988,13.95222282409668],[124.29414558410645,13.95805549621582],[124.30304145812988,13.96360969543457],[124.30108833312988,13.95222282409668]]],[[[124.34221076965332,13.942220687866211],[124.3127613067627,13.954999923706055],[124.32527351379395,13.981943130493164],[124.34221076965332,13.942220687866211]]],[[[122.17109870910645,13.99860954284668],[121.91748237609863,14.185277938842773],[122.12442207336426,14.088888168334961],[122.17109870910645,13.99860954284668]]],[[[122.25417518615723,14.722497940063477],[122.09860420227051,14.837778091430664],[122.21304512023926,14.839166641235352],[122.25417518615723,14.722497940063477]]],[[[122.05081367492676,14.996664047241211],[121.93081855773926,14.62916374206543],[121.81915473937988,14.991666793823242],[122.05081367492676,14.996664047241211]]],[[[120.00026893615723,16.225553512573242],[119.92442512512207,16.2994441986084],[119.97415351867676,16.34666633605957],[120.00277900695801,16.34055519104004],[120.00026893615723,16.225553512573242]]],[[[121.25665473937988,18.566110610961914],[121.93665504455566,18.269445419311523],[122.24165534973145,18.51277732849121],[122.17025947570801,17.607221603393555],[122.53333473205566,17.099443435668945],[121.37886238098145,15.332220077514648],[121.73387336730957,14.170831680297852],[122.23332405090332,13.897222518920898],[122.1655445098877,14.158056259155273],[122.71331977844238,14.33833122253418],[123.0999927520752,13.667497634887695],[123.34305000305176,14.086942672729492],[123.92498970031738,13.789167404174805],[123.53193855285645,13.575555801391602],[123.76277351379395,13.061666488647461],[124.19582557678223,13.057775497436523],[124.08276557922363,12.540555953979492],[123.84887886047363,12.731943130493164],[124.02858924865723,12.963052749633789],[123.32222175598145,13.008611679077148],[122.56099891662598,13.936567306518555],[122.60748481750488,13.163888931274414],[121.75470924377441,13.964445114135742],[121.27942848205566,13.593889236450195],[120.66110420227051,13.768331527709961],[120.59221076965332,14.231111526489258],[120.95665168762207,14.636945724487305],[120.5516529083252,14.826944351196289],[120.49331855773926,14.429719924926758],[120.08611488342285,14.785276412963867],[119.78692817687988,16.32305335998535],[119.92886543273926,16.38499641418457],[119.91914558410645,16.2902774810791],[119.93525886535645,16.242773056030273],[120.15664863586426,16.03611183166504],[120.42192268371582,16.155832290649414],[120.57054328918457,18.49083137512207],[121.25665473937988,18.566110610961914]],[[122.73526191711426,13.774168014526367],[122.74498176574707,13.781667709350586],[122.72747993469238,13.777223587036133],[122.73526191711426,13.774168014526367]]],[[[121.40054512023926,18.847219467163086],[121.27942848205566,18.86610984802246],[121.48442268371582,18.882776260375977],[121.40054512023926,18.847219467163086]]],[[[121.88275337219238,18.83333396911621],[121.83305549621582,18.880552291870117],[121.94609260559082,19.004446029663086],[121.88275337219238,18.83333396911621]]],[[[121.25139045715332,19.011945724487305],[121.20192909240723,19.065275192260742],[121.22026252746582,19.172773361206055],[121.25139045715332,19.011945724487305]]],[[[121.53970527648926,19.26666831970215],[121.37275886535645,19.364442825317383],[121.53055000305176,19.389719009399414],[121.53970527648926,19.26666831970215]]],[[[121.97470283508301,19.479997634887695],[121.90305519104004,19.550275802612305],[121.99359321594238,19.565275192260742],[121.97470283508301,19.479997634887695]]],[[[121.88693428039551,20.283334732055664],[121.84192848205566,20.282499313354492],[121.84636878967285,20.3527774810791],[121.88693428039551,20.283334732055664]]],[[[121.95443916320801,20.348608016967773],[121.92386817932129,20.4072208404541],[122.02665901184082,20.48333168029785],[121.95443916320801,20.348608016967773]]],[[[121.81218910217285,20.686662673950195],[121.87082099914551,20.8347225189209],[121.88333320617676,20.765275955200195],[121.81218910217285,20.686662673950195]]],[[[121.95694160461426,21.103609085083008],[121.94941902160645,21.106107711791992],[121.94970893859863,21.11805534362793],[121.95694160461426,21.103609085083008]]]]}},{"type":"Feature","properties":{"name":"Puerto Rico","iso2":"PR","iso3":"PRI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-67.880569,18.048332],[-67.93084699999989,18.109722000000104],[-67.84668,18.10749800000012],[-67.880569,18.048332]]],[[[-65.441391,18.090275],[-65.580292,18.114719],[-65.301117,18.147778],[-65.441391,18.090275]]],[[[-65.242783,18.302219],[-65.27528399999989,18.276943],[-65.338898,18.346664],[-65.242783,18.302219]]],[[[-66.99667399999987,18.504997],[-65.603058,18.232498],[-67.1872249999999,17.932499],[-67.266113,18.368053],[-66.99667399999987,18.504997]]]]}},{"type":"Feature","properties":{"name":"Russia","iso2":"RU","iso3":"RUS"},"geometry":{"type":"MultiPolygon","coordinates":[[[[131.87329292297363,42.95694160461426],[131.77997016906738,43.04944038391113],[131.9172077178955,43.02110481262207],[131.87329292297363,42.95694160461426]]],[[[146.13748359680176,43.45888710021973],[146.07608222961426,43.51333045959473],[146.22607612609863,43.52555274963379],[146.13748359680176,43.45888710021973]]],[[[146.66998481750488,43.70443916320801],[146.60467720031738,43.80388069152832],[146.90497016906738,43.83999061584473],[146.66998481750488,43.70443916320801]]],[[[47.73971748352051,43.93221473693848],[47.62803840637207,43.974435806274414],[47.78555488586426,43.958879470825195],[47.73971748352051,43.93221473693848]]],[[[146.148042678833,44.50999641418457],[146.56802558898926,44.43832588195801],[145.4374713897705,43.716936111450195],[146.148042678833,44.50999641418457]]],[[[148.82525825500488,45.33499336242676],[146.84051704406738,44.415544509887695],[147.93274116516113,45.4213809967041],[148.82525825500488,45.33499336242676]]],[[[47.96249580383301,45.50499153137207],[47.960275650024414,45.65304756164551],[47.99387550354004,45.53665351867676],[47.96249580383301,45.50499153137207]]],[[[48.468881607055664,45.67388343811035],[48.33777046203613,45.79721260070801],[48.404428482055664,45.794992446899414],[48.468881607055664,45.67388343811035]]],[[[48.72331428527832,45.698320388793945],[48.591928482055664,45.74749183654785],[48.49582862854004,45.882211685180664],[48.72331428527832,45.698320388793945]]],[[[150.0663776397705,45.847490310668945],[149.4374713897705,45.58360481262207],[150.49856758117676,46.19249153137207],[150.0663776397705,45.847490310668945]]],[[[150.874116897583,46.44082832336426],[150.79852485656738,46.44998359680176],[150.84192085266113,46.47110176086426],[150.874116897583,46.44082832336426]]],[[[150.764986038208,46.70388221740723],[150.730806350708,46.72276496887207],[150.76220893859863,46.727487564086914],[150.764986038208,46.70388221740723]]],[[[152.22552680969238,47.17471504211426],[152.013032913208,46.88888740539551],[151.71219062805176,46.801103591918945],[152.22552680969238,47.17471504211426]]],[[[152.519136428833,47.30721473693848],[152.388032913208,47.34415626525879],[152.5038776397705,47.377214431762695],[152.519136428833,47.30721473693848]]],[[[153.0160846710205,47.69304847717285],[153.07412910461426,47.80832862854004],[153.08026313781738,47.71415901184082],[153.0160846710205,47.69304847717285]]],[[[153.29052925109863,48.053606033325195],[153.13775825500488,48.10110664367676],[153.22329902648926,48.1330509185791],[153.29052925109863,48.053606033325195]]],[[[154.01944160461426,48.72332191467285],[154.11218452453613,48.89499855041504],[154.228853225708,48.90249061584473],[154.01944160461426,48.72332191467285]]],[[[153.9819049835205,48.92666053771973],[153.90191841125488,48.969987869262695],[154.00470161437988,48.96360969543457],[153.9819049835205,48.92666053771973]]],[[[154.454683303833,49.16916084289551],[154.5988483428955,49.11194038391113],[154.50055122375488,49.07444190979004],[154.454683303833,49.16916084289551]]],[[[154.7157917022705,49.26388740539551],[154.60244941711426,49.373605728149414],[154.90442085266113,49.624162673950195],[154.7157917022705,49.26388740539551]]],[[[154.42498970031738,49.73360633850098],[154.3749713897705,49.82499885559082],[154.45996284484863,49.81388282775879],[154.42498970031738,49.73360633850098]]],[[[155.78552436828613,50.18499183654785],[155.208589553833,50.080827713012695],[156.10412788391113,50.76111030578613],[155.78552436828613,50.18499183654785]]],[[[156.4038257598877,50.653398513793945],[156.16443061828613,50.72860145568848],[156.46386909484863,50.86944007873535],[156.4038257598877,50.653398513793945]]],[[[155.62079048156738,50.806100845336914],[155.44775581359863,50.897775650024414],[155.63916206359863,50.92083168029785],[155.62079048156738,50.806100845336914]]],[[[143.66192817687988,49.312211990356445],[143.2460651397705,49.379159927368164],[143.32025337219238,49.313608169555664],[143.66192817687988,49.312211990356445],[143.01776313781738,49.139719009399414],[142.53470039367676,48.00277900695801],[143.08828926086426,46.80166053771973],[143.49164009094238,46.808603286743164],[143.4738483428955,46.0927677154541],[143.37857246398926,46.5483341217041],[142.7096881866455,46.744157791137695],[142.07745552062988,45.89138221740723],[141.81274604797363,46.58610725402832],[142.18887519836426,47.97526741027832],[141.85244941711426,48.75027656555176],[142.26721382141113,51.12027168273926],[141.638032913208,52.31582832336426],[141.766939163208,53.37137794494629],[142.7983112335205,53.69748878479004],[142.39386177062988,54.237497329711914],[142.696626663208,54.42471504211426],[143.29080390930176,53.13027381896973],[143.220796585083,51.521379470825195],[144.75164985656738,48.64193916320801],[143.66192817687988,49.312211990356445]]],[[[137.77997016906738,54.36638832092285],[137.70831489562988,54.368600845336914],[137.91388130187988,54.50777626037598],[137.77997016906738,54.36638832092285]]],[[[137.632173538208,54.41304969787598],[137.54886054992676,54.5049991607666],[137.61856269836426,54.56527137756348],[137.632173538208,54.41304969787598]]],[[[19.697778701782227,54.479440689086914],[19.65110969543457,54.455827713012695],[19.627260208129883,54.463274002075195],[19.898202896118164,54.625959396362305],[19.697778701782227,54.479440689086914]]],[[[167.855806350708,54.68138313293457],[168.1169147491455,54.50777626037598],[167.43298530578613,54.86307716369629],[167.855806350708,54.68138313293457]]],[[[137.18829536437988,55.10222053527832],[137.04608345031738,54.917497634887695],[136.66726875305176,54.90506172180176],[137.18829536437988,55.10222053527832]]],[[[137.99133491516113,54.88555335998535],[137.70718574523926,54.61832618713379],[137.22131538391113,54.77372169494629],[137.57831001281738,55.1905460357666],[138.20413398742676,55.04388618469238],[137.99133491516113,54.88555335998535]]],[[[21.431386947631836,55.25193977355957],[22.842496871948242,54.89694404602051],[22.785886764526367,54.363840103149414],[19.797006607055664,54.437551498413086],[20.405000686645508,54.67916297912598],[19.872713088989258,54.64055061340332],[19.96944236755371,54.95749855041504],[20.942834854125977,55.28720283508301],[20.98481559753418,55.27655220031738],[20.538053512573242,54.94943428039551],[21.222497940063477,54.93194007873535],[21.26393699645996,55.24898719787598],[21.431386947631836,55.25193977355957]]],[[[166.1191120147705,55.3286075592041],[166.66302680969238,54.67416572570801],[165.83801460266113,55.26444435119629],[166.1191120147705,55.3286075592041]]],[[[164.65692329406738,59.08443641662598],[163.38553047180176,58.559404373168945],[163.69940376281738,59.01444435119629],[164.65692329406738,59.08443641662598]]],[[[150.59051704406738,59.01971626281738],[150.4545612335205,59.01780128479004],[150.74383735656738,59.11194038391113],[150.59051704406738,59.01971626281738]]],[[[149.10467720031738,59.18776893615723],[148.941011428833,59.141672134399414],[149.00525093078613,59.21110725402832],[149.10467720031738,59.18776893615723]]],[[[155.55581855773926,59.32193946838379],[155.47830390930176,59.317216873168945],[155.55581855773926,59.35916328430176],[155.55581855773926,59.32193946838379]]],[[[28.693052291870117,60.267770767211914],[28.551111221313477,60.349435806274414],[28.714998245239258,60.31138038635254],[28.693052291870117,60.267770767211914]]],[[[35.991106033325195,64.3258228302002],[35.854440689086914,64.40582466125488],[36.047494888305664,64.35554695129395],[35.991106033325195,64.3258228302002]]],[[[-172.54446411132812,64.61331367492676],[-172.75808715820312,64.66079902648926],[-172.48831176757812,64.63360786437988],[-172.54446411132812,64.61331367492676]]],[[[40.412492752075195,64.65359687805176],[40.47137641906738,64.56608772277832],[39.97471046447754,64.6827564239502],[40.412492752075195,64.65359687805176]]],[[[-172.590576171875,64.70331001281738],[-172.53115844726562,64.8430347442627],[-172.17111206054688,64.79525947570801],[-172.590576171875,64.70331001281738]]],[[[35.79083442687988,64.97331428527832],[35.52469825744629,65.15887641906738],[35.83443641662598,65.16832160949707],[35.79083442687988,64.97331428527832]]],[[[36.061662673950195,65.19026374816895],[36.30082893371582,65.20109748840332],[35.94332313537598,65.18193244934082],[36.061662673950195,65.19026374816895]]],[[[-169.0533447265625,65.74914741516113],[-169.07501220703125,65.81552314758301],[-168.98974609375,65.8088550567627],[-169.0533447265625,65.74914741516113]]],[[[69.33499336242676,66.6544361114502],[69.24331855773926,66.69331550598145],[69.33333015441895,66.71887397766113],[69.33499336242676,66.6544361114502]]],[[[70.03387641906738,66.72387886047363],[69.78915596008301,66.78027534484863],[69.95359992980957,66.76111030578613],[70.03387641906738,66.72387886047363]]],[[[42.7066593170166,66.68637275695801],[42.43249702453613,66.75860786437988],[42.62276649475098,66.78221321105957],[42.7066593170166,66.68637275695801]]],[[[69.2522144317627,66.78997993469238],[70.05525398254395,66.70332527160645],[70.10443305969238,66.53109931945801],[69.84109687805176,66.47831916809082],[69.41943550109863,66.76971626281738],[69.12664985656738,66.7885913848877],[69.2522144317627,66.78997993469238]]],[[[54.21193885803223,68.24971199035645],[54.28305244445801,68.33665657043457],[54.33693885803223,68.30386543273926],[54.21193885803223,68.24971199035645]]],[[[53.949716567993164,68.29275703430176],[53.86888313293457,68.34610176086426],[54.01333045959473,68.3621997833252],[53.949716567993164,68.29275703430176]]],[[[50.814157485961914,68.3722095489502],[51.16388130187988,68.4952564239502],[51.4566593170166,68.47693061828613],[50.814157485961914,68.3722095489502]]],[[[57.92083168029785,68.80331611633301],[57.86471748352051,68.76193428039551],[57.19999885559082,68.71887397766113],[57.92083168029785,68.80331611633301]]],[[[67.38304328918457,68.7774829864502],[67.14888191223145,68.82193183898926],[67.33859443664551,68.81915473937988],[67.38304328918457,68.7774829864502]]],[[[55.47231483459473,68.90904426574707],[55.224565505981445,68.90986824035645],[55.50842475891113,68.91211128234863],[55.47231483459473,68.90904426574707]]],[[[-179.62612915039062,68.90635871887207],[-175.463623046875,67.70747566223145],[-175.19110107421875,67.51080513000488],[-175.38031005859375,67.3449878692627],[-174.83029174804688,67.38273811340332],[-174.7427978515625,66.77304267883301],[-175.00033569335938,66.67109870910645],[-174.46194458007812,66.30107307434082],[-173.7586669921875,66.44803047180176],[-174.30307006835938,66.57776069641113],[-173.995849609375,66.69134712219238],[-174.12527465820312,66.98913764953613],[-174.65252685546875,67.06360054016113],[-173.66696166992188,67.13165473937988],[-173.17669677734375,67.06331062316895],[-173.35250854492188,66.83886909484863],[-171.72610473632812,66.95524787902832],[-170.64447021484375,66.2371997833252],[-169.69110107421875,66.07249641418457],[-170.58779907226562,65.86360359191895],[-170.63558959960938,65.61053657531738],[-171.544189453125,65.83360481262207],[-171.11557006835938,65.47636604309082],[-172.80029296875,65.6816577911377],[-172.1905517578125,65.44662666320801],[-172.693359375,65.23275947570801],[-172.12612915039062,65.08636665344238],[-173.20086669921875,64.78608894348145],[-172.3558349609375,64.45831489562988],[-173.19140625,64.25442695617676],[-173.413330078125,64.61998176574707],[-173.68167114257812,64.34721565246582],[-175.44888305664062,64.78442573547363],[-176.07806396484375,65.47026252746582],[-178.56307983398438,65.51638984680176],[-178.46054077148438,65.73637580871582],[-178.90945434570312,65.99386787414551],[-178.51699829101562,66.40277290344238],[-179.69558715820312,66.18303108215332],[-179.79837036132812,65.87051582336426],[-179.31500244140625,65.53608894348145],[-180,65.06891059875488],[-180,68.98010444641113],[-179.62612915039062,68.90635871887207]]],[[[54.65416145324707,68.9558277130127],[54.56777381896973,68.9558277130127],[54.69415473937988,68.99136543273926],[54.65416145324707,68.9558277130127]]],[[[66.17192268371582,69.08777046203613],[66.53776741027832,68.94359016418457],[65.95193672180176,69.09387397766113],[66.17192268371582,69.08777046203613]]],[[[59.23943519592285,69.17581367492676],[58.76055335998535,69.33360481262207],[59.19388008117676,69.23387336730957],[59.23943519592285,69.17581367492676]]],[[[34.40471076965332,69.33943367004395],[33.97304725646973,69.36609077453613],[34.2133731842041,69.4027271270752],[34.40471076965332,69.33943367004395]]],[[[67.13109016418457,69.36137580871582],[66.93803596496582,69.44359016418457],[67.21054267883301,69.42581367492676],[67.13109016418457,69.36137580871582]]],[[[50.30526924133301,69.16192817687988],[48.91276741027832,68.7361011505127],[48.21610450744629,68.89499092102051],[48.31276893615723,69.27916145324707],[48.94332313537598,69.50694465637207],[50.30526924133301,69.16192817687988]]],[[[161.44330024719238,68.88998603820801],[161.45800971984863,68.99553108215332],[161.13443183898926,69.08970832824707],[161.09634590148926,69.47053718566895],[161.37774848937988,69.53221321105957],[161.3888874053955,69.45915412902832],[161.28933906555176,69.41586494445801],[161.36136054992676,69.35859870910645],[161.31997871398926,69.24109077453613],[161.38611030578613,69.10247993469238],[161.51526069641113,68.9871997833252],[161.50915718078613,68.9155445098877],[161.44330024719238,68.88998603820801]]],[[[67.25248908996582,69.44470405578613],[67.02110481262207,69.4861011505127],[67.33831977844238,69.5888843536377],[67.25248908996582,69.44470405578613]]],[[[161.43774604797363,69.40803718566895],[161.3949909210205,69.59082221984863],[161.62219429016113,69.58859443664551],[161.43774604797363,69.40803718566895]]],[[[170.1510944366455,69.7341480255127],[169.984956741333,69.74803352355957],[170.20331001281738,69.78831672668457],[170.1510944366455,69.7341480255127]]],[[[169.4474811553955,69.80887031555176],[168.86828804016113,69.5677661895752],[167.7519245147705,69.82748603820801],[169.4474811553955,69.80887031555176]]],[[[83.0969409942627,70.12498664855957],[82.76860237121582,70.2088794708252],[82.86387825012207,70.25166511535645],[83.08276557922363,70.21859931945801],[83.11360359191895,70.19331550598145],[83.0969409942627,70.12498664855957]]],[[[59.46110725402832,70.27665901184082],[60.54610633850098,69.79915046691895],[59.60166358947754,69.71249580383301],[58.40860176086426,70.25027656555176],[59.03305244445801,70.47886848449707],[59.46110725402832,70.27665901184082]]],[[[83.55026435852051,70.46360969543457],[83.61276435852051,70.4377613067627],[83.53360176086426,70.37719917297363],[83.37970161437988,70.36499214172363],[83.4124927520752,70.44026374816895],[83.62442207336426,70.52415657043457],[83.55026435852051,70.46360969543457]]],[[[57.20471382141113,70.50888252258301],[56.965829849243164,70.51748847961426],[56.84166145324707,70.59915351867676],[57.20471382141113,70.50888252258301]]],[[[162.38189888000488,70.67915534973145],[162.484956741333,70.65109443664551],[162.23663520812988,70.65915107727051],[162.38189888000488,70.67915534973145]]],[[[83.3722095489502,70.68609809875488],[83.0697193145752,70.39776802062988],[83.21415901184082,70.80720710754395],[83.3722095489502,70.68609809875488]]],[[[161.69384956359863,70.75027656555176],[161.46328926086426,70.80359077453613],[161.65774726867676,70.80859565734863],[161.69384956359863,70.75027656555176]]],[[[160.6191120147705,70.81469917297363],[160.40802192687988,70.91914558410645],[160.71978950500488,70.81851387023926],[160.6191120147705,70.81469917297363]]],[[[53.59527015686035,71.11026191711426],[53.43249702453613,71.13693428039551],[53.542497634887695,71.18387031555176],[53.59527015686035,71.11026191711426]]],[[[53.360551834106445,71.29220771789551],[53.20416450500488,71.31109809875488],[53.129159927368164,71.35859870910645],[53.360551834106445,71.29220771789551]]],[[[52.85860633850098,71.3783130645752],[53.20749855041504,71.25110054016113],[53.14193916320801,70.97831916809082],[52.20888710021973,71.30554389953613],[52.85860633850098,71.3783130645752]]],[[[-175.620849609375,71.37776374816895],[-175.92361450195312,71.42581367492676],[-175.76419067382812,71.42440986633301],[-175.620849609375,71.37776374816895]]],[[[137.96109199523926,71.50305366516113],[137.67691230773926,71.41165351867676],[136.99133491516113,71.51555061340332],[137.96109199523926,71.50305366516113]]],[[[180.00000190734863,71.53586006164551],[180.00000190734863,70.9972095489502],[178.79101753234863,70.7964038848877],[178.61773872375488,71.0355396270752],[180.00000190734863,71.53586006164551]]],[[[-178.568603515625,71.56414985656738],[-177.439453125,71.22693061828613],[-180,70.9972095489502],[-180,71.53584480285645],[-178.568603515625,71.56414985656738]]],[[[138.5160846710205,71.8560962677002],[138.27386665344238,71.85998725891113],[138.36245918273926,71.88554573059082],[138.5160846710205,71.8560962677002]]],[[[128.1430377960205,72.5788745880127],[129.56109809875488,72.22526741027832],[128.76361274719238,72.07415962219238],[127.54971504211426,72.43332099914551],[126.65027046203613,72.43609809875488],[128.1430377960205,72.5788745880127]]],[[[77.76249885559082,72.29525947570801],[76.85470771789551,72.32998847961426],[77.6202564239502,72.63054084777832],[78.39305305480957,72.4891529083252],[77.76249885559082,72.29525947570801]]],[[[128.83886909484863,72.57666206359863],[128.10052680969238,72.63195991516113],[128.97220039367676,72.59082221984863],[128.83886909484863,72.57666206359863]]],[[[72.99304389953613,72.60247993469238],[72.84054756164551,72.67498970031738],[72.98498725891113,72.67608833312988],[72.99304389953613,72.60247993469238]]],[[[129.355806350708,72.7027759552002],[127.31414985656738,72.65332221984863],[128.30191230773926,72.78776741027832],[129.355806350708,72.7027759552002]]],[[[129.23025703430176,72.83194160461426],[129.29803657531738,72.80026435852051],[128.29052925109863,72.86609077453613],[129.23025703430176,72.83194160461426]]],[[[122.95583534240723,72.86331367492676],[123.60582160949707,72.77777290344238],[122.30246925354004,72.93748664855957],[122.95583534240723,72.86331367492676]]],[[[74.86276435852051,73.08970832824707],[74.6544361114502,72.85582160949707],[74.08970832824707,73.02054023742676],[74.86276435852051,73.08970832824707]]],[[[79.57083320617676,72.73027229309082],[78.57859992980957,72.84553718566895],[79.19470405578613,73.09582710266113],[79.57083320617676,72.73027229309082]]],[[[120.2138843536377,73.04248237609863],[119.62970161437988,73.11470222473145],[120.0869312286377,73.1524829864502],[120.2138843536377,73.04248237609863]]],[[[76.4527759552002,73.19053840637207],[76.73748970031738,73.15359687805176],[76.12275886535645,73.20721626281738],[76.4527759552002,73.19053840637207]]],[[[71.34109687805176,73.32499885559082],[71.13998603820801,73.28970527648926],[71.26277351379395,73.41415596008301],[71.34109687805176,73.32499885559082]]],[[[55.33166694641113,73.32998847961426],[56.58860206604004,73.13749885559082],[55.61527442932129,72.96138191223145],[56.262216567993164,72.96081733703613],[55.4294376373291,72.78415107727051],[55.94554328918457,72.66665840148926],[55.118051528930664,72.44803047180176],[55.57583045959473,72.1958179473877],[55.221017837524414,71.92561531066895],[56.228044509887695,71.19413948059082],[57.63999366760254,70.72638130187988],[55.18631935119629,70.55206489562988],[53.46360969543457,70.81387519836426],[53.74332618713379,70.94304084777832],[53.50833320617676,71.08610725402832],[54.24499702453613,71.12664985656738],[53.453325271606445,71.26111030578613],[53.9294376373291,71.4669361114502],[53.480546951293945,71.29165840148926],[53.3558292388916,71.56721687316895],[51.79722023010254,71.4749927520752],[51.41610145568848,71.73776435852051],[51.57444190979004,72.07083320617676],[52.39721870422363,72.07609748840332],[53.097490310668945,72.59471321105957],[52.74888038635254,72.63304328918457],[53.219438552856445,72.64721870422363],[52.37638282775879,72.72470283508301],[53.38193702697754,72.88109016418457],[53.15332221984863,73.15582466125488],[54.914438247680664,73.42221260070801],[55.33166694641113,73.32998847961426]]],[[[71.04693794250488,73.50000190734863],[71.26500129699707,73.43637275695801],[70.99914741516113,73.28888130187988],[71.6766529083252,73.17692756652832],[69.86638069152832,73.03276252746582],[69.97442817687988,73.40721321105957],[71.04693794250488,73.50000190734863]]],[[[127.29637336730957,73.51721382141113],[129.11828804016113,73.09471321105957],[126.58943367004395,72.53581428527832],[126.52693367004395,72.40054512023926],[126.30246925354004,72.50110054016113],[126.44999885559082,72.7855396270752],[126.3338794708252,72.89721870422363],[126.77192878723145,73.07638740539551],[126.6594181060791,73.41693305969238],[127.29637336730957,73.51721382141113]]],[[[76.3902759552002,73.52083015441895],[76.76609992980957,73.43387031555176],[76.07415962219238,73.5213794708252],[76.3902759552002,73.52083015441895]]],[[[128.05554389953613,73.4830493927002],[127.38804817199707,73.52026557922363],[127.70776557922363,73.5355396270752],[128.05554389953613,73.4830493927002]]],[[[80.36053657531738,73.50027656555176],[80.05664253234863,73.55581855773926],[80.40359687805176,73.54609870910645],[80.36053657531738,73.50027656555176]]],[[[76.0777759552002,73.55803108215332],[75.30632209777832,73.41833686828613],[75.62109565734863,73.54998970031738],[76.0777759552002,73.55803108215332]]],[[[124.60443305969238,73.72859382629395],[125.56025886535645,73.40304756164551],[126.30887031555176,73.54582405090332],[126.15664863586426,73.37442207336426],[126.71499824523926,73.08442878723145],[126.27805519104004,72.87997627258301],[126.38582038879395,72.79275703430176],[126.24443244934082,72.51887702941895],[126.34832954406738,72.37997627258301],[126.12552833557129,72.30053901672363],[124.76500129699707,72.67082405090332],[122.42804145812988,72.98193550109863],[123.65886878967285,73.16804695129395],[123.21914863586426,73.40471076965332],[123.37692451477051,73.6624927520752],[124.60443305969238,73.72859382629395]]],[[[142.15497016906738,73.88998603820801],[143.43191719055176,73.52249336242676],[143.5058307647705,73.23027229309082],[139.65359687805176,73.40220832824707],[142.15497016906738,73.88998603820801]]],[[[124.54525947570801,73.85331916809082],[124.28777503967285,73.88443183898926],[124.65999031066895,73.89804267883301],[124.54525947570801,73.85331916809082]]],[[[86.4871997833252,73.90887641906738],[86.22331428527832,73.96638679504395],[86.30137825012207,73.97720527648926],[86.4871997833252,73.90887641906738]]],[[[84.41914558410645,74.03193855285645],[84.38943672180176,73.95555305480957],[83.87942695617676,74.00665473937988],[84.41914558410645,74.03193855285645]]],[[[82.60971260070801,74.0486011505127],[82.31469917297363,74.11442756652832],[82.73637580871582,74.09887886047363],[82.60971260070801,74.0486011505127]]],[[[83.61581611633301,74.09305000305176],[82.8158130645752,74.09109687805176],[83.2027759552002,74.14972114562988],[83.61581611633301,74.09305000305176]]],[[[85.53442573547363,74.12747383117676],[85.40887641906738,74.18969917297363],[85.73278999328613,74.16862678527832],[85.53442573547363,74.12747383117676]]],[[[135.649995803833,74.20359992980957],[136.27249336242676,73.9358081817627],[135.35357856750488,74.25277900695801],[135.649995803833,74.20359992980957]]],[[[141.02054023742676,73.99275398254395],[140.07275581359863,74.09776496887207],[140.87439155578613,74.27110481262207],[141.02054023742676,73.99275398254395]]],[[[116.06888008117676,74.28692817687988],[115.88582038879395,74.32026863098145],[116.06749153137207,74.36914253234863],[116.06888008117676,74.28692817687988]]],[[[59.033884048461914,74.34276008605957],[58.93499183654785,74.35832405090332],[59.08111000061035,74.40915107727051],[59.033884048461914,74.34276008605957]]],[[[84.94525337219238,74.47776985168457],[84.74443244934082,74.39526557922363],[84.37303352355957,74.44859504699707],[84.94525337219238,74.47776985168457]]],[[[112.71331977844238,74.49887275695801],[113.43332099914551,74.39387702941895],[112.78777503967285,74.0919361114502],[111.45555305480957,74.3166675567627],[112.71331977844238,74.49887275695801]]],[[[85.43942451477051,74.45359992980957],[85.14499092102051,74.54026985168457],[85.65332221984863,74.5294361114502],[85.43942451477051,74.45359992980957]]],[[[86.21249580383301,74.5183277130127],[85.65942573547363,74.47053718566895],[85.82361030578613,74.57026863098145],[86.21249580383301,74.5183277130127]]],[[[79.38611030578613,74.6172046661377],[79.6121997833252,74.5949878692627],[79.14915657043457,74.6030445098877],[79.38611030578613,74.6172046661377]]],[[[85.65555000305176,74.79165840148926],[85.70027351379395,74.72165107727051],[85.09553718566895,74.74775886535645],[85.65555000305176,74.79165840148926]]],[[[87.04971504211426,74.97915840148926],[86.83526802062988,74.82638740539551],[86.21110725402832,74.89860725402832],[87.04971504211426,74.97915840148926]]],[[[82.15193367004395,75.11554145812988],[82.02720832824707,75.1283130645752],[82.10748481750488,75.15832710266113],[82.15193367004395,75.11554145812988]]],[[[82.10582160949707,75.41220283508301],[82.29193305969238,75.33055305480957],[82.01193428039551,75.17221260070801],[81.49304389953613,75.35832405090332],[82.10582160949707,75.41220283508301]]],[[[147.01831245422363,75.33471870422363],[150.95303535461426,75.13943672180176],[148.70440864562988,74.75999641418457],[146.07025337219238,75.22665596008301],[146.41497993469238,75.58610725402832],[147.01831245422363,75.33471870422363]]],[[[140.745943069458,75.65185737609863],[140.51944160461426,75.7058277130127],[140.7699909210205,75.67720222473145],[140.745943069458,75.65185737609863]]],[[[135.65387153625488,75.36499214172363],[135.44412422180176,75.4408130645752],[135.70800971984863,75.8499927520752],[136.17776679992676,75.61914253234863],[135.65387153625488,75.36499214172363]]],[[[59.19249153137207,75.88804817199707],[58.993608474731445,75.89109992980957],[59.278329849243164,75.90832710266113],[59.19249153137207,75.88804817199707]]],[[[81.60026741027832,75.93525886535645],[82.25694465637207,75.86943244934082],[81.55081367492676,75.9236011505127],[81.60026741027832,75.93525886535645]]],[[[82.9730396270752,75.96914863586426],[83.30247688293457,75.94136238098145],[82.2572193145752,75.95860481262207],[82.9730396270752,75.96914863586426]]],[[[58.754716873168945,75.89694404602051],[58.694711685180664,75.8994312286377],[59.26693916320801,75.96943855285645],[58.754716873168945,75.89694404602051]]],[[[96.76693916320801,75.97526741027832],[96.6958179473877,76.01138496398926],[97.33728218078613,76.10208320617676],[96.76693916320801,75.97526741027832]]],[[[140.91079902648926,76.06694221496582],[140.84720039367676,76.09553718566895],[141.07940864562988,76.10942268371582],[140.91079902648926,76.06694221496582]]],[[[60.472490310668945,76.15999031066895],[59.866106033325195,76.10415840148926],[60.04110908508301,76.15693855285645],[60.472490310668945,76.15999031066895]]],[[[139.19079780578613,76.07222175598145],[140.47912788391113,75.63611030578613],[141.06079292297363,75.64526557922363],[140.9718952178955,76.03915596008301],[141.61969184875488,76.01249885559082],[141.35663032531738,76.18054389953613],[145.39471626281738,75.51748847961426],[143.94970893859863,75.02693367004395],[142.90359687805176,75.13388252258301],[142.50604438781738,75.45372200012207],[143.04052925109863,75.66971015930176],[142.4474811553955,75.71110725402832],[142.1552448272705,75.37553596496582],[142.61245918273926,75.09971809387207],[143.70691108703613,74.93858528137207],[139.6469440460205,74.97915840148926],[139.09607124328613,74.64721870422363],[136.86136054992676,75.34915351867676],[137.40497016906738,75.35220527648926],[136.95855903625488,75.60421943664551],[137.74469184875488,75.74832344055176],[137.44998359680176,75.95471382141113],[139.19079780578613,76.07222175598145]]],[[[152.74133491516113,76.10775947570801],[152.45523262023926,76.15693855285645],[152.75665473937988,76.2119312286377],[152.74133491516113,76.10775947570801]]],[[[95.19941902160645,76.15776252746582],[95.00277900695801,76.17248725891113],[95.08450508117676,76.22079658508301],[95.19941902160645,76.15776252746582]]],[[[94.99748420715332,76.26915168762207],[94.84027290344238,76.17943000793457],[94.40803718566895,76.20498847961426],[94.99748420715332,76.26915168762207]]],[[[96.36638069152832,76.30108833312988],[96.6494312286377,76.24887275695801],[95.26361274719238,76.21304512023926],[96.36638069152832,76.30108833312988]]],[[[96.75694465637207,76.3227710723877],[96.66470527648926,76.29248237609863],[96.38304328918457,76.33194160461426],[96.75694465637207,76.3227710723877]]],[[[96.99748420715332,76.27720832824707],[96.71110725402832,76.21360969543457],[96.83442878723145,76.3469409942627],[96.99748420715332,76.27720832824707]]],[[[113.43997383117676,76.36053657531738],[113.11876106262207,76.36999702453613],[113.25888252258301,76.43637275695801],[113.43997383117676,76.36053657531738]]],[[[94.35721015930176,76.57443428039551],[93.86998176574707,76.58499336242676],[93.95181465148926,76.60981941223145],[94.35721015930176,76.57443428039551]]],[[[112.52192878723145,76.62248420715332],[112.7138843536377,76.51054573059082],[111.95665168762207,76.59860420227051],[112.52192878723145,76.62248420715332]]],[[[95.59887886047363,76.66998481750488],[95.41276741027832,76.69970893859863],[95.83194160461426,76.68553352355957],[95.59887886047363,76.66998481750488]]],[[[95.13304328918457,76.7027759552002],[95.32693672180176,76.66110420227051],[94.81303596496582,76.64888191223145],[95.13304328918457,76.7027759552002]]],[[[96.46408271789551,76.70601081848145],[96.2422046661377,76.60971260070801],[95.88916206359863,76.62137031555176],[96.46408271789551,76.70601081848145]]],[[[97.54637336730957,76.58221626281738],[97.31637763977051,76.60664558410645],[97.44053840637207,76.71499824523926],[97.54637336730957,76.58221626281738]]],[[[149.3144245147705,76.75360298156738],[149.16885566711426,76.65054512023926],[148.39221382141113,76.64360237121582],[149.3144245147705,76.75360298156738]]],[[[97.86998176574707,76.77026557922363],[97.72943305969238,76.81833076477051],[97.91943550109863,76.83831977844238],[97.86998176574707,76.77026557922363]]],[[[68.26609992980957,76.95860481262207],[68.93136787414551,76.78276252746582],[68.8611011505127,76.54193305969238],[61.28777503967285,75.32609748840332],[59.925554275512695,74.99914741516113],[60.68027687072754,74.93332099914551],[60.31860542297363,74.76054573059082],[59.50999641418457,74.79498481750488],[59.773324966430664,74.59109687805176],[59.169443130493164,74.71971321105957],[59.14721870422363,74.43858528137207],[58.18335151672363,74.57353401184082],[58.74276924133301,74.26693916320801],[58.13582801818848,73.98526191711426],[57.25750160217285,74.07609748840332],[57.91166114807129,73.9155445098877],[57.71527290344238,73.71304512023926],[56.55582618713379,73.88220405578613],[57.61361122131348,73.66220283508301],[56.72304725646973,73.6736011505127],[57.25332832336426,73.48776435852051],[56.75889015197754,73.24693489074707],[55.90777015686035,73.44026374816895],[55.977487564086914,73.31749153137207],[54.97165870666504,73.44220161437988],[54.22054481506348,73.32304573059082],[55.176103591918945,73.70610237121582],[53.63054847717285,73.7552661895752],[55.86638832092285,74.10247993469238],[55.07332801818848,74.26443672180176],[56.29055213928223,74.49136543273926],[55.571664810180664,74.65971565246582],[56.98458290100098,74.6871509552002],[55.829721450805664,74.79609870910645],[56.678606033325195,74.95221138000488],[55.79777717590332,75.1463794708252],[57.73721504211426,75.32304573059082],[57.50332832336426,75.49247932434082],[58.194711685180664,75.58831977844238],[58.00139045715332,75.67415046691895],[60.75000190734863,76.00610542297363],[61.06638526916504,76.27388191223145],[64.10971260070801,76.31137275695801],[68.26609992980957,76.95860481262207]]],[[[88.66470527648926,77.09637641906738],[88.95721626281738,77.12581062316895],[88.78305244445801,77.00499153137207],[88.66470527648926,77.09637641906738]]],[[[96.57554817199707,77.1302661895752],[96.16609382629395,76.9891529083252],[95.22915840148926,76.99331855773926],[96.57554817199707,77.1302661895752]]],[[[156.61773872375488,77.10386848449707],[156.43414497375488,77.1352710723877],[156.73217964172363,77.12581062316895],[156.61773872375488,77.10386848449707]]],[[[90.18026924133301,77.11581611633301],[89.96721076965332,77.11303901672363],[89.82971382141113,77.14082527160645],[90.18026924133301,77.11581611633301]]],[[[105.88472175598145,77.26138496398926],[105.78055000305176,77.27415657043457],[106.00776863098145,77.2824878692627],[105.88472175598145,77.26138496398926]]],[[[89.6816577911377,77.28442573547363],[89.48526191711426,77.17997932434082],[89.13582038879395,77.20498847961426],[89.6816577911377,77.28442573547363]]],[[[106.4024829864502,77.30359077453613],[106.33167457580566,77.31805610656738],[106.45833015441895,77.31526374816895],[106.4024829864502,77.30359077453613]]],[[[107.56192207336426,77.25499153137207],[107.20027351379395,77.23387336730957],[107.66665840148926,77.3308277130127],[107.56192207336426,77.25499153137207]]],[[[106.64665412902832,77.37608528137207],[106.50417518615723,77.38998603820801],[106.90081977844238,77.45915412902832],[106.64665412902832,77.37608528137207]]],[[[82.56025886535645,77.4619312286377],[82.1202564239502,77.50638008117676],[82.4438648223877,77.5102710723877],[82.56025886535645,77.4619312286377]]],[[[91.96638679504395,77.5999927520752],[91.73970222473145,77.64721870422363],[92.03776741027832,77.63081550598145],[91.96638679504395,77.5999927520752]]],[[[104.26748847961426,77.67581367492676],[106.29193305969238,77.36276435852051],[104.1172046661377,77.09082221984863],[107.50360298156738,76.92221260070801],[106.40109443664551,76.50972175598145],[111.10386848449707,76.7552661895752],[112.74275398254395,76.32832527160645],[112.56667518615723,76.0405445098877],[113.24275398254395,76.26220893859863],[113.89248847961426,75.8499927520752],[113.50943183898926,75.5324878692627],[112.33719825744629,75.84665107727051],[113.71748542785645,75.40860176086426],[108.18969917297363,73.67025947570801],[107.14248847961426,73.61470222473145],[105.2119312286377,72.76471138000488],[106.3338794708252,73.18719673156738],[110.9143238067627,73.69668769836426],[109.52916145324707,73.77026557922363],[110.20041084289551,74.02444648742676],[111.54332160949707,74.04498481750488],[111.20139503479004,73.96748542785645],[112.24832344055176,73.70694160461426],[112.88777351379395,73.96499824523926],[113.49942207336426,73.33415412902832],[113.48636817932129,72.95833015441895],[113.10443305969238,72.85359382629395],[113.17859077453613,72.72360420227051],[114.04471015930176,72.59721565246582],[113.15109443664551,72.83943367004395],[113.53082466125488,72.96026802062988],[113.54694557189941,73.2422046661377],[114.03386878967285,73.3419361114502],[113.47527503967285,73.5041675567627],[118.63443183898926,73.57165718078613],[118.99387550354004,73.4891529083252],[118.39221382141113,73.23581123352051],[119.81775856018066,72.9358081817627],[121.86580848693848,72.96805000305176],[124.72971534729004,72.62637519836426],[126.11775398254395,72.26693916320801],[126.37248420715332,72.35331916809082],[127.1294116973877,71.8510913848877],[127.22054481506348,71.39248847961426],[127.32608222961426,71.89804267883301],[126.71914863586426,72.38888740539551],[127.65860176086426,72.34749031066895],[128.7116413116455,71.77054023742676],[129.17993354797363,71.80026435852051],[129.0724811553955,72.00193977355957],[129.53994941711426,71.72221565246582],[128.84744453430176,71.60138130187988],[131.13025093078613,70.7310962677002],[132.18469429016113,71.21470832824707],[131.946626663208,71.28915596008301],[132.72802925109863,71.94192695617676],[133.67914009094238,71.43332099914551],[135.8649616241455,71.63971138000488],[137.85412788391113,71.11137580871582],[138.22134590148926,71.26220893859863],[137.82412910461426,71.38388252258301],[138.06607246398926,71.57361030578613],[139.932466506958,71.48498725891113],[139.3366413116455,71.94552803039551],[140.19830513000488,72.20332527160645],[139.08523750305176,72.23332405090332],[141.0241413116455,72.58581733703613],[140.74884223937988,72.88943672180176],[146.84802436828613,72.34749031066895],[144.13858222961426,72.27083015441895],[144.391939163208,72.17192268371582],[145.08636665344238,72.25915718078613],[146.930269241333,72.30941963195801],[145.96466255187988,71.8469409942627],[145.98855781555176,72.02554512023926],[146.33996772766113,72.12803840637207],[145.98550605773926,72.06137275695801],[145.89831733703613,72.20610237121582],[145.7116413116455,72.2522144317627],[145.60830879211426,72.24359321594238],[145.749116897583,72.20721626281738],[145.6149616241455,72.08055305480957],[145.80240058898926,71.92553901672363],[144.95691108703613,71.95833015441895],[145.21634101867676,71.82721138000488],[144.9133014678955,71.6958179473877],[145.31884956359863,71.65803718566895],[146.08828926086426,71.79387092590332],[147.13971138000488,72.31721687316895],[149.18524360656738,72.22249031066895],[150.07525825500488,71.88388252258301],[148.823579788208,71.66998481750488],[150.66775703430176,71.48942756652832],[150.02359199523926,71.20749092102051],[151.45331001281738,71.34332466125488],[152.1410846710205,70.99748420715332],[151.66360664367676,70.98082160949707],[152.5383014678955,70.83777046203613],[155.93719673156738,71.09443855285645],[159.05386543273926,70.86914253234863],[160.03802680969238,70.40555000305176],[159.72967720031738,69.83471870422363],[160.99524116516113,69.58831977844238],[160.96386909484863,69.10359382629395],[161.41165351867676,68.97970771789551],[161.06607246398926,68.56331062316895],[160.84607124328613,68.52276802062988],[161.12774848937988,68.55525398254395],[161.319429397583,68.79248237609863],[161.579683303833,68.91499519348145],[161.44607734680176,69.38554573059082],[164.01443672180176,69.76748847961426],[166.86050605773926,69.49054145812988],[167.78692817687988,69.77609443664551],[168.28332710266113,69.24165534973145],[170.61194038391113,68.75633430480957],[171.03192329406738,69.04220771789551],[170.60913276672363,69.58027839660645],[170.12384223937988,69.60998725891113],[170.56720161437988,69.77804756164551],[170.4718952178955,70.13415718078613],[173.19192695617676,69.77971076965332],[176.111909866333,69.89055061340332],[180.00000190734863,68.98010444641113],[180.00000190734863,65.06891059875488],[178.52221870422363,64.58804512023926],[178.75555610656738,64.68220710754395],[177.60940742492676,64.71805000305176],[176.89972114562988,65.08360481262207],[176.30276679992676,65.04998970031738],[177.303316116333,64.8277759552002],[174.43664741516113,64.68831062316895],[177.48608589172363,64.76138496398926],[177.63189888000488,64.31888008117676],[178.36746406555176,64.27388191223145],[178.75747871398926,63.63999366760254],[178.26165962219238,63.5624942779541],[178.68802070617676,63.3830509185791],[178.77221870422363,63.59499549865723],[179.40860176086426,63.142770767211914],[179.23663520812988,62.994157791137695],[179.56109809875488,62.62137794494629],[179.061372756958,62.28472328186035],[176.97552680969238,62.865549087524414],[177.26553535461426,62.574716567993164],[172.710786819458,61.42999458312988],[172.95608711242676,61.30277442932129],[170.641939163208,60.417497634887695],[170.24884223937988,59.909433364868164],[169.21023750305176,60.62276649475098],[167.0502643585205,60.32388496398926],[166.13775825500488,59.81527137756348],[166.34857368469238,60.48638343811035],[164.99719429016113,60.12943458557129],[165.182466506958,59.98110389709473],[164.83218574523926,59.78110694885254],[164.46856880187988,60.11138343811035],[164.15555000305176,59.8527774810791],[163.63553047180176,60.045549392700195],[163.17303657531738,59.559160232543945],[163.1935749053955,59.053606033325195],[162.87634468078613,59.1280460357666],[163.044771194458,59.01031684875488],[161.93887519836426,58.07444190979004],[162.34607124328613,57.68471717834473],[162.57107734680176,57.95110511779785],[163.2135944366455,57.83610725402832],[162.736909866333,57.35777473449707],[162.791353225708,56.79110908508301],[163.21386909484863,56.740549087524414],[163.35467720031738,56.1986026763916],[162.64526557922363,56.19193458557129],[163.08914375305176,56.53416633605957],[162.39358711242676,56.39999580383301],[162.57220649719238,56.26721382141113],[162.03692817687988,56.061662673950195],[161.71246528625488,55.4969425201416],[162.11218452453613,54.76194190979004],[160.0058307647705,54.13916206359863],[159.79165840148926,53.514719009399414],[160.05523872375488,53.09360694885254],[158.43054389953613,53.02193641662598],[158.64471626281738,52.89471626281738],[158.27581977844238,51.936655044555664],[156.668306350708,50.881662368774414],[155.54413032531738,55.303606033325195],[155.94885444641113,56.66610145568848],[156.9777545928955,57.414438247680664],[156.74884223937988,57.72832679748535],[158.23330879211426,58.01944160461426],[161.91443061828613,60.42276954650879],[163.65832710266113,60.87193489074707],[164.12774848937988,62.28277015686035],[165.64248847961426,62.452775955200195],[164.35940742492676,62.71221351623535],[163.26361274719238,62.545000076293945],[162.95025825500488,61.80638313293457],[163.28802680969238,61.664438247680664],[162.40332221984863,61.672494888305664],[160.13775825500488,60.58360481262207],[160.39135932922363,61.025827407836914],[159.78055000305176,60.94082832336426],[159.82718086242676,61.26138496398926],[160.3549518585205,61.94748878479004],[159.531099319458,61.66276741027832],[159.24746894836426,61.92222023010254],[157.48663520812988,61.80332374572754],[154.23272895812988,59.88193702697754],[154.11413764953613,59.45971870422363],[155.190523147583,59.357805252075195],[154.74164009094238,59.12693977355957],[153.36856269836426,59.243051528930664],[152.8771686553955,58.917497634887695],[151.309419631958,58.83693885803223],[151.073579788208,59.110551834106445],[152.28775215148926,59.226938247680664],[149.59857368469238,59.771379470825195],[148.743013381958,59.49166297912598],[148.898042678833,59.23916053771973],[143.926362991333,59.4133243560791],[142.15970039367676,59.069162368774414],[140.688570022583,58.2338809967041],[140.49633979797363,57.82332801818848],[135.15442085266113,54.85943794250488],[135.73663520812988,54.5705509185791],[136.81607246398926,54.651384353637695],[136.76080513000488,53.76860237121582],[137.17248725891113,53.83471870422363],[137.28912544250488,54.03360939025879],[137.06189155578613,54.14083290100098],[137.18716621398926,54.2147159576416],[137.738862991333,54.317216873168945],[137.30798530578613,54.11444282531738],[137.85913276672363,53.961381912231445],[137.31079292297363,53.53277015686035],[138.55386543273926,53.98943519592285],[138.23941230773926,53.5624942779541],[138.44412422180176,53.51055335998535],[138.641939163208,54.29527473449707],[139.74633979797363,54.30888557434082],[141.41913032531738,53.2902774810791],[141.19998359680176,52.98638343811035],[140.7055377960205,53.113054275512695],[141.51416206359863,52.213327407836914],[140.46051216125488,50.7066593170166],[140.69580268859863,50.08749580383301],[140.40747261047363,49.871660232543945],[140.17581367492676,48.4486026763916],[135.12967109680176,43.49888038635254],[133.15136909484863,42.68221473693848],[132.3105182647705,42.844438552856445],[132.35217475891113,43.29277229309082],[131.94302558898926,43.06388282775879],[132.0563678741455,43.31332588195801],[131.8105182647705,43.3255558013916],[131.22134590148926,42.55582618713379],[130.69998359680176,42.67916297912598],[130.69742012023926,42.29220771789551],[130.6388874053955,42.406938552856445],[130.60437202453613,42.42186164855957],[130.4052448272705,42.71805000305176],[131.12329292297363,42.91082191467285],[131.311372756958,43.392221450805664],[130.94998359680176,44.84110450744629],[131.86468696594238,45.34554481506348],[133.12219429016113,45.12860298156738],[133.90017890930176,46.250314712524414],[134.182466506958,47.32332801818848],[134.76721382141113,47.70749855041504],[134.74075508117676,48.26712989807129],[133.08856391906738,48.10166358947754],[132.521089553833,47.710275650024414],[130.98855781555176,47.68860054016113],[130.52163887023926,48.60777473449707],[130.67163276672363,48.864999771118164],[127.52942848205566,49.78916358947754],[127.58606910705566,50.208566665649414],[126.09554481506348,52.76444435119629],[123.38220405578613,53.52665901184082],[120.86387825012207,53.27971839904785],[120.02916145324707,52.76805305480957],[120.71360969543457,52.54471778869629],[120.77665901184082,52.114999771118164],[119.13860511779785,50.39471626281738],[119.36136817932129,50.33693885803223],[119.21415901184082,50.015275955200195],[117.87471199035645,49.520578384399414],[116.71138191223145,49.83046913146973],[114.31302833557129,50.28416633605957],[113.09082221984863,49.59860420227051],[110.7885913848877,49.14943885803223],[108.57222175598145,49.33360481262207],[107.94914436340332,49.678049087524414],[107.97712898254395,49.94362831115723],[106.66304206848145,50.33860206604004],[102.91858863830566,50.31527137756348],[102.32776832580566,50.569719314575195],[102.21887397766113,51.33360481262207],[98.93026924133301,52.14361000061035],[97.8277759552002,51.001108169555664],[98.28970527648926,50.29388618469238],[97.34082221984863,49.73443794250488],[94.6352710723877,50.02443885803223],[94.27499580383301,50.56944465637207],[92.3227710723877,50.81499671936035],[87.84070014953613,49.17295265197754],[87.34820747375488,49.09262275695801],[86.61665534973145,49.58721351623535],[86.77499580383301,49.788888931274414],[86.19108772277832,49.472490310668945],[85.25860786437988,49.591379165649414],[85.01443672180176,50.07583045959473],[84.36303901672363,50.21221351623535],[83.45637702941895,51.00249671936035],[81.46805000305176,50.74221992492676],[80.68783760070801,51.31472206115723],[80.07795906066895,50.75808906555176],[77.90803718566895,53.27110481262207],[76.52165412902832,53.99388313293457],[76.81164741516113,54.447771072387695],[74.42915534973145,53.47860145568848],[73.43719673156738,53.436105728149414],[73.23858833312988,53.64444160461426],[73.76388740539551,54.0655460357666],[72.61331367492676,54.145273208618164],[72.46859931945801,53.908884048461914],[72.0516529083252,54.387773513793945],[72.19609260559082,54.13749885559082],[71.18553352355957,54.10332679748535],[70.99693489074707,54.33915901184082],[71.27887153625488,54.69027137756348],[70.84332466125488,55.30193519592285],[69.18553352355957,55.343881607055664],[65.48332405090332,54.63804817199707],[65.21638679504395,54.31888771057129],[63.17222023010254,54.18638038635254],[62.547494888305664,53.87943458557129],[61.01416206359863,53.94748878479004],[61.226938247680664,53.81193733215332],[60.90555000305176,53.62027168273926],[61.57749366760254,53.51333045959473],[61.18471717834473,53.306657791137695],[62.11832618713379,53.004167556762695],[61.09916114807129,52.98166084289551],[60.69415473937988,52.68082618713379],[61.06193733215332,52.34249305725098],[60.00222206115723,51.958330154418945],[61.68582344055176,51.26583290100098],[61.38138008117676,50.78360939025879],[60.04361152648926,50.86332893371582],[59.542497634887695,50.47832679748535],[58.33777046203613,51.15609931945801],[57.48193550109863,50.86471748352051],[56.51082801818848,51.083330154418945],[55.69249153137207,50.53249549865723],[54.64721870422363,51.036943435668945],[54.523935317993164,50.52884101867676],[54.50638771057129,50.856943130493164],[53.428606033325195,51.49166297912598],[52.60332679748535,51.45694160461426],[52.338327407836914,51.78221321105957],[51.303049087524414,51.47971534729004],[50.77330207824707,51.769182205200195],[48.69748878479004,50.591936111450195],[48.796945571899414,49.94193458557129],[48.251665115356445,49.86971473693848],[47.520830154418945,50.43638038635254],[46.9294376373291,49.86361122131348],[46.79583168029785,49.3397159576416],[47.06276893615723,49.142770767211914],[46.499162673950195,48.417497634887695],[47.12276649475098,48.27166175842285],[47.38332557678223,47.68888282775879],[48.20443153381348,47.70498847961426],[49.02720832824707,46.77609443664551],[48.56054878234863,46.56499671936035],[49.2225284576416,46.3463077545166],[48.627763748168945,46.08276557922363],[48.713327407836914,45.830270767211914],[48.56582069396973,45.965829849243164],[47.83054542541504,45.65582466125488],[47.55221748352051,45.76944160461426],[47.637216567993164,45.55304145812988],[47.38027381896973,45.74471473693848],[47.56915473937988,45.5574893951416],[46.67971229553223,44.52304267883301],[47.35026741027832,44.02665138244629],[47.40720558166504,43.50110054016113],[47.698320388793945,43.86887550354004],[47.46221351623535,43.01915168762207],[48.58395576477051,41.835771560668945],[47.76693153381348,41.19609260559082],[46.57138252258301,41.87193489074707],[46.45175361633301,41.89705848693848],[44.934709548950195,42.76027870178223],[43.911935806274414,42.583322525024414],[42.849992752075195,43.179155349731445],[40.25338935852051,43.58252143859863],[40.00296974182129,43.3792667388916],[38.76027870178223,44.27026557922363],[36.575273513793945,45.184709548950195],[36.96054267883301,45.27499580383301],[36.830827713012695,45.43664741516113],[37.73720741271973,45.29916572570801],[37.59137153625488,45.62748146057129],[37.940263748168945,46.025827407836914],[38.57443428039551,46.08970832824707],[37.734994888305664,46.66916084289551],[38.5816593170166,46.650827407836914],[38.41081428527832,46.82805061340332],[39.29998970031738,47.07693672180176],[38.23582649230957,47.10943031311035],[38.30332374572754,47.55859565734863],[38.85360145568848,47.86082649230957],[39.79638862609863,47.85721778869629],[39.99888038635254,48.29722023010254],[39.656938552856445,48.61666297912598],[40.07666206359863,48.8749942779541],[39.69665718078613,49.01082801818848],[40.166940689086914,49.248605728149414],[40.1397647857666,49.60105323791504],[38.30777168273926,50.07388496398926],[38.02422523498535,49.903085708618164],[37.45860481262207,50.439714431762695],[35.60665321350098,50.36944007873535],[35.37188911437988,51.04143714904785],[34.382211685180664,51.26361274719238],[34.09804725646973,51.653879165649414],[34.41971778869629,51.80888557434082],[33.838884353637695,52.360551834106445],[33.41770362854004,52.35540199279785],[31.78388786315918,52.108049392700195],[31.266942977905273,53.02471351623535],[32.741106033325195,53.46305274963379],[31.76422691345215,53.802621841430664],[31.84416389465332,54.06443977355957],[30.781389236450195,54.79361152648926],[31.029722213745117,55.0433292388916],[30.92624855041504,55.60257148742676],[28.168012619018555,56.150156021118164],[27.701662063598633,56.91471290588379],[27.861108779907227,57.30221748352051],[27.372060775756836,57.5356388092041],[27.82305335998535,57.87388038635254],[27.42610740661621,58.813608169555664],[28.170358657836914,59.30978202819824],[28.015832901000977,59.47860145568848],[28.080278396606445,59.79638862609863],[30.24582862854004,59.97526741027832],[28.60194206237793,60.38443946838379],[28.686662673950195,60.73582649230957],[27.807832717895508,60.546403884887695],[31.588930130004883,62.91441535949707],[29.99333381652832,63.743608474731445],[30.578054428100586,64.22137641906738],[29.636667251586914,64.92805671691895],[29.81888771057129,65.65332221984863],[30.134164810180664,65.71916389465332],[29.07499885559082,66.89583015441895],[30.02861213684082,67.6947193145752],[28.693334579467773,68.19749641418457],[28.45749855041504,68.53193855285645],[28.820554733276367,68.84443855285645],[28.431943893432617,68.89694404602051],[28.95734214782715,69.05162239074707],[30.103334426879883,69.66305732727051],[30.910001754760742,69.54887580871582],[30.854841232299805,69.79231452941895],[33.09360694885254,69.74748420715332],[32.02639579772949,69.63653755187988],[33.02941703796387,69.47186470031738],[32.80999183654785,69.29609870910645],[33.52166175842285,69.42192268371582],[33.02276802062988,68.95332527160645],[33.71915626525879,69.33137702941895],[35.974992752075195,69.17303657531738],[40.99221992492676,67.71609687805176],[41.39055061340332,67.12275886535645],[41.21971321105957,66.83777046203613],[40.07332801818848,66.27777290344238],[38.60777473449707,66.05220222473145],[31.854997634887695,67.15387153625488],[33.732492446899414,66.42387580871582],[33.31276893615723,66.31608772277832],[34.847490310668945,65.90109443664551],[34.96360969543457,65.71776008605957],[34.69082832336426,65.80386543273926],[34.68166542053223,65.45109748840332],[34.37777137756348,65.3783130645752],[34.936105728149414,64.83831977844238],[34.78777503967285,64.54776191711426],[37.414995193481445,63.80388069152832],[38.07749366760254,64.01721382141113],[37.9788761138916,64.3166675567627],[37.14471626281738,64.40887641906738],[36.439714431762695,64.94275093078613],[37.03221321105957,65.20833015441895],[38.40860176086426,64.85887336730957],[38.046945571899414,64.64109992980957],[40.50583076477051,64.53526496887207],[39.75139045715332,65.55081367492676],[42.1683292388916,66.52276802062988],[43.29972267150879,66.42221260070801],[43.69748878479004,66.23581123352051],[43.35471534729004,66.0385913848877],[43.858049392700195,66.17692756652832],[44.17444038391113,65.87469673156738],[44.49638557434082,66.9074878692627],[43.75193977355957,67.31888008117676],[44.24582862854004,68.27026557922363],[43.311662673950195,68.68498420715332],[45.90332221984863,68.48221015930176],[46.520830154418945,68.14415168762207],[46.70694160461426,67.81303596496582],[45.38249397277832,67.73553657531738],[44.911935806274414,67.37275886535645],[46.60083198547363,66.85331916809082],[46.38555335998535,66.73970222473145],[47.699716567993164,66.98637580871582],[47.99499702453613,67.65027046203613],[49.10110664367676,67.62803840637207],[48.59110450744629,67.93498420715332],[52.074716567993164,68.54443550109863],[52.26860237121582,68.30581855773926],[52.733049392700195,68.46638679504395],[52.28833198547363,68.6141529083252],[53.78360939025879,68.96805000305176],[54.56082344055176,68.99247932434082],[53.59887886047363,68.90803718566895],[54.0191593170166,68.85525703430176],[53.71971321105957,68.65193367004395],[53.94582557678223,68.39999580383301],[53.20999336242676,68.26138496398926],[54.791940689086914,68.16304206848145],[55.32473182678223,68.55000495910645],[57.27610206604004,68.55581855773926],[58.898332595825195,68.99971199035645],[59.42721748352051,68.7452564239502],[59.07332801818848,68.42137336730957],[59.83610725402832,68.36665534973145],[59.811662673950195,68.68193244934082],[60.914438247680664,68.90471076965332],[60.14055061340332,69.57415962219238],[60.87443733215332,69.86360359191895],[64.15054512023926,69.54193305969238],[65.00277900695801,69.29803657531738],[64.78776741027832,69.14276313781738],[67.11609077453613,68.84276008605957],[67.03915596008301,68.78970527648926],[67.19304084777832,68.70471382141113],[68.15942573547363,68.41137886047363],[68.26500129699707,68.18748664855957],[68.43637275695801,68.2249927520752],[69.22026252746582,68.95721626281738],[68.45971870422363,68.9780445098877],[68.10165596008301,69.5466480255127],[67.00055122375488,69.69970893859863],[66.95027351379395,69.52887153625488],[66.79915046691895,69.57415962219238],[66.8733081817627,70.00110054016113],[67.3277759552002,70.09749031066895],[67.08804512023926,70.21721076965332],[67.33970832824707,70.75027656555176],[66.68887519836426,70.76054573059082],[66.89166450500488,71.07748603820801],[66.62303352355957,71.0516529083252],[68.46554756164551,71.81889533996582],[69.3338794708252,72.9488697052002],[71.56053352355957,72.90971565246582],[72.83333015441895,72.70860481262207],[72.88192939758301,72.28137397766113],[71.80247688293457,71.47249031066895],[72.84054756164551,70.86526679992676],[72.77804756164551,70.41804695129395],[72.4246997833252,70.27026557922363],[72.68637275695801,69.84971809387207],[72.55386543273926,68.97665596008301],[73.64804267883301,68.45776557922363],[73.0980396270752,68.2169361114502],[73.04081916809082,67.72415351867676],[72.0405445098877,67.29693794250488],[72.2310962677002,67.1605396270752],[71.41026496887207,66.9669361114502],[71.55859565734863,66.64526557922363],[70.69497871398926,66.50804328918457],[70.29136848449707,66.62387275695801],[70.73082160949707,66.7572193145752],[68.96776008605957,66.80415534973145],[69.38611030578613,66.50749397277832],[72.00000190734863,66.21943855285645],[73.84721565246582,66.9810962677002],[73.90887641906738,67.29803657531738],[74.73997688293457,67.69165229797363],[74.73166084289551,68.14305305480957],[74.33276557922363,68.3802661895752],[74.64055061340332,68.76915168762207],[76.59166145324707,68.96832466125488],[77.32443428039551,68.51693916320801],[77.0919361114502,67.77859687805176],[79.04484748840332,67.5671558380127],[77.46249580383301,67.76220893859863],[77.55859565734863,68.14387702941895],[78.1746997833252,68.26500129699707],[77.63499641418457,68.90776252746582],[76.03720283508301,69.2371997833252],[73.74942207336426,69.16804695129395],[73.89444160461426,69.42581367492676],[73.51638984680176,69.75555610656738],[74.31498908996582,70.6736011505127],[73.0152759552002,71.4216480255127],[73.53219795227051,71.81915473937988],[74.95804023742676,72.10942268371582],[74.82998847961426,72.83415412902832],[75.71582221984863,72.55664253234863],[75.24193000793457,71.37608528137207],[76.91581916809082,71.0697193145752],[79.11276435852051,71.00248908996582],[76.27054023742676,71.57165718078613],[76.09749031066895,71.92859077453613],[78.10473823547363,71.87614631652832],[77.36998176574707,72.09887886047363],[78.53804206848145,72.40359687805176],[81.65304756164551,71.70804023742676],[83.26164436340332,71.7210865020752],[82.25749397277832,71.25972175598145],[82.41443061828613,70.77110481262207],[82.08110237121582,70.5677661895752],[82.34610176086426,70.19859504699707],[82.16026496887207,70.57748603820801],[83.11886787414551,70.88749885559082],[82.63916206359863,70.17442512512207],[83.10693550109863,70.06860542297363],[83.19359016418457,70.1233081817627],[83.13054084777832,70.20804023742676],[82.95166206359863,70.32054328918457],[83.53166389465332,70.33915901184082],[83.74553108215332,70.45999336242676],[83.1483325958252,71.2361011505127],[83.62858772277832,71.62387275695801],[82.19247627258301,72.28305244445801],[80.72137641906738,72.52609443664551],[80.81721687316895,72.96609687805176],[80.2310962677002,73.1736011505127],[80.57249641418457,73.22053718566895],[80.24859809875488,73.31414985656738],[80.50999641418457,73.57165718078613],[87.0869312286377,73.85942268371582],[85.77832221984863,73.45971870422363],[86.78360176086426,72.99408149719238],[85.8480396270752,73.47526741027832],[87.66499519348145,73.89471626281738],[85.95109748840332,74.28082466125488],[87.13275337219238,74.36914253234863],[85.78915596008301,74.63081550598145],[86.02916145324707,74.81303596496582],[86.91304206848145,74.61248970031738],[87.38665962219238,74.94304084777832],[87.1816577911377,74.98997688293457],[87.78581428527832,75.02221870422363],[86.99498176574707,75.1513843536377],[94.16192817687988,75.94275093078613],[92.86526679992676,75.94832038879395],[93.15555000305176,76.09776496887207],[96.19775581359863,76.08526802062988],[95.74386787414551,75.85054206848145],[99.27693367004395,76.21415901184082],[99.7683277130127,76.03109931945801],[99.09443855285645,75.55497932434082],[100.18625831604004,75.16853523254395],[99.17192268371582,75.56999397277832],[99.87719917297363,76.09166145324707],[98.81387519836426,76.49275398254395],[102.23359870910645,76.37719917297363],[100.8783130645752,76.55137825012207],[101.23471260070801,76.75305366516113],[100.84971809387207,76.87858772277832],[103.10555458068848,77.63192939758301],[104.26748847961426,77.67581367492676]],[[86.90220832824707,73.69748115539551],[86.39499092102051,73.58831977844238],[86.73665046691895,73.59526252746582],[86.90220832824707,73.69748115539551]],[[40.27443885803223,64.87414741516113],[40.278879165649414,64.9458179473877],[40.20971870422363,64.99247932434082],[40.27443885803223,64.87414741516113]]],[[[107.6352710723877,78.16609382629395],[107.43887519836426,78.04942512512207],[106.49304389953613,78.12164497375488],[107.6352710723877,78.16609382629395]]],[[[93.75055122375488,78.15582466125488],[93.51971626281738,78.1877613067627],[93.6402759552002,78.22276496887207],[93.75055122375488,78.15582466125488]]],[[[106.76138496398926,78.30359077453613],[105.99275398254395,78.21415901184082],[106.45860481262207,78.33471870422363],[106.76138496398926,78.30359077453613]]],[[[92.70221138000488,79.07138252258301],[92.18261909484863,79.12718391418457],[92.72554206848145,79.07499885559082],[92.70221138000488,79.07138252258301]]],[[[102.97276496887207,79.33137702941895],[102.39333534240723,78.82859992980957],[103.94693183898926,79.13333320617676],[105.41443061828613,78.56469917297363],[99.34137153625488,78.01999092102051],[100.3783130645752,78.7452564239502],[101.16805458068848,78.75833320617676],[100.89388465881348,78.97665596008301],[101.62442207336426,78.98221015930176],[100.98887825012207,79.06109809875488],[101.55081367492676,79.34832954406738],[102.97276496887207,79.33137702941895]]],[[[92.80554389953613,79.38247871398926],[92.58221626281738,79.40693855285645],[92.98776435852051,79.41693305969238],[92.80554389953613,79.38247871398926]]],[[[92.46748542785645,79.42997932434082],[92.24359321594238,79.37997627258301],[91.80415534973145,79.4124927520752],[92.46748542785645,79.42997932434082]]],[[[99.9458179473877,79.4013843536377],[99.85054206848145,79.4155445098877],[100.01776313781738,79.43304634094238],[99.9458179473877,79.4013843536377]]],[[[91.46859931945801,79.45471382141113],[90.78193855285645,79.54915046691895],[91.16609382629395,79.52693367004395],[91.46859931945801,79.45471382141113]]],[[[76.23248481750488,79.60138130187988],[76.04193305969238,79.63472175598145],[77.61970710754395,79.51220893859863],[76.23248481750488,79.60138130187988]]],[[[100.01082038879395,79.6222095489502],[100.30664253234863,79.66470527648926],[99.90359687805176,79.5999927520752],[100.01082038879395,79.6222095489502]]],[[[91.65109443664551,79.65109443664551],[91.12442207336426,79.72249031066895],[91.85887336730957,79.66470527648926],[91.65109443664551,79.65109443664551]]],[[[58.68638038635254,79.94470405578613],[58.988046646118164,79.89554023742676],[58.27916145324707,79.9266529083252],[58.68638038635254,79.94470405578613]]],[[[94.3077564239502,80.01693916320801],[93.92747688293457,79.96832466125488],[93.98825263977051,80.0097827911377],[94.3077564239502,80.01693916320801]]],[[[49.379159927368164,79.9891529083252],[49.19360542297363,80.03221321105957],[49.43526649475098,80.00248908996582],[49.379159927368164,79.9891529083252]]],[[[51.20499610900879,80.03804206848145],[51.50193977355957,79.9316577911377],[50.04388618469238,79.9730396270752],[51.20499610900879,80.03804206848145]]],[[[91.17637825012207,80.05304145812988],[93.80859565734863,79.8883228302002],[91.9216480255127,79.67331123352051],[92.3499927520752,79.72776985168457],[90.86442756652832,80.05720710754395],[91.17637825012207,80.05304145812988]]],[[[59.42222023010254,79.92025947570801],[58.759164810180664,80.02276802062988],[59.84471321105957,80.06833076477051],[59.42222023010254,79.92025947570801]]],[[[49.59610176086426,80.0727710723877],[49.683053970336914,80.03637886047363],[49.330278396606445,80.06192207336426],[49.59610176086426,80.0727710723877]]],[[[50.25277900695801,80.1463794708252],[49.972490310668945,80.05415534973145],[49.53221321105957,80.15220832824707],[50.25277900695801,80.1463794708252]]],[[[97.61499214172363,80.1655445098877],[98.03442573547363,80.06749153137207],[97.19304084777832,79.70221138000488],[98.52859687805176,80.05247688293457],[100.01526832580566,79.82415962219238],[99.65915107727051,79.29582405090332],[99.03526496887207,79.29026985168457],[99.93887519836426,78.95332527160645],[97.3047046661377,78.84526252746582],[94.77720832824707,79.08442878723145],[94.33249092102051,79.46554756164551],[93.6988697052002,79.45610237121582],[93.87803840637207,79.60138130187988],[92.85081672668457,79.55386543273926],[94.61609077453613,79.81192207336426],[94.22221565246582,79.89776802062988],[94.93664741516113,80.09942817687988],[95.26944160461426,80.01638984680176],[95.58027839660645,80.11137580871582],[97.61499214172363,80.1655445098877]]],[[[60.261667251586914,80.16331672668457],[59.897775650024414,80.19165229797363],[60.289438247680664,80.16693305969238],[60.261667251586914,80.16331672668457]]],[[[55.15110206604004,80.22026252746582],[54.857500076293945,80.25248908996582],[55.54388618469238,80.29387092590332],[55.15110206604004,80.22026252746582]]],[[[53.621103286743164,80.29498481750488],[53.871660232543945,80.25665473937988],[52.18138313293457,80.27192878723145],[53.621103286743164,80.29498481750488]]],[[[54.221933364868164,80.20416450500488],[54.151384353637695,80.29942512512207],[54.439714431762695,80.2986011505127],[54.221933364868164,80.20416450500488]]],[[[57.096940994262695,80.34305000305176],[57.050546646118164,80.07499885559082],[55.71360969543457,80.1010913848877],[57.096940994262695,80.34305000305176]]],[[[52.45249366760254,80.32110786437988],[52.16666603088379,80.35026741027832],[52.521379470825195,80.3308277130127],[52.45249366760254,80.32110786437988]]],[[[55.3669376373291,80.42886543273926],[55.167497634887695,80.36943244934082],[54.977487564086914,80.41693305969238],[55.3669376373291,80.42886543273926]]],[[[56.30804634094238,80.3813648223877],[55.78611183166504,80.40721321105957],[55.87304878234863,80.43525886535645],[56.30804634094238,80.3813648223877]]],[[[54.637216567993164,80.39360237121582],[54.37027168273926,80.40582466125488],[54.863054275512695,80.45027351379395],[54.637216567993164,80.39360237121582]]],[[[57.96832466125488,80.48942756652832],[59.276384353637695,80.33415412902832],[57.71859931945801,80.09832954406738],[56.94638252258301,80.47442817687988],[57.96832466125488,80.48942756652832]]],[[[54.30166053771973,80.41914558410645],[53.77999305725098,80.46943855285645],[54.45888710021973,80.49803352355957],[54.30166053771973,80.41914558410645]]],[[[55.01583290100098,80.55693244934082],[55.16304969787598,80.49470710754395],[54.6411075592041,80.52804756164551],[55.01583290100098,80.55693244934082]]],[[[53.442216873168945,80.48498725891113],[53.10527229309082,80.61998176574707],[53.39860725402832,80.62664985656738],[53.442216873168945,80.48498725891113]]],[[[58.85527229309082,80.6402759552002],[58.80638313293457,80.58276557922363],[58.53777503967285,80.60582160949707],[58.85527229309082,80.6402759552002]]],[[[58.01055335998535,80.64109992980957],[57.87082862854004,80.55331611633301],[57.21305274963379,80.60359382629395],[58.01055335998535,80.64109992980957]]],[[[56.778879165649414,80.73581123352051],[56.9486026763916,80.69275093078613],[55.43249702453613,80.70833015441895],[56.778879165649414,80.73581123352051]]],[[[47.897775650024414,80.80331611633301],[48.76638984680176,80.6463794708252],[47.751665115356445,80.76638984680176],[47.30332374572754,80.6574878692627],[47.42360877990723,80.5888843536377],[46.08416175842285,80.43692207336426],[46.036386489868164,80.57222175598145],[44.857500076293945,80.61638069152832],[47.897775650024414,80.80331611633301]]],[[[62.21832466125488,80.81109809875488],[61.06610298156738,80.40359687805176],[59.22082710266113,80.64276313781738],[62.21832466125488,80.81109809875488]]],[[[55.44999885559082,80.85138130187988],[55.98276710510254,80.79582405090332],[53.97554969787598,80.81749153137207],[55.44999885559082,80.85138130187988]]],[[[58.98665809631348,80.79165840148926],[57.81638526916504,80.80581855773926],[58.756662368774414,80.89610481262207],[58.98665809631348,80.79165840148926]]],[[[50.1330509185791,80.84665107727051],[51.7469425201416,80.71220588684082],[48.80971717834473,80.37637519836426],[48.62276649475098,80.30026435852051],[49.113054275512695,80.1827564239502],[48.374162673950195,80.08720588684082],[46.61638832092285,80.29081916809082],[48.18387794494629,80.33137702941895],[47.38027381896973,80.45054817199707],[49.192216873168945,80.5213794708252],[49.68138313293457,80.71748542785645],[48.95416450500488,80.73137092590332],[50.44137763977051,80.90387153625488],[50.1330509185791,80.84665107727051]]],[[[79.97720527648926,80.95248603820801],[80.4377613067627,80.92637825012207],[78.97276496887207,80.83749580383301],[79.97720527648926,80.95248603820801]]],[[[58.533334732055664,80.95305061340332],[57.83416175842285,81.04525947570801],[58.69887733459473,81.02554512023926],[58.533334732055664,80.95305061340332]]],[[[50.59721565246582,81.04609870910645],[50.347490310668945,81.09027290344238],[50.98333168029785,81.10054206848145],[50.59721565246582,81.04609870910645]]],[[[56.24249458312988,81.1010913848877],[58.27860450744629,80.91971015930176],[56.096384048461914,81.08915901184082],[56.24249458312988,81.1010913848877]]],[[[58.7580509185791,81.07332038879395],[58.515275955200195,81.10443305969238],[58.80804634094238,81.09749031066895],[58.7580509185791,81.07332038879395]]],[[[54.74943733215332,81.10971260070801],[57.72082710266113,80.79248237609863],[54.4183292388916,81.00610542297363],[54.74943733215332,81.10971260070801]]],[[[60.98526954650879,80.91609382629395],[60.02499580383301,80.99165534973145],[61.65416145324707,81.11081123352051],[60.98526954650879,80.91609382629395]]],[[[58.445268630981445,81.1141529083252],[58.14943885803223,81.12886238098145],[58.64860725402832,81.13499641418457],[58.445268630981445,81.1141529083252]]],[[[91.25027656555176,81.06303596496582],[89.89360237121582,81.1685962677002],[91.57721138000488,81.14305305480957],[91.25027656555176,81.06303596496582]]],[[[65.45248603820801,81.02777290344238],[64.30304145812988,80.72998237609863],[62.504167556762695,80.81833076477051],[64.48359870910645,81.19108772277832],[65.45248603820801,81.02777290344238]]],[[[59.76638984680176,81.17025947570801],[59.01082801818848,81.20721626281738],[59.84471321105957,81.17997932434082],[59.76638984680176,81.17025947570801]]],[[[57.56499671936035,81.1252613067627],[56.99471473693848,81.1655445098877],[58.08055305480957,81.20971870422363],[57.56499671936035,81.1252613067627]]],[[[95.95860481262207,81.21721076965332],[97.96943855285645,80.71554756164551],[97.12915229797363,80.66276741027832],[97.42637825012207,80.3108081817627],[97.15887641906738,80.23359870910645],[94.8097095489502,80.13998603820801],[93.75305366516113,79.99582099914551],[92.06164741516113,80.17025947570801],[93.24664497375488,80.30554389953613],[91.42137336730957,80.3077564239502],[92.62387275695801,80.38499641418457],[91.88943672180176,80.45776557922363],[93.32554817199707,80.80581855773926],[92.48748970031738,80.76748847961426],[93.06860542297363,80.99443244934082],[95.95860481262207,81.21721076965332]]],[[[60.63888740539551,81.27221870422363],[60.37748908996582,81.24414253234863],[59.72221565246582,81.28332710266113],[60.63888740539551,81.27221870422363]]],[[[57.45804786682129,81.31360054016113],[57.90277290344238,81.29026985168457],[55.43166542053223,81.27165412902832],[57.45804786682129,81.31360054016113]]],[[[59.05332374572754,81.28499031066895],[58.46193885803223,81.33859443664551],[59.381662368774414,81.32415962219238],[59.05332374572754,81.28499031066895]]],[[[54.29361152648926,81.33333015441895],[54.42193794250488,81.27026557922363],[54.11471748352051,81.34721565246582],[54.29361152648926,81.33333015441895]]],[[[57.79666328430176,81.52998542785645],[58.57249641418457,81.41192817687988],[56.74138069152832,81.44859504699707],[57.79666328430176,81.52998542785645]]],[[[58.49083137512207,81.55887031555176],[58.22665596008301,81.58137702941895],[58.71971321105957,81.59971809387207],[58.49083137512207,81.55887031555176]]],[[[62.080827713012695,81.54414558410645],[61.654436111450195,81.6030445098877],[62.2036075592041,81.56498908996582],[62.080827713012695,81.54414558410645]]],[[[62.7933292388916,81.70860481262207],[63.80277442932129,81.65332221984863],[62.10416603088379,81.67248725891113],[62.7933292388916,81.70860481262207]]],[[[59.28750038146973,81.74275398254395],[57.88888740539551,81.70694160461426],[59.43776893615723,81.8166675567627],[59.28750038146973,81.74275398254395]]]]}},{"type":"Feature","properties":{"name":"Rwanda","iso2":"RW","iso3":"RWA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[29.952221,-2.309445],[29.85083,-2.759722],[29.024441,-2.744722],[28.868332,-2.394444],[29.596943,-1.385834],[29.974998,-1.464445],[30.48222,-1.063334],[30.894165,-2.076111],[30.57333,-2.399167],[29.952221,-2.309445]]]]}},{"type":"Feature","properties":{"name":"Saudi Arabia","iso2":"SA","iso3":"SAU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[41.957773208618164,16.708887100219727],[41.753610610961914,16.87611198425293],[42.17999458312988,16.566946029663086],[41.957773208618164,16.708887100219727]]],[[[41.98666572570801,16.753332138061523],[41.83722114562988,16.86861228942871],[41.84555244445801,17.009164810180664],[41.98666572570801,16.753332138061523]]],[[[37.08055305480957,24.959165573120117],[37.03582954406738,24.963056564331055],[37.04166603088379,24.996946334838867],[37.08055305480957,24.959165573120117]]],[[[35.754716873168945,27.0947208404541],[35.75777626037598,27.07694435119629],[35.726388931274414,27.128610610961914],[35.754716873168945,27.0947208404541]]],[[[49.53721046447754,27.36360740661621],[49.63861274719238,27.31638526916504],[49.45221138000488,27.285829544067383],[49.53721046447754,27.36360740661621]]],[[[34.59360694885254,27.90916633605957],[34.49221992492676,27.996110916137695],[34.54666328430176,27.99860954284668],[34.59360694885254,27.90916633605957]]],[[[44.721662521362305,29.198331832885742],[46.546945571899414,29.10420036315918],[47.45999336242676,28.999441146850586],[47.68888282775879,28.53888511657715],[48.41658973693848,28.545278549194336],[48.838876724243164,27.619718551635742],[50.15916633605957,26.656667709350586],[49.9938907623291,26.01999855041504],[50.83095741271973,24.749967575073242],[51.215166091918945,24.62088966369629],[51.5836124420166,24.259721755981445],[52.583330154418945,22.93889045715332],[55.199167251586914,22.69972038269043],[55.66610908508301,21.999723434448242],[55.00000190734863,20.000001907348633],[51.99929237365723,18.999345779418945],[48.76638984680176,18.266389846801758],[46.33305549621582,15.616945266723633],[46.333330154418945,16.66666603088379],[44.46750068664551,17.411943435668945],[43.3094425201416,17.457223892211914],[43.20611000061035,16.672224044799805],[42.789682388305664,16.377504348754883],[40.75999641418457,19.760278701782227],[39.17694282531738,21.099164962768555],[39.06277656555176,22.58333396911621],[38.452775955200195,23.782499313354492],[37.441667556762695,24.371389389038086],[37.235551834106445,25.1825008392334],[35.16055488586426,28.056665420532227],[34.571664810180664,28.08888816833496],[34.96138954162598,29.3608341217041],[36.07000160217285,29.18889045715332],[36.743608474731445,29.864721298217773],[37.50277900695801,30.002222061157227],[38.00139045715332,30.504167556762695],[37.00527381896973,31.505556106567383],[39.19674491882324,32.15494346618652],[40.41333198547363,31.948331832885742],[42.08500099182129,31.111661911010742],[44.721662521362305,29.198331832885742]]]]}},{"type":"Feature","properties":{"name":"Saint Kitts and Nevis","iso2":"KN","iso3":"KNA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-62.55278,17.094166],[-62.62194799999989,17.111385],[-62.599724,17.19722],[-62.55278,17.094166]]],[[[-62.70166799999987,17.336941],[-62.62528199999986,17.220833],[-62.863892,17.370831000000138],[-62.70166799999987,17.336941]]]]}},{"type":"Feature","properties":{"name":"Seychelles","iso2":"SC","iso3":"SYC"},"geometry":{"type":"MultiPolygon","coordinates":[[[[46.491386,-9.754446],[46.476105,-9.744167],[46.508331,-9.717779],[46.491386,-9.754446]]],[[[46.510551,-9.396946],[46.269165000000186,-9.463057],[46.204163,-9.389446],[46.510551,-9.396946]]],[[[46.413887,-9.358891],[46.276665,-9.346111],[46.42694100000014,-9.342779],[46.413887,-9.358891]]],[[[56.282219,-7.134167],[56.247215000000125,-7.194445],[56.278610000000214,-7.110834],[56.282219,-7.134167]]],[[[55.53527100000011,-4.763056],[55.376106,-4.627223],[55.45916,-4.55139],[55.53527100000011,-4.763056]]],[[[55.246109,-4.506945],[55.23166700000016,-4.448056],[55.26722000000015,-4.481668],[55.246109,-4.506945]]],[[[55.775833,-4.348333],[55.687218,-4.2875],[55.77166,-4.315556],[55.775833,-4.348333]]]]}},{"type":"Feature","properties":{"name":"South Africa","iso2":"ZA","iso3":"ZAF"},"geometry":{"type":"MultiPolygon","coordinates":[[[[37.85083,-46.956947],[37.576385000000215,-46.909447],[37.781944,-46.83223],[37.85083,-46.956947]]],[[[37.959442000000166,-46.658615],[37.856941,-46.626945],[37.942772,-46.60334],[37.959442000000166,-46.658615]]],[[[29.893887,-22.194447],[31.297504000000146,-22.414764],[32.016106,-24.459446],[31.96851,-25.95784],[31.33083,-25.751392],[30.902048,-26.305254],[30.818886000000106,-26.810558],[31.161663,-27.203056],[31.987499,-27.316113],[32.1334,-26.839626],[32.890427,-26.847145],[32.39027400000012,-28.537781],[31.325832,-29.390835],[30.0238880000002,-31.281113],[27.899998,-33.040558],[26.53055200000017,-33.753334],[25.724998,-33.767227],[25.701942,-34.031952],[22.544998,-34.005005],[20,-34.822002],[18.817776,-34.377785],[18.793331,-34.08667],[18.40472000000011,-34.30278],[18.441109,-33.706673],[17.8475,-32.830833],[18.292221,-32.624451],[18.27861000000013,-31.89278],[16.48959,-28.578178],[17.06361,-28.028614],[17.40472,-28.713612],[18.175831,-28.908611],[19.123055000000107,-28.962223],[19.99612,-28.421448],[20.000942,-24.765408],[20.811386,-25.883335],[20.642498,-26.828056],[21.667221,-26.864445],[22.624809000000113,-26.111565],[23.014832000000126,-25.299725],[24.6772,-25.827824],[25.50972,-25.67778],[25.871387,-24.744446],[26.845276,-24.264446],[26.95919,-23.752075],[28.29833200000013,-22.609447],[29.373623,-22.19241],[29.893887,-22.194447]],[[28.565552,-28.610001],[27.011108,-29.625278],[27.564617,-30.404911],[28.079937,-30.650528],[28.377777,-30.16028],[29.168888,-29.913891],[29.430832,-29.278614],[28.565552,-28.610001]]]]}},{"type":"Feature","properties":{"name":"Lesotho","iso2":"LS","iso3":"LSO"},"geometry":{"type":"MultiPolygon","coordinates":[[[[27.564617,-30.404911],[27.011108,-29.625278],[28.565552,-28.610001],[29.430832,-29.278614],[29.168888,-29.913891],[28.377777,-30.16028],[28.079937,-30.650528],[27.564617,-30.404911]]]]}},{"type":"Feature","properties":{"name":"Botswana","iso2":"BW","iso3":"BWA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[26.95919,-23.752075],[26.845276,-24.264446],[25.871387,-24.744446],[25.50972,-25.67778],[24.6772,-25.827824],[23.014832000000126,-25.299725],[22.624809000000113,-26.111565],[21.667221,-26.864445],[20.642498,-26.828056],[20.811386,-25.883335],[20.000942,-24.765408],[19.996666,-22.005001],[20.991943,-21.996948],[20.993286,-18.318417],[23.297108,-17.995949],[23.615578,-18.485069],[24.362499,-17.948612],[25.264431,-17.80225],[26.166111,-19.527779],[27.219997,-20.091667],[27.287453,-20.494965],[27.713165,-20.506432],[28.015831,-21.566113],[29.060555,-21.798058],[29.373623,-22.19241],[28.29833200000013,-22.609447],[26.95919,-23.752075]]]]}},{"type":"Feature","properties":{"name":"Senegal","iso2":"SN","iso3":"SEN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-17.148308,14.61392],[-17.537224,14.756109],[-16.878334,15.224998],[-16.527679,16.060249],[-16.280834,16.519722],[-14.345278,16.638611],[-12.244833,14.764385],[-12.057222,13.664721],[-11.378056,12.988054],[-11.373058,12.407774],[-12.345404,12.301748],[-13.713139,12.677221],[-14.516945,12.67972200000014],[-16.71777,12.322426],[-16.586945,12.632776],[-15.626945,12.531111],[-15.390001,12.831944],[-15.650002,12.555555],[-16.598057,12.791666],[-16.756111,12.564999],[-16.750874,13.059977],[-15.809723,13.159721],[-15.803612,13.347776],[-15.285002,13.374443],[-15.111668,13.595833],[-14.351112,13.237778],[-13.798613,13.406387],[-15.070278,13.826387],[-16.56567,13.589998],[-16.490837,13.958055],[-16.747223,13.951944],[-16.363056,14.166111],[-16.775837,14.012499],[-17.148308,14.61392]]]]}},{"type":"Feature","properties":{"name":"Slovenia","iso2":"SI","iso3":"SVN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[13.718655,46.526611],[14.544998,46.407494],[16.111805,46.86972],[16.607872,46.476234],[16.572498,46.475273],[15.654722,46.219444],[15.697777,45.844162],[15.174458,45.425819],[14.601387,45.675278],[13.591740000000101,45.481697],[13.716944,45.596107],[13.919167,45.637497],[13.480000000000103,46.011108],[13.669167,46.177498],[13.383055,46.297218],[13.718655,46.526611]]]]}},{"type":"Feature","properties":{"name":"Sierra Leone","iso2":"SL","iso3":"SLE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-12.525278,7.431389],[-12.952778,7.568333],[-12.591112,7.634444],[-12.525278,7.431389]]],[[[-11.214444999999898,9.997499],[-10.571526,9.059532],[-10.695835,8.298611],[-10.266651,8.488377],[-11.492331,6.927091000000132],[-12.958612,7.9],[-13.288057,8.496111000000127],[-13.05139,8.36861],[-13.120278999999897,8.461666000000122],[-12.897500999999863,8.567778],[-13.165279,8.51861],[-13.2425,8.802500000000123],[-13.132223,8.861944],[-13.29561,9.032143],[-12.456112,9.888332],[-11.214444999999898,9.997499]]]]}},{"type":"Feature","properties":{"name":"Singapore","iso2":"SG","iso3":"SGP"},"geometry":{"type":"MultiPolygon","coordinates":[[[[103.99054,1.383291],[103.640808,1.315555],[103.713593,1.429444],[103.99054,1.383291]]]]}},{"type":"Feature","properties":{"name":"Somalia","iso2":"SO","iso3":"SOM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[42.944092,11.002438],[43.249222,11.469534],[44.278328,10.447777],[44.898331,10.420555],[45.759995,10.875277],[46.448051,10.688889],[47.398888,11.179998],[50.085548,11.511944],[50.76944,11.979166],[51.277222,11.836666],[51.01416,10.442778],[51.412636,10.451515],[50.896942,10.319721],[50.83625,9.432688],[47.954437,4.463888],[46.014717,2.427778],[43.488609,0.649999],[41.558159,-1.674868],[40.998329,-0.866111],[40.98659500000011,2.829956],[41.905167,3.980322],[43.686386,4.891944],[44.950829,4.902499],[47.988243,8.004107],[47.01194,8.00111],[44.010551,9.007221],[42.848053,10.22361],[42.663055,10.6325],[42.944092,11.002438]]]]}},{"type":"Feature","properties":{"name":"Spain","iso2":"ES","iso3":"ESP"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-17.91278076171875,27.771665573120117],[-17.98278045654297,27.63749885559082],[-18.17055892944336,27.73722267150879],[-17.91278076171875,27.771665573120117]]],[[[-15.554166793823242,27.755834579467773],[-15.70250129699707,28.156110763549805],[-15.365556716918945,28.010278701782227],[-15.554166793823242,27.755834579467773]]],[[[-17.175003051757812,28.016942977905273],[-17.31694793701172,28.172224044799805],[-17.101947784423828,28.134721755981445],[-17.175003051757812,28.016942977905273]]],[[[-16.341114044189453,28.37027931213379],[-16.671390533447266,27.984167098999023],[-16.91278076171875,28.34139060974121],[-16.15694808959961,28.572221755981445],[-16.341114044189453,28.37027931213379]]],[[[-14.32722282409668,28.046388626098633],[-13.869722366333008,28.75139045715332],[-13.923055648803711,28.24916648864746],[-14.32722282409668,28.046388626098633]]],[[[-17.831947326660156,28.453889846801758],[-17.90444564819336,28.849443435668945],[-17.716392517089844,28.746110916137695],[-17.831947326660156,28.453889846801758]]],[[[-13.609724044799805,28.926389694213867],[-13.852222442626953,28.906389236450195],[-13.442501068115234,29.23166847229004],[-13.609724044799805,28.926389694213867]]],[[[-2.925277709960938,35.26666450500488],[-2.946945190429688,35.32916450500488],[-2.914722442626953,35.27360725402832],[-2.925277709960938,35.26666450500488]]],[[[-5.31944465637207,35.87693977355957],[-5.345832824707031,35.84166145324707],[-5.395557403564453,35.916337966918945],[-5.31944465637207,35.87693977355957]]],[[[-3.036109924316406,35.91277503967285],[-3.051111221313477,35.91583442687988],[-3.0272216796875,35.92444038391113],[-3.036109924316406,35.91277503967285]]],[[[1.577779769897461,38.68777656555176],[1.390279769897461,38.643327713012695],[1.383054733276367,38.72055244445801],[1.577779769897461,38.68777656555176]]],[[[1.531667709350586,38.95194435119629],[1.211946487426758,38.898332595825195],[1.519723892211914,39.11833381652832],[1.531667709350586,38.95194435119629]]],[[[3.247777938842773,39.73472023010254],[3.47972297668457,39.71110725402832],[3.06361198425293,39.26361274719238],[2.364168167114258,39.55583381652832],[2.98777961730957,39.91111183166504],[3.247777938842773,39.73472023010254]]],[[[4.273332595825195,39.96138954162598],[4.276388168334961,39.8063907623291],[3.796945571899414,40.017221450805664],[4.273332595825195,39.96138954162598]]],[[[-7.855554580688477,43.75999641418457],[-7.044818878173828,43.49040412902832],[-1.780876159667969,43.35992622375488],[-0.562221527099609,42.781389236450195],[1.445833206176758,42.601945877075195],[1.723611831665039,42.50943946838379],[3.177656173706055,42.43680763244629],[3.17527961730957,41.86749458312988],[0.964445114135742,41.03277778625488],[0.048891067504883,40.03610420227051],[-0.338054656982422,39.435556411743164],[0.207223892211914,38.73221015930176],[-0.511667251586914,38.32499885559082],[-0.715555191040039,37.606943130493164],[-1.643610000610352,37.37277412414551],[-2.129165649414063,36.73138618469238],[-4.398332595825195,36.72222328186035],[-5.334506988525391,36.16256141662598],[-5.355798721313477,36.16330909729004],[-6.037500381469727,36.18027687072754],[-6.355554580688477,36.8608341217041],[-7.431854248046875,37.253190994262695],[-7.446945190429688,37.69944190979004],[-6.939167022705078,38.178056716918945],[-7.321111679077148,38.44944190979004],[-6.954792022705078,39.026384353637695],[-7.532505035400391,39.66942024230957],[-7.017221450805664,39.674997329711914],[-6.931667327880859,41.01805305480957],[-6.187221527099609,41.579721450805664],[-6.594165802001953,41.9536075592041],[-8.204723358154297,41.87471961975098],[-8.201223373413086,42.15274238586426],[-8.74500846862793,41.95250129699707],[-8.898612976074219,42.10805702209473],[-8.579723358154297,42.35166358947754],[-8.86916732788086,42.25139045715332],[-8.719446182250977,42.69583320617676],[-9.041389465332031,42.528886795043945],[-9.20944595336914,43.15277290344238],[-7.855554580688477,43.75999641418457]],[[-6.924999237060547,37.17083168029785],[-6.973054885864258,37.210275650024414],[-6.954166412353516,37.18027687072754],[-6.924999237060547,37.17083168029785]]]]}},{"type":"Feature","properties":{"name":"Saint Lucia","iso2":"LC","iso3":"LCA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-60.954727,13.709444],[-61.079445,13.879999],[-60.930283,14.109444],[-60.954727,13.709444]]]]}},{"type":"Feature","properties":{"name":"Sudan","iso2":"SD","iso3":"SDN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[37.268608000000114,20.75111],[37.242218,20.785831],[37.263855,20.84972400000011],[37.268608000000114,20.75111]]],[[[31.453888,21.998333000000102],[36.888466,22.000111000000132],[37.309441,21.060276],[37.10527000000016,21.212219],[37.433327000000105,18.858055],[38.600693,17.994881],[37.423286000000104,17.034214],[36.995827,17.073887],[36.97305300000019,16.269444],[36.44328300000021,15.149952],[36.5428160000001,14.262053],[36.142693,12.706923000000117],[35.70108,12.666115],[35.096939000000106,11.826944],[34.864441,10.734999],[34.594444,10.887777],[34.28611,10.554165],[34.120552,8.577221000000122],[33.252777,8.458611000000118],[32.991104,7.924999],[33.711388,7.660277],[34.70472,6.677777000000106],[35.30194100000014,5.378055],[35.821663,5.32861],[35.940552,4.622499],[34.388191,4.609682],[33.996666,4.222777000000136],[33.516937,3.752222],[33.016663,3.888611000000111],[32.193329,3.511389000000108],[31.176666,3.795278],[30.858818,3.493394000000137],[29.64333,4.643611000000135],[28.363052,4.29],[27.455276,5.016388],[27.142776,5.771944],[26.437496000000124,6.077777],[26.404999,6.646388],[25.206944000000135,7.497499],[25.25333,7.850555],[24.192497000000117,8.30361],[24.201111,8.686943],[23.517776,8.714167],[23.669167,9.866943],[22.866505,10.922447],[22.46694200000013,12.621666],[21.827774,12.797499000000144],[22.294167,13.35861],[22.084442,13.779165],[22.55499600000013,14.125555000000148],[22.384163,14.55416500000014],[22.935833,15.11611],[22.937222000000105,15.561943],[23.999603,15.698709],[24.002747,19.499065],[24.000832000000116,20.001942],[25.000832,19.999119],[25.001423,21.999695],[31.271111000000104,21.998333000000102],[31.455555000000146,22.23222],[31.453888,21.998333000000102]]]]}},{"type":"Feature","properties":{"name":"Sweden","iso2":"SE","iso3":"SWE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[16.836666,56.82694200000013],[16.420830000000194,56.211105],[17.105553,57.348328],[16.836666,56.82694200000013]]],[[[18.206108,56.91194200000011],[18.119164,57.531105],[19.004719000000136,57.908607],[18.206108,56.91194200000011]]],[[[19.334442,57.955826],[19.12611,57.839722],[19.034443,57.901108],[19.334442,57.955826]]],[[[11.594444,57.932495000000145],[11.501944,58.036659],[11.735884,58.041714],[11.594444,57.932495000000145]]],[[[16.816666,58.116104],[16.77861,58.100555],[16.801109,58.12332900000011],[16.816666,58.116104]]],[[[11.806389000000195,58.120552],[11.40111,58.13027200000012],[11.6775,58.286659000000114],[11.806389000000195,58.120552]]],[[[19.236942,58.337219],[19.186665,58.391388],[19.331108,58.366104],[19.236942,58.337219]]],[[[17.691387,58.91693900000014],[17.639164,58.971107],[17.6758310000001,59.054718],[17.691387,58.91693900000014]]],[[[18.40583,59.023888],[18.35722,59.034996],[18.479164000000196,59.11999500000012],[18.40583,59.023888]]],[[[18.537220000000133,59.223885],[18.389442000000145,59.284721],[18.610275000000144,59.254166000000126],[18.537220000000133,59.223885]]],[[[17.786942,59.310555],[17.6055530000001,59.416664],[17.773888,59.372772],[17.786942,59.310555]]],[[[17.734722000000147,59.296104],[17.817497,59.2777710000001],[17.62277600000013,59.30527500000012],[17.52027500000011,59.418327],[17.734722000000147,59.296104]]],[[[17.266388000000177,59.374443],[17.07,59.459442],[17.266941,59.44416],[17.266388000000177,59.374443]]],[[[18.575554,59.448326],[18.570274,59.526382],[18.746944,59.544998],[18.575554,59.448326]]],[[[18.57,60.307777],[18.401108,60.36527300000013],[18.374165000000175,60.4997180000001],[18.57,60.307777]]],[[[17.509163,62.363327],[17.367222000000197,62.471664],[17.472221,62.458328],[17.509163,62.363327]]],[[[18.060833000000173,62.67083],[18.039165,62.73555000000012],[18.153053000000142,62.728882],[18.060833000000173,62.67083]]],[[[20.885555,63.751663000000136],[20.83805500000011,63.773331],[20.928608000000168,63.773331],[20.885555,63.751663000000136]]],[[[21.809166,68.570541],[23.66611100000017,67.941666],[23.431110000000103,67.46554600000015],[23.76777600000011,67.41610700000014],[23.571663,67.15666200000011],[24.007774,66.800552],[23.661942,66.31221],[24.167007000000126,65.814026],[22.644722,65.905548],[22.3291660000001,65.829712],[22.40583,65.535263],[21.766941,65.722488],[22.199165,65.54527300000014],[21.260555,65.337494],[21.621387,65.142212],[21.03611000000018,64.8244320000001],[21.584999,64.439713],[20.777775,63.869164],[19.428055,63.549438],[18.20861100000019,62.77861],[17.696663,62.991943],[18.048054,62.601387],[17.32888800000012,62.486938],[17.654720000000168,62.23111],[17.34972000000016,61.945274],[17.498886,61.63582600000014],[17.140274,61.719719],[17.150555,60.945],[19.081944000000192,59.75972],[17.941109,59.335548],[17.764442,59.400551],[17.845276,59.53305100000013],[17.71722000000011,59.66333],[17.59222,59.656105000000125],[17.648331,59.66583300000015],[17.654163,59.718048],[17.594166,59.80693800000013],[17.4447210000001,59.676109],[17.543152000000163,59.573006],[17.513054000000125,59.706383],[17.618332,59.73138400000012],[17.561171000000172,59.668449],[17.786663,59.535828],[17.73111,59.442772],[17.38361,59.654999],[16.020275,59.49499500000012],[16.88999900000016,59.383331],[16.692776,59.471382],[16.84027500000019,59.48944100000013],[17.375832,59.247498],[17.35083,59.32444],[17.847221,59.264442],[18.289444000000174,59.368607],[18.466663,59.330276000000126],[18.434444,59.433609],[18.640274,59.338882],[18.277222,59.31082900000011],[18.311386,59.1325],[17.894722000000115,58.858887],[17.663887,59.168327],[17.349998,58.75222000000015],[16.193607,58.62749500000011],[16.93861,58.4841610000001],[16.413330000000116,58.474716],[16.824718,58.19944],[16.613888,57.98693800000011],[16.770554000000175,57.884438],[16.495552,57.98555],[16.70070600000011,57.74015],[16.418610000000115,57.893326],[16.693333,57.469162],[15.865555,56.092216],[14.696665,56.161110000000164],[14.217222,55.830276000000126],[14.193546,55.386147],[12.982222,55.400551],[13.059721,55.693054],[12.451666000000102,56.2977750000001],[12.813332000000145,56.23277300000011],[12.622221,56.411942],[12.887499000000162,56.638329],[11.698889000000179,57.697220000000144],[11.88611,58.211937],[11.798054,58.318329],[11.201387000000182,58.399437],[11.113333000000125,59.00360900000011],[11.429192000000114,58.98764],[11.751110000000153,59.0902710000001],[11.815960000000189,59.8461],[12.494165,60.1111070000001],[12.594444000000124,60.516937],[12.209999,61.002495],[12.85611,61.36249500000012],[12.124443,61.728607],[12.295832000000132,62.261665],[11.936388,63.272217],[12.139444000000111,63.58416],[12.938055,64.05332900000015],[13.988333000000154,64.01805100000014],[14.116388,64.470551],[13.662498,64.58276400000013],[14.49305500000014,65.313599],[14.504999,66.13249200000014],[15.468054000000109,66.283875],[15.362778,66.479996],[16.353886,67.017776],[16.085831,67.41165200000013],[16.726944000000174,67.899155],[17.884163,67.945541],[18.090832,68.50776700000013],[19.937775,68.33749400000012],[20.350277000000176,68.7866520000001],[20.096943,69.042221],[20.580929,69.060303],[21.809166,68.570541]]]]}},{"type":"Feature","properties":{"name":"Syrian Arab Republic","iso2":"SY","iso3":"SYR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[42.355614,37.106926],[41.290276,36.355553],[41.003876,34.419434],[38.794701,33.377594],[36.837776,32.313606],[35.648888,32.685272],[35.623634,33.245728],[36.623741,34.204994],[36.459999,34.635277],[35.972771,34.647499],[35.733887,35.581665],[35.92244,35.926994],[36.69026900000014,36.236107],[36.659943,36.83371],[39.229996,36.665276],[40.770821,37.11805],[42.355614,37.106926]]]]}},{"type":"Feature","properties":{"name":"Switzerland","iso2":"CH","iso3":"CHE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[7.697223,47.543327000000104],[8.576420000000155,47.59137],[8.566111,47.806938],[9.566724,47.540451],[9.533569,47.274544],[9.474637,47.057457],[9.598635,47.063835],[10.471235,46.871353],[10.465277000000128,46.546387],[10.050278000000105,46.539993],[10.129999000000112,46.22721900000015],[9.281944000000124,46.49582700000015],[9.036665,45.837776],[8.436388000000136,46.463333000000105],[7.855742,45.91905200000012],[7.038054,45.93193800000013],[6.791389000000152,46.434166],[5.966666,46.209442],[6.990555000000143,47.497215],[7.588268,47.58448],[7.697223,47.543327000000104]],[[8.710255,47.696808],[8.670555,47.711105],[8.678595,47.693344],[8.710255,47.696808]]]]}},{"type":"Feature","properties":{"name":"Trinidad and Tobago","iso2":"TT","iso3":"TTO"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-60.923058,10.797222],[-61.008057,10.140554000000122],[-61.91806,10.042776],[-61.458336,10.278332],[-61.662224,10.709166000000124],[-60.923058,10.797222]]],[[[-60.63945,11.203054],[-60.847504,11.158333000000141],[-60.526672,11.346109],[-60.63945,11.203054]]]]}},{"type":"Feature","properties":{"name":"Thailand","iso2":"TH","iso3":"THA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[99.219162,6.532499],[99.159988,6.548888],[99.256119,6.571944],[99.219162,6.532499]]],[[[99.668045,6.496387],[99.594986,6.593888],[99.66281100000012,6.702995],[99.668045,6.496387]]],[[[100.536087,7.15611000000014],[100.520813,7.154999],[100.534973,7.174166],[100.536087,7.15611000000014]]],[[[99.38916,7.194721],[99.39360000000013,7.270555000000144],[99.419144,7.234165000000147],[99.38916,7.194721]]],[[[99.110809,7.46805500000012],[99.04248,7.525832],[99.0241550000002,7.636666],[99.110809,7.46805500000012]]],[[[99.11970500000021,7.591944],[99.045822,7.669443000000101],[99.12191800000014,7.665277],[99.11970500000021,7.591944]]],[[[98.434708,7.930554],[98.418045,7.93611],[98.43692,7.94361],[98.434708,7.930554]]],[[[98.603592,7.901111],[98.526093,8.121386],[98.61192300000013,8.048609],[98.603592,7.901111]]],[[[98.39984100000018,7.941753],[98.305252,7.757222],[98.282486,8.186386000000155],[98.39984100000018,7.941753]]],[[[98.616653,8.084442000000124],[98.568329,8.11722],[98.628311,8.189165],[98.616653,8.084442000000124]]],[[[98.266663,9.030554],[98.28082300000014,9.158054],[98.324432,9.084164],[98.266663,9.030554]]],[[[97.87915,9.381941000000126],[97.835266,9.402777000000142],[97.847214,9.43222],[97.87915,9.381941000000126]]],[[[97.89888,9.437498],[97.847488,9.45860900000011],[97.883881,9.475554],[97.89888,9.437498]]],[[[99.681366,9.506109],[99.664993,9.524443],[99.7086029999999,9.53861],[99.681366,9.506109]]],[[[98.467484,9.574999000000105],[98.45776400000014,9.573887000000113],[98.464432,9.585554],[98.467484,9.574999000000105]]],[[[99.976089,9.41361000000012],[99.93220500000015,9.546944],[100.080833,9.58861],[99.976089,9.41361000000012]]],[[[99.685532,9.606665],[99.676651,9.607498],[99.67359900000011,9.629164],[99.685532,9.606665]]],[[[98.407211,9.714165],[98.380814,9.732775000000103],[98.40832500000013,9.770832],[98.407211,9.714165]]],[[[100.08167300000011,9.686665],[99.99054,9.711388000000142],[99.987488,9.796387],[100.08167300000011,9.686665]]],[[[102.59552,11.56361],[102.531357,11.601387],[102.560226,11.754396],[102.59552,11.56361]]],[[[102.435791,11.954165],[102.29135100000022,11.97444200000011],[102.250549,12.15],[102.435791,11.954165]]],[[[102.241089,12.283888],[102.235527,12.285276],[102.2397,12.299442],[102.241089,12.283888]]],[[[100.68887300000014,12.923609],[100.671654,12.938332],[100.676376,12.952776],[100.68887300000014,12.923609]]],[[[100.816673,13.129442],[100.807213,13.180277],[100.821381,13.15055500000011],[100.816673,13.129442]]],[[[100.08132200000014,20.348841],[100.09137,20.348606],[100.58046,20.157768000000104],[100.50360100000015,19.526665],[101.281097,19.562218],[100.921371,17.56721900000015],[101.162773,17.459995],[102.089394,18.214983000000146],[102.683594,17.819996],[103.397217,18.434994],[103.985527,18.321663],[104.71832300000014,17.50333],[104.747208,16.528332],[105.637772,15.659721],[105.536102,14.563332000000116],[105.210602,14.349648],[103.180542,14.32972],[102.37719700000011,13.573887],[102.916092,11.635851],[102.06025700000012,12.567497],[100.85386700000018,12.682775],[100.976349,13.462809],[100.066673,13.41999800000012],[100.021378,12.194164],[99.149155,10.365553],[99.237488,9.25416600000014],[99.847763,9.30083100000013],[100.421082,7.159444000000136],[101.541367,6.851388],[102.09523,6.236138],[101.833862,5.743332],[101.56997700000014,5.916666],[101.139687,5.631943],[101.11551700000021,6.248888000000122],[100.654968,6.448332],[100.214981,6.711110000000119],[100.127113,6.424947],[98.656372,8.38361],[98.27415500000015,8.274443000000119],[98.742752,10.348608],[99.661652,11.826942],[99.112198,13.055832],[99.173965,13.727781],[98.201096,15.074999],[98.92804,16.38583],[98.68969700000011,16.284996],[97.346375,18.562496000000138],[97.774704,18.569996],[98.049988,19.807499000000135],[98.995529,19.780552],[99.522766,20.352776000000134],[100.08132200000014,20.348841]]]]}},{"type":"Feature","properties":{"name":"Tajikistan","iso2":"TJ","iso3":"TJK"},"geometry":{"type":"MultiPolygon","coordinates":[[[[74.915741,37.237328],[73.307205,37.462753],[71.6772,36.67601],[71.429428,37.075829],[71.591934,37.902618],[71.252777,37.922035],[71.363037,38.248497],[70.967209,38.472115],[70.161377,37.933372],[70.155823,37.536232],[69.515823,37.580826],[69.315262,37.115273],[68.887772,37.3386],[68.058014,36.932526],[67.779877,37.185822],[68.384155,38.195541],[68.123871,38.98555],[67.376373,39.212494],[67.441956,39.483582],[68.540268,39.55471],[69.009995,40.089714],[68.600815,40.178329],[69.308029,40.201385],[69.356094,40.772491],[69.732483,40.638603],[70.423874,41.049118],[70.796799,40.725594],[70.375534,40.376404],[70.98204,40.244843],[70.498032,39.90683],[69.540817,40.131378],[69.306091,39.539436],[70.997757,39.40094],[71.473038,39.6213],[72.248596,39.191856],[73.655685,39.454826],[73.817764,38.607712],[74.8566440000001,38.470482],[74.902771,37.647156],[75.187485,37.406586000000104],[74.915741,37.237328]]]]}},{"type":"Feature","properties":{"name":"Tokelau","iso2":"TK","iso3":"TKL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-171.214722,-9.377499],[-171.223907,-9.378889],[-171.224701,-9.345556],[-171.214722,-9.377499]]],[[[-171.843079,-9.207502],[-171.860535,-9.206667],[-171.853882,-9.168058],[-171.843079,-9.207502]]],[[[-172.483917,-8.587221],[-172.496979,-8.553888],[-172.483612,-8.566666],[-172.483917,-8.587221]]]]}},{"type":"Feature","properties":{"name":"Tonga","iso2":"TO","iso3":"TON"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-174.91085815429688,-21.426666259765625],[-174.97470092773438,-21.365833282470703],[-174.91143798828125,-21.306110382080078],[-174.91085815429688,-21.426666259765625]]],[[[-175.14584350585938,-21.178058624267578],[-175.35946655273438,-21.099170684814453],[-175.0472412109375,-21.139442443847656],[-175.14584350585938,-21.178058624267578]]],[[[-174.76083374023438,-20.276390075683594],[-174.79196166992188,-20.234722137451172],[-174.76004028320312,-20.237224578857422],[-174.76083374023438,-20.276390075683594]]],[[[-174.4139404296875,-19.926666259765625],[-174.42254638671875,-19.910003662109375],[-174.390869140625,-19.881668090820312],[-174.4139404296875,-19.926666259765625]]],[[[-174.318603515625,-19.821945190429688],[-174.35498046875,-19.81195068359375],[-174.31585693359375,-19.764171600341797],[-174.318603515625,-19.821945190429688]]],[[[-175.05667114257812,-19.800838470458984],[-175.09860229492188,-19.749725341796875],[-175.08169555664062,-19.706390380859375],[-175.05667114257812,-19.800838470458984]]],[[[-174.27252197265625,-19.752784729003906],[-174.30722045898438,-19.740833282470703],[-174.25613403320312,-19.688053131103516],[-174.27252197265625,-19.752784729003906]]],[[[-175.01834106445312,-19.691387176513672],[-175.03585815429688,-19.676666259765625],[-175.00558471679688,-19.65250015258789],[-175.01834106445312,-19.691387176513672]]],[[[-174.24447631835938,-19.656112670898438],[-174.28195190429688,-19.634445190429688],[-174.29196166992188,-19.594444274902344],[-174.24447631835938,-19.656112670898438]]],[[[-174.64697265625,-18.830280303955078],[-174.675048828125,-18.804447174072266],[-174.6497802734375,-18.783058166503906],[-174.62307739257812,-18.809444427490234],[-174.64697265625,-18.830280303955078]]],[[[-174.0614013671875,-18.704723358154297],[-174.09780883789062,-18.696388244628906],[-174.07363891601562,-18.681110382080078],[-174.0614013671875,-18.704723358154297]]],[[[-174.01974487304688,-18.717220306396484],[-174.0433349609375,-18.680835723876953],[-174.01919555664062,-18.694446563720703],[-174.01974487304688,-18.717220306396484]]],[[[-174.0897216796875,-18.674171447753906],[-174.1280517578125,-18.70333480834961],[-174.11581420898438,-18.671390533447266],[-174.0897216796875,-18.674171447753906]]],[[[-173.91055297851562,-18.638057708740234],[-174.07058715820312,-18.632503509521484],[-173.939208984375,-18.568893432617188],[-173.91055297851562,-18.638057708740234]]],[[[-175.64474487304688,-15.629167556762695],[-175.68392944335938,-15.589723587036133],[-175.62139892578125,-15.560834884643555],[-175.64474487304688,-15.629167556762695]]]]}},{"type":"Feature","properties":{"name":"Togo","iso2":"TG","iso3":"TGO"},"geometry":{"type":"MultiPolygon","coordinates":[[[[1.398542,9.429901],[1.635404,6.218721],[1.198891,6.100546],[0.525,6.947778],[0.727222,8.321388],[0.382735,8.760756],[0.550833,9.411388],[0.2175,9.457222],[0.368333,10.259443],[-0.149762,11.13854],[0.91797,10.996399],[0.776667,10.376665],[1.355,9.995277],[1.398542,9.429901]]]]}},{"type":"Feature","properties":{"name":"Sao Tome and Principe","iso2":"ST","iso3":"STP"},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.523889000000139,0.018333],[6.467222,0.259722000000139],[6.687778,0.402222],[6.523889000000139,0.018333]]],[[[7.423055,1.556111],[7.327222,1.607222000000107],[7.406666000000143,1.701944000000154],[7.423055,1.556111]]]]}},{"type":"Feature","properties":{"name":"Tunisia","iso2":"TN","iso3":"TUN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[10.99361,33.75],[10.865,33.638611],[10.72611,33.880829],[10.99361,33.75]]],[[[11.064722,34.64054900000015],[11.03500000000011,34.617493000000124],[10.961111000000102,34.655273],[11.064722,34.64054900000015]]],[[[11.13722,34.675278],[11.230833,34.821106],[11.302221,34.80332900000012],[11.13722,34.675278]]],[[[10.808611,37.119438],[10.791943,37.126389],[10.814722,37.125275000000116],[10.808611,37.119438]]],[[[9.845247000000143,37.139351],[10.252499,37.186386],[10.381943000000149,36.723328],[11.067778000000118,37.051384],[10.455276,36.123329],[11.128887,35.23583200000017],[10.005833,34.16693900000011],[10.331944,33.700272],[11.048611,33.61694300000012],[11.17111,33.210831],[11.526081,33.171135],[11.567499,32.442215],[10.287222,31.694164],[10.21361,30.730831],[9.537113,30.23439],[9.055277,32.099998],[8.34861,32.533333],[7.492499000000123,33.887497],[8.251665,34.64444],[8.183611,36.524162],[8.62203,36.941368],[9.672499000000187,37.338051],[9.845247000000143,37.139351]]],[[[8.917776000000174,37.510826],[8.896111000000133,37.525833],[8.9447210000001,37.538055],[8.917776000000174,37.510826]]]]}},{"type":"Feature","properties":{"name":"Turkey","iso2":"TR","iso3":"TUR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[26.078053,39.783600000000106],[25.97499500000015,39.829987],[26.07582900000017,39.839722],[26.078053,39.783600000000106]]],[[[25.824444,40.100266],[25.66388300000017,40.126389],[26.013611,40.157494],[25.824444,40.100266]]],[[[27.607220000000154,40.57222],[27.531109,40.648331],[27.735271,40.634438000000145],[27.607220000000154,40.57222]]],[[[35.09693100000018,41.961655],[35.506386000000106,41.638054],[36.051102,41.691933],[36.429153,41.242775],[38.361382,40.909431],[40.149994,40.920273],[41.531559,41.523876],[42.827492,41.584991],[43.46077,41.112961],[43.75193800000014,40.739998],[43.65749400000013,40.10859700000016],[44.347214,40.023888],[44.778862,39.70638300000017],[44.813042,39.630814],[44.605820000000136,39.78054],[44.4161,39.425262],[44.034157,39.3849950000001],[44.484154,38.345543],[44.223969,37.899151],[44.61805,37.727768],[44.787338,37.149712],[44.317215,36.970543],[44.116379,37.316376],[42.790825000000126,37.384720000000144],[42.355614,37.106926],[40.770821,37.11805],[39.229996,36.665276],[36.659943,36.83371],[36.69026900000014,36.236107],[35.92244,35.926994],[35.783875,36.312485],[36.217766,36.654999],[36.02193500000013,36.926384],[35.339989,36.539162],[34.659431,36.805275],[33.98860200000016,36.277771],[32.808884,36.02555100000011],[31.046661,36.849152],[30.623333000000144,36.850822],[30.40694,36.203606],[29.67721600000013,36.11833200000014],[28.454163,36.881386],[27.983887,36.55277300000013],[28.118332,36.800278],[27.37944000000016,36.680832],[28.328606,37.039719],[27.252499,36.96749900000013],[27.595276,37.232491],[27.193886,37.350822],[27.267773000000147,37.955544],[26.275829,38.264435],[26.369999,38.661942],[26.682217,38.307487],[27.161942000000124,38.443886],[26.730827,38.645821],[27.064442,38.874435],[26.644722000000144,39.263054],[26.951664,39.552773],[26.067219,39.483047],[26.707222,40.384995],[28.985271,40.356934],[28.795277,40.551384],[29.938049,40.723885],[29.12944000000016,40.914444],[29.166111,41.226662],[31.23111,41.0888750000001],[33.33387800000017,42.020264],[35.09693100000018,41.961655]]],[[[27.394997,42.008041],[28.013054,41.982216],[28.090549000000124,41.631386],[29.039162,41.057213],[27.50972,40.983597],[26.181107,40.045273],[26.826939,40.594437],[26.044720000000154,40.735825],[26.63388400000011,41.35443900000014],[26.361095,41.711052],[27.394997,42.008041]]]]}},{"type":"Feature","properties":{"name":"Tuvalu","iso2":"TV","iso3":"TUV"},"geometry":{"type":"MultiPolygon","coordinates":[[[[179.222366,-8.554146],[179.203705,-8.462443],[179.231094,-8.50492],[179.222366,-8.554146]]],[[[178.366913,-8.062778],[178.355804,-8.06139],[178.36969,-8.0275],[178.366913,-8.062778]]],[[[178.39776599999985,-8.015278],[178.39151,-8],[178.4030460000001,-7.991388],[178.39776599999985,-8.015278]]],[[[178.700531,-7.482223],[178.687469,-7.478889],[178.690796,-7.464445],[178.700531,-7.482223]]],[[[177.158875,-7.187778],[177.146362,-7.188611],[177.142212,-7.173611],[177.158875,-7.187778]]],[[[176.310242,-6.285556],[176.295258,-6.278056],[176.30886800000016,-6.257501],[176.310242,-6.285556]]],[[[177.295807,-6.113889],[177.28137200000012,-6.089444],[177.308868,-6.098889],[177.295807,-6.113889]]],[[[176.139709,-5.690556],[176.130249,-5.693333],[176.12939500000013,-5.675],[176.139709,-5.690556]]],[[[176.08136,-5.665277],[176.066376,-5.665277],[176.079407,-5.657778],[176.08136,-5.665277]]]]}},{"type":"Feature","properties":{"name":"Turkmenistan","iso2":"TM","iso3":"TKM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[53.069719314575195,38.89972114562988],[53.0786075592041,39.093881607055664],[53.10000038146973,38.751108169555664],[53.069719314575195,38.89972114562988]]],[[[58.78055000305176,42.65804481506348],[60.01444435119629,42.21749305725098],[60.140275955200195,41.38110542297363],[61.874162673950195,41.12555122375488],[62.551103591918945,39.934160232543945],[64.38302803039551,38.95312690734863],[66.64387702941895,38.00305366516113],[66.5377368927002,37.36638069152832],[65.7088794708252,37.53860664367676],[64.79803657531738,37.1249942779541],[64.50360298156738,36.28055000305176],[63.11944007873535,35.86194038391113],[63.10527229309082,35.45083045959473],[62.72221565246582,35.254716873168945],[62.309160232543945,35.14166450500488],[61.276559829711914,35.607248306274414],[61.15721321105957,36.64999580383301],[60.33305549621582,36.65609931945801],[59.338884353637695,37.53916358947754],[57.450273513793945,37.939157485961914],[57.21221351623535,38.281938552856445],[55.442766189575195,38.08610725402832],[54.681108474731445,37.44360542297363],[53.90564155578613,37.35085487365723],[53.9838809967041,38.91582679748535],[53.54138374328613,39.335824966430664],[53.162492752075195,39.175554275512695],[53.26416206359863,39.6552677154541],[53.73443794250488,39.523881912231445],[53.40832710266113,39.66582679748535],[53.57583045959473,39.96610450744629],[52.93471717834473,39.990549087524414],[53.004716873168945,39.762216567993164],[52.721933364868164,40.44610023498535],[52.91860389709473,41.08166694641113],[53.74638557434082,40.61527442932129],[54.41777229309082,40.7036075592041],[54.24471473693848,40.88027381896973],[54.7338809967041,41.10222053527832],[54.072771072387695,41.47554969787598],[53.80388069152832,42.12388038635254],[52.94665718078613,41.97304725646973],[52.81582832336426,41.69582557678223],[52.88193702697754,41.04722023010254],[52.440073013305664,41.74093818664551],[53.01500129699707,42.13888740539551],[54.173051834106445,42.33721351623535],[55.45694160461426,41.28666114807129],[56.00096321105957,41.32845497131348],[57.04471778869629,41.26027870178223],[56.98694038391113,41.89305305480957],[58.0266056060791,42.50464057922363],[58.51555061340332,42.3044376373291],[58.164438247680664,42.651933670043945],[58.78055000305176,42.65804481506348]]]]}},{"type":"Feature","properties":{"name":"United Republic of Tanzania","iso2":"TZ","iso3":"TZA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[39.682495,-7.993334],[39.591385,-7.945834],[39.901108,-7.638889],[39.682495,-7.993334]]],[[[39.4466630000002,-6.210556],[39.516106,-6.468612],[39.201385,-6.226945],[39.304161,-5.723889],[39.4466630000002,-6.210556]]],[[[39.736107,-5.462778],[39.676941,-4.941389],[39.857216,-4.908611],[39.736107,-5.462778]]],[[[31.677219,-0.999722],[33.920273,-1.001111],[37.602776,-2.995833],[37.613609,-3.504167],[39.20302600000011,-4.669618],[38.776382,-6.045556],[39.5478820000001,-6.994313],[39.274437,-7.579167],[39.387772,-8.9025],[39.8263850000001,-9.993057],[40.43681300000017,-10.478174],[39.268051000000156,-11.168056],[37.941383,-11.285002],[37.462044,-11.727329],[36.18972,-11.706667],[35.838333,-11.414722],[34.966728,-11.572111],[34.325272,-9.732779],[33.13472000000016,-9.494167],[32.940399,-9.405077],[31.041111,-8.590279],[30.77124000000012,-8.192247],[29.550278,-6.295279],[29.423885,-4.448056],[30.026108000000107,-4.269444],[30.83499900000018,-3.256945],[30.843662,-2.978794],[30.4175,-2.861945],[30.57333,-2.399167],[30.894165,-2.076111],[30.48222,-1.063334],[31.677219,-0.999722]]]]}},{"type":"Feature","properties":{"name":"Uganda","iso2":"UG","iso3":"UGA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[33.996666,4.222777000000136],[34.463333,3.671389],[35.0097200000001,1.895278],[33.907219,0.103056],[33.920273,-1.001111],[31.677219,-0.999722],[30.48222,-1.063334],[29.974998,-1.464445],[29.596943,-1.385834],[29.960552,0.825555],[31.302776,2.121388],[30.729721000000126,2.448055],[30.858818,3.493394000000137],[31.176666,3.795278],[32.193329,3.511389000000108],[33.016663,3.888611000000111],[33.516937,3.752222],[33.996666,4.222777000000136]]]]}},{"type":"Feature","properties":{"name":"United Kingdom","iso2":"GB","iso3":"GBR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-6.29083251953125,49.91221809387207],[-6.317499160766602,49.9152774810791],[-6.295000076293945,49.93388557434082],[-6.29083251953125,49.91221809387207]]],[[[-1.059720993041992,50.6874942779541],[-1.569999694824219,50.66055488586426],[-1.296943664550781,50.77194404602051],[-1.059720993041992,50.6874942779541]]],[[[-0.938331604003906,50.77749824523926],[-1.022499084472656,50.78582954406738],[-0.970832824707031,50.830827713012695],[-0.938331604003906,50.77749824523926]]],[[[-4.651666641235352,51.159440994262695],[-4.673334121704102,51.161386489868164],[-4.665555953979492,51.19500160217285],[-4.651666641235352,51.159440994262695]]],[[[-4.571388244628906,53.23861122131348],[-4.693889617919922,53.3013858795166],[-4.621665954589844,53.32139015197754],[-4.571388244628906,53.23861122131348]]],[[[-4.15333366394043,53.22555732727051],[-4.4022216796875,53.12583351135254],[-4.56916618347168,53.3880558013916],[-4.15333366394043,53.22555732727051]]],[[[-6.35333251953125,55.23777961730957],[-5.688055038452148,54.806108474731445],[-5.908332824707031,54.60472297668457],[-5.429721832275391,54.48360633850098],[-6.266975402832031,54.09983253479004],[-7.030834197998047,54.41777229309082],[-7.559444427490234,54.12693977355957],[-8.159444808959961,54.44194221496582],[-7.406389236450195,54.95333290100098],[-7.252506256103516,55.07059669494629],[-6.35333251953125,55.23777961730957]]],[[[-6.17277717590332,55.29305458068848],[-6.188333511352539,55.259721755981445],[-6.282499313354492,55.29222297668457],[-6.17277717590332,55.29305458068848]]],[[[-5.103610992431641,55.438608169555664],[-5.381111145019531,55.66861152648926],[-5.1602783203125,55.67916297912598],[-5.103610992431641,55.438608169555664]]],[[[-6.121665954589844,55.87888526916504],[-6.076665878295898,55.64999580383301],[-6.509166717529297,55.68222236633301],[-6.121665954589844,55.87888526916504]]],[[[-5.016387939453125,55.721940994262695],[-5.206388473510742,55.89943885803223],[-5.036388397216797,55.837778091430664],[-5.016387939453125,55.721940994262695]]],[[[-6.193889617919922,56.02916145324707],[-6.263055801391602,56.03611183166504],[-6.130832672119141,56.12082862854004],[-6.193889617919922,56.02916145324707]]],[[[-5.946945190429688,55.82999610900879],[-6.078887939453125,55.90555000305176],[-5.69444465637207,56.14721870422363],[-5.946945190429688,55.82999610900879]]],[[[-5.735000610351563,56.15805244445801],[-5.675277709960938,56.19194221496582],[-5.675832748413086,56.169443130493164],[-5.735000610351563,56.15805244445801]]],[[[-5.629999160766602,56.19693946838379],[-5.641944885253906,56.26027870178223],[-5.606388092041016,56.25444221496582],[-5.629999160766602,56.19693946838379]]],[[[-5.616666793823242,56.26888465881348],[-5.64555549621582,56.30111122131348],[-5.583889007568359,56.319719314575195],[-5.616666793823242,56.26888465881348]]],[[[-6.404722213745117,56.303606033325195],[-6.43638801574707,56.310556411743164],[-6.38194465637207,56.340829849243164],[-6.404722213745117,56.303606033325195]]],[[[-5.543611526489258,56.38277626037598],[-5.587778091430664,56.38916206359863],[-5.510000228881836,56.41111183166504],[-5.543611526489258,56.38277626037598]]],[[[-6.16583251953125,56.46472358703613],[-6.260000228881836,56.481943130493164],[-6.215555191040039,56.49777412414551],[-6.16583251953125,56.46472358703613]]],[[[-6.739166259765625,56.51583290100098],[-6.892778396606445,56.438608169555664],[-6.990833282470703,56.49444007873535],[-6.739166259765625,56.51583290100098]]],[[[-5.783611297607422,56.50889015197754],[-5.648332595825195,56.43583106994629],[-5.808610916137695,56.3174991607666],[-6.366111755371094,56.30888557434082],[-6.017778396606445,56.37471961975098],[-6.193611145019531,56.36138343811035],[-6.002777099609375,56.49416542053223],[-6.319999694824219,56.60305213928223],[-5.783611297607422,56.50889015197754]]],[[[-6.589166641235352,56.57999610900879],[-6.698888778686523,56.57999610900879],[-6.454444885253906,56.686105728149414],[-6.589166641235352,56.57999610900879]]],[[[-6.144721984863281,56.86999702453613],[-6.213054656982422,56.90694618225098],[-6.113611221313477,56.93249702453613],[-6.144721984863281,56.86999702453613]]],[[[-6.317499160766602,56.93416786193848],[-6.451665878295898,57.00610542297363],[-6.261667251586914,57.03777503967285],[-6.317499160766602,56.93416786193848]]],[[[-7.466943740844727,56.94082832336426],[-7.559999465942383,56.960275650024414],[-7.439722061157227,57.05444526672363],[-7.466943740844727,56.94082832336426]]],[[[-6.499166488647461,57.05221748352051],[-6.602500915527344,57.04638862609863],[-6.549444198608398,57.06805610656738],[-6.499166488647461,57.05221748352051]]],[[[-5.939167022705078,57.27805519104004],[-6.017778396606445,57.311662673950195],[-5.933889389038086,57.311662673950195],[-5.939167022705078,57.27805519104004]]],[[[-7.223054885864258,57.33749580383301],[-7.381389617919922,57.10860633850098],[-7.424999237060547,57.382219314575195],[-7.223054885864258,57.33749580383301]]],[[[-7.268888473510742,57.39888954162598],[-7.406389236450195,57.46416664123535],[-7.204721450805664,57.460832595825195],[-7.268888473510742,57.39888954162598]]],[[[-6.026945114135742,57.3286075592041],[-6.078332901000977,57.39416694641113],[-5.979999542236328,57.49582862854004],[-6.026945114135742,57.3286075592041]]],[[[-6.143888473510742,57.56805610656738],[-6.127222061157227,57.306108474731445],[-5.663888931274414,57.20499610900879],[-6.011943817138672,57.02221870422363],[-6.785833358764648,57.44610786437988],[-6.143888473510742,57.56805610656738]]],[[[-5.967777252197266,57.522775650024414],[-5.990833282470703,57.54083442687988],[-5.961666107177734,57.57499885559082],[-5.967777252197266,57.522775650024414]]],[[[-7.18861198425293,57.68721961975098],[-7.153888702392578,57.50943946838379],[-7.543333053588867,57.590829849243164],[-7.18861198425293,57.68721961975098]]],[[[-7.196666717529297,57.702219009399414],[-7.219165802001953,57.707773208618164],[-7.144721984863281,57.72361183166504],[-7.196666717529297,57.702219009399414]]],[[[-8.555278778076172,57.81083106994629],[-8.582500457763672,57.79888343811035],[-8.621389389038086,57.82277870178223],[-8.555278778076172,57.81083106994629]]],[[[-7.006389617919922,57.88138771057129],[-7.077777862548828,57.8799991607666],[-6.993610382080078,57.91861152648926],[-7.006389617919922,57.88138771057129]]],[[[-6.204166412353516,58.35611152648926],[-6.473888397216797,57.94027900695801],[-7.123056411743164,57.8174991607666],[-6.830278396606445,57.900835037231445],[-7.040555953979492,58.23333168029785],[-6.204166412353516,58.35611152648926]],[[-6.802221298217773,58.20305061340332],[-6.88972282409668,58.25249671936035],[-6.869167327880859,58.20388984680176],[-6.802221298217773,58.20305061340332]]],[[[-4.15333366394043,53.22555732727051],[-2.702499389648438,53.346384048461914],[-3.107500076293945,53.55166816711426],[-2.81361198425293,54.2227725982666],[-3.226110458374023,54.09861183166504],[-3.634166717529297,54.51194190979004],[-3.023056030273438,54.97055244445801],[-4.393054962158203,54.90805244445801],[-4.387222290039063,54.675554275512695],[-4.852222442626953,54.868608474731445],[-4.941110610961914,54.64888954162598],[-5.174165725708008,55.00055122375488],[-4.613332748413086,55.49499702453613],[-4.879722595214844,55.936105728149414],[-4.481668472290039,55.92110633850098],[-4.828605651855469,56.1131649017334],[-5.303333282470703,55.85055732727051],[-5.032222747802734,56.232500076293945],[-5.777500152587891,55.29666328430176],[-5.573610305786133,56.324716567993164],[-5.107778549194336,56.50777626037598],[-5.398666381835938,56.47866630554199],[-5.120000839233398,56.816667556762695],[-5.676944732666016,56.4938907623291],[-6.008333206176758,56.63749885559082],[-5.546943664550781,56.69194221496582],[-6.235000610351563,56.71916389465332],[-5.399723052978516,57.1058292388916],[-5.64961051940918,57.161611557006836],[-5.450277328491211,57.42027473449707],[-5.81916618347168,57.3638858795166],[-5.508611679077148,57.53472328186035],[-5.816667556762695,57.821664810180664],[-5.102777481079102,57.85083198547363],[-5.455278396606445,58.07638740539551],[-5.004722595214844,58.62333106994629],[-3.025554656982422,58.64750099182129],[-3.208610534667969,58.30444526672363],[-4.392221450805664,57.90527534484863],[-3.773056030273438,57.85110664367676],[-4.435832977294922,57.57499885559082],[-2.075555801391602,57.69944190979004],[-1.773332595825195,57.45805549621582],[-2.5272216796875,56.5786075592041],[-3.278055191040039,56.357500076293945],[-2.58277702331543,56.26805305480957],[-3.725276947021484,56.02749824523926],[-2.631111145019531,56.05471992492676],[-1.633888244628906,55.580827713012695],[-1.29749870300293,54.76361274719238],[-0.07499885559082,54.11194038391113],[0.11805534362793,53.56443977355957],[-0.718889236450195,53.699716567993164],[0.235555648803711,53.39943885803223],[0.341669082641602,53.095834732055664],[0.000036239624023,52.87954902648926],[1.282224655151367,52.927499771118164],[1.749444961547852,52.455827713012695],[1.223611831665039,51.80888557434082],[0.699724197387695,51.71944618225098],[0.950555801391602,51.60638618469238],[0.382780075073242,51.4505558013916],[1.385557174682617,51.387773513793945],[0.975000381469727,50.93194007873535],[0.242223739624023,50.738054275512695],[-0.254999160766602,50.82638740539551],[-0.796388626098633,50.72527503967285],[-0.926942825317383,50.83944129943848],[-1.154722213745117,50.84416389465332],[-2.434450149536133,50.541791915893555],[-2.924722671508789,50.731943130493164],[-3.716667175292969,50.20666694641113],[-4.379999160766602,50.3638858795166],[-5.193056106567383,49.955278396606445],[-5.712499618530273,50.053606033325195],[-4.226388931274414,51.189165115356445],[-3.02833366394043,51.20611000061035],[-2.379999160766602,51.75555610656738],[-3.346111297607422,51.378610610961914],[-5.246944427490234,51.73027229309082],[-4.130832672119141,52.33471870422363],[-4.133611679077148,52.914445877075195],[-4.760862350463867,52.78897285461426],[-4.15333366394043,53.22555732727051]],[[0.904722213745117,51.35805702209473],[0.908891677856445,51.416940689086914],[0.735002517700195,51.408334732055664],[0.904722213745117,51.35805702209473]]],[[[-2.918333053588867,58.731943130493164],[-3.036945343017578,58.81805610656738],[-2.886388778686523,58.83194160461426],[-2.918333053588867,58.731943130493164]]],[[[-3.231388092041016,58.77555274963379],[-3.418054580688477,58.90416145324707],[-3.134721755981445,58.80082893371582],[-3.231388092041016,58.77555274963379]]],[[[-2.793054580688477,58.95138740539551],[-3.194999694824219,58.91111183166504],[-3.351388931274414,59.10638618469238],[-2.793054580688477,58.95138740539551]]],[[[-2.681388854980469,59.19583320617676],[-2.55555534362793,59.303056716918945],[-2.390277862548828,59.28305244445801],[-2.681388854980469,59.19583320617676]]],[[[-2.889999389648438,59.29527473449707],[-2.877498626708984,59.22860908508301],[-3.076389312744141,59.33138465881348],[-2.889999389648438,59.29527473449707]]],[[[-1.296110153198242,60.491106033325195],[-1.037221908569336,60.444162368774414],[-1.268610000610352,59.85110664367676],[-1.291389465332031,60.24138832092285],[-1.693056106567383,60.27971839904785],[-1.296110153198242,60.491106033325195]]],[[[-1.029443740844727,60.49582862854004],[-1.170276641845703,60.52722358703613],[-1.098609924316406,60.729997634887695],[-1.029443740844727,60.49582862854004]]],[[[-0.819721221923828,60.68889045715332],[-0.965555191040039,60.68805122375488],[-0.878332138061523,60.84444618225098],[-0.758054733276367,60.81777381896973],[-0.819721221923828,60.68889045715332]]]]}},{"type":"Feature","properties":{"name":"Ukraine","iso2":"UA","iso3":"UKR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[33.040276000000205,46.011375],[32.759438,46.036110000000136],[32.965271,46.049431],[33.040276000000205,46.011375]]],[[[34.227486,46.061928],[34.158043000000106,46.100548],[34.229149,46.187759000000156],[34.227486,46.061928]]],[[[32.16776300000018,46.14582100000011],[31.584164,46.253319],[31.501106000000135,46.366653],[32.16776300000018,46.14582100000011]]],[[[33.41770200000022,52.3554],[33.838882,52.36055],[34.419716,51.808884],[34.098045000000155,51.65387700000015],[34.38221,51.263611],[35.37188700000016,51.041435],[35.606651,50.369438],[37.458603000000124,50.439713],[38.024223,49.903084],[38.30777,50.073883],[40.13976300000016,49.601051],[40.16693900000021,49.248604],[39.69665500000016,49.010826],[40.07666,48.87499200000012],[39.656937,48.616661],[39.998878,48.297218],[39.796387,47.857216],[38.853600000000114,47.860825],[38.303322,47.558594],[38.23582500000012,47.109428],[35.907204,46.65109300000013],[34.98526800000016,46.075829],[35.198044,46.443314],[35.05304,46.258041],[34.702492,46.175819],[34.561661000000214,45.984993],[34.401649000000106,46.013878],[34.542496,46.187485],[33.671928,46.220818],[34.63332400000016,45.94165],[34.46054100000012,45.7672120000001],[35.126656,45.326096],[35.34304,45.332497],[35.050262,45.613884],[34.763054,46.01554900000012],[34.666939,46.093597],[34.82720900000018,46.069443],[35.05387900000014,45.65387],[35.311661,45.38304100000012],[35.475266,45.29110000000016],[36.637215,45.376099],[36.439713,45.065536],[35.515266,45.116096],[33.955544000000174,44.38110400000012],[33.366936,44.579163],[33.54193900000021,45.111931],[32.48053700000017,45.395821],[33.771935,45.920540000000116],[33.611382,46.14721700000017],[31.791943000000146,46.2830510000001],[32.05915100000013,46.395821],[31.507771,46.57972],[32.647217,46.641106],[32.019707,46.629433000000134],[31.749435,47.25331900000013],[31.907494000000185,46.648872],[30.832771,46.548325],[30.25165900000016,45.876656],[29.746941000000135,45.619431],[29.633606,45.821106000000114],[29.664331,45.211803],[28.21484,45.448647],[28.971935,46.006653],[28.994434,46.47832500000011],[30.11694,46.386101],[29.949997,46.814156],[29.184441,47.443047],[29.141937000000155,47.98609200000014],[27.755554,48.451385],[26.634995,48.257164],[24.91944100000012,47.711662],[22.894804,47.95454],[22.151442,48.411919],[22.558052,49.079437],[22.886074,49.002914],[22.680828000000105,49.572495],[24.111385,50.56694],[23.604633,51.527695],[24.396664,51.886658],[25.775829000000158,51.939156],[30.551414000000108,51.251846],[30.94309600000011,52.073792000000125],[31.783886,52.108047],[33.41770200000022,52.3554]]]]}},{"type":"Feature","properties":{"name":"United States","iso2":"US","iso3":"USA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-75.1702880859375,19.9313907623291],[-75.22372436523438,19.90155601501465],[-75.1591796875,19.960695266723633],[-75.1702880859375,19.9313907623291]]],[[[-75.12139892578125,19.88749885559082],[-75.13973999023438,19.962873458862305],[-75.08528137207031,19.893041610717773],[-75.12139892578125,19.88749885559082]]],[[[-155.00558471679688,19.328882217407227],[-155.85946655273438,19.032777786254883],[-155.86444091796875,20.269163131713867],[-155.15863037109375,19.962495803833008],[-154.79281616210938,19.538610458374023],[-155.00558471679688,19.328882217407227]]],[[[-156.5472412109375,20.5252742767334],[-156.69863891601562,20.534719467163086],[-156.58529663085938,20.607221603393555],[-156.5472412109375,20.5252742767334]]],[[[-156.89199829101562,20.74416160583496],[-157.04837036132812,20.918054580688477],[-156.812255859375,20.843610763549805],[-156.89199829101562,20.74416160583496]]],[[[-156.47335815429688,20.89805030822754],[-155.98861694335938,20.7480525970459],[-156.42001342773438,20.58860969543457],[-156.70223999023438,20.924436569213867],[-156.47335815429688,20.89805030822754]]],[[[-156.89447021484375,21.161104202270508],[-156.70391845703125,21.158052444458008],[-157.30474853515625,21.100553512573242],[-156.89447021484375,21.161104202270508]]],[[[-160.53060913085938,21.643888473510742],[-160.53778076171875,21.63221549987793],[-160.5411376953125,21.641382217407227],[-160.53060913085938,21.643888473510742]]],[[[-157.73031616210938,21.41166114807129],[-158.1036376953125,21.295278549194336],[-158.27337646484375,21.580549240112305],[-157.971923828125,21.699438095092773],[-157.73031616210938,21.41166114807129]]],[[[-160.114990234375,21.88749885559082],[-160.24777221679688,21.813608169555664],[-160.0614013671875,22.013883590698242],[-160.114990234375,21.88749885559082]]],[[[-159.43362426757812,21.88138771057129],[-159.78530883789062,22.061384201049805],[-159.35165405273438,22.22138023376465],[-159.43362426757812,21.88138771057129]]],[[[-161.94168090820312,23.039438247680664],[-161.94833374023438,23.047216415405273],[-161.93832397460938,23.046388626098633],[-161.94168090820312,23.039438247680664]]],[[[-164.69613647460938,23.56471824645996],[-164.70751953125,23.5766658782959],[-164.69668579101562,23.578054428100586],[-164.69613647460938,23.56471824645996]]],[[[-81.77389526367188,24.544721603393555],[-81.8134994506836,24.54387092590332],[-81.72917175292969,24.560556411743164],[-81.77389526367188,24.544721603393555]]],[[[-82.11444091796875,24.54583168029785],[-82.13722229003906,24.593889236450195],[-82.09999084472656,24.58305549621582],[-82.11444091796875,24.54583168029785]]],[[[-81.71511840820312,24.553117752075195],[-81.71073913574219,24.595720291137695],[-81.64622497558594,24.577550888061523],[-81.71511840820312,24.553117752075195]]],[[[-81.47721862792969,24.636384963989258],[-81.51777458190918,24.684995651245117],[-81.47860717773438,24.67777442932129],[-81.47721862792969,24.636384963989258]]],[[[-81.58833312988281,24.589998245239258],[-81.55305480957031,24.687219619750977],[-81.50834655761719,24.6299991607666],[-81.58833312988281,24.589998245239258]]],[[[-81.10861206054688,24.706106185913086],[-81.13777160644531,24.70168113708496],[-81.05267333984375,24.71653175354004],[-81.10861206054688,24.706106185913086]]],[[[-81.34944152832031,24.62972068786621],[-81.42805480957031,24.748605728149414],[-81.36082458496094,24.700830459594727],[-81.34944152832031,24.62972068786621]]],[[[-80.96888732910156,24.742773056030273],[-81.02668762207031,24.71858787536621],[-80.9234619140625,24.769208908081055],[-80.96888732910156,24.742773056030273]]],[[[-80.84611511230469,24.79749870300293],[-80.82417297363281,24.82111167907715],[-80.78617095947266,24.82293128967285],[-80.84611511230469,24.79749870300293]]],[[[-80.6986083984375,24.866666793823242],[-80.74583435058594,24.842496871948242],[-80.70249938964844,24.880830764770508],[-80.6986083984375,24.866666793823242]]],[[[-80.64666557312012,24.902219772338867],[-80.66444396972656,24.89499855041504],[-80.62388610839844,24.932775497436523],[-80.64666557312012,24.902219772338867]]],[[[-167.99057006835938,25.002500534057617],[-168.00115966796875,25.00388526916504],[-168.00588989257812,25.01749610900879],[-167.99057006835938,25.002500534057617]]],[[[-80.57722473144531,24.9455509185791],[-80.25750732421875,25.34638786315918],[-80.37193298339844,25.143888473510742],[-80.57722473144531,24.9455509185791]]],[[[-80.22500610351562,25.40110969543457],[-80.23416137695312,25.402219772338867],[-80.1885986328125,25.49416160583496],[-80.22500610351562,25.40110969543457]]],[[[-80.16221618652344,25.669443130493164],[-80.185546875,25.68943977355957],[-80.15638732910156,25.73333168029785],[-80.16221618652344,25.669443130493164]]],[[[-171.72360229492188,25.76249885559082],[-171.73138427734375,25.760831832885742],[-171.72470092773438,25.791662216186523],[-171.72360229492188,25.76249885559082]]],[[[-81.68415832519531,25.8447208404541],[-81.7147216796875,25.888608932495117],[-81.66416931152344,25.888608932495117],[-81.68415832519531,25.8447208404541]]],[[[-173.94613647460938,26.06333351135254],[-173.96084594726562,26.079439163208008],[-173.94473266601562,26.08083152770996],[-173.94613647460938,26.06333351135254]]],[[[-82.12638854980469,26.44999885559082],[-82.20639038085938,26.54583168029785],[-82.02888488769531,26.444997787475586],[-82.12638854980469,26.44999885559082]]],[[[-82.22166442871094,26.612497329711914],[-82.2449951171875,26.63499641418457],[-82.2550048828125,26.698606491088867],[-82.22166442871094,26.612497329711914]]],[[[-82.07945251464844,26.487775802612305],[-82.17971801757812,26.69916343688965],[-82.13333129882812,26.69110679626465],[-82.07945251464844,26.487775802612305]]],[[[-82.26362609863281,26.716386795043945],[-82.28138732910156,26.808889389038086],[-82.25527954101562,26.759443283081055],[-82.26362609863281,26.716386795043945]]],[[[-97.17778015136719,26.0847225189209],[-97.38575744628906,26.838224411010742],[-97.38362121582031,27.20722007751465],[-97.17778015136719,26.0847225189209]]],[[[-82.58750915527344,27.32111167907715],[-82.68055725097656,27.42582893371582],[-82.6541748046875,27.418607711791992],[-82.58750915527344,27.32111167907715]]],[[[-97.38221740722656,27.21888542175293],[-97.31723022460938,27.49582862854004],[-97.04554557800293,27.843889236450195],[-97.38221740722656,27.21888542175293]]],[[[-96.88778686523438,28.030553817749023],[-97.03582763671875,27.875276565551758],[-96.86776733398438,28.13499641418457],[-96.88778686523438,28.030553817749023]]],[[[-96.55194091796875,28.26666831970215],[-96.81361389160156,28.092496871948242],[-96.40472412109375,28.392221450805664],[-96.55194091796875,28.26666831970215]]],[[[-96.36082458496094,28.402498245239258],[-96.31304931640625,28.45527458190918],[-96.22999572753906,28.485551834106445],[-96.36082458496094,28.402498245239258]]],[[[-80.66389465332031,28.258333206176758],[-80.74028015136719,28.478330612182617],[-80.62527465820312,28.59055519104004],[-80.66389465332031,28.258333206176758]]],[[[-90.87265014648438,29.046133041381836],[-90.95039367675781,29.06000328063965],[-90.92361450195312,29.060556411743164],[-90.87265014648438,29.046133041381836]]],[[[-90.73916625976562,29.045000076293945],[-90.75834655761719,29.048608779907227],[-90.64250183105469,29.073331832885742],[-90.73916625976562,29.045000076293945]]],[[[-90.33555603027344,29.057222366333008],[-90.2852783203125,29.08305549621582],[-90.29833984375,29.06694221496582],[-90.33555603027344,29.057222366333008]]],[[[-89.97528076171875,29.242773056030273],[-90.03111267089844,29.211942672729492],[-89.95500183105469,29.268056869506836],[-89.97528076171875,29.242773056030273]]],[[[-89.92832946777344,29.27861213684082],[-89.93527221679688,29.287500381469727],[-89.90750122070312,29.302221298217773],[-89.92832946777344,29.27861213684082]]],[[[-89.86000061035156,29.310277938842773],[-89.89389038085938,29.32305335998535],[-89.86972045898438,29.335275650024414],[-89.86000061035156,29.310277938842773]]],[[[-95.11111450195312,29.098054885864258],[-94.82139587402344,29.33860969543457],[-94.78472900390625,29.308053970336914],[-95.11111450195312,29.098054885864258]]],[[[-89.17054557800293,29.473051071166992],[-89.21916198730469,29.464719772338867],[-89.15695190429688,29.492494583129883],[-89.17054557800293,29.473051071166992]]],[[[-89.60110473632812,29.513887405395508],[-89.61833190917969,29.538331985473633],[-89.59028625488281,29.560556411743164],[-89.56582641601562,29.554719924926758],[-89.56221008300781,29.5211124420166],[-89.60110473632812,29.513887405395508]]],[[[-89.08029174804688,29.521387100219727],[-89.07888793945312,29.54555320739746],[-89.03721618652344,29.573610305786133],[-89.08029174804688,29.521387100219727]]],[[[-91.78666687011719,29.486108779907227],[-92.03443908691406,29.591665267944336],[-91.85638427734375,29.63499641418457],[-91.78666687011719,29.486108779907227]]],[[[-85.11111450195312,29.632219314575195],[-85.19804382324219,29.685274124145508],[-85.08168029785156,29.679162979125977],[-85.11111450195312,29.632219314575195]]],[[[-89.42860412597656,29.692773818969727],[-89.46861267089844,29.728609085083008],[-89.42250061035156,29.7227725982666],[-89.42860412597656,29.692773818969727]]],[[[-84.9727783203125,29.608888626098633],[-85.09500122070312,29.62388801574707],[-84.69221496582031,29.758333206176758],[-84.9727783203125,29.608888626098633]]],[[[-89.42416381835938,29.74083137512207],[-89.4888916015625,29.73805046081543],[-89.49110412597656,29.793054580688477],[-89.42416381835938,29.74083137512207]]],[[[-89.2852783203125,29.771387100219727],[-89.3416748046875,29.80388832092285],[-89.27555847167969,29.80916404724121],[-89.2852783203125,29.771387100219727]]],[[[-84.63890075683594,29.77833366394043],[-84.66722106933594,29.776945114135742],[-84.57342529296875,29.819997787475586],[-84.63890075683594,29.77833366394043]]],[[[-88.84584045410156,29.77638816833496],[-88.86874389648438,30.060606002807617],[-88.80583190917969,29.90638542175293],[-88.84584045410156,29.77638816833496]]],[[[-89.31777954101562,30.040834426879883],[-89.34638977050781,30.0594425201416],[-89.18499755859375,30.16666603088379],[-89.31777954101562,30.040834426879883]]],[[[-88.43777465820312,30.206106185913086],[-88.50056457519531,30.21888542175293],[-88.42805480957031,30.2127742767334],[-88.43777465820312,30.206106185913086]]],[[[-88.55221557617188,30.214719772338867],[-88.75418090820312,30.244718551635742],[-88.52639770507812,30.223051071166992],[-88.55221557617188,30.214719772338867]]],[[[-89.08111572265625,30.19972038269043],[-89.0916748046875,30.216665267944336],[-89.06051635742188,30.246675491333008],[-89.08111572265625,30.19972038269043]]],[[[-88.0947265625,30.241106033325195],[-88.3125,30.23277473449707],[-88.10777282714844,30.273611068725586],[-88.0947265625,30.241106033325195]]],[[[-86.5291748046875,30.40083122253418],[-87.29222106933594,30.33277702331543],[-86.7630615234375,30.404996871948242],[-86.5291748046875,30.40083122253418]]],[[[-118.40695190429688,32.816667556762695],[-118.59249877929688,33.046945571899414],[-118.3691635131836,32.85471534729004],[-118.40695190429688,32.816667556762695]]],[[[-79.36500358581543,33.00305366516113],[-79.36111450195312,33.049997329711914],[-79.33612060546875,33.067216873168945],[-79.36500358581543,33.00305366516113]]],[[[-119.44415283203125,33.21666145324707],[-119.5666732788086,33.28277015686035],[-119.48056030273438,33.27443885803223],[-119.44415283203125,33.21666145324707]]],[[[-118.30194091796875,33.30943489074707],[-118.44888305664062,33.32749366760254],[-118.59221458435059,33.48665809631348],[-118.30194091796875,33.30943489074707]]],[[[-77.96083068847656,33.85000038146973],[-78.01640319824219,33.874162673950195],[-77.94972229003906,33.91304969787598],[-77.96083068847656,33.85000038146973]]],[[[-120.0352783203125,34.023881912231445],[-120.10749816894531,33.90555000305176],[-120.2260971069336,34.00610542297363],[-120.0352783203125,34.023881912231445]]],[[[-120.29778289794922,34.02860450744629],[-120.43804931640625,34.036943435668945],[-120.3638916015625,34.0655460357666],[-120.29778289794922,34.02860450744629]]],[[[-119.86805725097656,34.08416175842285],[-119.51363372802734,34.04277229309082],[-119.788330078125,33.96721076965332],[-119.86805725097656,34.08416175842285]]],[[[-76.5352783203125,34.63555335998535],[-76.65472412109375,34.686105728149414],[-76.55915832519531,34.664995193481445],[-76.5352783203125,34.63555335998535]]],[[[-76.6824951171875,34.702219009399414],[-77.09805297851562,34.65054512023926],[-76.93110656738281,34.69137763977051],[-76.6824951171875,34.702219009399414]]],[[[-76.53195190429688,34.585824966430664],[-76.42083740234375,34.775827407836914],[-76.19972229003906,34.941659927368164],[-76.53195190429688,34.585824966430664]]],[[[-76.06777954101562,35.039438247680664],[-76.131103515625,35.00193977355957],[-76.03944396972656,35.061105728149414],[-76.06777954101562,35.039438247680664]]],[[[-76.01083374023438,35.074167251586914],[-75.98110961914062,35.114999771118164],[-75.76695251464844,35.19388008117676],[-76.01083374023438,35.074167251586914]]],[[[-75.5272216796875,35.235551834106445],[-75.65361022949219,35.22554969787598],[-75.51251220703125,35.7772159576416],[-75.5272216796875,35.235551834106445]]],[[[-75.61944580078125,35.82138252258301],[-75.72332763671875,35.941659927368164],[-75.66583251953125,35.92694282531738],[-75.61944580078125,35.82138252258301]]],[[[-75.90611267089844,37.112497329711914],[-75.89889526367188,37.13694190979004],[-75.87249755859375,37.1491641998291],[-75.90611267089844,37.112497329711914]]],[[[-75.788330078125,37.238046646118164],[-75.83750915527344,37.22776985168457],[-75.7852783203125,37.29860877990723],[-75.788330078125,37.238046646118164]]],[[[-75.6966552734375,37.40277290344238],[-75.71083068847656,37.390275955200195],[-75.6683349609375,37.460275650024414],[-75.6966552734375,37.40277290344238]]],[[[-121.8013916015625,38.05526924133301],[-121.82000732421875,38.06805610656738],[-121.79638671875,38.066667556762695],[-121.8013916015625,38.05526924133301]]],[[[-75.35417175292969,37.86666297912598],[-75.38417053222656,37.87221717834473],[-75.12110900878906,38.2630558013916],[-75.35417175292969,37.86666297912598]]],[[[-74.32945251464844,39.42166328430176],[-74.39445495605469,39.38249397277832],[-74.44415283203125,39.406938552856445],[-74.37625122070312,39.42074394226074],[-74.34805297851562,39.474435806274414],[-74.32945251464844,39.42166328430176]]],[[[-74.2469482421875,39.52555274963379],[-74.09999084472656,39.75083351135254],[-74.13833618164062,39.659433364868164],[-74.2469482421875,39.52555274963379]]],[[[-74.22000122070312,40.511667251586914],[-74.17694091796875,40.64193916320801],[-74.06277465820312,40.63943672180176],[-74.22000122070312,40.511667251586914]]],[[[-73.22332763671875,40.635271072387695],[-73.29472351074219,40.63388252258301],[-72.76666259765625,40.7661075592041],[-73.22332763671875,40.635271072387695]]],[[[-72.26222229003906,41.12526893615723],[-72.62110900878906,40.91304969787598],[-71.85610961914062,41.069162368774414],[-73.58277893066406,40.59610176086426],[-74.03250122070312,40.62582588195801],[-72.26222229003906,41.12526893615723]]],[[[-69.9949951171875,41.32805061340332],[-69.99388122558594,41.25027656555176],[-70.23416137695312,41.28360939025879],[-69.9949951171875,41.32805061340332]]],[[[-70.50639343261719,41.35721778869629],[-70.83805847167969,41.359994888305664],[-70.61721801757812,41.47387886047363],[-70.50639343261719,41.35721778869629]]],[[[-71.29750061035156,41.45860481262207],[-71.35833740234375,41.45916175842285],[-71.22250366210938,41.65416145324707],[-71.29750061035156,41.45860481262207]]],[[[-68.80332946777344,44.048051834106445],[-68.89805603027344,44.12388038635254],[-68.76445007324219,44.09499549865723],[-68.80332946777344,44.048051834106445]]],[[[-68.65083312988281,44.16888618469238],[-68.72138977050781,44.2288761138916],[-68.66806030273438,44.2852725982666],[-68.65083312988281,44.16888618469238]]],[[[-68.32084655761719,44.23721504211426],[-68.42832946777344,44.31999397277832],[-68.2630615234375,44.452775955200195],[-68.1683349609375,44.34554481506348],[-68.32084655761719,44.23721504211426]]],[[[-123.93804931640625,46.431108474731445],[-123.94915771484375,46.431108474731445],[-123.98306274414062,46.46915626525879],[-123.97250366210938,46.515275955200195],[-123.93804931640625,46.431108474731445]]],[[[-122.84306335449219,47.20694160461426],[-122.9022216796875,47.297494888305664],[-122.84555053710938,47.3124942779541],[-122.84306335449219,47.20694160461426]]],[[[-122.48222351074219,47.34971809387207],[-122.4505615234375,47.518327713012695],[-122.381103515625,47.39471626281738],[-122.48222351074219,47.34971809387207]]],[[[-122.50473022460938,48.30971717834473],[-122.37222290039062,47.919443130493164],[-122.75778198242188,48.2338809967041],[-122.50473022460938,48.30971717834473]]],[[[-122.8166732788086,48.416940689086914],[-122.93611145019531,48.457773208618164],[-122.87666320800781,48.564157485961914],[-122.8166732788086,48.416940689086914]]],[[[-123,48.44610023498535],[-123.17832946777344,48.59221839904785],[-122.99500274658203,48.52971839904785],[-123,48.44610023498535]]],[[[-122.92250061035156,48.7116641998291],[-122.74916076660156,48.651384353637695],[-123.0102767944336,48.60360908508301],[-122.92250061035156,48.7116641998291]]],[[[-123.05332946777344,48.97387886047363],[-123.09375,48.99943733215332],[-123.03431701660156,48.99943733215332],[-123.05332946777344,48.97387886047363]]],[[[-95.07806396484375,49.35916328430176],[-94.6058349609375,48.724435806274414],[-92.95306396484375,48.62332344055176],[-91.4183349609375,48.04110908508301],[-90.86860656738281,48.237497329711914],[-89.35665893554688,47.97971534729004],[-88.36805725097656,48.312211990356445],[-84.85694885253906,46.9022159576416],[-84.56500244140625,46.466386795043945],[-84.12638854980469,46.531938552856445],[-83.95889282226562,46.071664810180664],[-83.57749938964844,46.10527229309082],[-83.5977783203125,45.827219009399414],[-82.54306030273438,45.3558292388916],[-82.13027954101562,43.58526802062988],[-82.52139282226562,42.61888313293457],[-83.16860961914062,42.04610633850098],[-82.6966552734375,41.68387794494629],[-78.9869384765625,42.81999397277832],[-79.18472290039062,43.46554756164551],[-78.72471618652344,43.62943458557129],[-76.80194091796875,43.63360786437988],[-74.99082946777344,44.98665809631348],[-70.87860107421875,45.238603591918945],[-69.23249816894531,47.47137641906738],[-67.79499816894531,47.06999397277832],[-67.79916381835938,45.70110511779785],[-67.20654296875,45.18303871154785],[-66.96888732910156,44.83111000061035],[-67.18693542480469,44.661935806274414],[-67.55110168457031,44.66610145568848],[-67.56527709960938,44.55027198791504],[-67.77528381347656,44.546945571899414],[-68.04750061035156,44.346940994262695],[-68.10861206054688,44.460275650024414],[-68.32115173339844,44.46588325500488],[-68.55915832519531,44.41888618469238],[-68.54750061035156,44.31777381896973],[-68.61582946777344,44.30638313293457],[-68.79527282714844,44.579721450805664],[-69.0675048828125,44.06332588195801],[-69.72193908691406,43.78582954406738],[-69.77333068847656,44.07916450500488],[-69.82389831542969,43.71444129943848],[-70.17250061035156,43.78055000305176],[-70.72917175292969,43.12276649475098],[-70.58056640625,42.651933670043945],[-71.04444885253906,42.311105728149414],[-70.32472229003906,41.711381912231445],[-70.01112365722656,41.79722023010254],[-70.07888793945312,42.062211990356445],[-69.93638610839844,41.669443130493164],[-71.18582153320312,41.46666145324707],[-71.11111450195312,41.795000076293945],[-71.39138793945312,41.81193733215332],[-71.50527954101562,41.3669376373291],[-72.90638732910156,41.28611183166504],[-73.99748992919922,40.71346092224121],[-73.9566650390625,41.30526924133301],[-74.2691650390625,40.47471046447754],[-73.95222473144531,40.299997329711914],[-74.07640075683594,39.77694129943848],[-74.05387878417969,40.05749702453613],[-74.15028381347656,39.70499610900879],[-74.40556335449219,39.5161075592041],[-74.46259307861328,39.42106819152832],[-74.41555786132812,39.35527229309082],[-74.95500183105469,38.92416572570801],[-74.89277458190918,39.16777229309082],[-75.5574951171875,39.618051528930664],[-75.02851867675781,40.01230812072754],[-75.58860778808594,39.648881912231445],[-75.04388427734375,38.42166328430176],[-75.96083068847656,37.1522159576416],[-75.64404296875,37.9611759185791],[-75.88082885742188,37.94943428039551],[-75.83805847167969,38.398881912231445],[-76.24249267578125,38.3669376373291],[-75.9566650390625,38.64860725402832],[-76.36000061035156,38.85721778869629],[-75.83168029785156,39.57749366760254],[-76.61860656738281,39.254167556762695],[-76.3760986328125,38.36361122131348],[-76.66610717773438,38.480546951293945],[-76.30999755859375,38.04638862609863],[-77.24444580078125,38.398332595825195],[-77.06111145019531,38.9052677154541],[-77.32000732421875,38.34527015686035],[-76.24166870117188,37.90499305725098],[-76.35360717773438,37.618600845336914],[-77.13389587402344,38.17276954650879],[-76.28666687011719,37.5674991607666],[-76.381103515625,37.273881912231445],[-76.68276977539062,37.42971992492676],[-76.26806640625,37.07888221740723],[-77.23222351074219,37.29638862609863],[-75.989990234375,36.91388130187988],[-75.5291748046875,35.80388069152832],[-75.93888854980469,36.71666145324707],[-75.78555297851562,36.06999397277832],[-76.19554138183594,36.31999397277832],[-76.06304931640625,36.15332221984863],[-76.65666198730469,36.03110694885254],[-76.70611572265625,36.26416206359863],[-76.73056030273438,35.93943214416504],[-76.07084655761719,35.9919376373291],[-76.0352783203125,35.64999580383301],[-75.85360717773438,35.974992752075195],[-75.72027587890625,35.81443977355957],[-76.149169921875,35.33693885803223],[-77.05082702636719,35.53027534484863],[-76.46888732910156,35.27166175842285],[-76.76139831542969,34.98777198791504],[-77.07640075683594,35.15609931945801],[-76.94444274902344,34.977487564086914],[-76.33583068847656,34.88694190979004],[-77.42887878417969,34.7419376373291],[-77.93083190917969,33.92777442932129],[-77.961669921875,34.15860176086426],[-78.01362609863281,33.89193916320801],[-78.82749938964844,33.73027229309082],[-79.19644165039062,33.278940200805664],[-79.1885986328125,33.43638038635254],[-79.27139282226562,33.37332344055176],[-79.20584106445312,33.165544509887695],[-79.37171936035156,33.05894660949707],[-79.38194274902344,33.009721755981445],[-80.67166137695312,32.52166175842285],[-80.46722412109375,32.31582832336426],[-80.83694458007812,32.51666450500488],[-80.66999816894531,32.21415901184082],[-81.4969482421875,31.12555503845215],[-81.25527954101562,29.796667098999023],[-80.552490234375,28.524999618530273],[-80.4466552734375,27.864442825317383],[-80.60221862792969,28.607500076293945],[-80.84416198730469,28.790555953979492],[-80.75556945800781,28.415830612182617],[-80.0333251953125,26.786664962768555],[-80.39862060546875,25.184720993041992],[-81.08805847167969,25.11555290222168],[-80.915283203125,25.25139045715332],[-81.336669921875,25.80499839782715],[-81.73658752441406,25.959444046020508],[-81.97005462646484,26.482831954956055],[-81.77778625488281,26.710554122924805],[-82.06416320800781,26.545000076293945],[-82.01722717285156,26.964719772338867],[-82.30278015136719,26.837221145629883],[-82.6552734375,27.4616641998291],[-82.42250061035156,27.917497634887695],[-82.69137573242188,28.0322208404541],[-82.72250366210938,27.65694236755371],[-82.85333251953125,27.855276107788086],[-82.631103515625,28.88499641418457],[-83.66944885253906,29.90610694885254],[-84.20750427246094,30.105554580688477],[-85.35417175292969,29.676664352416992],[-85.63394165039062,30.104440689086914],[-85.39222717285156,30.0494441986084],[-86.26333618164062,30.49666404724121],[-88.02362060546875,30.21944236755371],[-87.75639343261719,30.285276412963867],[-88.02027893066406,30.701108932495117],[-88.13276672363281,30.314443588256836],[-90.41972351074219,30.198331832885742],[-89.66722106933594,30.167776107788086],[-89.65805053710938,29.87388801574707],[-89.39944458007812,30.050832748413086],[-89.75334167480469,29.630830764770508],[-89.6763916015625,29.523889541625977],[-89.18721008300781,29.339719772338867],[-89.00834655761719,29.176942825317383],[-89.40499877929688,28.926664352416992],[-89.27278137207031,29.155832290649414],[-90.17832946777344,29.572500228881836],[-90.2066650390625,29.091943740844727],[-91.2469482421875,29.24083137512207],[-91.8416748046875,29.830278396606445],[-92.30833435058594,29.53972053527832],[-93.84028625488281,29.704164505004883],[-93.84527587890625,29.98805046081543],[-93.85749816894531,29.67610740661621],[-94.77250671386719,29.3638858795166],[-94.475830078125,29.56138801574707],[-95.05943298339844,29.71888542175293],[-94.8880615234375,29.37555503845215],[-94.90278625488281,29.314443588256836],[-95.09388732910156,29.17777442932129],[-95.14083862304688,29.0575008392334],[-96.21278381347656,28.485551834106445],[-95.98582458496094,28.6491641998291],[-96.64167785644531,28.719717025756836],[-96.39834594726562,28.43610954284668],[-96.80360412597656,28.473051071166992],[-97.18472290039062,27.827497482299805],[-97.52055358886719,27.86638832092285],[-97.41111755371094,27.327497482299805],[-97.77389526367188,27.458887100219727],[-97.42388916015625,27.267499923706055],[-97.55943298339844,26.836111068725586],[-97.14073944091797,25.966428756713867],[-99.104736328125,26.434999465942383],[-99.5050048828125,27.570276260375977],[-101.40501403808594,29.77277946472168],[-102.30584716796875,29.88944435119629],[-103.375,29.023611068725586],[-104.54000854492188,29.671110153198242],[-104.90055847167969,30.572778701782227],[-106.40084838867188,31.750276565551758],[-108.2086181640625,31.783334732055664],[-108.20834350585938,31.33305549621582],[-111.04583740234375,31.33305549621582],[-113.05288696289062,31.971071243286133],[-114.80982971191406,32.50699043273926],[-114.7190933227539,32.71845817565918],[-117.12237358093262,32.53533363342285],[-117.48082733154297,33.32749366760254],[-118.53472900390625,34.05082893371582],[-120.62026977539062,34.57083320617676],[-120.61416625976562,35.13582801818848],[-121.86749267578125,36.3124942779541],[-121.79638671875,36.87943458557129],[-122.48805236816406,37.518327713012695],[-122.38694763183594,37.816667556762695],[-122.00583457946777,37.47137641906738],[-122.39334106445312,37.957773208618164],[-122.24054718017578,38.059160232543945],[-121.41999816894531,38.012773513793945],[-121.5766830444336,38.11583137512207],[-121.7361068725586,38.04471778869629],[-122.01862335205078,38.148115158081055],[-122.10973358154297,38.06138038635254],[-122.36528015136719,38.15555000305176],[-122.49137878417969,37.827775955200195],[-122.9970703125,38.005109786987305],[-122.96456146240234,38.239614486694336],[-122.8035945892334,38.08804512023926],[-123.10472106933594,38.46110725402832],[-123.70361328125,38.93249702453613],[-123.77583312988281,39.71721076965332],[-124.33222961425781,40.2661075592041],[-124.03999328613281,41.431108474731445],[-124.5244369506836,42.866106033325195],[-124.13834381103516,43.371103286743164],[-123.95195007324219,46.181108474731445],[-123.16357421875,46.19519233703613],[-124,46.32361030578613],[-124.04277038574219,46.65804481506348],[-124.01583862304688,46.654436111450195],[-123.989990234375,46.397775650024414],[-123.9416732788086,46.3911075592041],[-123.7525634765625,46.693071365356445],[-124.09750366210938,46.86138343811035],[-123.79666137695312,46.97609901428223],[-124.16194152832031,46.94110298156738],[-124.7158432006836,48.395273208618164],[-122.75110626220703,48.16110420227051],[-122.63027954101562,47.91582679748535],[-123.14750671386719,47.368600845336914],[-122.8364028930664,47.439157485961914],[-123.10249328613281,47.39972114562988],[-122.5655517578125,47.93804359436035],[-122.45472717285156,47.77443885803223],[-122.54998779296875,47.28277015686035],[-122.6191635131836,47.420549392700195],[-122.75862121582031,47.189714431762695],[-122.79750061035156,47.395273208618164],[-123.06861877441406,47.15165901184082],[-122.87860107421875,47.064157485961914],[-122.30972290039062,47.40110206604004],[-122.3791732788086,48.29166603088379],[-122.70445251464844,48.48610877990723],[-122.4375,48.59804725646973],[-122.76029968261719,48.99943733215332],[-95.1541748046875,48.99943733215332],[-95.07806396484375,49.35916328430176]],[[-122.4958267211914,47.59554481506348],[-122.50334167480469,47.71527290344238],[-122.58168029785156,47.67166328430176],[-122.4958267211914,47.59554481506348]],[[-123.9385986328125,45.53666114807129],[-123.91694641113281,45.56443977355957],[-123.93443298339844,45.55832862854004],[-123.9385986328125,45.53666114807129]],[[-77.85166931152344,34.11110877990723],[-77.82084655761719,34.17527198791504],[-77.8558349609375,34.1491641998291],[-77.85166931152344,34.11110877990723]]],[[[-179.10528564453125,51.21305274963379],[-179.14199829101562,51.26859474182129],[-179.08724975585938,51.29083442687988],[-179.10528564453125,51.21305274963379]]],[[[-178.96249389648438,51.311662673950195],[-178.94998168945312,51.39693641662598],[-178.90032958984375,51.354997634887695],[-178.96249389648438,51.311662673950195]]],[[[178.993013381958,51.57499885559082],[179.47134590148926,51.36749458312988],[178.63638496398926,51.637773513793945],[178.993013381958,51.57499885559082]]],[[[-178.7769775390625,51.74553871154785],[-178.842529296875,51.81915473937988],[-178.7427978515625,51.80777168273926],[-178.7769775390625,51.74553871154785]]],[[[178.39221382141113,51.7630558013916],[178.22302436828613,51.830827713012695],[178.32995796203613,51.81499671936035],[178.39221382141113,51.7630558013916]]],[[[-176.0128173828125,51.830270767211914],[-176.14334106445312,51.77443885803223],[-176.21945190429688,51.83138465881348],[-176.0128173828125,51.830270767211914]]],[[[-176.33642578125,51.72165870666504],[-176.41448974609375,51.854997634887695],[-176.2769775390625,51.86026954650879],[-176.33642578125,51.72165870666504]]],[[[-177.81390380859375,51.71970558166504],[-177.94998168945312,51.60637855529785],[-178.21807861328125,51.87193489074707],[-177.81390380859375,51.71970558166504]]],[[[-176.55059814453125,51.90582466125488],[-176.42974853515625,51.73026466369629],[-176.97503662109375,51.5958194732666],[-176.55059814453125,51.90582466125488]]],[[[-175.95111083984375,51.86887550354004],[-176.09307861328125,51.885263442993164],[-176.001953125,51.90887641906738],[-175.95111083984375,51.86887550354004]]],[[[-177.12222290039062,51.784433364868164],[-177.7044677734375,51.70083045959473],[-177.15725708007812,51.93832588195801],[-177.12222290039062,51.784433364868164]]],[[[-175.72503662109375,51.930551528930664],[-175.72918701171875,51.96610450744629],[-175.65750122070312,51.95694160461426],[-175.72503662109375,51.930551528930664]]],[[[-175.864990234375,51.96360969543457],[-175.94668579101562,51.97886848449707],[-175.80194091796875,51.98220252990723],[-175.864990234375,51.96360969543457]]],[[[178.53692817687988,51.89361000061035],[178.46829414367676,51.98472023010254],[178.60608100891113,51.947771072387695],[178.53692817687988,51.89361000061035]]],[[[179.73745918273926,51.90304756164551],[179.48608589172363,51.97221565246582],[179.65860176086426,52.02471351623535],[179.73745918273926,51.90304756164551]]],[[[177.68469429016113,52.07999610900879],[177.6049518585205,51.92027473449707],[177.241060256958,51.87693977355957],[177.68469429016113,52.07999610900879]]],[[[-176.0372314453125,51.964433670043945],[-176.19085693359375,52.05999183654785],[-176.04611206054688,52.10222053527832],[-176.0372314453125,51.964433670043945]]],[[[-173.515869140625,52.10693550109863],[-172.95559692382812,52.08554267883301],[-174.05697631835938,52.12027168273926],[-173.515869140625,52.10693550109863]]],[[[175.96109199523926,52.33555030822754],[175.88189888000488,52.37249183654785],[175.98773384094238,52.35360908508301],[175.96109199523926,52.33555030822754]]],[[[-172.38836669921875,52.28972053527832],[-172.6280517578125,52.25832557678223],[-172.43832397460938,52.39193153381348],[-172.38836669921875,52.28972053527832]]],[[[-173.99530029296875,52.29110145568848],[-175.33584594726562,52.0141544342041],[-174.18447875976562,52.416940689086914],[-173.99530029296875,52.29110145568848]]],[[[173.78775215148926,52.501108169555664],[173.73550605773926,52.35332679748535],[173.37524604797363,52.39943885803223],[173.78775215148926,52.501108169555664]]],[[[-171.23526000976562,52.45083045959473],[-171.30804443359375,52.49942970275879],[-171.21722412109375,52.51054573059082],[-171.23526000976562,52.45083045959473]]],[[[-170.60556030273438,52.590829849243164],[-170.8416748046875,52.554155349731445],[-170.6761474609375,52.69415473937988],[-170.60556030273438,52.590829849243164]]],[[[174.17776679992676,52.70555305480957],[174.07412910461426,52.711381912231445],[174.10217475891113,52.741106033325195],[174.17776679992676,52.70555305480957]]],[[[-170.11474609375,52.71832466125488],[-170.17999267578125,52.78387641906738],[-170.05499267578125,52.765268325805664],[-170.11474609375,52.71832466125488]]],[[[-169.675048828125,52.81777381896973],[-170.0130615234375,52.81833076477051],[-169.78115844726562,52.885263442993164],[-169.675048828125,52.81777381896973]]],[[[-170.04083251953125,52.853044509887695],[-170.12747192382812,52.88859748840332],[-169.99389457702637,52.901933670043945],[-170.04083251953125,52.853044509887695]]],[[[173.29998970031738,52.882211685180664],[172.92859077453613,52.74388313293457],[172.47635078430176,52.92444038391113],[173.29998970031738,52.882211685180664]]],[[[-169.72445678710938,52.943315505981445],[-169.75250244140625,53.026376724243164],[-169.67669677734375,53.03166389465332],[-169.72445678710938,52.943315505981445]]],[[[-168.24359130859375,53.25110054016113],[-169.08670043945312,52.82805061340332],[-168.35195922851562,53.47554969787598],[-167.79531860351562,53.49553871154785],[-168.24359130859375,53.25110054016113]]],[[[-166.20999145507812,53.705270767211914],[-166.2933349609375,53.79305458068848],[-166.09002685546875,53.839433670043945],[-166.20999145507812,53.705270767211914]]],[[[-166.60748291015625,53.829721450805664],[-166.21502685546875,53.92832374572754],[-166.75283813476562,53.44638252258301],[-167.84637451171875,53.30859565734863],[-166.80389404296875,53.648874282836914],[-167.02420043945312,53.95554542541504],[-166.60748291015625,53.829721450805664]]],[[[-165.251708984375,54.07609748840332],[-165.29779052734375,54.037492752075195],[-165.48193359375,54.07443428039551],[-165.251708984375,54.07609748840332]]],[[[-164.939208984375,54.12693977355957],[-164.965576171875,54.075273513793945],[-165.221923828125,54.08999061584473],[-164.939208984375,54.12693977355957]]],[[[-165.69696044921875,54.08471870422363],[-166.12307739257812,54.11638069152832],[-165.93832397460938,54.22054481506348],[-165.69696044921875,54.08471870422363]]],[[[-165.56057739257812,54.11026954650879],[-165.68197631835938,54.238046646118164],[-165.48641967773438,54.28804969787598],[-165.56057739257812,54.11026954650879]]],[[[-162.40057373046875,54.36944007873535],[-162.48971557617188,54.40971565246582],[-162.36831665039062,54.38833045959473],[-162.40057373046875,54.36944007873535]]],[[[-162.54388427734375,54.38138008117676],[-162.78640747070312,54.41471290588379],[-162.83111572265625,54.494157791137695],[-162.54388427734375,54.38138008117676]]],[[[-132.61944580078125,54.75444221496582],[-132.7811279296875,54.92527198791504],[-132.61886596679688,54.89610481262207],[-132.61944580078125,54.75444221496582]]],[[[-159.29501342773438,54.8669376373291],[-159.33612060546875,54.92721748352051],[-159.20693969726562,54.92444038391113],[-159.29501342773438,54.8669376373291]]],[[[-163.41363525390625,54.8911075592041],[-163.3699951171875,54.78499794006348],[-163.14501953125,54.7661075592041],[-163.04861450195312,54.6683292388916],[-164.95220947265625,54.57583045959473],[-164.43276977539062,54.930551528930664],[-163.41363525390625,54.8911075592041]]],[[[-162.29306030273438,54.83416175842285],[-162.4344482421875,54.931108474731445],[-162.23275756835938,54.96527290344238],[-162.29306030273438,54.83416175842285]]],[[[-131.32583618164062,54.856943130493164],[-131.48275756835938,54.93082618713379],[-131.23638916015625,54.99527168273926],[-131.32583618164062,54.856943130493164]]],[[[-159.43417358398438,54.9405460357666],[-159.479154586792,55.01416206359863],[-159.34942626953125,55.04916572570801],[-159.43417358398438,54.9405460357666]]],[[[-161.73971557617188,55.056100845336914],[-161.90695190429688,55.151384353637695],[-161.64138793945312,55.11332893371582],[-161.73971557617188,55.056100845336914]]],[[[-132.67471313476562,55.03305244445801],[-132.86471557617188,55.02999305725098],[-132.85333251953125,55.159433364868164],[-132.67471313476562,55.03305244445801]]],[[[-131.42584228515625,55.21110725402832],[-131.37222290039062,55.01361274719238],[-131.61749267578125,55.01111030578613],[-131.42584228515625,55.21110725402832]]],[[[-132.8358154296875,54.88916206359863],[-132.67999267578125,54.66610145568848],[-133.195556640625,55.23027229309082],[-132.8358154296875,54.88916206359863]]],[[[-159.51947021484375,55.064157485961914],[-159.65557861328125,55.05499458312988],[-159.5352783203125,55.24749183654785],[-159.51947021484375,55.064157485961914]]],[[[-161.56195068359375,55.21805000305176],[-161.70611572265625,55.20471382141113],[-161.53363037109375,55.25277900695801],[-161.56195068359375,55.21805000305176]]],[[[-159.84332275390625,55.13249397277832],[-160.24472045898438,54.901384353637695],[-159.8822021484375,55.29083442687988],[-159.84332275390625,55.13249397277832]]],[[[-133.24972534179688,55.20916175842285],[-133.439453125,55.30193519592285],[-133.29666137695312,55.33055305480957],[-133.24972534179688,55.20916175842285]]],[[[-160.33306884765625,55.24804878234863],[-160.528076171875,55.3205509185791],[-160.34695434570312,55.368600845336914],[-160.33306884765625,55.24804878234863]]],[[[-160.695556640625,55.39999580383301],[-160.461669921875,55.187211990356445],[-160.81640625,55.11832618713379],[-160.695556640625,55.39999580383301]]],[[[-133.59832763671875,55.2338809967041],[-133.65362358093262,55.36944007873535],[-133.44696044921875,55.4102725982666],[-133.59832763671875,55.2338809967041]]],[[[-131.72500610351562,55.134721755981445],[-131.84609985351562,55.419992446899414],[-131.61663818359375,55.28360939025879],[-131.72500610351562,55.134721755981445]]],[[[-163.14639282226562,55.393327713012695],[-163.19473266601562,55.42193794250488],[-163.136962890625,55.436105728149414],[-163.14639282226562,55.393327713012695]]],[[[-160.17889404296875,55.39610481262207],[-160.34194946289062,55.416940689086914],[-160.24972534179688,55.46305274963379],[-160.17889404296875,55.39610481262207]]],[[[-133.5050048828125,55.42721748352051],[-133.60165405273438,55.44748878479004],[-133.42138671875,55.48360633850098],[-133.5050048828125,55.42721748352051]]],[[[-133.57806396484375,55.49777412414551],[-133.758056640625,55.48721504211426],[-133.70248413085938,55.5513858795166],[-133.57806396484375,55.49777412414551]]],[[[-133.28945922851562,55.4758243560791],[-133.43667602539062,55.52749061584473],[-133.308349609375,55.55471229553223],[-133.28945922851562,55.4758243560791]]],[[[-133.50558471679688,55.69332313537598],[-133.67779541015625,55.78416633605957],[-133.29974365234375,55.79361152648926],[-133.50558471679688,55.69332313537598]]],[[[-133.24221801757812,55.77665901184082],[-133.32916259765625,55.87748908996582],[-133.21554565429688,55.86194038391113],[-133.24221801757812,55.77665901184082]]],[[[-158.86416625976562,55.80388069152832],[-158.832763671875,55.89388465881348],[-158.709716796875,55.83138465881348],[-158.86416625976562,55.80388069152832]]],[[[-134.24972534179688,55.81944465637207],[-134.33889770507812,55.91805458068848],[-134.09664916992188,55.9183292388916],[-134.24972534179688,55.81944465637207]]],[[[-155.58029174804688,55.77443885803223],[-155.739990234375,55.8286075592041],[-155.56390380859375,55.91860389709473],[-155.58029174804688,55.77443885803223]]],[[[-133.8477783203125,55.847490310668945],[-133.92721557617188,55.911935806274414],[-133.8477783203125,55.93526649475098],[-133.8477783203125,55.847490310668945]]],[[[-131.05056762695312,55.79972267150879],[-131.14279174804688,55.19693946838379],[-131.461669921875,55.28611183166504],[-131.348876953125,55.64499855041504],[-131.52194213867188,55.29305458068848],[-131.82223510742188,55.450273513793945],[-131.68389892578125,55.833330154418945],[-131.2650146484375,55.960824966430664],[-131.05056762695312,55.79972267150879]]],[[[-131.51947021484375,55.915544509887695],[-131.57693481445312,55.93194007873535],[-131.39944458007812,55.963884353637695],[-131.51947021484375,55.915544509887695]]],[[[-133.69528198242188,55.89638710021973],[-133.67971801757812,56.06638526916504],[-133.278076171875,56.139719009399414],[-133.69528198242188,55.89638710021973]]],[[[-133.93112182617188,56.28833198547363],[-133.94805908203125,56.30193519592285],[-133.92556762695312,56.298051834106445],[-133.93112182617188,56.28833198547363]]],[[[-133.48858642578125,56.33693885803223],[-132.1441650390625,55.480546951293945],[-132.5625,55.56777381896973],[-131.98858642578125,55.26416206359863],[-132.21859741210938,54.99249458312988],[-131.96304321289062,55.025827407836914],[-132.00390625,54.6905460357666],[-132.64138793945312,55.25027656555176],[-133.22250366210938,55.28305244445801],[-132.86749267578125,55.35388374328613],[-133.12860107421875,55.49471473693848],[-132.90835571289062,55.6280460357666],[-133.37222290039062,55.62054634094238],[-133.135009765625,55.88110542297363],[-133.25836181640625,56.15249061584473],[-133.61721801757812,56.20749855041504],[-133.48858642578125,56.33693885803223]]],[[[-132.09445190429688,56.09332466125488],[-132.31887817382812,55.91221046447754],[-132.71694946289062,56.151384353637695],[-132.41778564453125,56.35083198547363],[-132.09445190429688,56.09332466125488]]],[[[-132.81723022460938,56.2338809967041],[-133.05776977539062,56.347490310668945],[-132.63555908203125,56.434160232543945],[-132.81723022460938,56.2338809967041]]],[[[-132.50085258483887,56.35332679748535],[-132.49386596679688,56.43582344055176],[-132.38668823242188,56.39860725402832],[-132.50085258483887,56.35332679748535]]],[[[-132.13247680664062,56.34527015686035],[-132.05612182617188,56.11138343811035],[-132.37387084960938,56.48443794250488],[-132.13247680664062,56.34527015686035]]],[[[-153.95889282226562,56.50277900695801],[-154.13446044921875,56.50555610656738],[-153.87387084960938,56.55332374572754],[-153.95889282226562,56.50277900695801]]],[[[-156.99664306640625,56.555551528930664],[-157.3297119140625,56.53582954406738],[-157.25167846679688,56.58166694641113],[-156.99664306640625,56.555551528930664]]],[[[-132.3980712890625,56.58360481262207],[-132.43499755859375,56.5897159576416],[-132.37942504882812,56.60054969787598],[-132.3980712890625,56.58360481262207]]],[[[-154.48138427734375,56.60169792175293],[-154.40280151367188,56.54666328430176],[-154.7874755859375,56.414968490600586],[-154.48138427734375,56.60169792175293]]],[[[-154.21194458007812,56.49888038635254],[-154.35247802734375,56.54166603088379],[-154.08499145507812,56.608049392700195],[-154.21194458007812,56.49888038635254]]],[[[-169.67337036132812,56.608598709106445],[-169.47137451171875,56.59221076965332],[-169.7861328125,56.6138858795166],[-169.67337036132812,56.608598709106445]]],[[[-132.7730712890625,56.49471473693848],[-132.87359619140625,56.79610633850098],[-132.52890014648438,56.59527015686035],[-132.7730712890625,56.49471473693848]]],[[[-133.98748779296875,56.87082862854004],[-133.90280151367188,56.75305366516113],[-134.02471923828125,56.64721870422363],[-133.83056640625,56.79610633850098],[-133.69137573242188,56.59971809387207],[-133.92056274414062,56.61416053771973],[-133.84609985351562,56.29083442687988],[-133.97320556640625,56.35610389709473],[-133.97332763671875,56.08166694641113],[-134.0655517578125,56.30582618713379],[-134.123046875,55.99582862854004],[-134.06527709960938,56.550546646118164],[-134.40890502929688,56.82943916320801],[-133.98748779296875,56.87082862854004]]],[[[-133.31777954101562,56.99388313293457],[-132.92501831054688,56.643327713012695],[-133.3519287109375,56.83860206604004],[-133.08193969726562,56.523881912231445],[-133.5755615234375,56.433603286743164],[-133.69696044921875,56.83194160461426],[-133.89056396484375,56.89694404602051],[-133.73611450195312,56.89305305480957],[-134.01806640625,57.014719009399414],[-133.31777954101562,56.99388313293457]]],[[[-153.25335693359375,56.99833106994629],[-153.40750122070312,57.072771072387695],[-153.23416137695312,57.205827713012695],[-152.883056640625,57.15027046203613],[-153.25335693359375,56.99833106994629]]],[[[-170.1661376953125,57.16331672668457],[-170.4139404296875,57.17416572570801],[-170.15057373046875,57.22832679748535],[-170.1661376953125,57.16331672668457]]],[[[-135.79583740234375,56.98638343811035],[-135.71054077148438,57.32361030578613],[-135.54611206054688,57.12943458557129],[-135.79583740234375,56.98638343811035]]],[[[-134.9375,57.35888862609863],[-134.65362358093262,56.16304969787598],[-135.67279052734375,57.351938247680664],[-134.9375,57.35888862609863]]],[[[-134.79251098632812,57.30027198791504],[-134.97470092773438,57.41526985168457],[-134.81362915039062,57.416940689086914],[-134.79251098632812,57.30027198791504]]],[[[-153.20889282226562,57.8124942779541],[-153.53640747070312,57.93471717834473],[-153.35333251953125,57.93638038635254],[-153.26974487304688,57.8991641998291],[-153.20889282226562,57.8124942779541]]],[[[-152.35443115234375,57.890275955200195],[-152.50335693359375,57.933053970336914],[-152.417236328125,57.97638130187988],[-152.35443115234375,57.890275955200195]]],[[[-153.116943359375,57.94999885559082],[-152.15139770507812,57.604440689086914],[-153.02279663085938,57.47360420227051],[-152.5958251953125,57.3699893951416],[-153.16946411132812,57.34554481506348],[-152.95611572265625,57.25388526916504],[-153.26028442382812,57.22776985168457],[-153.5,57.06388282775879],[-153.73165893554688,57.05971717834473],[-153.54998779296875,56.983049392700195],[-153.97970581054688,56.738603591918945],[-153.73776245117188,57.13082313537598],[-154.47943115234375,57.12027168273926],[-154.10110473632812,57.11638832092285],[-154.29779052734375,56.84887886047363],[-154.80111694335938,57.28611183166504],[-154.20721435546875,57.66666603088379],[-153.6280517578125,57.26944160461426],[-153.88027954101562,57.64305305480957],[-153.58111572265625,57.612497329711914],[-153.9283447265625,57.811105728149414],[-153.4969482421875,57.627214431762695],[-153.31527709960938,57.7258243560791],[-153.479154586792,57.839433670043945],[-153.21304321289062,57.78833198547363],[-153.15057373046875,57.8638858795166],[-153.04806518554688,57.82749366760254],[-153.292236328125,58.001665115356445],[-153.116943359375,57.94999885559082]]],[[[-153.18527221679688,58.09249305725098],[-152.88778686523438,57.991106033325195],[-153.41806030273438,58.05888557434082],[-153.18527221679688,58.09249305725098]]],[[[-136.43722534179688,57.846384048461914],[-136.48443603515625,58.09332466125488],[-136.33056640625,58.01027870178223],[-136.43722534179688,57.846384048461914]]],[[[-135.74276733398438,58.25610542297363],[-135.48248291015625,58.15555000305176],[-135.707763671875,57.97832679748535],[-134.9302978515625,58.02804756164551],[-135.2047119140625,57.942216873168945],[-135.01055908203125,57.77694129943848],[-135.88751220703125,57.988603591918945],[-135.29696655273438,57.73166084289551],[-134.92166137695312,57.75694465637207],[-134.84332275390625,57.46277046203613],[-135.80416870117188,57.76333045959473],[-135.54278564453125,57.47221565246582],[-135.83084106445312,57.38582801818848],[-136.4122314453125,57.81582832336426],[-136.02972412109375,57.84916114807129],[-136.35220336914062,58.219438552856445],[-135.74276733398438,58.25610542297363]]],[[[-151.84722900390625,58.16971778869629],[-151.89666557312012,58.19415473937988],[-151.83554077148438,58.26860237121582],[-151.84722900390625,58.16971778869629]]],[[[-134.45443725585938,58.31332588195801],[-134.25973510742188,58.19499397277832],[-134.68389892578125,58.2983341217041],[-134.56695556640625,58.340829849243164],[-134.45443725585938,58.31332588195801]]],[[[-152.4091796875,58.365549087524414],[-151.9727783203125,58.233049392700195],[-153.23138427734375,58.16916084289551],[-152.4091796875,58.365549087524414]]],[[[-134.67471313476562,58.16054725646973],[-134.16915893554688,58.15971565246582],[-133.87582397460938,57.67276954650879],[-134.28860473632812,58.077219009399414],[-133.86026000976562,57.360551834106445],[-134.48666381835938,57.02555274963379],[-134.61331176757812,57.224992752075195],[-134.31027221679688,57.33610725402832],[-134.572509765625,57.48971748352051],[-134.3497314453125,57.54277229309082],[-134.65444946289062,57.59832954406738],[-134.9566650390625,58.40777015686035],[-134.67471313476562,58.16054725646973]]],[[[-152.49386596679688,58.47221565246582],[-152.66055297851562,58.5433292388916],[-152.3458251953125,58.627214431762695],[-152.49386596679688,58.47221565246582]]],[[[-160.95693969726562,58.55694007873535],[-161.11309814453125,58.65527534484863],[-160.68722534179688,58.81833076477051],[-160.95693969726562,58.55694007873535]]],[[[-152.31332397460938,58.90832710266113],[-152.36026000976562,58.91638374328613],[-152.16140747070312,58.942216873168945],[-152.31332397460938,58.90832710266113]]],[[[-150.69168090820312,59.306657791137695],[-150.77667236328125,59.32888221740723],[-150.61663818359375,59.389719009399414],[-150.69168090820312,59.306657791137695]]],[[[-153.41140747070312,59.330278396606445],[-153.55221557617188,59.36471748352051],[-153.403076171875,59.406938552856445],[-153.41140747070312,59.330278396606445]]],[[[-150.3114013671875,59.420549392700195],[-150.44027709960938,59.40110206604004],[-150.29278564453125,59.46305274963379],[-150.3114013671875,59.420549392700195]]],[[[-144.58499145507812,59.81027412414551],[-144.50390625,59.89444160461426],[-144.20889282226562,60.00555610656738],[-144.58499145507812,59.81027412414551]]],[[[-148.1611328125,59.94110298156738],[-148.24581909179688,59.94249153137207],[-147.99221801757812,60.0402774810791],[-148.1611328125,59.94110298156738]]],[[[-148.02780151367188,59.94665718078613],[-147.88333129882812,60.067216873168945],[-147.81723022460938,60.06888771057129],[-148.02780151367188,59.94665718078613]]],[[[-148.11553955078125,59.99638557434082],[-147.96722412109375,60.15304756164551],[-147.87664794921875,60.10388374328613],[-148.11553955078125,59.99638557434082]]],[[[-148.03390502929688,60.18943214416504],[-148.15139770507812,60.041940689086914],[-148.30972290039062,60.02971839904785],[-148.03390502929688,60.18943214416504]]],[[[-147.8499755859375,59.77694129943848],[-147.193603515625,60.35332679748535],[-146.92333984375,60.309160232543945],[-147.8499755859375,59.77694129943848]]],[[[-147.71194458007812,60.37610054016113],[-147.75973510742188,60.165544509887695],[-147.90972900390625,60.23472023010254],[-147.71194458007812,60.37610054016113]]],[[[-148.07943725585938,60.28277015686035],[-148.14251708984375,60.3205509185791],[-147.98330688476562,60.38388252258301],[-148.07943725585938,60.28277015686035]]],[[[-166.10971069335938,60.39915657043457],[-165.68142700195312,60.29471778869629],[-165.55972290039062,59.92360877990723],[-166.19305419921875,59.75443458557129],[-167.41806030273438,60.18942451477051],[-166.10971069335938,60.39915657043457]]],[[[-146.3538818359375,60.40749549865723],[-146.07888793945312,60.4052677154541],[-146.72415161132812,60.374711990356445],[-146.3538818359375,60.40749549865723]]],[[[-145.12277221679688,60.30721473693848],[-145.28195190429688,60.32999610900879],[-145.08694458007812,60.41666603088379],[-145.12277221679688,60.30721473693848]]],[[[-172.52029418945312,60.38833045959473],[-172.20697021484375,60.31304359436035],[-173.05364990234375,60.497209548950195],[-172.52029418945312,60.38833045959473]]],[[[-151.95556640625,60.42276954650879],[-151.95111083984375,60.512216567993164],[-151.85638427734375,60.48971748352051],[-151.95556640625,60.42276954650879]]],[[[-146.2469482421875,60.45499610900879],[-146.320556640625,60.494157791137695],[-145.74972534179688,60.59471321105957],[-146.2469482421875,60.45499610900879]]],[[[-147.37277221679688,60.66166114807129],[-147.47555541992188,60.68888282775879],[-147.31390380859375,60.67749214172363],[-147.37277221679688,60.66166114807129]]],[[[-147.92556762695312,60.66221046447754],[-148.00418090820312,60.726938247680664],[-147.84609985351562,60.69999885559082],[-147.92556762695312,60.66221046447754]]],[[[-148.14083862304688,60.642221450805664],[-148.21417236328125,60.75444221496582],[-148.10861206054688,60.73638343811035],[-148.14083862304688,60.642221450805664]]],[[[-164.98831176757812,60.82249641418457],[-165.01751708984375,60.87443733215332],[-164.90362358093262,60.85360908508301],[-164.98831176757812,60.82249641418457]]],[[[-146.75335693359375,60.80721473693848],[-146.83193969726562,60.836381912231445],[-146.744140625,60.88138008117676],[-146.75335693359375,60.80721473693848]]],[[[-147.15084838867188,60.86027717590332],[-147.31777954101562,60.884164810180664],[-147.07528686523438,60.8991641998291],[-147.15084838867188,60.86027717590332]]],[[[-147.92889404296875,60.80694007873535],[-148.133056640625,60.79972267150879],[-148.10665893554688,60.912492752075195],[-147.92889404296875,60.80694007873535]]],[[[-170.31890869140625,63.254716873168945],[-170.31585693359375,63.25387763977051],[-170.29611206054688,63.238046646118164],[-170.31890869140625,63.254716873168945]]],[[[-170.31890869140625,63.254716873168945],[-170.36221313476562,63.28249549865723],[-170.34188842773438,63.271127700805664],[-170.31890869140625,63.254716873168945]]],[[[-170.46676635742188,63.334184646606445],[-170.40390014648438,63.3044376373291],[-170.48583984375,63.34110450744629],[-170.46676635742188,63.334184646606445]]],[[[-170.54364013671875,63.35971260070801],[-170.49026489257812,63.341928482055664],[-170.5511474609375,63.360551834106445],[-170.54364013671875,63.35971260070801]]],[[[-170.59500122070312,63.37193489074707],[-170.58197021484375,63.368051528930664],[-170.86325073242188,63.41851234436035],[-170.59500122070312,63.37193489074707]]],[[[-162.37747192382812,63.544443130493164],[-162.70361328125,63.571664810180664],[-162.4202880859375,63.63749885559082],[-162.37747192382812,63.544443130493164]]],[[[-171.465576171875,63.60666084289551],[-170.30001831054688,63.69415473937988],[-168.70086669921875,63.290544509887695],[-169.6661376953125,62.943315505981445],[-170.51889038085938,63.37803840637207],[-170.856689453125,63.46193885803223],[-171.46112060546875,63.314714431762695],[-171.850830078125,63.50860786437988],[-171.72695922851562,63.79221534729004],[-171.465576171875,63.60666084289551]]],[[[-166.6591796875,66.10331916809082],[-166.443603515625,66.18081855773926],[-166.16946411132812,66.22137641906738],[-166.6591796875,66.10331916809082]]],[[[-165.36444091796875,66.42637825012207],[-165.4708251953125,66.41415596008301],[-164.76223754882812,66.53831672668457],[-165.36444091796875,66.42637825012207]]],[[[-156.44696044921875,71.26361274719238],[-155.58694458007812,71.16276741027832],[-156.1824951171875,70.91832160949707],[-155.97360229492188,70.75583076477051],[-155.08749389648438,71.1513843536377],[-154.24386596679688,70.7794361114502],[-152.25250244140625,70.83526802062988],[-152.49859619140625,70.6494312286377],[-152.07611083984375,70.57499885559082],[-152.62942504882812,70.55748176574707],[-151.73248291015625,70.55720710754395],[-151.96609497070312,70.44359016418457],[-149.17471313476562,70.49081611633301],[-144.95220947265625,69.96832466125488],[-143.28057861328125,70.11831855773926],[-141.00299072265625,69.64236640930176],[-140.99554443359375,60.30721473693848],[-139.06805419921875,60.35222053527832],[-139.18890380859375,60.088884353637695],[-137.5908203125,59.238603591918945],[-137.47805786132812,58.90721321105957],[-135.47360229492188,59.80193519592285],[-133.42999267578125,58.45916175842285],[-131.82415771484375,56.596940994262695],[-130.01507568359375,55.90918159484863],[-130.17471313476562,55.75444221496582],[-129.99053955078125,55.28166389465332],[-130.68612670898438,54.76194190979004],[-131.00863647460938,55.004167556762695],[-130.461669921875,55.327775955200195],[-131.05612182617188,55.12276649475098],[-130.6138916015625,55.29610633850098],[-130.86416625976562,55.308603286743164],[-131.01028442382812,56.10638618469238],[-131.90057373046875,55.85527229309082],[-131.75250244140625,55.80777168273926],[-131.95498657226562,55.501108169555664],[-132.1602783203125,55.5786075592041],[-131.76974487304688,56.19693946838379],[-132.7913818359375,57.08804512023926],[-133.50836181640625,57.19360542297363],[-133.06304931640625,57.34887886047363],[-133.64056396484375,57.69638252258301],[-133.00057983398438,57.51500129699707],[-133.55694580078125,57.90249061584473],[-133.12136840820312,57.857500076293945],[-134.05499267578125,58.07193946838379],[-133.7691650390625,58.518327713012695],[-134.1541748046875,58.197771072387695],[-134.510009765625,58.35388374328613],[-134.76141357421875,58.382211685180664],[-135.33526611328125,59.46832466125488],[-135.30471801757812,59.08360481262207],[-135.55056762695312,59.2288761138916],[-135.08554077148438,58.233049392700195],[-135.91555786132812,58.3830509185791],[-136.06832885742188,58.81777381896973],[-135.76947021484375,58.90027046203613],[-136.1622314453125,59.03360939025879],[-136.23471069335938,58.75083351135254],[-137.05667114257812,59.06860542297363],[-137.12554931640625,58.82193946838379],[-136.5736083984375,58.83860206604004],[-136.02749633789062,58.387216567993164],[-136.6541748046875,58.21527290344238],[-138.443603515625,59.191659927368164],[-139.71054077148438,59.49582862854004],[-139.49386596679688,59.98221015930176],[-139.28555297851562,59.57138252258301],[-138.89279174804688,59.806657791137695],[-139.5,60.03305244445801],[-140.40335083007812,59.69804573059082],[-141.37664794921875,59.86638832092285],[-141.39083862304688,60.13860511779785],[-143.92333984375,59.994157791137695],[-144.9364013671875,60.30166053771973],[-144.61138916015625,60.71554756164551],[-145.29415893554688,60.35027503967285],[-145.85943603515625,60.49166297912598],[-145.62582397460938,60.67193794250488],[-146.26113891601562,60.64805030822754],[-146.04083251953125,60.79860877990723],[-146.65335083007812,60.699716567993164],[-146.1241455078125,60.84332466125488],[-146.75668334960938,60.955270767211914],[-146.30084228515625,61.13082313537598],[-147.366943359375,60.887773513793945],[-147.54666137695312,61.154436111450195],[-147.86526489257812,60.83249855041504],[-148.05221557617188,60.949716567993164],[-147.7197265625,61.27804756164551],[-148.69973754882812,60.78972053527832],[-148.197509765625,60.62610054016113],[-148.68417358398438,60.44832801818848],[-147.93695068359375,60.46221351623535],[-148.43112182617188,60.192766189575195],[-148.0977783203125,60.20749855041504],[-148.31777954101562,60.16888618469238],[-148.43582153320312,59.94887733459473],[-149.2861328125,59.86888313293457],[-149.41696166992188,60.11832618713379],[-149.52584838867188,59.71666145324707],[-149.73193359375,59.96055030822754],[-149.74359130859375,59.65860176086426],[-150.0341796875,59.79638862609863],[-149.91583251953125,59.7147159576416],[-150.01364135742188,59.62748908996582],[-150.34942626953125,59.46554756164551],[-150.213623046875,59.71666145324707],[-150.47360229492188,59.46444129943848],[-150.54168701171875,59.59166145324707],[-150.90750122070312,59.24332618713379],[-151.98056030273438,59.28055000305176],[-150.99276733398438,59.7772159576416],[-151.87664794921875,59.75388526916504],[-151.30389404296875,60.38555335998535],[-151.40890502929688,60.727487564086914],[-150.399169921875,61.03721809387207],[-149.028076171875,60.8477725982666],[-150.06417846679688,61.154436111450195],[-149.41696166992188,61.50860786437988],[-151.5836181640625,60.976938247680664],[-152.4302978515625,60.288888931274414],[-153.10305786132812,60.289438247680664],[-152.57720947265625,60.064714431762695],[-154.26083374023438,59.142221450805664],[-153.26779174804688,58.84860420227051],[-154.10333251953125,58.48193550109863],[-154.23361206054688,58.13110542297363],[-156.489990234375,57.33111000061035],[-156.54861450195312,56.977487564086914],[-158.42306518554688,56.44388008117676],[-158.64999389648438,56.26444435119629],[-158.12054443359375,56.23360633850098],[-158.50527954101562,55.9888858795166],[-158.60110473632812,56.18804359436035],[-159.667236328125,55.577219009399414],[-159.84109497070312,55.85110664367676],[-161.25418090820312,55.346940994262695],[-161.48553466796875,55.48110389709473],[-161.14169311523438,55.538888931274414],[-161.5625,55.62276649475098],[-161.9677734375,55.101938247680664],[-162.45416259765625,55.03833198547363],[-162.62664794921875,55.29944038391113],[-162.5625,54.955270767211914],[-163.1844482421875,55.139719009399414],[-163.04446411132812,54.9374942779541],[-163.36026000976562,54.81193733215332],[-163.25863647460938,54.97332191467285],[-163.32305908203125,55.121660232543945],[-161.79998779296875,55.88665962219238],[-160.24972534179688,55.77054786682129],[-160.57470703125,55.98665809631348],[-160.34695434570312,56.28555488586426],[-158.64056396484375,56.76111030578613],[-158.64889526367188,57.05332374572754],[-157.93804931640625,57.4919376373291],[-157.39666557312012,57.490549087524414],[-157.7066650390625,57.643327713012695],[-157.6099853515625,58.0897159576416],[-157.13861083984375,58.162492752075195],[-157.55361938476562,58.38249397277832],[-156.7791748046875,59.151384353637695],[-158.18832397460938,58.60638618469238],[-158.49249267578125,58.99943733215332],[-157.99276733398438,58.90499305725098],[-158.53695678710938,59.17527198791504],[-158.89752197265625,58.39554786682129],[-160.32666015625,59.05971717834473],[-162.17138671875,58.64972114562988],[-161.56582641601562,59.10360908508301],[-161.99221801757812,59.1441593170166],[-161.70526123046875,59.496660232543945],[-162.15139770507812,60.24554634094238],[-162.37222290039062,60.176103591918945],[-161.87942504882812,60.702219009399414],[-162.5694580078125,60.31638526916504],[-162.52166557312012,59.99276924133301],[-164.06527709960938,59.824167251586914],[-165.42529296875,60.55526924133301],[-164.66500854492188,60.91166114807129],[-164.26446533203125,60.778879165649414],[-164.42916870117188,60.55332374572754],[-163.957763671875,60.78027534484863],[-163.66946411132812,60.58721351623535],[-163.40972900390625,60.756662368774414],[-163.89561462402344,60.85688591003418],[-163.5513916015625,60.903879165649414],[-165.15029907226562,60.928049087524414],[-164.82223510742188,61.11110877990723],[-165.12054443359375,61.083879470825195],[-165.13861083984375,61.256662368774414],[-165.16372680664062,61.17004585266113],[-165.3699951171875,61.20083045959473],[-165.15057373046875,61.416940689086914],[-165.05967712402344,61.41684150695801],[-164.99842834472656,61.469770431518555],[-164.84527587890625,61.49444007873535],[-164.71609497070312,61.62555122375488],[-165.01724243164062,61.50000190734863],[-165.0755615234375,61.43221473693848],[-165.1611328125,61.43249702453613],[-165.28750610351562,61.333879470825195],[-165.40750122070312,61.208330154418945],[-165.34136962890625,61.15721321105957],[-165.38668823242188,61.06860542297363],[-166.19778442382812,61.59471321105957],[-165.24722290039062,62.44610023498535],[-164.63641357421875,62.417497634887695],[-164.852783203125,62.57027626037598],[-164.479154586792,62.74582862854004],[-164.87777709960938,62.83555030822754],[-164.31832885742188,63.00694465637207],[-164.41055297851562,63.21193885803223],[-163.11166381835938,63.05193519592285],[-162.31195068359375,63.54110908508301],[-161.15167236328125,63.51249885559082],[-160.77749633789062,63.868600845336914],[-161.5291748046875,64.41887092590332],[-160.78390502929688,64.72192573547363],[-161.1824951171875,64.93748664855957],[-162.790283203125,64.33610725402832],[-163.17001342773438,64.65526008605957],[-163.17584228515625,64.4074878692627],[-166.12136840820312,64.57470893859863],[-166.96194458007812,65.18887519836426],[-166.05889892578125,65.25610542297363],[-168.131103515625,65.6655445098877],[-164.35360717773438,66.59471321105957],[-163.625,66.56721687316895],[-164.18832397460938,66.19609260559082],[-163.65640258789062,66.07054328918457],[-161.00335693359375,66.20416450500488],[-161.91000366210938,66.2744312286377],[-161.9061279296875,66.53526496887207],[-162.63613891601562,66.86886787414551],[-162.33694458007812,66.95833015441895],[-161.60055541992188,66.44775581359863],[-160.23056030273438,66.39972114562988],[-160.26419067382812,66.64749336242676],[-161.50668334960938,66.53387641906738],[-161.89779663085938,66.72831916809082],[-161.50112915039062,66.97915840148926],[-162.46112060546875,66.99247932434082],[-162.35055541992188,67.16137886047363],[-163.73248291015625,67.11360359191895],[-164.1241455078125,67.60998725891113],[-166.82778930664062,68.35081672668457],[-166.3726043701172,68.4167652130127],[-166.2158203125,68.88304328918457],[-163.64529418945312,69.10693550109863],[-161.94223022460938,70.30720710754395],[-162.11886596679688,70.15165901184082],[-159.9375,70.59332466125488],[-160.1986083984375,70.47165107727051],[-159.83612060546875,70.2683277130127],[-159.28555297851562,70.53055000305176],[-160.12442016601562,70.61526679992676],[-159.66806030273438,70.79803657531738],[-157.97943115234375,70.83749580383301],[-156.44696044921875,71.26361274719238]],[[-135.55416870117188,58.32999610900879],[-135.62527465820312,58.3830509185791],[-135.72610473632812,58.35943794250488],[-135.55416870117188,58.32999610900879]]]]}},{"type":"Feature","properties":{"name":"Burkina Faso","iso2":"BF","iso3":"BFA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-2.834048,11.002007],[-2.685561,9.481817],[-3.633611,9.954443000000111],[-4.704445,9.698055],[-5.51985,10.436272],[-5.273056,11.843887],[-4.4175,12.300831],[-4.337223,13.121666],[-3.964253,13.50383],[-3.437675,13.166498],[-3.2575,13.696665],[-2.879167,13.655554],[-2.474722,14.287498],[-2.006945,14.187777],[-1.980834,14.474722],[-0.725278,15.082777],[0.235048,14.915068],[0.602222,13.703888],[1.285306,13.349957],[0.991667,13.371666],[0.989167,13.047222],[1.578333,12.629999],[2.1425,12.694443],[2.397925,11.896152],[2.014722,11.422499],[1.435278,11.458887],[0.91797,10.996399],[-0.149762,11.13854],[-0.618333,10.911665],[-2.834048,11.002007]]]]}},{"type":"Feature","properties":{"name":"Uruguay","iso2":"UY","iso3":"URY"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-57.806396,-30.748219],[-57.608002,-30.184925],[-56.811394,-30.105278],[-56.008923,-31.079794],[-55.581947,-30.845837],[-53.879723,-31.967781],[-53.093056,-32.729729],[-53.522781,-33.147781],[-53.374298,-33.740669],[-54.145004,-34.671394],[-56.320282,-34.910561],[-57.117783,-34.462227],[-57.840279,-34.494728],[-58.402779,-33.929726],[-58.361946,-33.133339],[-58.146393,-33.101952],[-58.045563,-32.934723],[-58.199242,-32.45031],[-57.806396,-30.748219]]]]}},{"type":"Feature","properties":{"name":"Uzbekistan","iso2":"UZ","iso3":"UZB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[64.383026,38.953125],[62.551102,39.934158],[61.874161,41.125549],[60.14027400000012,41.381104],[60.014442,42.217491],[58.780548,42.658043],[58.16443600000011,42.651932],[58.51554900000011,42.304436],[58.02660400000016,42.504639],[56.986938,41.893051],[57.044716,41.260277],[56.000961,41.32845300000015],[55.99749,45.001106],[58.569717,45.571106],[62.025108,43.484787],[64.931366,43.73777],[65.82193,42.877213],[66.123871,42.99694100000012],[66.02916,42.003052],[66.526382,42.003052],[66.7199860000002,41.174995],[67.935532,41.183327],[68.455261,40.59777100000012],[69.05636600000011,41.379433000000105],[70.97081,42.254669],[71.276382,42.195511],[70.187195,41.52829],[71.418045,41.118553],[71.69136,41.556335],[72.19548,41.006592],[73.173035,40.822998],[71.710541,40.145767],[70.98204,40.244843],[70.375534,40.376404],[70.796799,40.725594],[70.423874,41.049118],[69.732483,40.638603],[69.356094,40.772491],[69.308029,40.201385],[68.600815,40.178329],[69.009995,40.089714],[68.540268,39.55471],[67.441956,39.483582],[67.376373,39.212494],[68.123871,38.98555],[68.384155,38.195541],[67.779877,37.185822],[66.537735,37.366379],[66.64387500000012,38.003052000000125],[64.383026,38.953125]]]]}},{"type":"Feature","properties":{"name":"Saint Vincent and the Grenadines","iso2":"VC","iso3":"VCT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-61.416946,12.590277],[-61.45417,12.593887],[-61.425835,12.612499],[-61.416946,12.590277]]],[[[-61.32805599999989,12.687777],[-61.347778,12.701666],[-61.31056199999989,12.734999],[-61.32805599999989,12.687777]]],[[[-61.216667,12.998055],[-61.252228,12.988609],[-61.199722,13.044722],[-61.216667,12.998055]]],[[[-61.173058,13.1325],[-61.28139499999989,13.207777000000164],[-61.177223,13.384165],[-61.173058,13.1325]]]]}},{"type":"Feature","properties":{"name":"Venezuela","iso2":"VE","iso3":"VEN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-61.00361633300781,8.548887252807617],[-61.266395568847656,8.509164810180664],[-61.080833435058594,8.61027717590332],[-61.00361633300781,8.548887252807617]]],[[[-61.04778289794922,8.629446029663086],[-61.1844482421875,8.598611831665039],[-61.16722869873047,8.651945114135742],[-61.04778289794922,8.629446029663086]]],[[[-61.04194641113281,8.640275955200195],[-61.146949768066406,8.654443740844727],[-61.17778015136719,8.679445266723633],[-60.9344482421875,8.718332290649414],[-61.04194641113281,8.640275955200195]]],[[[-60.82722473144531,8.649442672729492],[-60.988616943359375,8.635557174682617],[-60.84083557128906,8.728055953979492],[-60.82722473144531,8.649442672729492]]],[[[-60.976112365722656,8.725831985473633],[-61.17028045654297,8.693334579467773],[-61.042503356933594,8.821111679077148],[-60.860557556152344,8.853334426879883],[-60.976112365722656,8.725831985473633]]],[[[-61.070556640625,8.892499923706055],[-61.09972381591797,8.891111373901367],[-61.065834045410156,8.976945877075195],[-60.84861755371094,9.093610763549805],[-61.070556640625,8.892499923706055]]],[[[-60.87028503417969,9.108331680297852],[-60.9586181640625,9.066946029663086],[-60.863616943359375,9.193334579467773],[-60.87028503417969,9.108331680297852]]],[[[-60.730003356933594,9.18638801574707],[-60.841392517089844,9.116666793823242],[-60.822784423828125,9.201665878295898],[-60.730003356933594,9.18638801574707]]],[[[-62.288612365722656,9.755556106567383],[-62.28639221191406,9.934167861938477],[-62.249168395996094,9.856943130493164],[-62.288612365722656,9.755556106567383]]],[[[-62.64750671386719,10.302499771118164],[-62.788063049316406,10.414999008178711],[-62.78722381591797,10.478612899780273],[-62.64750671386719,10.302499771118164]]],[[[-63.9072265625,10.72944450378418],[-63.996673583984375,10.802221298217773],[-63.90666961669922,10.777498245239258],[-63.9072265625,10.72944450378418]]],[[[-65.26861572265625,10.881109237670898],[-65.417236328125,10.924722671508789],[-65.21194458007812,10.956110000610352],[-65.26861572265625,10.881109237670898]]],[[[-63.804725646972656,11.021387100219727],[-64.40583801269531,10.967500686645508],[-63.88111114501953,11.176942825317383],[-63.804725646972656,11.021387100219727]]],[[[-66.64834594726562,11.758611679077148],[-66.61056518554688,11.821111679077148],[-66.58639526367188,11.771665573120117],[-66.64834594726562,11.758611679077148]]],[[[-66.1158447265625,11.773611068725586],[-66.19306945800781,11.817220687866211],[-66.10861206054688,11.825555801391602],[-66.1158447265625,11.773611068725586]]],[[[-64.57223510742188,11.80555534362793],[-64.64389038085938,11.82472038269043],[-64.61500358581543,11.89555549621582],[-64.57223510742188,11.80555534362793]]],[[[-69.77084350585938,11.696111679077148],[-68.4183349609375,11.179998397827148],[-68.16000366210938,10.496946334838867],[-66.23529052734375,10.642221450805664],[-65.08139038085938,10.060556411743164],[-63.69750213623047,10.485555648803711],[-64.25889587402344,10.661664962768555],[-61.882781982421875,10.733331680297852],[-62.91667175292969,10.528055191040039],[-63.000282287597656,10.271665573120117],[-62.78212356567383,10.399694442749023],[-62.62805938720703,10.107778549194336],[-63.01722717285156,10.097776412963867],[-62.80528259277344,10.008611679077148],[-62.61750030517578,10.089723587036133],[-62.61333465576172,10.222776412963867],[-62.5352783203125,10.20222282409668],[-62.31806182861328,9.704999923706055],[-62.2005615234375,9.905553817749023],[-62.210838317871094,9.634443283081055],[-62.18861389160156,10.015832901000977],[-61.738616943359375,9.595556259155273],[-61.62250518798828,9.906110763549805],[-60.85028076171875,9.440832138061523],[-60.78361511230469,9.304998397827148],[-61.08222961425781,9.10222053527832],[-60.94972229003906,9.179445266723633],[-61.0977783203125,8.963335037231445],[-61.208892822265625,8.595556259155273],[-61.59889221191406,8.554998397827148],[-61.073890686035156,8.400835037231445],[-60.90222930908203,8.582223892211914],[-59.99028015136719,8.535276412963867],[-59.8255615234375,8.236112594604492],[-60.71916961669922,7.535554885864258],[-60.288612365722656,7.057222366333008],[-61.13402557373047,6.711042404174805],[-61.38972473144531,5.940000534057617],[-60.730369567871094,5.204801559448242],[-60.57972717285156,4.94666862487793],[-60.98500061035156,4.52055549621582],[-62.74583435058594,4.032499313354492],[-62.875,3.560277938842773],[-63.343055725097656,3.961111068725586],[-64.01779174804688,3.886110305786133],[-64.7952880859375,4.281389236450195],[-64.19111633300781,3.594446182250977],[-64.04501342773438,2.482500076293945],[-63.361114501953125,2.419168472290039],[-63.39305877685547,2.151388168334961],[-65.51889038085938,0.649721145629883],[-65.58973693847656,0.989168167114258],[-66.31195068359375,0.750558853149414],[-66.87188720703125,1.221643447875977],[-67.1925048828125,2.392499923706055],[-67.82833862304688,2.825002670288086],[-67.29055786132812,3.397500991821289],[-67.85972595214844,4.558610916137695],[-67.45445251464844,6.193056106567383],[-69.24528503417969,6.081388473510742],[-70.11917114257812,6.975835800170898],[-72,7.018888473510742],[-72.4716796875,7.491945266723633],[-72.32528686523438,8.095556259155273],[-72.77972412109375,9.080278396606445],[-73.37806701660156,9.171388626098633],[-72.49305725097656,11.121110916137695],[-72.2093505859375,11.250001907348633],[-71.97723388671875,11.664999008178711],[-71.32472229003906,11.853055953979492],[-71.96833801269531,11.55583381652832],[-71.57695007324219,10.714445114135742],[-72.12750244140625,9.813055038452148],[-71.61805725097656,9.04194450378418],[-71.05528259277344,9.341390609741211],[-71.49751281738281,10.960000991821289],[-69.79861450195312,11.427778244018555],[-69.814453125,11.690832138061523],[-70.23834228515625,11.63166618347168],[-70.02694702148438,12.195276260375977],[-69.77084350585938,11.696111679077148]],[[-61.20667266845703,9.585832595825195],[-61.41166687011719,9.72972297668457],[-61.32695007324219,9.646665573120117],[-61.20667266845703,9.585832595825195]]]]}},{"type":"Feature","properties":{"name":"British Virgin Islands","iso2":"VG","iso3":"VGB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-64.660843,18.383888],[-64.65251199999989,18.441109],[-64.558334,18.451942],[-64.660843,18.383888]]],[[[-64.422501,18.43861],[-64.412231,18.506107],[-64.322235,18.506107],[-64.422501,18.43861]]],[[[-64.31140099999988,18.746109],[-64.270004,18.696388],[-64.408066,18.735832],[-64.31140099999988,18.746109]]]]}},{"type":"Feature","properties":{"name":"Viet Nam","iso2":"VN","iso3":"VNM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[106.600273,8.647778],[106.555817,8.688887],[106.659378,8.764740000000103],[106.600273,8.647778]]],[[[103.4985960000001,9.31361],[103.469437,9.279444],[103.467209,9.304443],[103.4985960000001,9.31361]]],[[[106.26275600000011,9.528887],[106.088058,9.754438],[106.2855220000001,9.586943],[106.26275600000011,9.528887]]],[[[106.54357900000011,9.82583],[106.41857900000016,9.934443],[106.48578600000016,9.902222000000137],[106.54357900000011,9.82583]]],[[[106.59662600000016,10.257221000000115],[106.664413,10.243053],[106.586906,10.256943],[106.59662600000016,10.257221000000115]]],[[[106.63719200000017,10.269999],[106.75247200000015,10.234442],[106.511642,10.29361],[106.63719200000017,10.269999]]],[[[104.083862,10.361942],[104.02638200000015,10.080276],[103.837196,10.36944200000012],[104.083862,10.361942]]],[[[107.092468,10.32222],[107.063858,10.383333],[107.20636000000016,10.432775],[107.092468,10.32222]]],[[[106.89524800000018,10.372219],[106.88748200000012,10.510555],[106.97914100000011,10.408888],[106.89524800000018,10.372219]]],[[[108.958588,10.504166],[108.930252,10.510277],[108.930252,10.550276],[108.958588,10.504166]]],[[[106.904694,10.520832],[106.875793,10.530277],[106.851357,10.561943],[106.871384,10.595519],[106.852188,10.625553000000153],[106.87941000000015,10.63722],[106.92746,10.592775],[106.930252,10.544722],[106.904694,10.520832]]],[[[106.852188,10.403610000000128],[106.755539,10.481386],[106.749977,10.562498000000119],[106.786301,10.578066],[106.7532120000001,10.660968000000125],[106.856476,10.60388200000014],[106.835747,10.569703000000118],[106.87413,10.502499],[106.852188,10.403610000000128]]],[[[109.332764,12.187777],[109.245247,12.227497],[109.33148200000014,12.221088],[109.332764,12.187777]]],[[[109.3936,12.350275000000124],[109.387207,12.34972],[109.385269,12.366941],[109.3936,12.350275000000124]]],[[[107.919434,16.349442],[107.86692800000012,16.35944],[107.661217,16.572613],[107.919434,16.349442]]],[[[107.73027,20.127773],[107.711647,20.131939000000116],[107.7383120000002,20.144440000000102],[107.73027,20.127773]]],[[[107.378311,20.799164],[107.334991,20.846664],[107.382477,20.824165],[107.378311,20.799164]]],[[[107.068047,20.727493],[106.9080430000001,20.832218],[107.033867,20.856106],[107.068047,20.727493]]],[[[106.75277700000018,20.854164000000125],[106.719147,20.870831],[106.74108900000013,20.871109],[106.75277700000018,20.854164000000125]]],[[[106.873306,20.78722],[106.770828,20.852497],[106.78137200000012,20.922497],[106.873306,20.78722]]],[[[106.9480290000001,20.936382],[106.93221300000013,20.936939],[106.927467,20.944717],[106.9480290000001,20.936382]]],[[[107.4885860000002,20.839165],[107.464706,20.821384],[107.554153,20.966106000000124],[107.4885860000002,20.839165]]],[[[106.89388300000022,20.965549],[106.916656,20.954441],[106.888046,20.965549],[106.89388300000022,20.965549]]],[[[107.460823,20.942219],[107.454712,20.943886],[107.45498700000022,20.950272],[107.46219600000015,20.967495],[107.476089,20.972218000000126],[107.47831700000015,20.966106000000124],[107.4733120000001,20.954441],[107.460823,20.942219]]],[[[106.75360100000015,20.950829],[106.688873,20.956661],[106.67942800000017,20.97749300000011],[106.75360100000015,20.950829]]],[[[107.746933,20.937218],[107.747757,21.019165],[107.790817,20.981937000000116],[107.746933,20.937218]]],[[[107.462769,20.90304900000011],[107.39498900000015,20.896664000000115],[107.476723,20.946983],[107.502403,21.012671],[107.554428,21.038052],[107.462769,20.90304900000011]]],[[[107.859421,21.037777],[107.80693100000016,20.986938],[107.8311,21.034996],[107.859421,21.037777]]],[[[107.578323,20.977219],[107.567207,21.020554],[107.6207430000002,21.11783600000011],[107.578323,20.977219]]],[[[107.513321,21.128330000000105],[107.509163,21.133331],[107.53221100000016,21.145828],[107.513321,21.128330000000105]]],[[[107.383881,21.04638700000011],[107.47194700000014,21.27142],[107.604431,21.218884],[107.383881,21.04638700000011]]],[[[107.742752,21.308887000000126],[107.7083280000002,21.305275],[107.81804700000012,21.356384],[107.742752,21.308887000000126]]],[[[107.996643,21.39471800000011],[107.933319,21.364162],[107.828598,21.371384],[107.996643,21.39471800000011]]],[[[105.577477,23.059162000000143],[106.70720700000018,22.864998000000142],[106.693314,22.03083],[107.990021,21.542412],[107.414703,21.326107],[107.36998000000014,21.022221],[107.154427,20.924995000000152],[106.6438830000001,21.021385],[106.776932,20.69916200000013],[105.954163,19.92083000000015],[105.61387600000015,18.977219],[106.698868,17.399719],[108.830276,15.42083200000016],[109.466377,12.8933320000001],[109.145538,12.435555],[109.269989,11.892498],[109.17330900000016,12.120552],[109.021103,11.353331],[107.997742,10.699165],[107.26619000000014,10.376129],[106.999748,10.657166000000132],[106.961189,10.466075],[106.93219,10.567221000000103],[106.94329800000011,10.593609000000129],[106.904137,10.631386000000134],[106.744133,10.669998000000135],[106.770813,10.591108000000148],[106.73830400000011,10.560613000000117],[106.736359,10.513054],[106.591553,10.429691],[106.738571,10.469442],[106.79274,10.386944],[106.784698,10.277498],[106.424316,10.311384],[106.776367,10.079998],[106.290527,10.25083200000013],[106.618027,9.811388],[106.11718800000014,10.238331],[106.54303,9.583609],[105.820534,10.002499],[106.19412200000014,9.366941],[105.02110300000012,8.592775],[104.742752,8.604998000000151],[105.107468,9.945276],[104.445328,10.422739],[105.101913,10.955553],[106.203308,10.770554],[105.851067,11.659998],[106.458214,11.665863000000101],[106.420242,11.973608],[107.54749300000012,12.35360900000012],[107.489151,14.448608],[107.5466,14.708618],[107.695251,15.270832],[107.1755370000001,15.784164],[107.464706,16.078609000000128],[106.685532,16.45805],[106.561096,16.996941],[105.183319,18.334442],[105.193863,18.642494],[103.87943300000015,19.29361],[104.03724700000012,19.69294400000011],[104.640266,19.611942],[104.979156,20.004997],[104.3819270000001,20.444717],[104.6436,20.660275000000112],[104.109154,20.977219],[103.693588,20.657219],[103.170532,20.846664],[102.976089,21.739437],[102.676651,21.65583],[102.14074700000012,22.396286],[102.479713,22.773888],[103.030548,22.435551],[103.33638000000016,22.79638700000011],[103.964432,22.499111],[105.35386700000018,23.3347210000001],[105.577477,23.059162000000143]]]]}},{"type":"Feature","properties":{"name":"United States Virgin Islands","iso2":"VI","iso3":"VIR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-64.761948,17.774166],[-64.560287,17.748333],[-64.896118,17.67666600000014],[-64.761948,17.774166]]],[[[-64.665283,18.332222],[-64.79028299999987,18.33083],[-64.731949,18.371944],[-64.665283,18.332222]]],[[[-64.841675,18.312496],[-65.026947,18.36277800000012],[-64.9039,18.364719],[-64.841675,18.312496]]]]}},{"type":"Feature","properties":{"name":"Namibia","iso2":"NA","iso3":"NAM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[23.284721,-17.662502],[23.476109,-17.625835],[24.969997,-17.559723],[25.264431,-17.80225],[24.362499,-17.948612],[23.615578,-18.485069],[23.297108,-17.995949],[20.993286,-18.318417],[20.991943,-21.996948],[19.996666,-22.005001],[20.000942,-24.765408],[19.99612,-28.421448],[19.123055000000107,-28.962223],[18.175831,-28.908611],[17.40472,-28.713612],[17.06361,-28.028614],[16.48959,-28.578178],[15.294167,-27.322502],[14.463333,-24.109169],[14.511389,-22.55278],[11.804722,-18.081947],[11.752783000000107,-17.254833],[13.16055500000013,-16.952778],[13.993219,-17.423946],[18.451538,-17.389835],[18.915833000000134,-17.815556],[20.854164,-18.016392],[23.284721,-17.662502]]]]}},{"type":"Feature","properties":{"name":"Wallis and Futuna Islands","iso2":"WF","iso3":"WLF"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-178.042511,-14.319447],[-178.140564,-14.316389],[-178.189453,-14.236113],[-178.042511,-14.319447]]],[[[-176.161438,-13.352777],[-176.156158,-13.213614],[-176.121094,-13.263334],[-176.161438,-13.352777]]]]}},{"type":"Feature","properties":{"name":"Samoa","iso2":"WS","iso3":"WSM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-171.429749,-14.019724],[-172.064758,-13.874443],[-171.822266,-13.807503],[-171.429749,-14.019724]]],[[[-172.285858,-13.486387],[-172.214172,-13.807777],[-172.780609,-13.533335],[-172.285858,-13.486387]]]]}},{"type":"Feature","properties":{"name":"Swaziland","iso2":"SZ","iso3":"SWZ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[30.902048,-26.305254],[31.33083,-25.751392],[31.96851,-25.95784],[32.1334,-26.839626],[31.987499,-27.316113],[31.161663,-27.203056],[30.818886000000106,-26.810558],[30.902048,-26.305254]]]]}},{"type":"Feature","properties":{"name":"Yemen","iso2":"YE","iso3":"YEM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[53.340828,12.108889],[53.25666,12.124998000000119],[53.291664,12.134443],[53.340828,12.108889]]],[[[53.085831,12.13361],[53.011383,12.158609],[53.09610700000016,12.175554],[53.085831,12.13361]]],[[[52.234161,12.201111],[52.395828,12.155277],[52.083054,12.222776],[52.234161,12.201111]]],[[[43.438606,12.631109],[43.396111000000104,12.666388],[43.443886000000106,12.659443],[43.438606,12.631109]]],[[[53.774719,12.616388000000114],[54.476944000000145,12.557777],[53.753609,12.308054000000126],[53.325829,12.545832000000104],[53.774719,12.616388000000114]]],[[[42.755829000000205,13.69861],[42.677216,13.666111],[42.793884,13.781111],[42.755829000000205,13.69861]]],[[[42.78749800000011,13.91],[42.689163,14.01361100000014],[42.766388,14.066944000000106],[42.78749800000011,13.91]]],[[[42.594719,15.271944000000147],[42.568886,15.3925],[42.642494,15.458332],[42.594719,15.271944000000147]]],[[[52.23194100000015,15.674166],[49.098885,14.519165],[48.69805100000022,14.039999],[45.666664,13.341665],[45.055443,12.751296],[43.957222,12.592777],[43.46721600000015,12.677776],[43.247498000000206,13.210278000000145],[42.681107,15.208332],[42.78968,16.377502],[43.206108,16.672222],[43.309441,17.4572220000001],[44.46749900000012,17.41194200000014],[46.333328,16.666664],[46.333054,15.616943],[48.766388,18.266388000000106],[51.99929,18.999344000000136],[53.114441,16.642778],[52.29888200000019,16.27222100000013],[52.23194100000015,15.674166]]]]}},{"type":"Feature","properties":{"name":"Zambia","iso2":"ZM","iso3":"ZMB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[24.969997,-17.559723],[23.476109,-17.625835],[22.000149000000135,-16.171661],[21.998333,-13.004168],[24.020554,-13.00639],[23.986206,-10.870461],[24.44833,-11.463612],[25.332222000000115,-11.193335],[25.35972200000012,-11.641668],[26.004719,-11.9025],[26.86861,-11.973612],[27.199249,-11.567905],[27.66000000000011,-12.296667],[28.441944,-12.519724],[29.015831,-13.397779],[29.589443,-13.221945],[29.801388,-13.454168],[29.80505,-12.155247],[29.49361,-12.458057],[29.031387,-12.383057],[28.363331,-11.550835],[28.699718000000104,-10.653334],[28.372219,-9.260834],[28.901665,-8.478613],[30.77124000000012,-8.192247],[31.041111,-8.590279],[32.940399,-9.405077],[33.702278,-10.561857],[33.250549,-10.886667],[33.273331,-12.144445],[33.54583,-12.359446],[33.046387,-12.603889],[32.678886,-13.60639],[33.222229,-14.012566],[30.21301700000018,-14.981716],[30.415756,-15.631872],[28.927219,-15.972223],[28.759441,-16.552223],[27.825275,-16.959167],[27.038055,-17.959446],[25.264431,-17.80225],[24.969997,-17.559723]]]]}},{"type":"Feature","properties":{"name":"Zimbabwe","iso2":"ZW","iso3":"ZWE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[32.987808,-17.265003],[33.073051000000106,-18.348892],[32.699165,-18.944447],[33.0188830000001,-19.943336],[32.50222000000011,-20.598614],[32.488876,-21.344448],[31.297504000000146,-22.414764],[29.893887,-22.194447],[29.373623,-22.19241],[29.060555,-21.798058],[28.015831,-21.566113],[27.713165,-20.506432],[27.287453,-20.494965],[27.219997,-20.091667],[26.166111,-19.527779],[25.264431,-17.80225],[27.038055,-17.959446],[27.825275,-16.959167],[28.759441,-16.552223],[28.927219,-15.972223],[30.415756,-15.631872],[30.422775,-16.009167],[31.276665,-16.018612],[32.98114,-16.709053],[32.987808,-17.265003]]]]}},{"type":"Feature","properties":{"name":"Indonesia","iso2":"ID","iso3":"IDN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[121.85999488830566,-10.61027717590332],[121.6908130645752,-10.566389083862305],[121.99693489074707,-10.441110610961914],[121.85999488830566,-10.61027717590332]]],[[[123.21470832824707,-10.81222152709961],[122.80774879455566,-10.794723510742188],[123.39026832580566,-10.436944961547852],[123.21470832824707,-10.81222152709961]]],[[[123.40054512023926,-10.342777252197266],[123.30859565734863,-10.276666641235352],[123.45332527160645,-10.13972282409668],[123.40054512023926,-10.342777252197266]]],[[[120.02916145324707,-9.383333206176758],[120.81025886535645,-9.979166030883789],[120.72442817687988,-10.199722290039062],[120.16470527648926,-10.231388092041016],[118.93109321594238,-9.561111450195312],[120.02916145324707,-9.383333206176758]]],[[[125.16404914855957,-9.066141128540039],[125.12798881530762,-9.435955047607422],[124.43525886535645,-10.162778854370117],[123.48831367492676,-10.316389083862305],[124.04616355895996,-9.33997917175293],[124.34309577941895,-9.46337890625],[124.44572639465332,-9.18480110168457],[124.94544792175293,-8.954038619995117],[125.16404914855957,-9.066141128540039]]],[[[115.59471321105957,-8.804166793823242],[115.46999549865723,-8.734443664550781],[115.51249885559082,-8.670000076293945],[115.59471321105957,-8.804166793823242]]],[[[119.69053840637207,-8.802778244018555],[119.60748481750488,-8.773611068725586],[119.63305854797363,-8.60079574584961],[119.69053840637207,-8.802778244018555]]],[[[122.96943855285645,-8.572500228881836],[122.98803901672363,-8.456666946411133],[123.17775917053223,-8.442222595214844],[122.96943855285645,-8.572500228881836]]],[[[119.46164894104004,-8.440277099609375],[119.58554267883301,-8.563055038452148],[119.44719886779785,-8.754167556762695],[119.46164894104004,-8.440277099609375]]],[[[113.38889503479004,-8.497220993041992],[113.29553413391113,-8.500556945800781],[113.28581428527832,-8.440000534057617],[113.38889503479004,-8.497220993041992]]],[[[124.2905445098877,-8.329166412353516],[124.11525917053223,-8.55555534362793],[123.90693855285645,-8.452499389648438],[124.2905445098877,-8.329166412353516]]],[[[123.76442909240723,-8.32722282409668],[123.21748542785645,-8.536666870117188],[123.93914985656738,-8.242498397827148],[123.76442909240723,-8.32722282409668]]],[[[123.28109931945801,-8.405834197998047],[123.01609992980957,-8.378055572509766],[123.22083473205566,-8.233610153198242],[123.28109931945801,-8.405834197998047]]],[[[128.21997261047363,-8.210556030273438],[128.20831489562988,-8.287221908569336],[128.07995796203613,-8.259445190429688],[128.21997261047363,-8.210556030273438]]],[[[116.54915046691895,-8.775001525878906],[115.84414863586426,-8.755279541015625],[116.38749885559082,-8.204999923706055],[116.73581123352051,-8.363054275512695],[116.54915046691895,-8.775001525878906]]],[[[127.66832160949707,-8.244443893432617],[127.60582160949707,-8.20694351196289],[127.77110481262207,-8.188888549804688],[127.66832160949707,-8.244443893432617]]],[[[129.0080280303955,-8.269445419311523],[128.82831001281738,-8.198888778686523],[128.9696979522705,-8.183889389038086],[129.0080280303955,-8.269445419311523]]],[[[117.54081916809082,-8.390277862548828],[117.48137092590332,-8.191389083862305],[117.67581367492676,-8.156110763549805],[117.54081916809082,-8.390277862548828]]],[[[138.87356758117676,-8.414722442626953],[138.54471015930176,-8.333053588867188],[138.81414985656738,-8.154722213745117],[138.87356758117676,-8.414722442626953]]],[[[118.31192207336426,-8.37472152709961],[118.6483325958252,-8.294445037841797],[118.66609382629395,-8.552223205566406],[118.99693489074707,-8.31361198425293],[119.17804145812988,-8.720277786254883],[118.45720863342285,-8.871944427490234],[118.40637397766113,-8.584722518920898],[118.15498542785645,-8.871944427490234],[116.75139045715332,-9.009445190429688],[117.12275886535645,-8.378610610961914],[117.96637916564941,-8.74860954284668],[118.2844181060791,-8.594165802001953],[117.73552894592285,-8.152223587036133],[118.31192207336426,-8.37472152709961]]],[[[122.98108863830566,-8.149444580078125],[122.83249092102051,-8.601663589477539],[121.76555061340332,-8.892223358154297],[119.79623603820801,-8.720342636108398],[120.52249336242676,-8.257223129272461],[122.28830909729004,-8.644445419311523],[122.98108863830566,-8.149444580078125]]],[[[124.57776832580566,-8.135833740234375],[125.13971138000488,-8.329166412353516],[124.35080909729004,-8.454444885253906],[124.57776832580566,-8.135833740234375]]],[[[125.58167457580566,-8.317499160766602],[125.49609565734863,-8.269445419311523],[125.6413745880127,-8.135833740234375],[125.58167457580566,-8.317499160766602]]],[[[119.07248878479004,-8.267499923706055],[119.07859992980957,-8.133890151977539],[119.13693428039551,-8.195554733276367],[119.07248878479004,-8.267499923706055]]],[[[115.5022144317627,-8.178611755371094],[115.70776557922363,-8.40916633605957],[115.12608528137207,-8.854166030883789],[114.44553565979004,-8.104721069335938],[115.5022144317627,-8.178611755371094]]],[[[127.84359931945801,-8.101110458374023],[128.12744331359863,-8.171667098999023],[128.02527046203613,-8.267499923706055],[127.84359931945801,-8.101110458374023]]],[[[130.80414009094238,-8.352222442626953],[131.013032913208,-8.0897216796875],[131.180269241333,-8.129720687866211],[130.80414009094238,-8.352222442626953]]],[[[127.2138843536377,-8.113332748413086],[127.15305519104004,-8.099166870117188],[127.18166542053223,-8.02194595336914],[127.2138843536377,-8.113332748413086]]],[[[129.76443672180176,-8.061111450195312],[129.6069049835205,-7.803888320922852],[129.84329414367676,-7.840555191040039],[129.76443672180176,-8.061111450195312]]],[[[126.72136878967285,-7.673055648803711],[125.77221870422363,-8.008890151977539],[125.97221565246582,-7.658611297607422],[126.72136878967285,-7.673055648803711]]],[[[130.98913764953613,-7.723333358764648],[130.98413276672363,-7.664165496826172],[131.12884712219238,-7.626665115356445],[130.98913764953613,-7.723333358764648]]],[[[127.38109016418457,-7.658611297607422],[127.36804389953613,-7.513889312744141],[127.48193550109863,-7.528888702392578],[127.38109016418457,-7.658611297607422]]],[[[138.96829414367676,-7.556110382080078],[138.44470405578613,-8.383333206176758],[137.63525581359863,-8.430000305175781],[138.15469551086426,-7.513889312744141],[138.96829414367676,-7.556110382080078]]],[[[130.8649616241455,-7.494165420532227],[130.98358345031738,-7.520833969116211],[130.84442329406738,-7.547222137451172],[130.8649616241455,-7.494165420532227]]],[[[131.07275581359863,-7.511388778686523],[131.00332832336426,-7.424999237060547],[131.1774616241455,-7.408611297607422],[131.07275581359863,-7.511388778686523]]],[[[121.77858924865723,-7.424444198608398],[121.76193428039551,-7.359165191650391],[121.83055305480957,-7.342777252197266],[121.77858924865723,-7.424444198608398]]],[[[121.10832405090332,-7.394443511962891],[121.09332466125488,-7.304721832275391],[121.16858863830566,-7.352222442626953],[121.10832405090332,-7.394443511962891]]],[[[131.27276802062988,-7.372776031494141],[131.216646194458,-7.359165191650391],[131.263032913208,-7.300554275512695],[131.27276802062988,-7.372776031494141]]],[[[120.93137550354004,-7.283611297607422],[121.06360054016113,-7.304721832275391],[120.78970527648926,-7.277500152587891],[120.93137550354004,-7.283611297607422]]],[[[131.73608589172363,-7.214166641235352],[131.10968208312988,-8.000833511352539],[131.24328804016113,-7.479999542236328],[131.73608589172363,-7.214166641235352]]],[[[131.92718696594238,-7.106943130493164],[131.968843460083,-7.254444122314453],[131.72857856750488,-7.158611297607422],[131.92718696594238,-7.106943130493164]]],[[[114.4024829864502,-7.181110382080078],[114.29332160949707,-7.082500457763672],[114.37024879455566,-7.066110610961914],[114.4024829864502,-7.181110382080078]]],[[[128.639986038208,-7.219165802001953],[128.5260944366455,-7.143611907958984],[128.61523628234863,-7.064722061157227],[128.639986038208,-7.219165802001953]]],[[[120.74165534973145,-7.075555801391602],[120.66914558410645,-7.145553588867188],[120.63054084777832,-7.016387939453125],[120.74165534973145,-7.075555801391602]]],[[[113.99136543273926,-6.880277633666992],[113.50388526916504,-7.225276947021484],[112.6877613067627,-7.051111221313477],[113.99136543273926,-6.880277633666992]]],[[[115.2933292388916,-6.83879280090332],[115.57083320617676,-6.925832748413086],[115.29109382629395,-7.008333206176758],[115.2933292388916,-6.83879280090332]]],[[[138.690523147583,-6.761388778686523],[138.78665351867676,-6.84083366394043],[138.61108589172363,-6.736110687255859],[138.690523147583,-6.761388778686523]]],[[[131.59219551086426,-6.678888320922852],[131.62634468078613,-6.707500457763672],[131.53579902648926,-6.801387786865234],[131.59219551086426,-6.678888320922852]]],[[[134.66885566711426,-6.774166107177734],[134.62634468078613,-6.715555191040039],[134.69775581359863,-6.586387634277344],[134.66885566711426,-6.774166107177734]]],[[[105.19304084777832,-6.684444427490234],[105.11303901672363,-6.611665725708008],[105.25360298156738,-6.5272216796875],[105.19304084777832,-6.684444427490234]]],[[[134.68387031555176,-6.56110954284668],[134.6833209991455,-6.451665878295898],[134.746919631958,-6.523056030273438],[134.68387031555176,-6.56110954284668]]],[[[134.58609199523926,-6.391666412353516],[134.5422077178955,-6.535833358764648],[134.34552192687988,-6.356943130493164],[134.58609199523926,-6.391666412353516]]],[[[134.83191108703613,-6.471944808959961],[134.78802680969238,-6.393054962158203],[134.858003616333,-6.289443969726563],[134.83191108703613,-6.471944808959961]]],[[[134.34411811828613,-6.804166793823242],[134.06720161437988,-6.826665878295898],[134.1027545928955,-6.173055648803711],[134.51471138000488,-6.584999084472656],[134.34411811828613,-6.804166793823242]]],[[[134.15637397766113,-6.04749870300293],[134.40359687805176,-6.286109924316406],[134.133882522583,-6.154722213745117],[134.15637397766113,-6.04749870300293]]],[[[134.73135566711426,-6.036666870117188],[134.60302925109863,-6.370553970336914],[134.2680377960205,-6.117221832275391],[134.73135566711426,-6.036666870117188]]],[[[106.16330909729004,-6.014165878295898],[108.31109809875488,-6.260278701782227],[108.73442268371582,-6.814998626708984],[110.39082527160645,-6.979721069335938],[110.91998481750488,-6.409999847412109],[111.15277290344238,-6.69999885559082],[112.56025886535645,-6.912221908569336],[112.84554481506348,-7.599721908569336],[114.44832038879395,-7.800554275512695],[114.37164497375488,-8.521112442016602],[114.62109565734863,-8.746665954589844],[113.23275947570801,-8.281112670898438],[111.65109443664551,-8.362499237060547],[109.28970527648926,-7.699443817138672],[108.16304206848145,-7.783054351806641],[106.42331123352051,-7.371387481689453],[106.50943183898926,-6.979166030883789],[105.24331855773926,-6.810277938842773],[106.16330909729004,-6.014165878295898]]],[[[124.05832099914551,-6.0272216796875],[123.96582221984863,-5.948055267333984],[123.97664833068848,-5.875831604003906],[124.05832099914551,-6.0272216796875]]],[[[120.48193550109863,-6.483610153198242],[120.47998237609863,-5.766666412353516],[120.56137275695801,-6.024444580078125],[120.48193550109863,-6.483610153198242]]],[[[104.83611488342285,-5.828056335449219],[104.76888465881348,-5.747777938842773],[104.84832954406738,-5.774999618530273],[104.83611488342285,-5.828056335449219]]],[[[112.69275093078613,-5.852775573730469],[112.58777046203613,-5.843889236450195],[112.63498878479004,-5.739442825317383],[112.69275093078613,-5.852775573730469]]],[[[132.74133491516113,-5.950277328491211],[132.69330024719238,-5.59638786315918],[132.8083209991455,-5.806943893432617],[132.74133491516113,-5.950277328491211]]],[[[132.79553413391113,-5.68638801574707],[132.73855781555176,-5.639165878295898],[132.781099319458,-5.532777786254883],[132.79553413391113,-5.68638801574707]]],[[[132.34051704406738,-5.57722282409668],[132.30191230773926,-5.517221450805664],[132.37661933898926,-5.538331985473633],[132.34051704406738,-5.57722282409668]]],[[[123.8108081817627,-5.599166870117188],[123.68831062316895,-5.472221374511719],[123.80275917053223,-5.533611297607422],[123.8108081817627,-5.599166870117188]]],[[[134.57718086242676,-5.430000305175781],[134.73135566711426,-5.974721908569336],[134.30218696594238,-6.025833129882813],[134.20633125305176,-5.708053588867188],[134.57718086242676,-5.430000305175781]]],[[[102.38498878479004,-5.485832214355469],[102.10054206848145,-5.332500457763672],[102.38081550598145,-5.372499465942383],[102.38498878479004,-5.485832214355469]]],[[[132.84939765930176,-6.003334045410156],[133.16885566711426,-5.295555114746094],[133.111909866333,-5.591667175292969],[132.84939765930176,-6.003334045410156]]],[[[123.62581062316895,-5.376665115356445],[123.52110481262207,-5.251943588256836],[123.62719917297363,-5.282499313354492],[123.62581062316895,-5.376665115356445]]],[[[122.01693916320801,-5.474166870117188],[121.80859565734863,-5.272222518920898],[121.91330909729004,-5.058610916137695],[122.01693916320801,-5.474166870117188]]],[[[115.78249549865723,-4.831943511962891],[115.8530445098877,-4.747220993041992],[115.85247993469238,-4.785554885864258],[115.78249549865723,-4.831943511962891]]],[[[131.74218940734863,-4.768610000610352],[131.72162055969238,-4.691944122314453],[131.75442695617676,-4.723333358764648],[131.74218940734863,-4.768610000610352]]],[[[122.73776435852051,-4.651111602783203],[122.60555458068848,-5.420276641845703],[122.28499031066895,-5.385000228881836],[122.37109565734863,-4.759721755981445],[122.73776435852051,-4.651111602783203]]],[[[129.934419631958,-4.566387176513672],[129.85913276672363,-4.556665420532227],[129.938570022583,-4.507499694824219],[129.934419631958,-4.566387176513672]]],[[[129.87466621398926,-4.530832290649414],[129.86108589172363,-4.521389007568359],[129.87967109680176,-4.505556106567383],[129.87466621398926,-4.530832290649414]]],[[[123.21277046203613,-4.697498321533203],[122.97971534729004,-5.107221603393555],[123.21555519104004,-5.29749870300293],[122.6513843536377,-5.68638801574707],[122.90358924865723,-4.48499870300293],[123.21277046203613,-4.697498321533203]]],[[[131.670259475708,-4.536943435668945],[131.61050605773926,-4.428333282470703],[131.672212600708,-4.487220764160156],[131.670259475708,-4.536943435668945]]],[[[133.57525825500488,-4.251943588256836],[133.61551094055176,-4.300554275512695],[133.31414985656738,-4.10444450378418],[133.57525825500488,-4.251943588256836]]],[[[131.3427448272705,-4.117498397827148],[131.3044147491455,-4.124164581298828],[131.27276802062988,-4.073610305786133],[131.3427448272705,-4.117498397827148]]],[[[123.08859443664551,-4.008888244628906],[123.15387153625488,-4.241666793823242],[122.95776557922363,-4.100276947021484],[123.08859443664551,-4.008888244628906]]],[[[101.0344181060791,-4.025833129882813],[101.0274829864502,-4.005277633666992],[101.0486011505127,-3.994998931884766],[101.0344181060791,-4.025833129882813]]],[[[131.24469184875488,-4.045555114746094],[131.2096881866455,-3.983331680297852],[131.24469184875488,-4.001943588256836],[131.24469184875488,-4.045555114746094]]],[[[131.43579292297363,-4.076389312744141],[131.37884712219238,-3.960832595825195],[131.41943550109863,-3.960277557373047],[131.43579292297363,-4.076389312744141]]],[[[134.15970039367676,-3.934999465942383],[134.19940376281738,-3.991109848022461],[134.07275581359863,-3.934165954589844],[134.15970039367676,-3.934999465942383]]],[[[127.22831916809082,-3.904167175292969],[127.14888191223145,-3.830278396606445],[127.23387336730957,-3.827499389648438],[127.22831916809082,-3.904167175292969]]],[[[128.779146194458,-3.703887939453125],[128.74829292297363,-3.643054962158203],[128.79080390930176,-3.638889312744141],[128.779146194458,-3.703887939453125]]],[[[123.12552833557129,-3.626667022705078],[123.05774879455566,-3.578056335449219],[123.14777565002441,-3.543054580688477],[123.12552833557129,-3.626667022705078]]],[[[128.40277290344238,-3.640832901000977],[128.43109321594238,-3.522499084472656],[128.56329536437988,-3.576665878295898],[128.40277290344238,-3.640832901000977]]],[[[122.35193061828613,-3.560832977294922],[122.27998542785645,-3.572500228881836],[122.32053565979004,-3.514919281005859],[122.35193061828613,-3.560832977294922]]],[[[128.33496284484863,-3.625831604003906],[127.91832160949707,-3.740833282470703],[128.27331733703613,-3.512222290039063],[128.33496284484863,-3.625831604003906]]],[[[128.66470527648926,-3.538331985473633],[128.720796585083,-3.619165420532227],[128.55496406555176,-3.509721755981445],[128.66470527648926,-3.538331985473633]]],[[[132.7035846710205,-3.5191650390625],[132.62329292297363,-3.421388626098633],[132.67413520812988,-3.418609619140625],[132.7035846710205,-3.5191650390625]]],[[[122.44525337219238,-3.490554809570313],[122.41304206848145,-3.384445190429688],[122.4719181060791,-3.456943511962891],[122.44525337219238,-3.490554809570313]]],[[[116.38275337219238,-3.645553588867188],[116.31694221496582,-3.537500381469727],[116.41693305969238,-3.377498626708984],[116.38275337219238,-3.645553588867188]]],[[[127.63275337219238,-3.365278244018555],[127.48108863830566,-3.293333053588867],[127.5697193145752,-3.263889312744141],[127.63275337219238,-3.365278244018555]]],[[[116.11831855773926,-4.036109924316406],[116.00861549377441,-3.649166107177734],[116.26776313781738,-3.223054885864258],[116.11831855773926,-4.036109924316406]]],[[[127.77026557922363,-3.254444122314453],[127.63611030578613,-3.225831985473633],[127.75943183898926,-3.153055191040039],[127.77026557922363,-3.254444122314453]]],[[[100.5244312286377,-3.186166763305664],[100.49080848693848,-3.162776947021484],[100.50055122375488,-3.127222061157227],[100.5244312286377,-3.186166763305664]]],[[[126.99387550354004,-3.145000457763672],[127.23665046691895,-3.617500305175781],[126.7008228302002,-3.834444046020508],[126.01748847961426,-3.35444450378418],[126.1030445098877,-3.100555419921875],[126.99387550354004,-3.145000457763672]]],[[[127.88472175598145,-3.038331985473633],[127.82054328918457,-3.021665573120117],[127.99165534973145,-2.930000305175781],[127.88472175598145,-3.038331985473633]]],[[[106.88916206359863,-3.024444580078125],[106.72136878967285,-2.966388702392578],[106.81247901916504,-2.893054962158203],[106.88916206359863,-3.024444580078125]]],[[[129.8124713897705,-2.919721603393555],[130.58413887023926,-3.133333206176758],[130.82995796203613,-3.872776031494141],[129.89749336242676,-3.335832595825195],[128.87829780578613,-3.20777702331543],[128.46246528625488,-3.458332061767578],[128.17386054992676,-3.068887710571289],[127.90609931945801,-3.537500381469727],[128.17386054992676,-2.855554580688477],[129.8124713897705,-2.919721603393555]]],[[[107.42720222473145,-2.938888549804688],[107.36136817932129,-2.871110916137695],[107.48137092590332,-2.823333740234375],[107.42720222473145,-2.938888549804688]]],[[[107.07971382141113,-2.911664962768555],[107.03720283508301,-2.864999771118164],[107.0727710723877,-2.819999694824219],[107.07971382141113,-2.911664962768555]]],[[[100.46277046203613,-3.133333206176758],[100.45942878723145,-3.333889007568359],[100.17637825012207,-2.799999237060547],[100.46277046203613,-3.133333206176758]]],[[[131.579683303833,-2.656389236450195],[131.56524848937988,-2.651666641235352],[131.65442085266113,-2.621389389038086],[131.579683303833,-2.656389236450195]]],[[[107.83276557922363,-2.534999847412109],[108.26582527160645,-2.755556106567383],[108.07332038879395,-3.23527717590332],[107.60942268371582,-3.211387634277344],[107.83276557922363,-2.534999847412109]]],[[[100.03109931945801,-2.841943740844727],[99.9871997833252,-2.489166259765625],[100.21415901184082,-2.718610763549805],[100.03109931945801,-2.841943740844727]]],[[[133.59497261047363,-2.525554656982422],[133.499116897583,-2.425556182861328],[133.61441230773926,-2.477499008178711],[133.59497261047363,-2.525554656982422]]],[[[99.74109077453613,-2.376388549804688],[99.70359992980957,-2.342777252197266],[99.7371997833252,-2.350276947021484],[99.74109077453613,-2.376388549804688]]],[[[134.567476272583,-2.453054428100586],[134.51666450500488,-2.396944046020508],[134.56884956359863,-2.292778015136719],[134.567476272583,-2.453054428100586]]],[[[123.16693305969238,-2.19416618347168],[123.15165901184082,-2.19416618347168],[123.16805458068848,-2.176387786865234],[123.16693305969238,-2.19416618347168]]],[[[123.44978523254395,-2.125568389892578],[123.43802833557129,-2.11138916015625],[123.45610237121582,-2.115554809570313],[123.44978523254395,-2.125568389892578]]],[[[99.85971260070801,-2.370832443237305],[99.56999397277832,-2.222221374511719],[99.56860542297363,-2.029167175292969],[99.85971260070801,-2.370832443237305]]],[[[123.88553810119629,-2.075555801391602],[123.84443855285645,-2.053888320922852],[123.86499214172363,-2.008609771728516],[123.88553810119629,-2.075555801391602]]],[[[134.36883735656738,-2.158054351806641],[134.325532913208,-2.08860969543457],[134.38580513000488,-2.003889083862305],[134.36883735656738,-2.158054351806641]]],[[[123.76776313781738,-2.04749870300293],[123.75833320617676,-2.02027702331543],[123.7774829864502,-1.998332977294922],[123.76776313781738,-2.04749870300293]]],[[[126.05664253234863,-2.482500076293945],[125.89470863342285,-2.213333129882813],[125.91805458068848,-1.972221374511719],[126.05664253234863,-2.482500076293945]]],[[[124.36665534973145,-2.011388778686523],[124.30081367492676,-1.976943969726563],[124.35721015930176,-1.966110229492188],[124.36665534973145,-2.011388778686523]]],[[[123.4780445098877,-1.946109771728516],[123.46692848205566,-1.943611145019531],[123.48471260070801,-1.935277938842773],[123.4780445098877,-1.946109771728516]]],[[[123.54498481750488,-1.927778244018555],[123.5355396270752,-1.924999237060547],[123.54305458068848,-1.913331985473633],[123.54498481750488,-1.927778244018555]]],[[[123.6594181060791,-1.963333129882813],[123.6513843536377,-1.953887939453125],[123.65416145324707,-1.901666641235352],[123.6594181060791,-1.963333129882813]]],[[[123.71692848205566,-1.955833435058594],[123.70054817199707,-1.936666488647461],[123.73221015930176,-1.899721145629883],[123.71692848205566,-1.955833435058594]]],[[[123.69109535217285,-1.914167404174805],[123.67249488830566,-1.899721145629883],[123.67249488830566,-1.884721755981445],[123.69109535217285,-1.914167404174805]]],[[[123.8288745880127,-2.010555267333984],[123.78276252746582,-1.878610610961914],[123.85550880432129,-1.954446792602539],[123.8288745880127,-2.010555267333984]]],[[[123.76500129699707,-1.877222061157227],[123.75749397277832,-1.873611450195313],[123.76721382141113,-1.862777709960938],[123.76500129699707,-1.877222061157227]]],[[[123.38690376281738,-1.883857727050781],[123.36693000793457,-1.875831604003906],[123.36831855773926,-1.856388092041016],[123.38690376281738,-1.883857727050781]]],[[[125.43831062316895,-1.806667327880859],[126.34915351867676,-1.823055267333984],[125.46666145324707,-1.939998626708984],[125.43831062316895,-1.806667327880859]]],[[[99.28610420227051,-1.826389312744141],[99.25193977355957,-1.820833206176758],[99.26915168762207,-1.789999008178711],[99.28610420227051,-1.826389312744141]]],[[[123.07916450500488,-1.906389236450195],[123.12082099914551,-1.754444122314453],[123.15416145324707,-1.832500457763672],[123.07916450500488,-1.906389236450195]]],[[[134.17608833312988,-1.944999694824219],[134.16052436828613,-1.845556259155273],[134.2338581085205,-1.740833282470703],[134.17608833312988,-1.944999694824219]]],[[[125.00665473937988,-1.718889236450195],[125.32332038879395,-1.887222290039063],[124.32747840881348,-1.879720687866211],[125.00665473937988,-1.718889236450195]]],[[[108.69693183898926,-1.723054885864258],[108.68193244934082,-1.699722290039063],[108.77971076965332,-1.704442977905273],[108.69693183898926,-1.723054885864258]]],[[[130.188570022583,-2.064167022705078],[129.7157917022705,-1.885831832885742],[130.3505573272705,-1.680204391479492],[130.188570022583,-2.064167022705078]]],[[[123.29776191711426,-1.791389465332031],[123.26748847961426,-1.766944885253906],[123.36971473693848,-1.673053741455078],[123.29776191711426,-1.791389465332031]]],[[[136.29358100891113,-1.688610076904297],[136.902193069458,-1.799165725708008],[135.41803169250488,-1.60999870300293],[136.29358100891113,-1.688610076904297]]],[[[108.84915351867676,-1.670831680297852],[108.79971504211426,-1.568056106567383],[108.93054389953613,-1.544166564941406],[108.84915351867676,-1.670831680297852]]],[[[106.09082221984863,-1.771665573120117],[106.31833076477051,-2.435832977294922],[106.78166389465332,-2.591943740844727],[106.60193061828613,-2.913055419921875],[106.71776008605957,-3.098333358764648],[105.97831916809082,-2.822776794433594],[105.74471473693848,-2.129165649414063],[105.13220405578613,-2.067499160766602],[105.57361030578613,-1.529167175292969],[106.09082221984863,-1.771665573120117]]],[[[135.13830757141113,-1.48527717590332],[135.33081245422363,-1.492776870727539],[135.09442329406738,-1.512777328491211],[135.13830757141113,-1.48527717590332]]],[[[127.87943458557129,-1.426942825317383],[128.14526557922363,-1.68055534362793],[127.3783130645752,-1.633888244628906],[127.87943458557129,-1.426942825317383]]],[[[127.32832527160645,-1.439998626708984],[127.27277565002441,-1.413331985473633],[127.36665534973145,-1.366109848022461],[127.32832527160645,-1.439998626708984]]],[[[109.14499092102051,-1.316665649414063],[109.10471534729004,-1.289999008178711],[109.1718921661377,-1.257776260375977],[109.14499092102051,-1.316665649414063]]],[[[123.19497871398926,-1.29749870300293],[123.53137397766113,-1.434720993041992],[122.8611011505127,-1.581110000610352],[122.89749336242676,-1.186666488647461],[123.19497871398926,-1.29749870300293]]],[[[127.61470222473145,-1.257778167724609],[127.45583534240723,-1.234443664550781],[127.55053901672363,-1.171667098999023],[127.61470222473145,-1.257778167724609]]],[[[109.22859382629395,-1.233331680297852],[109.21971321105957,-1.192777633666992],[109.25804328918457,-1.169443130493164],[109.22859382629395,-1.233331680297852]]],[[[129.92886543273926,-1.211387634277344],[129.74051094055176,-1.208610534667969],[129.86664009094238,-1.142778396606445],[129.92886543273926,-1.211387634277344]]],[[[109.62378883361816,-0.984834671020508],[109.77887153625488,-1.13861083984375],[109.41858863830566,-1.263334274291992],[109.49247932434082,-0.979721069335938],[109.62378883361816,-0.984834671020508]]],[[[98.92915534973145,-0.950277328491211],[99.23887825012207,-1.78388786315918],[98.6030445098877,-1.223054885864258],[98.92915534973145,-0.950277328491211]]],[[[134.92248725891113,-1.138055801391602],[134.84301948547363,-0.941944122314453],[134.993013381958,-1.023611068725586],[134.92248725891113,-1.138055801391602]]],[[[130.9313678741455,-0.93638801574707],[130.96441841125488,-1.357221603393555],[130.6388874053955,-0.983888626098633],[130.9313678741455,-0.93638801574707]]],[[[130.91638374328613,-0.794721603393555],[130.3969440460205,-0.926387786865234],[130.48663520812988,-0.835277557373047],[130.91638374328613,-0.794721603393555]]],[[[135.48773384094238,-0.675556182861328],[136.38611030578613,-1.120832443237305],[135.89221382141113,-1.191389083862305],[135.48773384094238,-0.675556182861328]]],[[[127.28109931945801,-0.808332443237305],[127.15358924865723,-0.770000457763672],[127.20443916320801,-0.619167327880859],[127.28109931945801,-0.808332443237305]]],[[[98.5152759552002,-0.632221221923828],[98.4891529083252,-0.599443435668945],[98.50972175598145,-0.600831985473633],[98.5152759552002,-0.632221221923828]]],[[[130.60608100891113,-0.541110992431641],[130.45581245422363,-0.468610763549805],[130.660249710083,-0.426666259765625],[130.60608100891113,-0.541110992431641]]],[[[121.91330909729004,-0.475276947021484],[121.64333534240723,-0.548055648803711],[121.74136543273926,-0.418609619140625],[121.91330909729004,-0.475276947021484]]],[[[104.22831916809082,-0.417221069335938],[104.19748115539551,-0.395832061767578],[104.23166084289551,-0.391666412353516],[104.22831916809082,-0.417221069335938]]],[[[133.111909866333,-0.536388397216797],[134.11108589172363,-0.835277557373047],[134.15970039367676,-2.31944465637207],[134.466646194458,-2.864444732666016],[134.63611030578613,-2.513889312744141],[135.00415229797363,-3.341388702392578],[135.4919147491455,-3.358333587646484],[136.35663032531738,-2.253889083862305],[137.190523147583,-2.103054046630859],[137.1310749053955,-1.792778015136719],[137.85663032531738,-1.47166633605957],[141.00247383117676,-2.607084274291992],[141.00702095031738,-9.128467559814453],[139.98523139953613,-8.193611145019531],[140.146089553833,-7.884721755981445],[138.90860176086426,-8.296667098999023],[139.09552192687988,-7.564165115356445],[138.6611042022705,-7.203332901000977],[139.22247505187988,-7.162500381469727],[138.56192207336426,-6.90888786315918],[139.1894245147705,-6.969444274902344],[138.68191719055176,-6.720554351806641],[138.0644245147705,-5.406110763549805],[134.64358711242676,-4.121387481689453],[134.96551704406738,-3.939722061157227],[134.2157917022705,-3.963054656982422],[133.63748359680176,-3.491666793823242],[133.82885932922363,-2.961666107177734],[133.44970893859863,-3.871389389038086],[132.90164375305176,-4.091388702392578],[132.81802558898926,-3.303054809570313],[131.95581245422363,-2.783611297607422],[132.722749710083,-2.817222595214844],[133.238862991333,-2.416110992431641],[133.68414497375488,-2.716388702392578],[133.936372756958,-2.103054046630859],[132.301362991333,-2.269443511962891],[131.88244819641113,-1.642221450805664],[130.9635944366455,-1.403055191040039],[131.25555610656738,-0.822776794433594],[132.26971626281738,-0.384166717529297],[133.111909866333,-0.536388397216797]],[[133.61969184875488,-3.449443817138672],[133.62329292297363,-3.429473876953125],[133.61023139953613,-3.435832977294922],[133.61969184875488,-3.449443817138672]]],[[[104.49609565734863,-0.626943588256836],[104.28804206848145,-0.393888473510742],[104.53109931945801,-0.37388801574707],[104.49609565734863,-0.626943588256836]]],[[[122.01138496398926,-0.414443969726563],[121.85443305969238,-0.365833282470703],[122.04443550109863,-0.33277702331543],[122.01138496398926,-0.414443969726563]]],[[[127.57499885559082,-0.323331832885742],[127.81775856018066,-0.870832443237305],[127.30359077453613,-0.519166946411133],[127.57499885559082,-0.323331832885742]]],[[[104.44413948059082,-0.32611083984375],[104.4024829864502,-0.285554885864258],[104.48803901672363,-0.278055191040039],[104.44413948059082,-0.32611083984375]]],[[[122.08333015441895,-0.4102783203125],[122.0869312286377,-0.265556335449219],[122.14026832580566,-0.382221221923828],[122.08333015441895,-0.4102783203125]]],[[[127.18303871154785,-0.528888702392578],[127.10498237609863,-0.297222137451172],[127.23387336730957,-0.256111145019531],[127.18303871154785,-0.528888702392578]]],[[[98.50166511535645,-0.539722442626953],[98.32609748840332,-0.539722442626953],[98.43026924133301,-0.246389389038086],[98.50166511535645,-0.539722442626953]]],[[[103.61914253234863,-0.389720916748047],[103.45471382141113,-0.362220764160156],[103.53333473205566,-0.234167098999023],[103.75972175598145,-0.312221527099609],[103.61914253234863,-0.389720916748047]]],[[[122.36360359191895,-0.28416633605957],[122.22387886047363,-0.200555801391602],[122.32805061340332,-0.230833053588867],[122.36360359191895,-0.28416633605957]]],[[[122.22580909729004,-0.278055191040039],[122.14026832580566,-0.229442596435547],[122.18887519836426,-0.197221755981445],[122.22580909729004,-0.278055191040039]]],[[[103.55330848693848,-0.196388244628906],[103.50139045715332,-0.194999694824219],[103.53465461730957,-0.184232711791992],[103.55330848693848,-0.196388244628906]]],[[[104.7402515411377,-0.136943817138672],[104.92943000793457,-0.334165573120117],[104.43248176574707,-0.201944351196289],[104.7402515411377,-0.136943817138672]]],[[[121.61387825012207,-0.206666946411133],[121.56247901916504,-0.156665802001953],[121.63192939758301,-0.123056411743164],[121.61387825012207,-0.206666946411133]]],[[[97.87664985656738,-0.105278015136719],[97.82388496398926,-0.067777633666992],[97.86693000793457,-0.064167022705078],[97.87664985656738,-0.105278015136719]]],[[[104.87663459777832,-0.065555572509766],[104.83191871643066,-0.060832977294922],[104.84219551086426,-0.024442672729492],[104.87663459777832,-0.065555572509766]]],[[[130.87744331359863,-0.019166946411133],[131.25555610656738,-0.387777328491211],[130.68829536437988,-0.079442977905273],[130.91580390930176,-0.40888786315918],[130.21328926086426,-0.206666946411133],[130.87744331359863,-0.019166946411133]],[[130.66971015930176,-0.328887939453125],[130.66638374328613,-0.315832138061523],[130.662202835083,-0.325277328491211],[130.66971015930176,-0.328887939453125]]],[[[98.54748725891113,-0.370555877685547],[98.29193305969238,-0.012222290039063],[98.44413948059082,-0.06138801574707],[98.54748725891113,-0.370555877685547]]],[[[129.55468940734863,-0.21360969543457],[129.2883014678955,0.041391372680664],[129.54052925109863,-0.138889312744141],[129.55468940734863,-0.21360969543457]]],[[[127.45720863342285,-0.012222290039063],[127.39276313781738,0.00694465637207],[127.4105396270752,0.144166946411133],[127.45720863342285,-0.012222290039063]]],[[[98.83474922180176,0.107778549194336],[98.51335334777832,0.133058547973633],[98.76280403137207,0.171667098999023],[98.83474922180176,0.107778549194336]]],[[[104.48193550109863,0.023611068725586],[104.40721321105957,0.090002059936523],[104.40915107727051,0.171667098999023],[104.48193550109863,0.023611068725586]]],[[[104.70192909240723,0.023611068725586],[104.4913501739502,0.237222671508789],[104.54496955871582,0.22166633605957],[104.70192909240723,0.023611068725586]]],[[[104.41191291809082,0.29222297668457],[104.34276008605957,0.370832443237305],[104.42637825012207,0.323610305786133],[104.41191291809082,0.29222297668457]]],[[[127.3852710723877,0.270833969116211],[127.32776832580566,0.336668014526367],[127.38860511779785,0.378610610961914],[127.3852710723877,0.270833969116211]]],[[[103.07359504699707,0.57166862487793],[103.03801918029785,0.654722213745117],[103.06607246398926,0.646390914916992],[103.07359504699707,0.57166862487793]]],[[[104.28164863586426,0.623056411743164],[104.2371997833252,0.689443588256836],[104.28164863586426,0.665555953979492],[104.28164863586426,0.623056411743164]]],[[[103.48359870910645,0.616945266723633],[103.46555519104004,0.630556106567383],[103.51360511779785,0.699167251586914],[103.48359870910645,0.616945266723633]]],[[[103.18524360656738,0.508054733276367],[103.22302436828613,0.703332901000977],[103.29692268371582,0.553888320922852],[103.18524360656738,0.508054733276367]]],[[[127.40387153625488,0.619722366333008],[127.38388252258301,0.751943588256836],[127.44637489318848,0.712778091430664],[127.40387153625488,0.619722366333008]]],[[[104.29414558410645,0.706666946411133],[104.18997383117676,0.775278091430664],[104.27361488342285,0.791669845581055],[104.29414558410645,0.706666946411133]]],[[[104.59831428527832,0.758054733276367],[104.50859260559082,0.756113052368164],[104.55164527893066,0.795000076293945],[104.59831428527832,0.758054733276367]]],[[[103.0941333770752,0.72389030456543],[103.07718849182129,0.750555038452148],[103.1052417755127,0.79777717590332],[103.0941333770752,0.72389030456543]]],[[[103.7158145904541,0.792501449584961],[103.70414924621582,0.759443283081055],[103.66219520568848,0.832223892211914],[103.7158145904541,0.792501449584961]]],[[[127.32222175598145,0.750001907348633],[127.32415962219238,0.864168167114258],[127.37497901916504,0.812223434448242],[127.32222175598145,0.750001907348633]]],[[[103.52580451965332,0.80000114440918],[103.41913032531738,0.871110916137695],[103.48969459533691,0.845834732055664],[103.52580451965332,0.80000114440918]]],[[[103.93636512756348,0.766389846801758],[103.81997871398926,0.886110305786133],[103.88913917541504,0.859445571899414],[103.93636512756348,0.766389846801758]]],[[[103.83220100402832,0.756113052368164],[103.73413276672363,0.886945724487305],[103.81997871398926,0.825834274291992],[103.83220100402832,0.756113052368164]]],[[[103.43692207336426,0.647222518920898],[103.37996101379395,0.891668319702148],[103.50747871398926,0.746389389038086],[103.43692207336426,0.647222518920898]]],[[[103.47857856750488,0.86833381652832],[103.40524482727051,0.908891677856445],[103.46135902404785,0.915834426879883],[103.47857856750488,0.86833381652832]]],[[[104.24273872375488,0.819723129272461],[104.17553901672363,0.790834426879883],[104.09471321105957,0.947221755981445],[104.24273872375488,0.819723129272461]]],[[[102.62423133850098,0.994138717651367],[103.04135322570801,0.714166641235352],[102.40608406066895,0.878057479858398],[102.62423133850098,0.994138717651367]]],[[[103.93496894836426,0.926111221313477],[103.8369083404541,1.010278701782227],[103.93857002258301,0.999166488647461],[103.93496894836426,0.926111221313477]]],[[[104.84305000305176,0.957502365112305],[104.79358863830566,1.024721145629883],[104.83943367004395,1.018613815307617],[104.84305000305176,0.957502365112305]]],[[[107.55664253234863,0.96583366394043],[107.55053901672363,1.037778854370117],[107.59636878967285,1.008054733276367],[107.55664253234863,0.96583366394043]]],[[[103.03719520568848,1.037778854370117],[103.14692878723145,0.837499618530273],[102.65775489807129,1.054166793823242],[103.03719520568848,1.037778854370117]]],[[[120.67720222473145,1.035554885864258],[120.61638069152832,1.071943283081055],[120.63889503479004,1.076112747192383],[120.67720222473145,1.035554885864258]]],[[[120.38804817199707,1.020002365112305],[120.36609077453613,1.032224655151367],[120.38611030578613,1.080835342407227],[120.38804817199707,1.020002365112305]]],[[[104.66689491271973,1.023828506469727],[104.58331489562988,0.81916618347168],[104.23026466369629,1.084169387817383],[104.66689491271973,1.023828506469727]]],[[[103.43968391418457,0.98750114440918],[103.31970405578613,1.040277481079102],[103.34163856506348,1.119722366333008],[103.43968391418457,0.98750114440918]]],[[[104.03360176086426,0.982221603393555],[103.90136909484863,1.093889236450195],[104.11942481994629,1.183610916137695],[104.03360176086426,0.982221603393555]]],[[[102.39525032043457,0.923891067504883],[102.2130298614502,1.405000686645508],[102.4760684967041,1.226667404174805],[102.39525032043457,0.923891067504883]]],[[[97.52636909484863,1.41722297668457],[97.93635749816895,0.978055953979492],[97.81079292297363,0.549722671508789],[97.11468696594238,1.393335342407227],[97.52636909484863,1.41722297668457]]],[[[125.21499824523926,1.389165878295898],[125.16638374328613,1.395280838012695],[125.2994556427002,1.526079177856445],[125.21499824523926,1.389165878295898]]],[[[102.49608039855957,1.444723129272461],[102.49191474914551,1.259721755981445],[101.99442481994629,1.611112594604492],[102.49608039855957,1.444723129272461]]],[[[98.5997486114502,1.625555038452148],[98.42746162414551,1.678888320922852],[98.55505561828613,1.681665420532227],[98.5997486114502,1.625555038452148]]],[[[125.14166450500488,1.421388626098633],[124.24609565734863,0.375001907348633],[120.2422046661377,0.344999313354492],[120.06609535217285,-0.613054275512695],[120.66638374328613,-1.395553588867188],[121.08305549621582,-1.423610687255859],[121.6222095489502,-0.805000305175781],[121.92775917053223,-0.963333129882813],[123.07083320617676,-0.559720993041992],[123.4477481842041,-0.835277557373047],[123.33138465881348,-1.057222366333008],[122.81999397277832,-0.913331985473633],[121.67165565490723,-1.922222137451172],[121.29802894592285,-1.803054809570313],[122.47747993469238,-3.158054351806641],[122.19497871398926,-3.571109771728516],[122.89554023742676,-4.396389007568359],[122.10471534729004,-4.526111602783203],[122.0888843536377,-4.84083366394043],[121.55304145812988,-4.746665954589844],[121.61470222473145,-4.064722061157227],[120.8813648223877,-3.536945343017578],[121.07610511779785,-2.758888244628906],[120.77192878723145,-2.612499237060547],[120.20027351379395,-2.965000152587891],[120.46277046203613,-5.624164581298828],[119.46499824523926,-5.563610076904297],[119.50610542297363,-3.5272216796875],[118.92221260070801,-3.569721221923828],[118.75916481018066,-2.774166107177734],[119.35331916809082,-1.938888549804688],[119.51721382141113,-0.876388549804688],[119.71859931945801,-0.653610229492188],[119.86303901672363,-0.843889236450195],[119.62275886535645,-0.005277633666992],[119.83305549621582,-0.0897216796875],[120.03249549865723,0.712778091430664],[120.28720283508301,0.989721298217773],[120.57303810119629,0.775278091430664],[120.95054817199707,1.342500686645508],[123.83915901184082,0.829446792602539],[124.97110176086426,1.694723129272461],[125.14166450500488,1.421388626098633]]],[[[97.11718940734863,2.011110305786133],[97.09274482727051,2.11250114440918],[97.14831733703613,2.065832138061523],[97.11718940734863,2.011110305786133]]],[[[101.60164070129395,1.709165573120117],[101.39803504943848,1.989168167114258],[101.6455249786377,2.120000839233398],[101.60164070129395,1.709165573120117]]],[[[96.64108467102051,2.065832138061523],[96.61079597473145,2.121946334838867],[96.66913032531738,2.108888626098633],[96.64108467102051,2.065832138061523]]],[[[96.64053535461426,2.152776718139648],[96.59802436828613,2.191110610961914],[96.64859199523926,2.178888320922852],[96.64053535461426,2.152776718139648]]],[[[127.89499092102051,1.796667098999023],[127.79358863830566,0.795000076293945],[128.18829536437988,1.378057479858398],[128.72635078430176,1.556943893432617],[128.6974811553955,1.101945877075195],[128.21023750305176,0.784723281860352],[128.9052448272705,0.200277328491211],[127.87664985656738,0.310556411743164],[128.39526557922363,-0.894721984863281],[127.66609382629395,-0.225831985473633],[127.39499092102051,1.054723739624023],[128.05468940734863,2.195276260375977],[127.89499092102051,1.796667098999023]]],[[[97.32776069641113,2.032224655151367],[97.10357856750488,2.219999313354492],[97.28802680969238,2.22416877746582],[97.32776069641113,2.032224655151367]]],[[[127.79498481750488,2.205556869506836],[127.75665473937988,2.27055549621582],[127.81360054016113,2.261667251586914],[127.79498481750488,2.205556869506836]]],[[[118.57138252258301,2.316389083862305],[118.64972114562988,2.176668167114258],[118.56053352355957,2.264444351196289],[118.57138252258301,2.316389083862305]]],[[[125.43081855773926,2.313055038452148],[125.36775398254395,2.369165420532227],[125.4508228302002,2.379446029663086],[125.43081855773926,2.313055038452148]]],[[[128.1611042022705,2.282224655151367],[128.1191120147705,2.338335037231445],[128.16302680969238,2.404165267944336],[128.1611042022705,2.282224655151367]]],[[[109.06749153137207,2.485002517700195],[108.97318458557129,2.540163040161133],[109.10748481750488,2.530000686645508],[109.06749153137207,2.485002517700195]]],[[[128.4980182647705,2.05000114440918],[128.23217964172363,2.306112289428711],[128.56469917297363,2.632776260375977],[128.4980182647705,2.05000114440918]]],[[[125.40637397766113,2.626665115356445],[125.35471534729004,2.724443435668945],[125.41443061828613,2.807222366333008],[125.40637397766113,2.626665115356445]]],[[[106.24498176574707,2.736665725708008],[106.1977481842041,2.812223434448242],[106.24304389953613,2.78666877746582],[106.24498176574707,2.736665725708008]]],[[[96.43219184875488,2.343057632446289],[95.6969165802002,2.818891525268555],[95.8833179473877,2.918889999389648],[96.43219184875488,2.343057632446289]]],[[[108.83249092102051,2.844999313354492],[108.77361488342285,2.891389846801758],[108.88333320617676,3.001668930053711],[108.83249092102051,2.844999313354492]]],[[[107.75943183898926,2.97416877746582],[107.76555061340332,3.021665573120117],[107.81218910217285,3.00111198425293],[107.75943183898926,2.97416877746582]]],[[[105.7249927520752,2.833890914916992],[105.69832038879395,3.060556411743164],[105.84887886047363,2.979166030883789],[105.7249927520752,2.833890914916992]]],[[[106.28943061828613,3.159723281860352],[106.21277046203613,3.121389389038086],[106.20332527160645,3.226667404174805],[106.28943061828613,3.159723281860352]]],[[[117.52304267883301,3.285554885864258],[117.41137886047363,3.302778244018555],[117.4619312286377,3.343889236450195],[117.52304267883301,3.285554885864258]]],[[[106.28055000305176,3.230833053588867],[106.23471260070801,3.256113052368164],[106.2874927520752,3.373334884643555],[106.28055000305176,3.230833053588867]]],[[[117.66414833068848,3.28416633605957],[117.53943061828613,3.426668167114258],[117.67249488830566,3.419721603393555],[117.66414833068848,3.28416633605957]]],[[[117.60748481750488,3.47722053527832],[117.43332099914551,3.559167861938477],[117.58748817443848,3.524446487426758],[117.60748481750488,3.47722053527832]]],[[[117.39082527160645,3.561944961547852],[117.51748847961426,3.474443435668945],[117.21666145324707,3.545557022094727],[117.39082527160645,3.561944961547852]]],[[[117.88553810119629,3.456666946411133],[117.78970527648926,3.577779769897461],[117.86580848693848,3.548891067504883],[117.88553810119629,3.456666946411133]]],[[[125.88388252258301,3.362222671508789],[125.66359901428223,3.718332290649414],[125.91137886047363,3.491666793823242],[125.88388252258301,3.362222671508789]]],[[[117.82527351379395,3.740556716918945],[117.78830909729004,3.750001907348633],[117.81553840637207,3.755556106567383],[117.82527351379395,3.740556716918945]]],[[[126.84414863586426,3.738054275512695],[126.79221534729004,3.733335494995117],[126.73887825012207,3.842222213745117],[126.84414863586426,3.738054275512695]]],[[[117.84776496887207,3.797224044799805],[117.73082160949707,3.863611221313477],[117.80193519592285,3.855279922485352],[117.84776496887207,3.797224044799805]]],[[[126.71138191223145,3.798055648803711],[126.60803413391113,4.041109085083008],[126.72360420227051,3.91166877746582],[126.71138191223145,3.798055648803711]]],[[[117.68969917297363,3.97416877746582],[117.6463794708252,4.140279769897461],[117.75000190734863,4.068609237670898],[117.68969917297363,3.97416877746582]]],[[[117.88693428039551,4.026945114135742],[117.68692207336426,4.168336868286133],[117.72664833068848,4.169721603393555],[117.9035587310791,4.174043655395508],[117.88693428039551,4.026945114135742]]],[[[108.18166542053223,3.647500991821289],[108.18166542053223,4.196386337280273],[108.40693855285645,3.875833511352539],[108.18166542053223,3.647500991821289]]],[[[116.04942512512207,4.279443740844727],[117.5920581817627,4.169820785522461],[117.39276313781738,4.107500076293945],[117.82805061340332,3.70222282409668],[117.03027534484863,3.594167709350586],[117.44413948059082,3.43055534362793],[117.27304267883301,3.222776412963867],[118.09665107727051,2.30555534362793],[117.87191963195801,1.876668930053711],[119.00861549377441,0.980833053588867],[118.34387397766113,0.843057632446289],[117.89444160461426,1.119722366333008],[118.03499031066895,0.810277938842773],[117.46748542785645,0.103612899780273],[117.62248420715332,-0.779722213745117],[116.9236011505127,-1.254444122314453],[116.74331855773926,-1.024166107177734],[116.75554847717285,-1.367500305175781],[116.22249031066895,-1.779167175292969],[116.60415840148926,-2.229721069335938],[115.98387336730957,-3.588888168334961],[114.70665168762207,-4.176944732666016],[114.48108863830566,-3.498611450195313],[113.67109870910645,-3.476110458374023],[113.06469917297363,-2.993888854980469],[111.88942909240723,-3.573888778686523],[111.74971199035645,-2.741943359375],[111.55026435852051,-3.024444580078125],[110.23748970031738,-2.979442596435547],[109.90358924865723,-1.828332901000977],[110.05774879455566,-1.333889007568359],[109.72971534729004,-0.953611373901367],[109.27249336242676,-0.854999542236328],[109.51442909240723,-0.726943969726563],[109.12024879455566,-0.502222061157227],[108.84549140930176,0.810564041137695],[109.26500129699707,1.393335342407227],[108.98193550109863,1.211668014526367],[109.06694221496582,1.532224655151367],[109.64856910705566,2.073408126831055],[109.66998481750488,1.613054275512695],[110.55525398254395,0.853891372680664],[111.82721138000488,0.998613357543945],[112.47276496887207,1.568056106567383],[113.65833473205566,1.224721908569336],[114.5627613067627,1.433610916137695],[114.8047046661377,2.24888801574707],[115.2371997833252,2.522500991821289],[115.13971138000488,2.906110763549805],[115.49553108215332,3.040002822875977],[115.68525886535645,4.171945571899414],[116.04942512512207,4.279443740844727]],[[117.29553413391113,-0.878332138061523],[117.2885913848877,-0.831666946411133],[117.27221870422363,-0.876943588256836],[117.29553413391113,-0.878332138061523]]],[[[126.75972175598145,3.985834121704102],[126.74054145812988,4.54194450378418],[126.91609382629395,4.273611068725586],[126.75972175598145,3.985834121704102]]],[[[125.49136543273926,4.732778549194336],[125.47886848449707,4.734445571899414],[125.49193000793457,4.745553970336914],[125.49136543273926,4.732778549194336]]],[[[107.96443367004395,4.674722671508789],[107.93831062316895,4.701944351196289],[108.00470924377441,4.772222518920898],[107.96443367004395,4.674722671508789]]],[[[95.73857307434082,5.58527946472168],[96.34774971008301,5.222776412963867],[97.51886177062988,5.246667861938477],[98.2705249786377,4.142499923706055],[99.97775459289551,2.947500228881836],[100.00164985656738,2.601945877075195],[100.20913887023926,2.703332901000977],[100.94246101379395,1.820554733276367],[100.79720497131348,2.214445114135742],[101.05552864074707,2.28639030456543],[102.42191505432129,0.800554275512695],[102.93245887756348,0.695001602172852],[103.08191871643066,0.445554733276367],[102.53996467590332,0.166669845581055],[103.3510913848877,0.536111831665039],[103.73969459533691,0.281110763549805],[103.81419563293457,-0.001028060913086],[103.26970863342285,-0.258888244628906],[103.49080848693848,-0.216943740844727],[103.34236335754395,-0.364095687866211],[103.5999927520752,-0.441110610961914],[103.36081123352051,-0.702220916748047],[104.37915229797363,-1.041389465332031],[104.48943519592285,-1.924999237060547],[104.87943458557129,-2.146944046020508],[104.53249549865723,-2.772777557373047],[104.8621997833252,-2.289443969726563],[105.61248970031738,-2.394166946411133],[106.05525398254395,-3.031389236450195],[105.73248481750488,-5.89777946472168],[105.26860237121582,-5.44416618347168],[105.13971138000488,-5.796110153198242],[104.54498481750488,-5.506389617919922],[104.56077766418457,-5.929746627807617],[101.62692451477051,-3.246110916137695],[100.29358863830566,-0.806388854980469],[99.63582038879395,0.076944351196289],[99.1361255645752,0.261388778686523],[98.77086067199707,1.748613357543945],[97.75192451477051,2.269166946411133],[96.88025093078613,3.677499771118164],[95.53108406066895,4.682775497436523],[95.23080635070801,5.570833206176758],[95.73857307434082,5.58527946472168]],[[104.2138843536377,-1.039443969726563],[104.24331855773926,-1.023611068725586],[104.2008228302002,-1.037221908569336],[104.2138843536377,-1.039443969726563]],[[102.85970497131348,0.274446487426758],[102.92691230773926,0.322221755981445],[102.83386421203613,0.281110763549805],[102.85970497131348,0.274446487426758]]],[[[95.15802192687988,5.594724655151367],[95.10885810852051,5.61250114440918],[95.1424732208252,5.660833358764648],[95.15802192687988,5.594724655151367]]],[[[95.11969184875488,5.670278549194336],[95.00802803039551,5.73527717590332],[95.06358528137207,5.749444961547852],[95.11969184875488,5.670278549194336]]],[[[95.34247016906738,5.774168014526367],[95.21774482727051,5.913053512573242],[95.38163948059082,5.849721908569336],[95.34247016906738,5.774168014526367]]]]}},{"type":"Feature","properties":{"name":"Guadeloupe","iso2":"GP","iso3":"GLP"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-61.24556,15.871666],[-61.329445,15.92861],[-61.266945,16.014999],[-61.24556,15.871666]]],[[[-61.037224,16.311108],[-61.08667,16.29583],[-60.988617,16.346107000000146],[-61.037224,16.311108]]],[[[-61.346115,16.334164],[-61.695007,15.949165],[-61.783615,16.333054],[-61.346115,16.334164]]],[[[-62.811394,17.888332],[-62.869171,17.929722000000154],[-62.79084,17.912498],[-62.811394,17.888332]]]]}},{"type":"Feature","properties":{"name":"Netherlands Antilles","iso2":"AN","iso3":"ANT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-68.19528198242188,12.221109390258789],[-68.25111389160156,12.02055549621582],[-68.41612243652344,12.25694465637207],[-68.19528198242188,12.221109390258789]]],[[[-68.96556091308594,12.198888778686523],[-69.16361999511719,12.366388320922852],[-68.7469482421875,12.040277481079102],[-68.96556091308594,12.198888778686523]]],[[[-62.96111297607422,17.460832595825195],[-62.996673583984375,17.52055549621582],[-62.93861389160156,17.490278244018555],[-62.96111297607422,17.460832595825195]]]]}},{"type":"Feature","properties":{"name":"United Arab Emirates","iso2":"AE","iso3":"ARE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[53.965271000000115,24.176666],[53.62388600000011,24.162777],[53.85110500000022,24.269165],[53.965271000000115,24.176666]]],[[[53.324165,24.267776],[53.243607,24.276665],[53.341110000000214,24.328888],[53.324165,24.267776]]],[[[53.10971800000013,24.311386],[53.079437,24.32555400000011],[53.085831,24.352776],[53.10971800000013,24.311386]]],[[[54.264717000000104,24.288887],[54.174438,24.324997],[54.231384,24.35083],[54.264717000000104,24.288887]]],[[[52.616104,24.268608],[52.572777,24.339722],[52.639717,24.3722190000001],[52.616104,24.268608]]],[[[53.3980480000001,24.324718],[53.387497,24.368889],[53.428329000000105,24.366943],[53.3980480000001,24.324718]]],[[[54.472496,24.418888],[54.328331,24.45972100000013],[54.380272,24.502499],[54.472496,24.418888]]],[[[54.515549,24.504719],[54.48555,24.509163],[54.469719,24.536942],[54.515549,24.504719]]],[[[54.440826,24.50111],[54.400833,24.514721],[54.465553,24.589996],[54.440826,24.50111]]],[[[55.61749300000011,25.57],[55.609718000000186,25.569443],[55.620552,25.583611],[55.61749300000011,25.57]]],[[[56.183331,25.654989],[56.269722,25.636015],[56.373528,24.979382],[56.104164,24.734722000000104],[56.037498,24.938889],[55.7794420000001,24.563889000000145],[56.024719,24.076111],[55.510277000000116,23.97277500000014],[55.199165000000136,22.699718],[52.583328,22.938890000000114],[51.583611000000104,24.25972],[52.080551,23.955555],[54.118607,24.139442],[54.424164,24.281666],[54.650276000000105,24.746944],[55.863609,25.72333100000013],[56.079941,26.065559],[56.183331,25.654989]]]]}},{"type":"Feature","properties":{"name":"Timor-Leste","iso2":"TL","iso3":"TLS"},"geometry":{"type":"MultiPolygon","coordinates":[[[[124.44572729730143,-9.184801455158606],[124.34309325995272,-9.463379556533425],[124.04616116616907,-9.339979205869994],[124.44572729730143,-9.184801455158606]]],[[[127.25305200000011,-8.477499],[125.1279887712715,-9.435955217796248],[125.16404989666458,-9.066142474253581],[124.94544874451074,-8.95403931930285],[125.844147,-8.481667],[127.25305200000011,-8.477499]]]]}},{"type":"Feature","properties":{"name":"Pitcairn Islands","iso2":"PN","iso3":"PCN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-130.076935,-25.079723],[-130.107483,-25.063335],[-130.065002,-25.063335],[-130.076935,-25.079723]]],[[[-124.780853,-24.675835],[-124.795853,-24.666115],[-124.77252199999987,-24.666946],[-124.780853,-24.675835]]],[[[-128.289185,-24.409721],[-128.336945,-24.329166],[-128.303894,-24.33028],[-128.289185,-24.409721]]]]}},{"type":"Feature","properties":{"name":"Palau","iso2":"PW","iso3":"PLW"},"geometry":{"type":"MultiPolygon","coordinates":[[[[132.226624,5.292777000000129],[132.20831300000012,5.31111],[132.230255,5.307221],[132.226624,5.292777000000129]]],[[[134.166077,6.885277],[134.139435,6.934721000000124],[134.174988,6.923888],[134.166077,6.885277]]],[[[134.274994,7.010278],[134.227753,6.987777],[134.27832,7.070833],[134.274994,7.010278]]],[[[134.392761,7.140277],[134.353851,7.168055000000109],[134.381897,7.192498],[134.392761,7.140277]]],[[[134.377747,7.215833],[134.344116,7.269444],[134.438873,7.278888],[134.377747,7.215833]]],[[[134.470795,7.36111],[134.5174870000001,7.308054],[134.448303,7.331944],[134.470795,7.36111]]],[[[134.561371,7.371943],[134.485229,7.438054000000108],[134.634155,7.729444],[134.561371,7.371943]]]]}},{"type":"Feature","properties":{"name":"Marshall Islands","iso2":"MH","iso3":"MHL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[168.113586,5.600277],[168.094971,5.613333],[168.12439,5.641666000000114],[168.113586,5.600277]]],[[[168.09024,5.630554000000146],[168.074982,5.631943],[168.077148,5.650265],[168.09024,5.630554000000146]]],[[[171.75192300000012,6.080555],[171.727173,6.086110000000147],[171.733582,6.096388],[171.75192300000012,6.080555]]],[[[172.090515,6.219721],[172.07412700000012,6.222221000000104],[172.080261,6.229721],[172.090515,6.219721]]],[[[171.914154,7.092499000000117],[171.89413500000015,7.101665],[171.929962,7.133888],[171.914154,7.092499000000117]]],[[[168.768036,7.298332],[168.78637700000016,7.288888],[168.670258,7.328888],[168.768036,7.298332]]],[[[168.574677,7.398055000000113],[168.554962,7.423055],[168.5585940000001,7.471388],[168.574677,7.398055000000113]]],[[[168.967194,7.574166],[168.944427,7.615276],[168.974976,7.60111],[168.967194,7.574166]]],[[[168.251373,7.749443],[168.233582,7.74861],[168.220245,7.766944],[168.251373,7.749443]]],[[[167.738861,8.725275],[167.724396,8.729719],[167.740784,8.747776],[167.738861,8.725275]]],[[[170.844971,8.886944],[170.834961,8.893332],[170.846924,8.916109],[170.844971,8.886944]]],[[[165.536926,9.19722],[165.522491,9.207775],[165.5269170000001,9.218609000000143],[165.536926,9.19722]]],[[[166.829956,9.32222],[166.811646,9.336943],[166.830261,9.335831],[166.829956,9.32222]]],[[[170.248016,9.544722],[170.244965,9.533609000000112],[170.233307,9.55888700000014],[170.248016,9.544722]]],[[[170.15387,9.639442],[170.1355290000001,9.633333],[170.161652,9.645277],[170.15387,9.639442]]],[[[169.97161900000017,10.436386],[169.96386700000014,10.43333200000015],[169.944122,10.451109],[169.97161900000017,10.436386]]],[[[166.885254,11.144722],[166.841339,11.153332],[166.900543,11.168610000000115],[166.885254,11.144722]]],[[[169.866913,11.232775],[169.85553,11.231941],[169.858856,11.241386],[169.866913,11.232775]]],[[[162.33828700000012,11.351942],[162.323578,11.354164],[162.341644,11.362219],[162.33828700000012,11.351942]]],[[[167.520813,11.377775],[167.512207,11.393888],[167.5260930000002,11.386665],[167.520813,11.377775]]],[[[165.55609100000018,11.615831],[165.5130310000002,11.638611],[165.547211,11.634443000000104],[165.55609100000018,11.615831]]],[[[165.29165600000013,11.700554],[165.27191200000013,11.706387],[165.284698,11.714165],[165.29165600000013,11.700554]]],[[[168.987732,14.580832],[168.974976,14.58111],[169.003876,14.598053],[168.987732,14.580832]]]]}},{"type":"Feature","properties":{"name":"Saint Pierre and Miquelon","iso2":"PM","iso3":"SPM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-56.150833,46.758049],[-56.23722099999986,46.763885000000144],[-56.173889,46.80999],[-56.150833,46.758049]]],[[[-56.271111,46.994156],[-56.368332,46.784721],[-56.390282,47.118881],[-56.271111,46.994156]]]]}},{"type":"Feature","properties":{"name":"Saint Helena","iso2":"SH","iso3":"SHN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-9.892223,-40.390839],[-10.028611999999896,-40.309448],[-9.95222299999989,-40.306671],[-9.892223,-40.390839]]],[[[-12.206389999999885,-37.112503],[-12.331666999999868,-37.107506],[-12.259445,-37.05278],[-12.206389999999885,-37.112503]]],[[[-5.662222999999869,-15.987501],[-5.793056,-15.994167],[-5.704167,-15.903057],[-5.662222999999869,-15.987501]]],[[[-14.36389,-7.979723],[-14.381945,-7.883612],[-14.293056,-7.945278],[-14.36389,-7.979723]]]]}},{"type":"Feature","properties":{"name":"San Marino","iso2":"SM","iso3":"SMR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[12.415798,43.957954],[12.509998,43.986938],[12.459166,43.896111],[12.415798,43.957954]]]]}},{"type":"Feature","properties":{"name":"Turks and Caicos Islands","iso2":"TC","iso3":"TCA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-71.140289,21.431942],[-71.150558,21.470833],[-71.135559,21.511108000000107],[-71.140289,21.431942]]],[[[-72.460556,21.629719],[-72.45667999999989,21.699718000000118],[-72.433624,21.713333],[-72.460556,21.629719]]],[[[-71.468903,21.654999],[-71.53334,21.734444],[-71.462784,21.720833],[-71.468903,21.654999]]],[[[-71.657791,21.82333],[-71.65888999999987,21.739719000000107],[-71.850571,21.845833],[-71.657791,21.82333]]],[[[-72.2622219999999,21.75111],[-72.327225,21.855831],[-72.247787,21.795555],[-72.2622219999999,21.75111]]],[[[-71.88417099999987,21.847221],[-72.03334,21.942776],[-71.912231,21.943333],[-71.88417099999987,21.847221]]]]}},{"type":"Feature","properties":{"name":"Western Sahara","iso2":"EH","iso3":"ESH"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-15.741997,21.338284],[-16.953056,21.338333],[-17.05233,20.764095000000125],[-16.917225,21.943054],[-16.719448,22.26083],[-16.491112,22.334164],[-16.075558,23.324444],[-15.766668,23.781666],[-15.777225,23.908882],[-16.00639,23.6675],[-15.838058,23.896938],[-14.901112,24.688053],[-14.480278,26.171108],[-13.574167,26.731667],[-13.174961,27.666958],[-8.666668,27.666664],[-8.66679,27.290459],[-8.666944999999885,26.000275000000116],[-12.000557,26],[-12.000278,23.454441000000102],[-13.105278,22.893055],[-12.999723,21.338055000000125],[-15.741997,21.338284]]]]}},{"type":"Feature","properties":{"name":"Serbia","iso2":"RS","iso3":"SRB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[20.071423,42.560913],[20.348888,42.886383],[19.228809,43.513214],[19.51083,43.679718],[19.237019,44.011009],[19.620476,44.048454],[19.104443,44.355827],[19.371387,44.88916],[19.039719,44.861382],[19.423885,45.22583],[18.980324000000138,45.378624],[18.81702,45.912964],[20.261024,46.114853],[21.513611,45.151108],[21.400398,44.780823],[22.146385,44.479164],[22.479164,44.710274],[22.764893,44.559006],[22.457333,44.474358],[22.681435,44.224701],[22.367222,43.826942],[23.004997,43.192772],[22.442219,42.821663],[22.365276,42.323883],[20.589642,41.882187],[20.071423,42.560913]]]]}},{"type":"Feature","properties":{"name":"Holy See (Vatican City)","iso2":"VA","iso3":"VAT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[12.445090330888661,41.90311752178489],[12.45165333958056,41.907989033391274],[12.456660170953796,41.901426024699205],[12.445090330888661,41.90311752178489]]]]}},{"type":"Feature","properties":{"name":"Svalbard","iso2":"SJ","iso3":"SJM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-8.290895462036133,70.97415351867676],[-9.120058059692383,70.85775947570801],[-7.927001953125,71.15081977844238],[-8.290895462036133,70.97415351867676]]],[[[19.18194007873535,74.35971260070801],[18.79194450378418,74.48166084289551],[19.29972267150879,74.4749927520752],[19.18194007873535,74.35971260070801]]],[[[25.016111373901367,76.46638679504395],[24.936384201049805,76.4488697052002],[25.58222007751465,76.70665168762207],[25.016111373901367,76.46638679504395]]],[[[23.285554885864258,77.26471138000488],[23.13527488708496,77.23526191711426],[23.036386489868164,77.25999641418457],[23.285554885864258,77.26471138000488]]],[[[23.336111068725586,78.19748115539551],[23.059720993041992,78.01609992980957],[24.910276412963867,77.74971199035645],[22.6411075592041,77.25305366516113],[22.407499313354492,77.42082405090332],[22.77833366394043,77.54776191711426],[20.858888626098633,77.46249580383301],[21.64499855041504,77.9124927520752],[20.903051376342773,78.11499214172363],[23.336111068725586,78.19748115539551]]],[[[21.501665115356445,78.56553840637207],[22.028886795043945,78.5808277130127],[22.271944046020508,78.26361274719238],[20.671110153198242,78.18748664855957],[20.124719619750977,78.47221565246582],[21.501665115356445,78.56553840637207]]],[[[26.847497940063477,78.70749092102051],[26.396387100219727,78.77083015441895],[27.017499923706055,78.69304084777832],[26.847497940063477,78.70749092102051]]],[[[11.271944046020508,78.60693550109863],[12.163610458374023,78.19970893859863],[10.488611221313477,78.8963794708252],[11.271944046020508,78.60693550109863]]],[[[29.030553817749023,78.91609382629395],[29.708051681518555,78.8963794708252],[28.01972007751465,78.86747932434082],[29.030553817749023,78.91609382629395]]],[[[30.209440231323242,78.97638130187988],[30.06694221496582,79.00110054016113],[30.336111068725586,78.98887825012207],[30.209440231323242,78.97638130187988]]],[[[21.226106643676758,79.0374927520752],[20.98249626159668,79.01416206359863],[20.923608779907227,79.02998542785645],[21.226106643676758,79.0374927520752]]],[[[20.83305549621582,79.05415534973145],[20.046110153198242,79.0374927520752],[20.19972038269043,79.12469673156738],[20.83305549621582,79.05415534973145]]],[[[20.00750160217285,79.2422046661377],[19.9547176361084,79.22665596008301],[20.168886184692383,79.31915473937988],[20.00750160217285,79.2422046661377]]],[[[20.10944175720215,79.36581611633301],[20.18027687072754,79.3388843536377],[19.628332138061523,79.3883228302002],[20.10944175720215,79.36581611633301]]],[[[10.92277717590332,79.65109443664551],[10.712221145629883,79.71360969543457],[11.076108932495117,79.66276741027832],[10.92277717590332,79.65109443664551]]],[[[11.000555038452148,79.74026679992676],[10.639165878295898,79.75000190734863],[10.756109237670898,79.78332710266113],[11.000555038452148,79.74026679992676]]],[[[16.81916618347168,79.8722095489502],[18.09833335876465,79.72026252746582],[17.63555335998535,79.37248420715332],[18.356943130493164,79.6283130645752],[18.92055320739746,79.16415596008301],[21.549165725708008,78.76776313781738],[18.965551376342773,78.45610237121582],[19.092222213745117,78.09553718566895],[18.410829544067383,78.02165412902832],[18.292776107788086,77.50638008117676],[17.73832893371582,77.47110176086426],[16.919164657592773,76.79971504211426],[17.198331832885742,76.69470405578613],[16.612775802612305,76.57054328918457],[15.498052597045898,76.87997627258301],[16.51972007751465,76.99859809875488],[14.467222213745117,77.1716480255127],[13.914167404174805,77.52777290344238],[16.223051071166992,77.43498420715332],[14.739164352416992,77.65860176086426],[17.0061092376709,77.93136787414551],[13.94194221496582,77.71666145324707],[13.588888168334961,78.04942512512207],[17.301664352416992,78.42025947570801],[16.328886032104492,78.45221138000488],[16.83111000061035,78.67192268371582],[15.464166641235352,78.45166206359863],[15.193330764770508,78.58804512023926],[15.379999160766602,78.84471321105957],[14.385557174682617,78.49775886535645],[14.726388931274414,78.38388252258301],[13.00666618347168,78.19748115539551],[12.360555648803711,78.48027229309082],[13.198610305786133,78.54081916809082],[11.333333969116211,78.96054267883301],[12.505556106567383,78.90803718566895],[11.755277633666992,79.0758228302002],[12.113054275512695,79.29582405090332],[11.236387252807617,79.09305000305176],[10.676942825317383,79.54498481750488],[13.82472038269043,79.8752613067627],[12.447778701782227,79.56637763977051],[13.484441757202148,79.5808277130127],[13.257223129272461,79.47137641906738],[14.058889389038086,79.2602710723877],[13.886945724487305,79.54136848449707],[14.584997177124023,79.80415534973145],[16.44999885559082,78.90387153625488],[15.638055801391602,79.82721138000488],[16.307775497436523,80.0627613067627],[16.81916618347168,79.8722095489502]]],[[[27.837778091430664,80.11026191711426],[27.674165725708008,80.12275886535645],[28.07444190979004,80.14415168762207],[27.837778091430664,80.11026191711426]]],[[[36.84916114807129,80.13998603820801],[36.59054756164551,80.15498542785645],[36.76027870178223,80.16081428527832],[36.84916114807129,80.13998603820801]]],[[[32.36638832092285,80.09443855285645],[31.44944190979004,80.08581733703613],[33.63749885559082,80.21331977844238],[32.36638832092285,80.09443855285645]]],[[[18.55333137512207,80.24553108215332],[18.119443893432617,80.28471565246582],[18.75861167907715,80.30192756652832],[18.55333137512207,80.24553108215332]]],[[[24.335832595825195,80.38415718078613],[24.128610610961914,80.39305305480957],[24.196943283081055,80.45416450500488],[24.335832595825195,80.38415718078613]]],[[[19.933332443237305,80.47747993469238],[21.86055564880371,80.26776313781738],[21.598608016967773,80.11831855773926],[22.22638511657715,79.97915840148926],[22.578611373901367,80.2986011505127],[22.361108779907227,80.41026496887207],[22.88694190979004,80.49026679992676],[23.360830307006836,80.42943000793457],[23.101388931274414,80.12082099914551],[24.83638572692871,80.35081672668457],[27.244997024536133,79.90498542785645],[23.511667251586914,79.17886543273926],[19.63555335998535,79.60386848449707],[22.312498092651367,79.79693794250488],[18.771387100219727,79.71748542785645],[18.154165267944336,79.90999031066895],[18.8094425201416,79.99470710754395],[17.783056259155273,80.12776374816895],[19.34055519104004,80.08638191223145],[19.584165573120117,80.1513843536377],[18.979997634887695,80.33665657043457],[19.837778091430664,80.2138843536377],[19.46333122253418,80.45471382141113],[19.933332443237305,80.47747993469238]]],[[[24.26500129699707,80.47110176086426],[23.97443962097168,80.49054145812988],[24.174997329711914,80.50915718078613],[24.26500129699707,80.47110176086426]]],[[[19.933332443237305,80.47747993469238],[19.8447208404541,80.50305366516113],[20.130277633666992,80.51277351379395],[19.933332443237305,80.47747993469238]]],[[[20.753610610961914,80.62137031555176],[20.499162673950195,80.65776252746582],[20.793333053588867,80.64749336242676],[20.753610610961914,80.62137031555176]]],[[[21.330278396606445,80.70027351379395],[21.364999771118164,80.67886543273926],[21.02638816833496,80.6816577911377],[21.330278396606445,80.70027351379395]]],[[[20.81916618347168,80.71914863586426],[20.51833152770996,80.75999641418457],[21.00666618347168,80.70138740539551],[20.81916618347168,80.71914863586426]]]]}},{"type":"Feature","properties":{"name":"Saint Martin","iso2":"MF","iso3":"MAF"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-63.00666799999988,18.080555],[-63.01145899999989,18.067276],[-63.139839,18.058601],[-63.00666799999988,18.080555]]]]}},{"type":"Feature","properties":{"name":"Saint Barthelemy","iso2":"BL","iso3":"BLM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-63.028336,18.015553],[-63.139839,18.058601],[-63.01145899999989,18.067276],[-63.028336,18.015553]]]]}},{"type":"Feature","properties":{"name":"Guernsey","iso2":"GG","iso3":"GGY"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-2.590834,49.422493],[-2.670278,49.434166000000104],[-2.501667,49.507774],[-2.590834,49.422493]]]]}},{"type":"Feature","properties":{"name":"Jersey","iso2":"JE","iso3":"JEY"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-2.015,49.214165],[-2.205278,49.180832],[-2.247222,49.253052],[-2.015,49.214165]]]]}},{"type":"Feature","properties":{"name":"South Georgia South Sandwich Islands","iso2":"GS","iso3":"SGS"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-27.325836,-59.427223],[-27.298058,-59.473061],[-27.412502,-59.434448],[-27.325836,-59.427223]]],[[[-26.582779,-59.070007],[-26.665001,-59.025841],[-26.501114,-59.036949],[-26.582779,-59.070007]]],[[[-26.246391,-58.407501],[-26.24889,-58.498611],[-26.459167,-58.427223],[-26.246391,-58.407501]]],[[[-26.41278099999988,-57.80806],[-26.512222,-57.771118],[-26.443336,-57.743896],[-26.41278099999988,-57.80806]]],[[[-26.660835,-57.086395],[-26.728888999999896,-57.062782],[-26.675835,-57.056396],[-26.660835,-57.086395]]],[[[-27.10861199999988,-56.717506],[-27.209724,-56.693611],[-27.129448,-56.682228],[-27.10861199999988,-56.717506]]],[[[-27.563892,-56.320557],[-27.600002,-56.281113],[-27.549446,-56.27417],[-27.563892,-56.320557]]],[[[-37.038612,-54.511673],[-37.083618,-54.512779],[-37.105835,-54.471115],[-37.038612,-54.511673]]],[[[-37.495003,-54.010559],[-36.288063,-54.266396],[-35.782501,-54.765556],[-36.115837,-54.887222],[-37.411392,-54.268333],[-37.239448999999865,-54.147781],[-38.033058,-54.048889],[-37.495003,-54.010559]]]]}},{"type":"Feature","properties":{"name":"Taiwan","iso2":"TW","iso3":"TWN"},"geometry":{"type":"MultiPolygon","coordinates":[[[[121.576393,22.001389],[121.490257,22.078609],[121.546944,22.078053],[121.576393,22.001389]]],[[[119.66943400000011,23.549999],[119.526703,23.535461],[119.59832800000018,23.606941],[119.66943400000011,23.549999]]],[[[118.223602,24.40416300000011],[118.207489,24.412495000000106],[118.241364,24.445827],[118.223602,24.40416300000011]]],[[[118.4191440000001,24.395828],[118.275543,24.399162],[118.401657,24.521664],[118.4191440000001,24.395828]]],[[[121.734711,25.138885],[122.002213,25.006943000000106],[121.839706,24.476383000000126],[120.71637700000011,21.928051],[120.05275700000018,23.044998],[120.111366,23.620274],[121.00916300000014,25.008888000000113],[121.734711,25.138885]]],[[[119.92942800000012,26.134995],[119.909416,26.159439],[119.95247700000019,26.159996000000106],[119.92942800000012,26.134995]]],[[[119.96720900000017,26.187496000000138],[119.956383,26.215549],[120.006104,26.219162],[119.96720900000017,26.187496000000138]]]]}}]} \ No newline at end of file diff --git a/src/plugins/tile_map/public/__tests__/blues.png b/src/plugins/tile_map/public/__tests__/blues.png deleted file mode 100644 index 89d6734eb123a0033cf7bb712d4894a0205019ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14095 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 LJz4H}{rCR@yo?jZ diff --git a/src/plugins/tile_map/public/__tests__/coordinate_maps_visualization.js b/src/plugins/tile_map/public/__tests__/coordinate_maps_visualization.js deleted file mode 100644 index f2830e58e0eea..0000000000000 --- a/src/plugins/tile_map/public/__tests__/coordinate_maps_visualization.js +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import ngMock from 'ng_mock'; -import { ImageComparator } from 'test_utils/image_comparator'; -import dummyESResponse from './dummy_es_response.json'; -import initial from './initial.png'; -import blues from './blues.png'; -import shadedGeohashGrid from './shaded_geohash_grid.png'; -import heatmapRaw from './heatmap_raw.png'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_CATALOGUE from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_manifest.json'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_FILES from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_files.json'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_TILES from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_tiles.json'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_STYLE_ROAD_MAP_BRIGHT from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_style_bright'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_STYLE_ROAD_MAP_DESATURATED from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_style_desaturated'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import EMS_STYLE_DARK_MAP from '../../../maps_legacy/public/__tests__/map/ems_mocks/sample_style_dark'; - -import { createTileMapVisualization } from '../tile_map_visualization'; -import { createTileMapTypeDefinition } from '../tile_map_type'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ExprVis } from '../../../visualizations/public/expressions/vis'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { BaseVisType } from '../../../visualizations/public/vis_types/base_vis_type'; -import { - getPrecision, - getZoomPrecision, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../maps_legacy/public/map/precision'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ServiceSettings } from '../../../maps_legacy/public/map/service_settings'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { KibanaMap } from '../../../maps_legacy/public/map/kibana_map'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { BaseMapsVisualizationProvider } from '../../../maps_legacy/public/map/base_maps_visualization'; - -function mockRawData() { - const stack = [dummyESResponse]; - let node; - do { - node = stack.pop(); - if (typeof node === 'object') { - // eslint-disable-next-line guard-for-in - for (const key in node) { - if (node.hasOwnProperty(key)) { - if (key === 'aggConfig') { - node[key].makeLabel = () => 'foobar'; - } - } - stack.push(node[key]); - } - } - } while (stack.length); -} -mockRawData(); - -const THRESHOLD = 0.45; -const PIXEL_DIFF = 64; - -describe('CoordinateMapsVisualizationTest', function () { - let domNode; - let CoordinateMapsVisualization; - let vis; - let dependencies; - let visType; - - let imageComparator; - - let getManifestStub; - beforeEach(ngMock.module('kibana')); - beforeEach( - ngMock.inject((Private, $injector) => { - const mapConfig = { - emsFileApiUrl: '', - emsTileApiUrl: '', - emsLandingPageUrl: '', - }; - const tilemapsConfig = { - options: { - attribution: '123', - }, - }; - - const serviceSettings = new ServiceSettings(mapConfig, tilemapsConfig); - const BaseMapsVisualization = new BaseMapsVisualizationProvider( - (...args) => new KibanaMap(...args), - serviceSettings - ); - const uiSettings = $injector.get('config'); - - dependencies = { - getZoomPrecision, - getPrecision, - BaseMapsVisualization, - uiSettings, - serviceSettings, - }; - - visType = new BaseVisType(createTileMapTypeDefinition(dependencies)); - - CoordinateMapsVisualization = createTileMapVisualization(dependencies); - - getManifestStub = serviceSettings.__debugStubManifestCalls(async (url) => { - //simulate network calls - if (url.startsWith('https://foobar')) { - return EMS_CATALOGUE; - } else if (url.startsWith('https://tiles.foobar')) { - return EMS_TILES; - } else if (url.startsWith('https://files.foobar')) { - return EMS_FILES; - } else if (url.startsWith('https://raster-style.foobar')) { - if (url.includes('osm-bright-desaturated')) { - return EMS_STYLE_ROAD_MAP_DESATURATED; - } else if (url.includes('osm-bright')) { - return EMS_STYLE_ROAD_MAP_BRIGHT; - } else if (url.includes('dark-matter')) { - return EMS_STYLE_DARK_MAP; - } - } - }); - }) - ); - - afterEach(() => { - getManifestStub.removeStub(); - }); - - describe('CoordinateMapsVisualization - basics', function () { - beforeEach(async function () { - setupDOM('512px', '512px'); - - imageComparator = new ImageComparator(); - vis = new ExprVis({ - type: visType, - }); - vis.params = { - mapType: 'Scaled Circle Markers', - isDesaturated: true, - addTooltip: true, - heatClusterSize: 1.5, - legendPosition: 'bottomright', - mapZoom: 2, - mapCenter: [0, 0], - dimensions: { - metric: { - accessor: 1, - label: 'test', - format: { id: 'string' }, - }, - bucket: { - accessor: 0, - }, - }, - }; - const mockAggs = { - byType: (type) => { - return mockAggs.aggs.find((agg) => agg.type.type === type); - }, - aggs: [ - { - type: { - type: 'metrics', - }, - fieldFormatter: (x) => { - return x; - }, - makeLabel: () => { - return 'foobar'; - }, - }, - { - type: { - type: 'buckets', - }, - params: { useGeoCentroid: true }, - }, - ], - }; - vis.getAggConfig = function () { - return mockAggs; - }; - vis.aggs = mockAggs; - }); - - afterEach(function () { - teardownDOM(); - imageComparator.destroy(); - }); - - it('should initialize OK (may fail in dev env)', async function () { - const coordinateMapVisualization = new CoordinateMapsVisualization(domNode, vis); - await coordinateMapVisualization.render(dummyESResponse, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - - const mismatchedPixels = await compareImage(initial, 0); - coordinateMapVisualization.destroy(); - expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF); - }); - - it('should toggle to Heatmap OK', async function () { - const coordinateMapVisualization = new CoordinateMapsVisualization(domNode, vis); - await coordinateMapVisualization.render(dummyESResponse, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - - vis.params.mapType = 'Heatmap'; - await coordinateMapVisualization.render(dummyESResponse, vis.params, { - resize: false, - params: true, - aggs: false, - data: false, - uiState: false, - }); - - const mismatchedPixels = await compareImage(heatmapRaw, 1); - coordinateMapVisualization.destroy(); - expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF); - }); - - it('should toggle back&forth OK between mapTypes (may fail in dev env)', async function () { - const coordinateMapVisualization = new CoordinateMapsVisualization(domNode, vis); - await coordinateMapVisualization.render(dummyESResponse, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - - vis.params.mapType = 'Heatmap'; - await coordinateMapVisualization.render(dummyESResponse, vis.params, { - resize: false, - params: true, - aggs: false, - data: false, - uiState: false, - }); - - vis.params.mapType = 'Scaled Circle Markers'; - await coordinateMapVisualization.render(dummyESResponse, vis.params, { - resize: false, - params: true, - aggs: false, - data: false, - uiState: false, - }); - - const mismatchedPixels = await compareImage(initial, 0); - coordinateMapVisualization.destroy(); - expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF); - }); - - it('should toggle to different color schema ok (may fail in dev env)', async function () { - const coordinateMapVisualization = new CoordinateMapsVisualization(domNode, vis); - await coordinateMapVisualization.render(dummyESResponse, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - - vis.params.colorSchema = 'Blues'; - await coordinateMapVisualization.render(dummyESResponse, vis.params, { - resize: false, - params: true, - aggs: false, - data: false, - uiState: false, - }); - - const mismatchedPixels = await compareImage(blues, 0); - coordinateMapVisualization.destroy(); - expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF); - }); - - it('should toggle to different color schema and maptypes ok', async function () { - const coordinateMapVisualization = new CoordinateMapsVisualization(domNode, vis); - await coordinateMapVisualization.render(dummyESResponse, vis.params, { - resize: false, - params: true, - aggs: true, - data: true, - uiState: false, - }); - - vis.params.colorSchema = 'Greens'; - vis.params.mapType = 'Shaded Geohash Grid'; - await coordinateMapVisualization.render(dummyESResponse, vis.params, { - resize: false, - params: true, - aggs: false, - data: false, - uiState: false, - }); - - const mismatchedPixels = await compareImage(shadedGeohashGrid, 0); - coordinateMapVisualization.destroy(); - expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF); - }); - }); - - async function compareImage(expectedImageSource, index) { - const elementList = domNode.querySelectorAll('canvas'); - const firstCanvasOnMap = elementList[index]; - return imageComparator.compareImage(firstCanvasOnMap, expectedImageSource, THRESHOLD); - } - - function setupDOM(width, height) { - domNode = document.createElement('div'); - domNode.style.top = '0'; - domNode.style.left = '0'; - domNode.style.width = width; - domNode.style.height = height; - domNode.style.position = 'fixed'; - domNode.style.border = '1px solid blue'; - domNode.style['pointer-events'] = 'none'; - document.body.appendChild(domNode); - } - - function teardownDOM() { - domNode.innerHTML = ''; - document.body.removeChild(domNode); - } -}); diff --git a/src/plugins/tile_map/public/__tests__/dummy_es_response.json b/src/plugins/tile_map/public/__tests__/dummy_es_response.json deleted file mode 100644 index 1c54857f9d67a..0000000000000 --- a/src/plugins/tile_map/public/__tests__/dummy_es_response.json +++ /dev/null @@ -1,1810 +0,0 @@ -{ - "featureCollection": { - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -84.9070567265153, - 36.36630680412054 - ] - }, - "properties": { - "geohash": "dn", - "doc_count": 715, - "geohash_meta": { - "center": [ - 36.5625, - -84.375 - ], - "rectangle": [ - [ - 33.75, - -90 - ], - [ - 33.75, - -78.75 - ], - [ - 39.375, - -78.75 - ], - [ - 39.375, - -90 - ] - ] - }, - "value": 715 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -84.9149083904922, - 41.58417354337871 - ] - }, - "properties": { - "geohash": "dp", - "doc_count": 657, - "geohash_meta": { - "center": [ - 42.1875, - -84.375 - ], - "rectangle": [ - [ - 39.375, - -90 - ], - [ - 39.375, - -78.75 - ], - [ - 45, - -78.75 - ], - [ - 45, - -90 - ] - ] - }, - "value": 657 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -95.05993634462357, - 36.32617760449648 - ] - }, - "properties": { - "geohash": "9y", - "doc_count": 623, - "geohash_meta": { - "center": [ - 36.5625, - -95.625 - ], - "rectangle": [ - [ - 33.75, - -101.25 - ], - [ - 33.75, - -90 - ], - [ - 39.375, - -90 - ], - [ - 39.375, - -101.25 - ] - ] - }, - "value": 623 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -73.9467297680676, - 42.102721743285656 - ] - }, - "properties": { - "geohash": "dr", - "doc_count": 576, - "geohash_meta": { - "center": [ - 42.1875, - -73.125 - ], - "rectangle": [ - [ - 39.375, - -78.75 - ], - [ - 39.375, - -67.5 - ], - [ - 45, - -67.5 - ], - [ - 45, - -78.75 - ] - ] - }, - "value": 576 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -95.22280854173005, - 41.98196731042117 - ] - }, - "properties": { - "geohash": "9z", - "doc_count": 555, - "geohash_meta": { - "center": [ - 42.1875, - -95.625 - ], - "rectangle": [ - [ - 39.375, - -101.25 - ], - [ - 39.375, - -90 - ], - [ - 45, - -90 - ], - [ - 45, - -101.25 - ] - ] - }, - "value": 555 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -84.76328378543258, - 31.699854251928627 - ] - }, - "properties": { - "geohash": "dj", - "doc_count": 528, - "geohash_meta": { - "center": [ - 30.9375, - -84.375 - ], - "rectangle": [ - [ - 28.125, - -90 - ], - [ - 28.125, - -78.75 - ], - [ - 33.75, - -78.75 - ], - [ - 33.75, - -90 - ] - ] - }, - "value": 528 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -95.2651846781373, - 31.394152916036546 - ] - }, - "properties": { - "geohash": "9v", - "doc_count": 510, - "geohash_meta": { - "center": [ - 30.9375, - -95.625 - ], - "rectangle": [ - [ - 28.125, - -101.25 - ], - [ - 28.125, - -90 - ], - [ - 33.75, - -90 - ], - [ - 33.75, - -101.25 - ] - ] - }, - "value": 510 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -118.95955030806363, - 36.473086257465184 - ] - }, - "properties": { - "geohash": "9q", - "doc_count": 390, - "geohash_meta": { - "center": [ - 36.5625, - -118.125 - ], - "rectangle": [ - [ - 33.75, - -123.75 - ], - [ - 33.75, - -112.5 - ], - [ - 39.375, - -112.5 - ], - [ - 39.375, - -123.75 - ] - ] - }, - "value": 390 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -106.9422698020935, - 36.371589582413435 - ] - }, - "properties": { - "geohash": "9w", - "doc_count": 257, - "geohash_meta": { - "center": [ - 36.5625, - -106.875 - ], - "rectangle": [ - [ - 33.75, - -112.5 - ], - [ - 33.75, - -101.25 - ], - [ - 39.375, - -101.25 - ], - [ - 39.375, - -112.5 - ] - ] - }, - "value": 257 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -95.21766104735434, - 46.71993430238217 - ] - }, - "properties": { - "geohash": "cb", - "doc_count": 248, - "geohash_meta": { - "center": [ - 47.8125, - -95.625 - ], - "rectangle": [ - [ - 45, - -101.25 - ], - [ - 45, - -90 - ], - [ - 50.625, - -90 - ], - [ - 50.625, - -101.25 - ] - ] - }, - "value": 248 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -119.4527724198997, - 47.01064535882324 - ] - }, - "properties": { - "geohash": "c2", - "doc_count": 241, - "geohash_meta": { - "center": [ - 47.8125, - -118.125 - ], - "rectangle": [ - [ - 45, - -123.75 - ], - [ - 45, - -112.5 - ], - [ - 50.625, - -112.5 - ], - [ - 50.625, - -123.75 - ] - ] - }, - "value": 241 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -106.35303659364581, - 41.90058804117143 - ] - }, - "properties": { - "geohash": "9x", - "doc_count": 233, - "geohash_meta": { - "center": [ - 42.1875, - -106.875 - ], - "rectangle": [ - [ - 39.375, - -112.5 - ], - [ - 39.375, - -101.25 - ], - [ - 45, - -101.25 - ], - [ - 45, - -112.5 - ] - ] - }, - "value": 233 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -119.78077582083642, - 42.019549501128495 - ] - }, - "properties": { - "geohash": "9r", - "doc_count": 202, - "geohash_meta": { - "center": [ - 42.1875, - -118.125 - ], - "rectangle": [ - [ - 39.375, - -123.75 - ], - [ - 39.375, - -112.5 - ], - [ - 45, - -112.5 - ], - [ - 45, - -123.75 - ] - ] - }, - "value": 202 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -77.02892781235278, - 37.012665029615164 - ] - }, - "properties": { - "geohash": "dq", - "doc_count": 188, - "geohash_meta": { - "center": [ - 36.5625, - -73.125 - ], - "rectangle": [ - [ - 33.75, - -78.75 - ], - [ - 33.75, - -67.5 - ], - [ - 39.375, - -67.5 - ], - [ - 39.375, - -78.75 - ] - ] - }, - "value": 188 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -106.99090437032282, - 47.078339285217226 - ] - }, - "properties": { - "geohash": "c8", - "doc_count": 158, - "geohash_meta": { - "center": [ - 47.8125, - -106.875 - ], - "rectangle": [ - [ - 45, - -112.5 - ], - [ - 45, - -101.25 - ], - [ - 50.625, - -101.25 - ], - [ - 50.625, - -112.5 - ] - ] - }, - "value": 158 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -107.13654454797506, - 32.61927543673664 - ] - }, - "properties": { - "geohash": "9t", - "doc_count": 138, - "geohash_meta": { - "center": [ - 30.9375, - -106.875 - ], - "rectangle": [ - [ - 28.125, - -112.5 - ], - [ - 28.125, - -101.25 - ], - [ - 33.75, - -101.25 - ], - [ - 33.75, - -112.5 - ] - ] - }, - "value": 138 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -152.64550829306245, - 59.914903342723846 - ] - }, - "properties": { - "geohash": "bd", - "doc_count": 126, - "geohash_meta": { - "center": [ - 59.0625, - -151.875 - ], - "rectangle": [ - [ - 56.25, - -157.5 - ], - [ - 56.25, - -146.25 - ], - [ - 61.875, - -146.25 - ], - [ - 61.875, - -157.5 - ] - ] - }, - "value": 126 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -81.2875135615468, - 26.6619403520599 - ] - }, - "properties": { - "geohash": "dh", - "doc_count": 96, - "geohash_meta": { - "center": [ - 25.3125, - -84.375 - ], - "rectangle": [ - [ - 22.5, - -90 - ], - [ - 22.5, - -78.75 - ], - [ - 28.125, - -78.75 - ], - [ - 28.125, - -90 - ] - ] - }, - "value": 96 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -161.96613382548094, - 60.42251357808709 - ] - }, - "properties": { - "geohash": "b6", - "doc_count": 95, - "geohash_meta": { - "center": [ - 59.0625, - -163.125 - ], - "rectangle": [ - [ - 56.25, - -168.75 - ], - [ - 56.25, - -157.5 - ], - [ - 61.875, - -157.5 - ], - [ - 61.875, - -168.75 - ] - ] - }, - "value": 95 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -162.01718556694686, - 64.50348428450525 - ] - }, - "properties": { - "geohash": "b7", - "doc_count": 83, - "geohash_meta": { - "center": [ - 64.6875, - -163.125 - ], - "rectangle": [ - [ - 61.875, - -168.75 - ], - [ - 61.875, - -157.5 - ], - [ - 67.5, - -157.5 - ], - [ - 67.5, - -168.75 - ] - ] - }, - "value": 83 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -152.76569221168756, - 64.75516308099031 - ] - }, - "properties": { - "geohash": "be", - "doc_count": 77, - "geohash_meta": { - "center": [ - 64.6875, - -151.875 - ], - "rectangle": [ - [ - 61.875, - -157.5 - ], - [ - 61.875, - -146.25 - ], - [ - 67.5, - -146.25 - ], - [ - 67.5, - -157.5 - ] - ] - }, - "value": 77 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -86.92213883623481, - 45.67713766358793 - ] - }, - "properties": { - "geohash": "f0", - "doc_count": 70, - "geohash_meta": { - "center": [ - 47.8125, - -84.375 - ], - "rectangle": [ - [ - 45, - -90 - ], - [ - 45, - -78.75 - ], - [ - 50.625, - -78.75 - ], - [ - 50.625, - -90 - ] - ] - }, - "value": 70 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -115.65346693620086, - 33.081501605920494 - ] - }, - "properties": { - "geohash": "9m", - "doc_count": 61, - "geohash_meta": { - "center": [ - 30.9375, - -118.125 - ], - "rectangle": [ - [ - 28.125, - -123.75 - ], - [ - 28.125, - -112.5 - ], - [ - 33.75, - -112.5 - ], - [ - 33.75, - -123.75 - ] - ] - }, - "value": 61 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -65.73361264541745, - 18.2236089091748 - ] - }, - "properties": { - "geohash": "de", - "doc_count": 41, - "geohash_meta": { - "center": [ - 19.6875, - -61.875 - ], - "rectangle": [ - [ - 16.875, - -67.5 - ], - [ - 16.875, - -56.25 - ], - [ - 22.5, - -56.25 - ], - [ - 22.5, - -67.5 - ] - ] - }, - "value": 41 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -143.12310453504324, - 64.18042578734457 - ] - }, - "properties": { - "geohash": "bg", - "doc_count": 39, - "geohash_meta": { - "center": [ - 64.6875, - -140.625 - ], - "rectangle": [ - [ - 61.875, - -146.25 - ], - [ - 61.875, - -135 - ], - [ - 67.5, - -135 - ], - [ - 67.5, - -146.25 - ] - ] - }, - "value": 39 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -124.1186392866075, - 42.33813495375216 - ] - }, - "properties": { - "geohash": "9p", - "doc_count": 37, - "geohash_meta": { - "center": [ - 42.1875, - -129.375 - ], - "rectangle": [ - [ - 39.375, - -135 - ], - [ - 39.375, - -123.75 - ], - [ - 45, - -123.75 - ], - [ - 45, - -135 - ] - ] - }, - "value": 37 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -137.9709525872022, - 59.20598397497088 - ] - }, - "properties": { - "geohash": "bf", - "doc_count": 36, - "geohash_meta": { - "center": [ - 59.0625, - -140.625 - ], - "rectangle": [ - [ - 56.25, - -146.25 - ], - [ - 56.25, - -135 - ], - [ - 61.875, - -135 - ], - [ - 61.875, - -146.25 - ] - ] - }, - "value": 36 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -132.43937451392412, - 55.6085482891649 - ] - }, - "properties": { - "geohash": "c1", - "doc_count": 35, - "geohash_meta": { - "center": [ - 53.4375, - -129.375 - ], - "rectangle": [ - [ - 50.625, - -135 - ], - [ - 50.625, - -123.75 - ], - [ - 56.25, - -123.75 - ], - [ - 56.25, - -135 - ] - ] - }, - "value": 35 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -98.05168284103274, - 27.216137498617172 - ] - }, - "properties": { - "geohash": "9u", - "doc_count": 33, - "geohash_meta": { - "center": [ - 25.3125, - -95.625 - ], - "rectangle": [ - [ - 22.5, - -101.25 - ], - [ - 22.5, - -90 - ], - [ - 28.125, - -90 - ], - [ - 28.125, - -101.25 - ] - ] - }, - "value": 33 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -133.99208377115428, - 57.29258285835385 - ] - }, - "properties": { - "geohash": "c4", - "doc_count": 30, - "geohash_meta": { - "center": [ - 59.0625, - -129.375 - ], - "rectangle": [ - [ - 56.25, - -135 - ], - [ - 56.25, - -123.75 - ], - [ - 61.875, - -123.75 - ], - [ - 61.875, - -135 - ] - ] - }, - "value": 30 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -68.79461143165827, - 45.693174339830875 - ] - }, - "properties": { - "geohash": "f2", - "doc_count": 24, - "geohash_meta": { - "center": [ - 47.8125, - -73.125 - ], - "rectangle": [ - [ - 45, - -78.75 - ], - [ - 45, - -67.5 - ], - [ - 50.625, - -67.5 - ], - [ - 50.625, - -78.75 - ] - ] - }, - "value": 24 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -163.01397004164755, - 54.89952846430242 - ] - }, - "properties": { - "geohash": "b3", - "doc_count": 24, - "geohash_meta": { - "center": [ - 53.4375, - -163.125 - ], - "rectangle": [ - [ - 50.625, - -168.75 - ], - [ - 50.625, - -157.5 - ], - [ - 56.25, - -157.5 - ], - [ - 56.25, - -168.75 - ] - ] - }, - "value": 24 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -156.45671758800745, - 20.677654556930065 - ] - }, - "properties": { - "geohash": "8e", - "doc_count": 21, - "geohash_meta": { - "center": [ - 19.6875, - -151.875 - ], - "rectangle": [ - [ - 16.875, - -157.5 - ], - [ - 16.875, - -146.25 - ], - [ - 22.5, - -146.25 - ], - [ - 22.5, - -157.5 - ] - ] - }, - "value": 21 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -151.52415155433118, - 68.92314183991402 - ] - }, - "properties": { - "geohash": "bs", - "doc_count": 18, - "geohash_meta": { - "center": [ - 70.3125, - -151.875 - ], - "rectangle": [ - [ - 67.5, - -157.5 - ], - [ - 67.5, - -146.25 - ], - [ - 73.125, - -146.25 - ], - [ - 73.125, - -157.5 - ] - ] - }, - "value": 18 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -124.08633585087955, - 46.76067248918116 - ] - }, - "properties": { - "geohash": "c0", - "doc_count": 13, - "geohash_meta": { - "center": [ - 47.8125, - -129.375 - ], - "rectangle": [ - [ - 45, - -135 - ], - [ - 45, - -123.75 - ], - [ - 50.625, - -123.75 - ], - [ - 50.625, - -135 - ] - ] - }, - "value": 13 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -158.69247693568468, - 21.67966120876372 - ] - }, - "properties": { - "geohash": "87", - "doc_count": 12, - "geohash_meta": { - "center": [ - 19.6875, - -163.125 - ], - "rectangle": [ - [ - 16.875, - -168.75 - ], - [ - 16.875, - -157.5 - ], - [ - 22.5, - -157.5 - ], - [ - 22.5, - -168.75 - ] - ] - }, - "value": 12 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -169.91430887952447, - 14.246335001662374 - ] - }, - "properties": { - "geohash": "84", - "doc_count": 12, - "geohash_meta": { - "center": [ - 14.0625, - -174.375 - ], - "rectangle": [ - [ - 11.25, - -180 - ], - [ - 11.25, - -168.75 - ], - [ - 16.875, - -168.75 - ], - [ - 16.875, - -180 - ] - ] - }, - "value": 12 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -145.1541736163199, - 14.100071671418846 - ] - }, - "properties": { - "geohash": "8f", - "doc_count": 10, - "geohash_meta": { - "center": [ - 14.0625, - -140.625 - ], - "rectangle": [ - [ - 11.25, - -146.25 - ], - [ - 11.25, - -135 - ], - [ - 16.875, - -135 - ], - [ - 16.875, - -146.25 - ] - ] - }, - "value": 10 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -163.34791378118098, - 69.16283434722573 - ] - }, - "properties": { - "geohash": "bk", - "doc_count": 9, - "geohash_meta": { - "center": [ - 70.3125, - -163.125 - ], - "rectangle": [ - [ - 67.5, - -168.75 - ], - [ - 67.5, - -157.5 - ], - [ - 73.125, - -157.5 - ], - [ - 73.125, - -168.75 - ] - ] - }, - "value": 9 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -67.16800019145012, - 44.8411110509187 - ] - }, - "properties": { - "geohash": "dx", - "doc_count": 6, - "geohash_meta": { - "center": [ - 42.1875, - -61.875 - ], - "rectangle": [ - [ - 39.375, - -67.5 - ], - [ - 39.375, - -56.25 - ], - [ - 45, - -56.25 - ], - [ - 45, - -67.5 - ] - ] - }, - "value": 6 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -169.80291330255568, - 56.72484784852713 - ] - }, - "properties": { - "geohash": "b4", - "doc_count": 4, - "geohash_meta": { - "center": [ - 59.0625, - -174.375 - ], - "rectangle": [ - [ - 56.25, - -180 - ], - [ - 56.25, - -168.75 - ], - [ - 61.875, - -168.75 - ], - [ - 61.875, - -180 - ] - ] - }, - "value": 4 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -145.57611141353846, - 68.11608082149178 - ] - }, - "properties": { - "geohash": "bu", - "doc_count": 3, - "geohash_meta": { - "center": [ - 70.3125, - -140.625 - ], - "rectangle": [ - [ - 67.5, - -146.25 - ], - [ - 67.5, - -135 - ], - [ - 73.125, - -135 - ], - [ - 73.125, - -146.25 - ] - ] - }, - "value": 3 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -171.11272992566228, - 63.72657997068018 - ] - }, - "properties": { - "geohash": "b5", - "doc_count": 2, - "geohash_meta": { - "center": [ - 64.6875, - -174.375 - ], - "rectangle": [ - [ - 61.875, - -180 - ], - [ - 61.875, - -168.75 - ], - [ - 67.5, - -168.75 - ], - [ - 67.5, - -180 - ] - ] - }, - "value": 2 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -174.20635032467544, - 52.220348292030394 - ] - }, - "properties": { - "geohash": "b1", - "doc_count": 2, - "geohash_meta": { - "center": [ - 53.4375, - -174.375 - ], - "rectangle": [ - [ - 50.625, - -180 - ], - [ - 50.625, - -168.75 - ], - [ - 56.25, - -168.75 - ], - [ - 56.25, - -180 - ] - ] - }, - "value": 2 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -145.76861112378538, - 18.1244444148615 - ] - }, - "properties": { - "geohash": "8g", - "doc_count": 2, - "geohash_meta": { - "center": [ - 19.6875, - -140.625 - ], - "rectangle": [ - [ - 16.875, - -146.25 - ], - [ - 16.875, - -135 - ], - [ - 22.5, - -135 - ], - [ - 22.5, - -146.25 - ] - ] - }, - "value": 2 - } - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -123.75373472459614, - 39.26203776150942 - ] - }, - "properties": { - "geohash": "9n", - "doc_count": 1, - "geohash_meta": { - "center": [ - 36.5625, - -129.375 - ], - "rectangle": [ - [ - 33.75, - -135 - ], - [ - 33.75, - -123.75 - ], - [ - 39.375, - -123.75 - ], - [ - 39.375, - -135 - ] - ] - }, - "value": 1 - } - } - ] - }, - "meta": { - "min": 1, - "max": 715, - "geohashPrecision": 2, - "geohashGridDimensionsAtEquator": [ - 1252300, - 624100 - ] - } -} diff --git a/src/plugins/tile_map/public/__tests__/geohash_layer.js b/src/plugins/tile_map/public/__tests__/geohash_layer.js deleted file mode 100644 index 000a0e16dd16b..0000000000000 --- a/src/plugins/tile_map/public/__tests__/geohash_layer.js +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import { GeohashLayer } from '../geohash_layer'; -// import heatmapPng from './heatmap.png'; -import scaledCircleMarkersPng from './scaled_circle_markers.png'; -// import shadedCircleMarkersPng from './shadedCircleMarkers.png'; -import { ImageComparator } from 'test_utils/image_comparator'; -import GeoHashSampleData from './dummy_es_response.json'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { KibanaMap } from '../../../maps_legacy/public/map/kibana_map'; - -describe('geohash_layer', function () { - let domNode; - let expectCanvas; - let kibanaMap; - let imageComparator; - - function setupDOM() { - domNode = document.createElement('div'); - domNode.style.top = '0'; - domNode.style.left = '0'; - domNode.style.width = '512px'; - domNode.style.height = '512px'; - domNode.style.position = 'fixed'; - domNode.style['pointer-events'] = 'none'; - document.body.appendChild(domNode); - - expectCanvas = document.createElement('canvas'); - document.body.appendChild(expectCanvas); - } - - function teardownDOM() { - domNode.innerHTML = ''; - document.body.removeChild(domNode); - document.body.removeChild(expectCanvas); - } - - describe('GeohashGridLayer', function () { - beforeEach(async function () { - setupDOM(); - imageComparator = new ImageComparator(); - kibanaMap = new KibanaMap(domNode, { - minZoom: 1, - maxZoom: 10, - }); - kibanaMap.setZoomLevel(3); - kibanaMap.setCenter({ - lon: -100, - lat: 40, - }); - }); - - afterEach(function () { - // return; - kibanaMap.destroy(); - teardownDOM(); - imageComparator.destroy(); - }); - - [ - { - options: { mapType: 'Scaled Circle Markers', colorRamp: 'Yellow to Red' }, - expected: scaledCircleMarkersPng, - }, - // https://github.com/elastic/kibana/issues/19393 - // { - // options: { mapType: 'Shaded Circle Markers', colorRamp: 'Yellow to Red' }, - // expected: shadedCircleMarkersPng - // }, - // FAILING: https://github.com/elastic/kibana/issues/33323 - // { - // options: { - // mapType: 'Heatmap', - // heatmap: { - // heatClusterSize: '2' - // } - // }, - // expected: heatmapPng - // } - ].forEach(function (test) { - it(`${test.options.mapType} (may fail in dev env)`, async function () { - const geohashGridOptions = test.options; - const geohashLayer = new GeohashLayer( - GeoHashSampleData.featureCollection, - GeoHashSampleData.meta, - geohashGridOptions, - kibanaMap.getZoomLevel(), - kibanaMap - ); - kibanaMap.addLayer(geohashLayer); - - const elementList = domNode.querySelectorAll('canvas'); - expect(elementList.length).to.equal(1); - const canvas = elementList[0]; - - const mismatchedPixels = await imageComparator.compareImage(canvas, test.expected, 0.1); - expect(mismatchedPixels).to.be.lessThan(16); - }); - }); - - it('should not throw when fitting on empty-data layer', function () { - const geohashLayer = new GeohashLayer( - { - type: 'FeatureCollection', - features: [], - }, - {}, - { mapType: 'Scaled Circle Markers', colorRamp: 'Yellow to Red' }, - kibanaMap.getZoomLevel(), - kibanaMap - ); - kibanaMap.addLayer(geohashLayer); - - expect(() => { - kibanaMap.fitToData(); - }).to.not.throwException(); - }); - - it('should not throw when resizing to 0 on heatmap', function () { - const geohashGridOptions = { - mapType: 'Heatmap', - heatmap: { - heatClusterSize: '2', - }, - }; - - const geohashLayer = new GeohashLayer( - GeoHashSampleData.featureCollection, - GeoHashSampleData.meta, - geohashGridOptions, - kibanaMap.getZoomLevel(), - kibanaMap - ); - kibanaMap.addLayer(geohashLayer); - domNode.style.width = 0; - domNode.style.height = 0; - expect(() => { - kibanaMap.resize(); - }).to.not.throwException(); - }); - }); -}); diff --git a/src/plugins/tile_map/public/__tests__/heatmap.png b/src/plugins/tile_map/public/__tests__/heatmap.png deleted file mode 100644 index b355849c117669a114c679c4f30793a863e63aa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87025 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Λ@$hcZ?F3D+~o84oD&^_bppDOBflR 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≻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 Q&tU)pPgg&ebxsLQ03Wch;{X5v diff --git a/src/plugins/tile_map/public/__tests__/heatmap_raw.png b/src/plugins/tile_map/public/__tests__/heatmap_raw.png deleted file mode 100644 index 6737c9d0dc8073816f4566523d515995200b78ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16071 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

    m6%XZLoqh|8xrLCaZWO{LZm;Y*$ZrwUs2`n~Ls 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 diff --git a/src/plugins/tile_map/public/__tests__/initial.png b/src/plugins/tile_map/public/__tests__/initial.png deleted file mode 100644 index d108407c5838878f466470753eae908f218c0bff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14011 zcmeHu`9IrvyS~!J)U>Los-h3iptel3_O&h18EUDmN>D0vY_%pNWYp7^*xIVCmKdhA zVi{|!(N2Z2MNzv*MNw-S5wS#aLelg4e$VUt0p|xl_#w&XyddcBaSz_yQeIac5N*nZ;FN`<4v192M*S|{#5rGqa_SFe}W zH+LI**ZnH^%aNgfd)VE!^o+Bc`fMX*S(TjJ>D8aKkUuO5zulRb-I$*Z@24#E-%J+_ zb@yxx!}mTL8aMoDcN|iCQ#$}z9Zn|_X0J3X#j-HaPRC`^JSXVj3XxB zN@-t6c1kg)IkC58JB#aY!bG{x{%-R0nBLu9*3w8mTTer8Q+B>TM|)#a$Z^fB!DGN? zj@mJEBM#8o1fP3eWPV~d3eK7|-X)JASN=-FD)KBtZ=*>k%9;L)bCG1~UhfMUqoNts zN5JJz&z1!0YiLchu0EE=u&M9-dUBE*rWJicV^m=RysduVmsWuY?}291Bln`?+P+Qu zF1M9~`?$4wX4M9>b=eU;6C$Y(En{`=U1@d&al&ESzDJ2#(2rnF^;cwV-H4NA zf5@LRX70+CU+!tx?&$ZA`Mk0{!R{@6DQ?!Xl?GKueTZ(24ss$)pdUm3eQ@R)wU1Sv zj%w?65?Rrc-9(`Ubj!Py=QrYvC-!C?`I!UmG(8yrj&^xDC!xT~v&#uJ zql6#O@m=o8Tv2@4Sp#a9GmsixU9Bo>xoW|-lRkzTx4#}^ec;xY05%xU&F%Q5w1NhC zPp7>_h|x?(Jl?E*PShJn9=|2x6Fr{TxkhS$-4DA@wyVWW<4!Qs=X+_?lUxZP@=L2h zpk}IT30q9%ezc;Fes8v+Axav&d2Pv@dn8hR`mD>+x$KVRZF+Sz_;3>kcFLmB}s8ygV?cam0~ zolm5$$+qW*KlS=kuW$QZk%;yv?ITc}d)I%S+cgZ+b7ih zrLd@vGcakzWp8QgVR&AR3Sl#?rpp?0!FHn@^^?9+N2Dn9h|Zo5v;~K7x_F0}6mq}b zsIGLnIce+f$5pUVd@!pPXUw?XQol5((@+}Uus0wmk(#$EPg)i^;N*pqwRKqzq|3{R zo^b1dJL|ELD*5@PFZ1paaM5A?>770E6<)S(#3d*}A#s3wehm6Rl@wfTjZq*~?tEHm z9BZEU_z{rv0I0WpnOOh+t2ErYrSd(1w~X$UFtfapg||=R@j1 zlTsVX=gc#NA#a zS-fama=t}{)SZDrMf0?K(LS*Loj>NsXi(G0zAypiLot$CA&l)%^;;+g|7Pclzs1VL z$E1*+B3n0YBEx_lEQ=zizXqQ1oBdnbhsIo`uD=ohx*DCGd+b9)^#6-{szDK7Kj3a$ z{2$`PxJvgCB#ThW{tMc#6#@T5NFWZxJcX!9I z#Yqh@cJ0M)Wspl0YqydWI<|8#PXhmfSZ)AauL5+$rUUS-Vej_HD~*Kl@fPd?FNLj& z`?>%z>N1l_FzO53Ykl=4=dEJ*7W8j)iO%UeEapEf&E)vR;!u$ZVY4X*5MnJZIN0Lx z(uS@~szm7{D5FS3ji`jEK3|b6gjG-6_6etsMF-!fZo(S%9#4hwO#AN+cv0jjksFsPh1>10h`#HV~;CC6xn*A zBu)$lm;QA{%AG}${XqTt02}mM_~}%hV^{)w9Pu1k>+ufTv4@Bw!yA(-e5YUzWl^QW zZ70jsGpSgrFhw$T{)T#{Et{QXdGkOMAuEI=N-PHK zCFSm?uZ9f;1NyZEn4mX1#2M=I_aFKO-rwjOz=Lg>4-LBAjV5z4ol4GfG!ggn{3&#w zTK05&k-)5NMP4%8AwNW(o=@}q{LW+JR9~v7zHGwt_kWz1L>NBFyjpZIQ3=`E*V7-% z<}c@BU?uYP4iE!*g9{yz4z_a=YqJMMI!glEb{J;u&*e~*RP*iOSrOsdsG;>C(X}tP zdaco~l~HExtsHGnw^cW$Gt9)`JxbV@BG^8VNZ6kTx_*TJ!4I6In`h-flrGqT4mFk{ zF})7DDuoRt@r6(aRbr#Yxwb{(iBgxJS5X3(9wqZ0B}#6Ob$RJ>u37s|TC;z6&ud3J zI_$vHJbPYX0 ztH=dnroC)8WG}?C{y3)ChCu3ojz66p`}~Ja{hKI?26;NZVR8|l{RXbiqZMl3X>|>u z-2Fh2i`7|ej7N8Bp|%^sx7?(WsvXV3_^S7Y!4K!&pLZLHCpS`+jDxjGB(y-KRs-AwMFoT#`fhtV; zDD@84B7dGb`}HOegSst`Y6~<428HLgc}1#DF&tOmv&r82vvrz%N~u~!EoJE;j?uSA z#PLvhGTDM0Fqw&G#tkLF+%Gya5iQkPa&G5S*C!TZLN@87cx%vAR*Pzm01*uK8iq^D z%2F<)Iv$$RMvYjC)X!nlB(LvyT65^W^1;@?$uyYCQCeCUMb%g}0e$XEY zXk=Lw;p21py?)$Z(S1@ko=QlVA%4}(`E`)1T<;n$f86xc+Rm$n;*U)h@BF#4akJE# z5Ocn=LPc&ZCXB4%8?<*N(xP}V7iTb}aw~sCRlWj=F&2Dd<(>gfUKN_}mu-#M+a+y$ zT7Y7W>R8{N%eTtU_KBmTE)~ylEao_7dqK+xs;M? zs1+BTk-TA6XO;NKm+$@h_n=-$aR-I?hd)ej{BWUQ#Jxqd&B9R@dqUE2@ zoo82cRN1nH4_9wVp-R9*QL8hrkcgU3-$27D@Uf%5BZBYjKQ zoZ9{3d^`uilt3tPS=;aBDxu+7cOSfdbn$I`C94|97YEvLdT2Ejxk z$gH>4$%Olmex3>sigL19PK)LsXS)FNG5^*pPc2c;@6%aLWmHESkD42N6a}|kwJ15)wsXfa z*9b9$9^VQJTz_0byPRj2y{ezmB6@)4KMp3q98mSpWyo+QyQq20Nart)jR`tMe>Ri- z^vTnxRB1r;HuA!n%=H6BCuqjjpR38W_I5l$Fb1o8&Ajgc;5KS|ybZAP$$x0Os?WOa z0(x;=M|*7l*>Rm#ojmJG1qON!!0wc{#RVu&mgb6^Q5X6k+ngdL;3{gST9uO$lug>W z$!6g%6PHBixhYPz*#M22SEN7)wEW@19&5PWN`un@L z2W~K@|4W9Y$Q*;E+`S}MKD6^-K`pyj^Vx|5+s1*3aEVhz)*o2z6Un|C*a%VDd=;d< zxu2{sZ*3}u0VK?+O}8T`6Y(Jn^0sbEf;|5v*jr~}j&iQEcOWzsZbe<`wkUPES{{#Y zmM~*~{PNfbLy3?^dBwrWpSzdNS%Pi-b!FxN*xTI-RIPm>A_GbpcV&bk+Eg+qs^ovj za!(|nodYzvj^ow_^*+8=cZ63Hsv`BhwwNHXeoh|2#!NYf2rN zpm7Jom}^Br2)81vGf0e+AuHtjp8t^cLBx0|6-EKiKxP+4kZ0?;G|m(K>I-bf4uq1P z&yST4?-0#^)9xEd86x1$?y7uhb#7KbOwj^v@|9Pcrj#kev@BH#CvL0mGGeHM`_t#W zscsH)5#?EnRhk|%-szwcJB0z9k|yLzxAoMbXwCR%#s!`g5aXA=yk8}`*>4zVx~70z zYW=2hbp=HS3e^|r2ovG?lN>Oe)_9?AM1+<$3Wn2Qk$pVc&>e(f* zXClFSH)chMo!#^84|-XJz)#}Ah>$0vovEjc^w%evQ#3n;Q%xHq6ez1o+_L(ppr!e~ zuC_^l0ZE|H;fZN)eaFoo*Wj3I(9~0ElSWNJx7@?pU~t_{+K}^7pA7AU2)iU{OTwui zJ~`xYIft-pKey6VROu=yf{gNMFDap2O#Lo0x#jzc_GPiBXNN%2;ymnHs_a9OjSL_@ z0#T6L(7plor={vPiK;3Q>R4(1<7V|$mnKa5g0Xfra=4;O+fh@#f=!ISRc?^03X5=2i3`+if`Y^E)`$cTNQF7l?}AMc(t6n;&Z9xao*tD1j9PgNEN5&!Hs2JW4y! zJG=en)OL@eg%``m9dn1h0k|tIK6^HyE8F^oEyd{!Ixjc=Zlb~;pawywZWR?O1-9N} zl~QUozI^eLHL6~2s#a}-nYXtE%xyDFFS?Bz!oF3rX#Gp|mL%iNi6z6%r|0$}!p($@ zxm@6j)jjJQ3RJ=Ak9}qGrh+GCLwQ&vtFL_TE`XmZbbl;f=9$DJaL6*}1czjY$t= zg=M(5PB6^o;O)$wHwd4Q*l|!hdU}SxM%uu#Rr6q89qs*!NO{o8)uTR&glziBj=`Z` z2B%B1ST1K2Y*8Fd(Hk*X%dlMNKnm4!NhU4f3kPDf_CF2bFzoeE%TGfr%~so$9md=i z{)z}D&~rMT?ANCRa2;;;9ev$uF}-oUF3o8dDoV@t{cr12x-UBP#o@mTmxEF=W-%q9 zqO?e}QG#|imC@Ic+>T+aC2##2PU=1BXIsSh%;8vjiOKUE6%7irJnZK$; z@a8$TxLs38m6(r7>p6Y#x7HGM(+jvAi6i`+2GszkK^3|#%wL+5)TUhs>rXh=(-r_i zREku+9p3dMXgwR1=awjfwH5`l_%d)}lq^rNO^C-P9D8M&f+q(#$uM$0N$L~|r9p{7YP>bKojncV&RR+_k=oE^GRaz>;3-JrWc_rq%2RA<+u zjB6U3(TUr=IO^+Dq_yS6 z*7dki*Sf|Rk<0`&DNqLp%^Fk7F}8ue-S5s#Az9V0;ZCaVIOxjO9fn1-yIUm8*EiT! z41JrhlwYuY;MPp^_&Eif0Byd!jnjxT%DW4MZ&^q^$xs7FZK1+5*K{;T6wxt|J&x}p zYEP|yc@#$0y3D1mjZbX7SWTB*wtxWbNk?ibv?N5iX2;5z(>sRjHPyKwA>%LNN{%=B zP%u69l&$9QWYFwMk}ih!uRyH>ET5(9LxKm|5-w0@me4&AgBO1@dK41JCp3-Q0`TiX zn|T+Ojo0-5f-TptE{oTMosLL5DE4EUglfyPhNa1tG=~xmi62j=1i&cb#`Mgret&pi zA8v0~V(MYfe1fsyxBr%rx4(O8J^uV9lP#fs-e9XnMSY4mITVUusK7JZ>Vw!J?kx1; z%)&NLM4ecBdASCsEIR_V!dH*8TN-!!Ezv*bcAz<6dv(9(rtUbGzkBh*{} z``jPg!6rTYDCeI0`8)!hDXP19f{*W9#QtvqvZRjS{R3TFmAMd_6nG!Omw9VgfB!PR zH<`0d?FzSaE@>`(tp43|L?c^~*915^58|vRuV-@f?m3&@y9%_U-`&U*=R5w;*(HbX8m=a! z1W`+i<^!t1n$HZzfx(s4@+x=OagWFU?l*9MC@;{*X-;ZCtV?2}N zj)O$kj5DvB`Wxu3a{A=KyZd*joQ|IU&%t7!r^Ib~HF{YyyITIrO;Sz(LrRN)A(+_d z9z!2a7pYqG!Up1uK7^N>9zavgIcRmlI{MsphlKXa1%OKvW1r4%SgZ95?7(mbf>FdW zB+@4fo4ya-CD|kFR6VpRvbt*#zmgr$Umh7iV$GqPpWJgv*gsqKSv* z!5VdUzbzAF6#2nN%Q|L3^+P#t*+B`L-ogHF?8yR-gzHYXU{%R+!+=B$89>to?DjhH z|DSJ2gU6U|4r96(v-7wx{`0E|ut(XdhZpqAoETg#@rmGKdP(I7UKOLG#v}HhoB+Sh z%^&BSMmi;=8wKg^+BDK7vFXkYn{GHa zkNW=J_x~H`!})Z^IOiSX@x!xSu6wSz=6$VeUURNHNKsz$KIS7#5D0W%>dk9q5D091 z_XqtR@XHB{Y%mB!4U&5O>aDZx&Mcby+ldr*#C$F1NN62O9(COY1sz=??R!HN%krSc zB%UN+17s<#`k!t|1&7J)L5ERtCyhKmJMUTGIc^oDppYbng%OU@;Wd7KUHV!Hi6*Qk z^o8BvrFM`Fdc^ZYSCd^Up|ooYi(SEWuclkEUE%6vS|}ANlL!)~qBoc@-J1=?mn~Bt zk1!qd_ecHrol<}Q8iZ>97}_e!7^F}7KO_7euK#N=;ZP6=i!+7J=lws^{qsAqaWeA1 zMvE|lS^Dgw(EVTic_Ii^J>CZAe@3UEmvD?qJtn>P_xXf?0lfb;;J+UDuLu6Wl!I5|AQR*)<|MR#?!h9@0d}e3W;R`Vx8*S9hm;q z@^4v33Q+iqS~w`!D)AmQjuJ)&qM}PH`-b83TTQo!(&2tCt;5f~j%yp#RM-#z-~It4 zWGvE5j_JDW1;*gat6nkAoV_NMBH_tW^TfP7;k5FG9j$w*Smbf}L*jiEpO=`d z?9NWYdF|!yN@G^TfKSM~hp?H1? zv4-%FzLjruHaT&(Rxe&kc_x@4nlZ?Qep@Jl2KIl__re_BD;xLrQX`W!1t!eTN3O(> z@%Au8mZI;q|G(k}TQ%P7e7tGMH>R!5mc9L;M0Y?*H|`e?4&LfpTg(gWkMcVPeGqQynQLRXep^7cTVKGOXV`3WVA!>+PrE zO;82@YF5dnDi;w{T7^mTZFVt`7@yl%xSXFBs#EUrAA>;zCyTI$UsL4QzbLf@P!10C z6gW9m{yU1Hl(=!p{lPquc#IMbEXCHUq9WCkuYWQyk7rmZBv7v3Gso{x`tM){CIlya{|irjDC+U3Oz*YSR+}G?k?=cp z#>@l*xFfV_$u>+(MR*G4J=yH3gwMx%1arh#F23BZ#da~6{m{RPo~R)ihh`Q?x0 zgn_calOq$ZXj%J*}q( zk~t_Iwf$KP>AO42vpw&Enk%7$n=+Bt<20r9_TPiaZxKQI{P#MbCI5Kz_&;OAule6& zsny!~ufu;E6YpBc5fT)Zz|ARaMRn&&>c6g>5x;x7{C&7mHr~O!#C-=a&5S(dS8;TfU%=&YvBEmJ|2a(t~$ks4Eoc-Qhh!zm)Hhljtry&pZaqQuR7!HA4 zZ!x}q-0cw@e55}~{`j}YsdoSq{d9U^YKJ&r?XSf_f7x2R2)DwqN?zB zd(@tekiT@_*xxDWb9FkM*%0Us(s%k3#kjyA7j&Xe0Sq}9!8wo&ktv;QDK zi(Fite_$i%9u#b%UrBPZtOsw@YB55ylxL*Fa?j`&u2 zU?(TP_mz8B7XdVgfy;QV@2bJWiO+C-E_kMDyo%NCU99k?Mu@<_!d(Ol*wzZ`K-k^| zzDl=O{q^;8CmvXqY@EtXsGg}m)2p372xE2m-E-IL)7_zSV#o`8Edxw%6_|2zWe zGXT?^>aD!me<9)scy(o)Yu|tP^9W2*;G{@s!5>&u{(~9mdcdp~{r73J{@@H$A6OE0 ztTj&D-&wB#Y#O!tMEdYAs@wyh*SN&juIBHo8*0F;o_1~Be*umo9>~l;(%ZVNR1D1eUzhyX zCI5en5@LPGte#|FB?C666!uq42@wMewK%Y(U$6=rq`WcO+87pMifheek^1|!wLZju zjgCpGs6UGDE+uj$B6?znJO8n?%ItP(x1_7?HpTl#?3eizz0e8l?)KkDp2!ze=Ps7+ zg&npdFj?HvOPc)--^sJJf{M`mARCOrCqYuI#^qDr#nqU;qW#_syqg-S7HsZ#50YasRLC<}h_IiI9ucA7wCe{}L1zyK&I z00^OxCgBI!(6#TGn$ig=35kwIOMx~yf)HNkt!_mA{bLQ$z(kkr8`psTXuG!K_(F5c z8v=a2UrQvxOJ$lYC%g4QIQef?RVHdsJYSl)ObPpKlM03-sCID2JX4GZ{NI})-)&{8_&@x$bE=HV-Xz8F4SN<=x_ZfC#UovvN}gu zARJ7HhyxJHOR9`Q2g^d!zxY)LyRmE^yFy^d>6VeFmbpydz~|L-Ma1CY#8O-xWeG`3 zwT9y$F({JyWywPerFPXlmBwUvV3@rA)vo@w&-X!K$ z=EZE{k_@oGr7ZU1cA4J#{%~_XPYq2?&RI7+@75ZedT&7(XaO7rktup@5xcV{c=x_U(+v4;K0v!-83>WPV3OFg*ceaP)I zyv!#S$Jt?uX>F2o83Uk8fY-eM9*~SyM?6_qr|$>KHh(3pKaosil<$U*$nJ1P0uT1H zIqL^Zk^iccPbe17DIcvU+{sG#a<+JNd=_2|_q(`a%|E!6dzRqIa|zkxcMmd}maI3< zW1FzEQ;WT=XNUVPX$u|T`0-tS1EKEHL0dx)MXSM74SdTwIlZ;ek3qW^!6UmHfzOiq z$f#Uh*F_aR&()w2JF~Qq?OWzNwDVx;dwKwaP0uIRXYL#>8n;T$Eyh0Ul!0^uJg2<7-%>roVmr@A zEh{VQw$$47CRGbfxh~)Rqoib)6`*Cg!J?5qX$G%T@3-#wD8Q|)YFB=`obpLbmzilz z=^2YI@E=al>@dKP+u{A-Zp>&eg^a$0HH$&t)F; z1fWJU?lyXS^-@S0c0^{H_OcFs`U`EnaHf8C^zg`*oXTaJo*?uy_@6RDx(t$+V2`^K zMkg~g<2|x}^1~6U1tTx)s=N!)G)|Iy|6HiAUk9QWW_lCYJIz(m-}7D3yplEEe;vDS zLykX(c@TG~$`oJuCwfI91m#7*UUe)UnzgV?*{Fl2EU4ZZ1zq|dIpC;?Vrsk_@BD+@DTvy0u6!ZvQW z*|nKy7jBx_;`XW>Zv?=Dif-%UP)2@WXO;Cf3Vu`s+@~Sp~~3Ss^c3)@tb`o z+~S#X8tqq)&m&LAf1xV(_Ch_U)}N0k7t_--*t0$^Xe4nit;^o~T6fU|6CTu1>fC;X z&WIR)i7E_!~@>?99!t-w{5@Uik2hy~gOtcVLTgeI<8hE;hYP&~JzJh6L88}k1 z43dbB^=UC)qH-TB9G}efo=5vhO%+%g7g-L+jORNo!|Rbu^RFiKnqxC9TfSN9vgvF! zNH%FV2|FuYH0QkWSZQ=P9-Bu#C_k;o%Cmfp3%R{J#UieXdx`fL5qJ6wTkc8uYc0O| zJ!8I1zxJ@H!JUDc`P!?)?mO|rg?BY@mu6uuoiArTy$1kNw+i-^zxdA-Y-_)(>5%-u zdp0T2+>q$*#LR@lysG&53Y1mlU|!)da=o+Xp%s#IdxZmOtTc0j(hBu29LEC7PZO(6 z@&-!dT zUPccGG>ZkEauN!R8ty##Uo;yXX=DDDl>U(xFL*(X3j`-PuQ-|`8%pa}czMPRT>NFp;@|mJOJ2&s*khizD zN&NXTQ1RoGFXA21LaE~_AYP(>!`ppb3<&;Or#du}JB$ICHo9-lzq)ixii#MbzwV*k zJAFrT)oBoPbA+sN*em#RM$a*hgolrBF10*!hf07qwd;(n#6k6jtkkB|&P4WSVU3D8 ze-HBkY`*dznv<7%8R-EiJ`DQFrGBrsDgV#CGH{u4qgrpe`kLl!d!8w_9 z@{SUVW36gKswMj-QWygl@A6TEs<+nj^QWX2hx2YmTj1OtCqsh*9e(bL>gi?Q$HYPheW_s?5#bNc zRDi@#_~jJwU6PlAX-#04!qC}PQdN*z$Iyv?9f2#GGE#ZEi#$BxIFg}HpMBm-5Lb+{!twLdSXqss{WFkoXpU1w zm1WF7o5?wDFHT%Ps#1J_)=vGegtl-4wnGY`a8?9)sHPW#%ILn(*9p154m zp-wiTTF*4AQocgkyVE+Xx;UQzk0%*ogW>2Cd&^>c0CzW?d%?P0hH;j!ghANPkrj~6 zGEr=2#Gbv{tbmTGy7MlS)uc<*-pYc$f^?n0&6nsrRGn=m8+^n-I=sBX@dCj77vKid zfKEZuMq=gS;Y4x?bWoe*ee0t5Nur}0RWBxcH_ruTlCZ8t_&B=f) z@tp-9IqwQCxNb$qz>@gr68Fhptk{9q690oj|2BNK1HyyoOt&R<5 z`-V7*&FFC{7t(Bqi|YkeSBT>S4ss|y63bT+t5fwX{jI>d^Ebr=Y%+}6!@I%+(3cnm z$cozFda&hM!kX1R zl4p0)1gTa!p0hNlIm~}b2qo8KBywSNIoG%8(!R z0wdcM65BW3B0Zi@WvEcC67y^2j z?(=Du<*bI7i137GhXYE0gvyONLjvb{&An~_Me=IhIL_2Tcke*ir$udz3ijoL@9N_h zunInOBiPx8(KgQHj(Lo1Zf!{I{g57X zT8xcS27!HeZ=C+Y?gy}?^O!YMRu4Bbbx^J-p(d55>;8|gEyy$LiCK;vuXsS>qD3z8Q*91tPUiRih;z*rK2!pX!ZGUR`yq|N`Ck|H)AQ-zk+Tn_1?kU*zI z1m;Gz#odS%X(3IUZ)#rPCzxDsdf=-CjJISLB0HM7ot8bOxi+J+<)Jx=&p1j8ZZT>> zH>P4+fh`Jb`MB2*ZVXd&>$i6awTc1w;Jgx~bfKhwXb>6&ZU!r^d>a2)T5*@(TDQ-Q zs0MvG+iE!0@k@N~l@z-m171SIFPqnEEZ}b3Npr>s{D^Trd*0zJx2Fz^!e9tIE#!#k zZ-WNwx07uFksp|aZ``q4P%iP06wJ zj!{UdCf|!d$9mce*TZ99h9uU-rLS8M(Li~kgIv^YM0Q5{CmhFRm>~Bo6zAb2E_cE8H9q^UvM*yCgq!Q`mc@+gX%e$vG+!J$f(>iX zEfrRr3$*T5 z2Ht-Jsdu$MHT*4CRAr$b_$I$4tncYq1PI}bfpCQKHxz!>fZE|ZzsJ9TZ*N91Hg&=R ztJ-O6UPyuFr*N)@CQh82_V2Vs_VxEKmjKDY6Z|CLRi=t)ZeqRdVEG)j{;0u=$5%}&yI?T0V?oQDtt=K1$Z&fLh_&;8?ROsf)2|g?S-%>#f&$!1h zWk3^}YhBHc;(gT1%xgT3cYbFj+)LV7kq$i*XKuDPHrfwuC<=qU-8YaIOce%>S0|IE zO(|qv%NApF3oXfL&82EVA{eV$l&p|Ct*zv&h{D_`u{f94bWdq-t>K~4e=6+%QFL*| zzgjcu_9rx1HeBK}mhCzH$m{!?@>ffUb!QxoJHjJLOPl3-5ift7b%X|;uVUEj>o)dT znOg=;xs(V{VcxjhXkIC^tM7(5vap!dZg_DJ+Mpf+xY6*zzs&ye1r_!YZQnF&rDP)7 z{{CymF$a36nh&6G$1_9v#Ued3aig|;e(e=rYqy4lN{>aLa5SS#k_VGcnw;I$+2&`& z?N{#lD3X$6=oliX?5@TkyTa}k_T~NKR|{n+X%>9$!hv!!B}$j<-99$8m&*9jt`$-B z_3+NM?3yxKA{P)>KYORoiZ` zx{j1C@#2~^#7%b%KG|<^T==DbI(X9x1h|ItI{V|S`Ld5&5qEtO0mkz49yv&!C596( zR8_r%0D4}%i)MX@)wet+(Av;wc}gos^NbI_dCdLvVf#}y8`SSfCbo54o{ zRgm$%yzw}$n02F2LoqGpzcRh&zfClA*U2Wss@PJ z0O~A;h0fPo2@CC=nTIO2do`gg;RnGDCnr^wcJE@?>+}#XwRq8`uu?He%HDyEQS0XA zz2o(lm2oN&se-%`m;w)j^vpi#gi5hNuEo%>g_1_CzUXoNC@K(|Ki%oD6O+S_UM~nx zi-`32IR#&@Q#+410(?!w>)rMw(C*v~D>HRXOv}0QK_LTZ`E%)h?aA3V%IfArQv4C3 zGpEdtby!;$`1&pi{mu=g08x6#e_Ka>?SWNZ)~Eu5pPULl>6_6rAYPN7rZ5cK)WmO_ z)~jz6tgA3MeL-|~)4J4ssn@c{)}n%mnEpxIMIpVH;@GB@qcxac|1PcJb|n(yDdOC( zBV&H07G2%Yr;KNW9p(pJ22XO}CrFM)S`QXSTt}|ERVtxr?M2t{y#t3xL#n~EdJhne zESbir<{owRVUk+aMMNp|-=SF$O3vvBmOCx%>tG;he{e*+&J)`%QwCdi zJVmeU8iA74sGC3bqxlrwo8nsAm+Dk=AnLeL@ z%c!ydS`djbiTlR@w_bX^wy`P;*t?Us1iZ6>D~Aj{R2>BpOVB(UlIKqTe#$@^Y6IEl zAFYbQWe#20jaI+H2S(t~R*}%tajsfziFCgy&vYPuQGqoCyw&f;$5w-=+-S3jAxZSH z`b%mN`q?7{ciayR+$As@68Jy10w+kLTLtWPwl1&PlQnm#JtIhTDad7ezl+j;<+RPg zaagyELVfS_6?nrlj;)RZ7x@G&^E$Pv7MFyvIy379DSN9OWGdA-ple$WNTueUw>n?3 zm6%~vAu~PVw&)wagh#kk4^(<^MkMoc5sUo1GUz*S`@(06n58Ez1_k)vC$%+x(+r8b zexR&+>?dTx_U^t41OqE%F|KmhJxB(Z1m0^ZEgVv(1Z%CIeh}~HgauI@=3q_mZ{c%^ zarvZ)rrq%!Dy?_0{L&p`WtIu>Vz>_A7#@arS9P-x+H~Vnz>iM0W#Q(sl9B-r z^OEs`LV7UTYS zGupW1^^J|i%{-HfwIvQzFeocm|JM|@8QrDt36!T~!#8K%qGuvw0 z459&w_)6_e)lZ1TZtkWUF0!_7Pp6IBiDL0ut5r#xl96U27NmzGk+ws705BbKU3uP2 zH*^4Y+%p1|pL|!XcZ(&ZnjhhR@_nk2*}JOlwlcf3eJwWjEJQ624U=X^`K#aIL>oKS zn7@qeACC5r;INlqY02#fePkSlUw)|X(u9|3JjXYs5MhYZAzqJDrJG~zP*J63lFkm3 zn2Y);I8TY>$_vo+_glh5pL=|s;Z_y{x-6x`DTT&GsQYQgyO8hsXC?gP&#IG~q?pv7S+RZ$4XiUtuzjuitCaWpo+=In$0Y6Na*{zK zwRdTQN`$K$GnHFBjdgxYnT=@cSjpBN7XHZ>lz0e!9*NoZt8rd6loe#A5HWi@wtFb{ z#qTT?hJb7>4mzZqu3T)FX0xdWyf`;@?dZsK=^ljXPf1znC7AKEDn7l15Qr|+WG*>> zYg(Bn82C+@#FgC*3|;re{M#qb#&xBBa-GJ?!D3}5l0MPBsIF}PrDOia@}rqN#K$YO znYejJN;rduE1m@YCj$hb(xVT|PCVAH`GwYnM32Nl=^weM^lD?2C6d}Ffg-__T?ZylQ=Ke_WGLmGr2lE6Hcjf3Ivx^K?9i*0iKMlAGH2C^>58_=b=pnIqO z3j-R;C1%4Vwm}x(vrHBJZ;zjeVulXML0=KS zjP25*sWl~erIjS_9s|m^1D8cOFE7J+XM24nv*=d(@O?e+*FVAgXBcL`9m~fOrB_WA~iSi0MPhtt*Zjc_kZzX2p{)5Vj z2(0%2T09bIZASNe@E(MK(Z<1)!oq_d@k@E(yZ+Ip6qTPyIL6Whes{mf(l7h=i5%*x zsc5^|E>oFQZE?F!q8GlkegCJ{j20dZ5U;R;YOq(Z&28UFNI%YZ_2 zsFF}#DuPol{c%7pM^3_+7qNX zoD2O)8q~*koshotFO&nyjZ|M{WOjos-SeLItQD~^hmDomY7?USL&c!#BqgFC8G8NU z@v|NgQA_Mh*xoU|J3pV{$M?NM?`lcB#lYLL&@Ei=td_te4@K$`z#?&1f7%c3T53cM ziC^$;A8N_SJf|BU(9k%s_r(rtOBZ>AT0sE@vD9j$A3LHEpnj*t%m#LVe=&I1_YwSt z6G?j%^Es#^LvvX8o9Rw680oIK`K#Egzz+MhDNrZv# z<#|_K$5#2amm~!wBPr&B*7+e=+E0B{0>F^FvH_1)70`D0+S}WaQ3@Q5`h^A}JLSQh zyVswggAX;bYLphPJQT;=Ng})H2nZ6Nb9G97e`_TyG2A( zh?H=cGx-S7kKYj!DVJt(!ouZcSS>bT2c%EGNr9477s8Ym9OUVM3X~HNs7+*LsDK9Q zgYs$amFwE=t>&{jL1HDRsj{5Wk?`=_J#%qT@di9xnMR)&x(5<4^B+m@_hr_2QZJA zE?;W?fDyBhyj@r(UHI&xeXJF+d8j1|^Pgu3q{YP0>a(LrllH4uVh$JVg1^Ly zF~vx+ABRSBoaq?QMqXtpRyc{m5 zvbcSZ%7e6UG-HswYnCLC3eLa>w&$tKNj?_D36enpRZ(InZC{PLu1J?1GEYAHOU|N%}Ku+$YhB+>AWP3|<ukM{T_7i`z~QpQ?fhc71E`}CAS(vyY#aPCTr}kq(8tc{q149^Mrnxfy}aTunSEdI zKK~P=G4BFTk|=z9i$;96DT9L8qRI&vJbYuje}W*1ZuYhx986vZNW(*h+K~W;uCaMncHbIIJ8>57wH90$04cu7Eo36Uw_2;(__$ zSvw`UGqNQ{fQ^|g6W3WPDt4rZkyZPz@K4&90XTSAy`y+mvmBr>i!DzYaY-sH zJAA5!PYJv?`P!9`A~})89B0`jyl&3r-^#^(`PxX`)r3)V_3I?NqdPz(!7_);v@6c>4j>);+@{LlG@t8lnk@@S^JK=c|N z6oF>gwx_FE2aY%QD#kT>` zWlHrW$vv4TL{CcHTU;A5oscb&t%#P|<^t`)B;Ki&QWnhrOJQXCLgr<@9fPq@DNCn{ zD_J*B#pt@^@W?@|C^I(=rD-L?VE{;zBtVB)ovXVtQnFihpQlIl4DD33ry_#|KuK#P zhOZO`*Y^q0D}WlV2v)g=4tfLX)m!i_-+SfxtSJwIy>lUH1>~aIv6;&uh>RgBf+_-e zerNOCmB(}0K;SV-6+~z!hQgE|UGCcyVQp2xq3(c;Fi?Mvx@KcV z`F?J$_%bs43u!<5OOKzJgZF*!4E|9jr-NZCW59zNj!PbIYt|RvN7)#?v?&r!QO}2H z_3Lah4jNvpis|I<<>>ylr2SEPudZR3z+F>be|}#q>(Qg)@AZV(p7yK*Zd)XM%N0b| zsMb8lQVtmn(QiW-;8^qf^hnMqo_3KlVj6EQoJmIpQAbZtng-H8A&6d>Z6nJgj7oLj z%(685os$`~5k@9QW(XtMf0NgK7QgU_T&acN0T7R_T9wO;1o!ibhB}$_kyi{(oc8Q; zalk#wQ}_qgYw0}kK2d=!JYd?H(#H_q(O{ti$)&1YHW!fxJ(7014xVLIF~YE8HL`zc zh;%KmrD8|75qY496rh-bwU9#(t#-97V(cPD5>}*c5=6Q_Ikgw}Qh@FKd&IwFr3!>gMF6oi3S_9z-l0w08A zDejdcl`JP07BY}D!k#XJx-+dMSeB7d*|rlU)@Bp{f^W;v><0isBSr5(_rWHcFTcmj zN;PFbXUv!lJ1dxL8Xx1LL$l^VwJ9pySRS2yrI)h}WVOEn-w}B4-^`s|y$bAk+pcxp z$dFWRI6iJ`E)sGr)?LJ&(0FdC8OmMot`|^}9(tZ9mVKBXaIc>&wYhN>*pw3x00_?A z3Cg5V1)QM5$XFL>bJkAllrBfv`||?^QPgi@kp`iToq=vG+eh zVt$$iv<=^xodmhZWAc za1&+djr*qIp)yM({`NtqtiYGVnf$4^s!zhzi=D^q9$h%{_+Xj!La|ce>67n;q6?@< z0^GnU5}$r%Ijmx30OUyU*S};ju1W~c!nrMHHj_1=m>30#LCFz>fkl<;qSq=kUnzdL zi-4G`k@FjaOnUJJ^1xORWL#UO^G7UcyNnm|w9Da|G3)v??cRyUrO}ps+@ci-^ zylcz*_4M>=73s~D{f+Bw^UN;12J5d%xpPu=-z&A6Om&nm{icr48Kws(2H!roKRS{9 zzJ#rFgL2|ia?&``1iK8x>)5zJE7qPJ4?YM8sD2si!~wUhLvzjt1qJMo%QHkN6W#8MG5lW8o02=P# zCxwR-+g%34h)>v=n1>u3Ooxk}Pv!!!YT+9!vp6gb^QEabE;NXBp4a{3y`-}?=7yHy z>s87Ndjb@_@GeVDA2^6mbZYT$FFN2GG=OpUr`cZ@g$1cZJ_7hb zT@ySnd~d1(WgZ#fE^6U^xRLxIXRq2SyGnR%zelCb(vmgE^^ywfriXtzh#asdGFm2l z1qZCHf3iE;+Nj;x-6E!Ne`oYIPndDYub0XsRlv#77bmXQSrc3=D|*}Ls{Y^>Bs3n| z>uk)A$ZNi$LJ5AW??!nqrsHvmQ;=X-?R|=Ij~exKP`MC_w1D8AE)X&Qk9EciLu`xB zU?%{aJ6#^^gJ+^Pcb|+C$ID5{QYP`cHt0Et|KRa-{$O|*mgTCYU-jcsr>Oe40?Oju zCB4v0Peuv4m*8#Zs;xhcihYBAGcD$D`22%RrTKZ70@s^r&AJKZiaR~A?@CUzCD_GW ziD3WMuM5e)5g-O73N&ce!bqPCJe_DxV`cy9i|izYe+9hE?$0vs-;NHw&;8mKkaPYW zWE0?VVefG=#d#k_>3v&^ex`}%zdXTK#li{ys+=NVa=~(IVbElLi7d)=xnATTw{M>A z`7typ{t{!P&G@P^s5W4Bp99nPugwd&P_5t}v3Y%|=g{;$xQ~A}dPvuZY6k&Bl4mv5D zciY1^c|eiI`wTPj z0y$n0OnxGn1Z-X;3jm{0<-MiXVNfkVV33>8$v~s(o1!2f`?ZLr zt3#jZrlHP_QyL|7kg?^Eb6YF+_<3GOZ3}o*tN_U&5uO-EHke-QCTlMGZpSgyk%$`XsdM8VbMD7nQC`7+8vV#Qyxi z2LCcZA5nBXPvWGD)3Q8@2`NTjQ2WzuBPcW+fUK~zHN-c0A-#|fG#LrKSRKw4hk7A9 z+u|t?9s$xog#5wit2=1`kT8%D5*Ub6&yTVFiquPYBA9zHFSH)xE;GQq3IX+PZtgp1 zctmgE6R=taVa%pY*L(GINy^%l)1LHv&pxWFBZfCp=X^OkUxsqis;XUTa!NmAcc@Fo zt?e?cv~P|xahf!oy&bT4?lqLlH^HhNaEmD!@_6ACB*ahYamq+LUL3MBw`=n|lYZ_k z90N+j@>iqLe@D%RNo~kr>vQqL1MO+08rnzIZlv$toTSS}RD^*jcR2V(JiNsm$?{1U z&O$CzwEB{*Lvw@GbBvr0gI!m~u0?B2Z8o!}^Syk2oid(BXS1TzOitZG49=yF&#YD|XVI%iAdWrHOO-|TvPl@y2lvvac(?wkNnx~7R5D=RsTA3hb zp8}d7`bsWz4yFBtyr`q1Zj-Qg;yzbJ4ihv6_W@9cP{`HiBt*OciV~8t0!$-!vf&QY z0+o~n@(Ofsj{Fc6DOn9-_fCIWfSQh7NwUuCM;ABN(hpy9P8748vdEnY9lVd$v_LNy zElPVS{EN;W{k=;ybQTim)?8pd#b+T;9oe&!Qu4Od$cdpu8VJ#MXrg|^*J~x}nLAz8 z?cPIS;En_dU^(HW#vO`nSN$*%$&^!~8?vYHoE|>B@T1;ZPJy3!Q zdfWceb!v=4!Cb_==ZQAOs?Q_(e?*y!a*rx;q^!HfTIp=wfpn~fYCf+jnGVzF#}%i+ z3(BjW(LT!&1x)kANBWZ)l3;PDA$UoZ;I+Y1{H^Da>PaZ(A(D*q0zWWL&hkwMO#e;N z-IXGP@HrB5ycTK57Y*-wt$YmnHa61~BZ04}k~#d)(ti{mHHZEYTL`fNnrygyJO%I{ zMc|fcoyMe@jDhxR!xPmP$12qF(%pX3kS_(eBuv~@G7$Yc>X6NK`8*Ul{!7IRw|np- za+PML)$Z(sjoqHmegJUe17&s9s?Gb-CLI^aPzQ<$bR&9yCt2Eh{zVZe4xgyM=9g8} zu6A7a`S?*R;5$Xiv&s@9ZAtSw5IMfO3HY5Ci2T^lS%~`>MZfOem9*QK>Ay5dKJ=5b zw;khMnN^JS{Ld2Pp2G~@)njr7sMzr8q-k@)2xSg!R5xePBr^#|MPljHIKJC|w6^x(zv^gGxStN*>>P6N-$7ON}9_NYWX}7o#h2`NpkK3C z_x1h}ts&~e^J$M^d?uKP6?A>wBB@uwGJf=2nsQPKTe9-u+a>B*Z|y2-&DrX`!o%gG zXXoD64Nv0FzO~|Xs&dHe_%_K_H+Jia^kOs`zzj#1WQQAFe#HZQinhVU}k31>IQoclsBdU0OTu@^cTz zZD8=CAF;#%l}&T8wyR~VS%rn110UXn^Q3IuUh^+ZxN^B@JqS=$4euS0&r9GaRrpS9 zUN6(hqy14fK&FyU`+2t5SDlFYO3^+8eE2X!$ERmc;LjNLxy`RB_?&rjva_FPDYZv- zz0HM>{sg|1%qHaG5uo%@Drk{`XAer)Hmc>$$6 zZtzv_a@eE63@8OkRT0}6yNvyjVOnCW-WtZx|IxEAG}HxP)a^rzQsXg1Mpt?H^KHS+ zy^FAH-(WFG2AQBtpsRfM{A@h>MAW4(WtZB8EFyJ}x{=HhwzFg1uTx_ELFAxve>U20 z&2%)@kD|zB?qXj6lT-tM^vLqT(o5Ba#$Tw-rRtf&*U+&mTZKnJCyq-~+wgvl~OWkPr4u_Fm^HM%ZC|%O&bz?ND z<6a$4RqmAMrczE%1X6?eiit~R%W2btFy3gNOuQNc+WP)6W9~6X55#u_ScuQx)`LwDFxeCb5 zr&ScGl1N#1cj`4edFQ;bYDnUL#rAiRfCDDkaOqw-gi<<3$4wH6;bZltzy>aYpVfyaG{S|J-!=w9*~wR#d#c*G$f+Fn&^;*HCng z8yP^1M0HW`Q6&j^b5}|X(pZhRr%7k!*^cV@0NF+5rf+{At$4a^`AUP8E35I!3b2jL zn;l7AkHZ0aGd4EqRwM_^$aDX`C5Dk3oBX{JpvIlpJZ<7e82I{*KgFwt2Z43bNsVf; zvu0nxKmuqBegVeoJ7t<#H^%E=_H3yL`O<0rETPGFycAF;Kxo_<{wWX-z6X@DjfdLp zCV>w+L7A}n9>H-&w4hI;H8l84b`d%m@yA-#$*H@xdE1m|@BA~pPNX2#cV)>>4-Fd# z(bK&jRDF03qxg0o%5SqjEG{lCRspZ_xnX{i+hb|D$)tfI@aSk@iUzgyUmriA{sN9{ z3aTC6rM3jk-AO1M?S4}MA>LicyjD|OsE_Zy_VMjQ)bd?*AGk)s6dL^eI$(6O=T~A_ zsV0ot*TSm0%k0*ID@nd4c|cE~Ec1#;*pVzIJJb=)3>hI)uAw0W7(V+7si`o!P)lCH zj_=pY5bt8Y|I_qLX!c9gbL0Q3y>pLedjB7|t;ystr6|YAItnM`&cU#gqg1YEN_B7#1C)en#c7krggA>!Kg(rORn91yyfFBmXk zW%7?81=eqC+H=C7S`v|HuYJ`uy#uMp>2B;a(ABkK>|6QF2GvWrp?%Z9PkRLbAk+4EIZUNmB zOKs6x_K{;)!3QqgtE<`VeAJ>gkdt*mLD#AWmel|8W`CY}?%5=ZfBtwbse3k)<(r+f zma*qdo`ue_mPw&~xsL$eGe9R^(co|Y^VgK=S?e?2`& z+-3PU=r&L8pL44m#6YL$QFSum7*0$G{x}PnHw)h&KQZpV$#n>KrT()_{A(B{`r z$TF^_`*IzKe=Qg(MOKR`dj!~g42M8@&XM-)->Mb}++oFn=diZ}9|I*5~-;&%Jl+6ynlW?VPt{* zb1u!rU$)Xx{yLgLr{5i`U9h=3UQlK|i0$}gFwxj}5VL-h+TNZ!Lr14iFlv^E?#ZBk z4eDB1>8UL;h;Pfn|BG?@u?g#aTjgR@L%|+pkFt*0&k*RFqmSo}EQqK7x`TDEH!>!& z{d5uy{AE#8l0jiteWfB^2QPOWE5G6B;1I~}xw8qYKio8}>Fy;BJ}+ZS$s>_hMJ1Kb z!xyoS!<;~nRDgUd);#qshMy7Fc~gbPr%89-XrEll5h=$$WPQ= zXtChUjK?v#2%W&c!@H)eFYxo(i}a1`=qg5D5kj@S%+K7DqYA^@cwTk*^%=%-Bj%dOMDZ0f zu(p&f#bb2%JOpZgacBmkhP%Ewp6w}LH!-iou5N9{o7`eVMv1@%R*Yb(xpN_Q_}A{7 zp^j4uJQor-&M0bWNvF*Smrn3qth4Jb^~KiwWK!?l{I)MgMpG^_@hF)-}MUn+>U~c=%1($c5_v13lfhs1S&ef zvez1D@_Hl}uT`d6KcXPN8Lgy_m>sB_eevaV>Ihr4IZeb=YM#eTL9cykqnUE296WDF z%UljweW*lQn^ifPd^gZ*@a?p=L8}k6#||i?Yk7e`BZqE)i7>uRCDRkV5a(c0>$f>B zg5T_p;oDH+O9K`fQWg+lw_2|7ql~Fln6Rv=jm@XNKh3c8v;uD=M;8}3>#zN@99owy zm6H$DDcx<_JfeXKF~oNg3~#&L;#PvoPGwHtI;1qS`w;8bxeXF&bmBl%XX_*GaptMO zuQt{dGqU{}Yq=bQE+5gJGk{U3r-4V1Lj>?)jnLaSAAhpi#h#wNUQ`u+h4F|}^?4)H zDA~%gVn*(g>Du`JxF`Y%0XykSglW>6QgFe3LyejEwxIeFLp*H-|Ky!d86xcZ$o+T4 zwd~1_XGj;}{bkjPKI%ZrQ4$(l(sqYu?rp-V*9@E4IQz{Q6jR(Da&hzTQ*BH(Oj9b& zR=!RwX0p@TH7}cyA8oZOs$2?aPY*lt!U0PcYO4aZYLHuea4P*Bmr@b`aIsRtrcPtf z8$GS^)I$@ILJ9yV(5IlW)xr}>-K)p5R6Aqvlc2I-z2W@S39S0Zu@#_0IScdNTMQs% zG`uTzGjwOw?ut9{dJZSkm5v)4<7gWK4&C5yepo^*42WDdy)&kRZr3rhSI@5lV!!^E znneUqX;Nchx~R;29~7xl#0d3OCk=z>#g+C>O!JI8Wfi8!#}{A6USHC>J@N|B_-bB5 z9I(k7uqifc*Fsaj>act}^HYNU9!CWPF=ndX+GzjG+yTq-xPg zkd!;_yv;B`F&GF72obYyhfE#&Z7Cf+cTNZx7l8x;R1+eZi2}geBAGi-((c}dGTV#; z7#IO~AVkafCQJ)RkCrYmPQXC8EfN?Q5nS7E!cqZUsZYDi1x%Dw1}J!-!C(2CFiSv} zr4{$*9ZUBERNgaW@b@=iS%9vrEdRYbmhOQndkD|To&6>Z1?WP3sMfHPfn+9JY%patv}`Ut%*nd4%ny zQ{7J`RiTI=r^J{V=Jfa}lBYiG#=%wQ*nPcj+5un+%L!)dbFgXu0RKxM>4x#O#(Q=D zHJ$R;mx#S@=ab~o`b(LyMTCKmv5vQ&I1#q$WCA`nnfgcje<*2o`AB~6&3O0ZANe7%P(hh_5A>FuIo z9e)XsRNm8(Q;~MTxn|>{*0OJ?Uofc><5+d`YcaG{-L~DeBEX-o7EHRk*n_fW@Ygb; z&`wo1rz%!*t$?-$Eb5Rt$m+p`VleFD%WNFA>l$%!vm_?j+VUZv*}Yam`x_hJX=n$I zWjsg-xV+sceqiDI`r5GVxzsqm^i^KGP=3&!;Vvaxo6w?~5mq2* z85WAXFjcAw%M_DQ{mAcPzeR)~x%%2@W+f(^6b+*3iFLJ87{6}>~cDqYIM z0BGYG&+@30E{vPW!hl%ZNzz87XX<(Gs2wFQG3m@UD;jDbhBU2CGmeO3vhGvrXc~-g zqr7?nf$_}PI78FO@3YDzoL5o*@J)8@s%0533qeZ>3@5lVx)hGow3T({Vat>~dOIm^ z1bjhS0eE@3+eb~n6LJWElSM6UO#we_Q2;)&8ZYg@Cx-;!qK;x|Dd0noJusxMzwFzA zOP&&$a9&+oN=g6=U7+;5Weds$@Q9oc{r^&%6Q)_?!)YjYgvw72C&u_KPl#v2`gBx$ zb||MSlXFLtxmMU{Gd#`fVzEeO#Ak|%id^@2Uup*}p7(OJ$`LOBWKIV1pEyRcRa9DN znm^8`WvH~oT5o$=|0}^?$XisH^d=-F?RfZ9%)W+jL+(|1aWPkH>*j{hKE7E(JlEEy zRR7w$d8|;EMh)4Cy14Lh7m8uJx{uqZNRo&D^F*p!elN4DIl#p8LbFlt+3js`P-N=Y z6^4+I$n@4b0?x{mS(^}PspZV8R^0R-t1(W_qBk&Rggk|O7is1ojd3<(&EZ@?%ac1|2#$ko*XgB zh1|JAen&?9m8!e`<_xO+u!b+|pShE(vl-_6!#gHe1Mlt-KaeIDT`)pb1m8!r{eh@d zIk~BDyIQ_0?yJ&+6;Hxsx?Rg-b#z?Z!efUYdUtZi&ZMf^#FPs``>5Q)*ffK4f$?AN zP*79&lQHLy>|9-0KZiC;{qS_IIo;hEtzpb(U%ld8*%x>%l1fYEO@8O@W6?YJu-@Hy z;7sw&S?MX>y}!Twef};gDFgfFufT)U$K>ooGURX3Zby*6YeTd7H~9MfRq;E}WQBYF z;Qtvy4KcreJ@?<~L}~9y_d4S|#=HODC&<~wNN@jq=N><{C^#op^b^s4L+(I{CvQdr z-x+}3!Qo7OaIgJ;hDi4gp!}WudKvE&9z-RrQDf1e{QDsAOcWf*{r}n`<-0aHT7OaY z|Aqh)R{kde@=v&TsUiGN9)#Te?-?Kh^#9q<|BB%M3N7#tQ|xUz&0F`7QR^WxRxm>F zsd0jF*b#iWUSUcbt8@D(h=~!sN9&T8VVM7^nsl{j2Mr`wxY!jX;8KGZ*=!7N{00^1 z$b|4cv)$_VHypr0Lt!>)Aa6EjWCUfe2tk|Eb;41oC_|~EzrJ^0wkWLJ>I-76w~Pi%nnQCJvv^|2{3kwz|5t<5o8lfDo>!7uD?vMu8%)4hNg+ zj?L_FU-ePk=)81-=p-#9>j`nAtaxcp44yVy^B3b;IG<20-$a@wc0fkdyn|hOMR8+= z`Hw}1H!;IqwWnsRTZLz)Mg46)|Cym7zkj7dufnr@@5JB>`jzRjJagZT!S>L}+znzF zhRONZi^BuHoyu7^=!0-Ey%frU-Gl3j~wv#%-n>zw>%W=)z%ci!K)8*-(&Y3Anf;&d`6l;Zkdj@%_v^Y7<>ec#we>(%bOVLJB6KT`4t*bs zx!Qg+9JFcF8wq~fBpC1kyPn&RyrR5RFQ+|~nq;bccvm<*owFmYRh=Zdd!GMRjXF?Q z`Pse7JvJNp9-ineeJ)HnBoU5=r{>pxkx?3+Og-ChU9E!C5#H+VDZzjXFtzj&VLA2I zq<-z1cLPsExSM9>2?RbA0VulV!iBdW=8fC-?1x2fx95D|i$=l@|(0rO|+iZ(27y@M(8IN?JCmzn~=4-%3fg%*w&b(;*_^sLOu2 zEA?z$U#4>}tM_&x*^;7>(20#OWG-pXnBHIyQWhBq`StSMtneAaXQe!=k#J1xCRDO{ zJv>NC3h!n0D)aQ3+i-o-==-MLCL7 z`LZ0>%E4vHeV3iSYRQkMuWz=31-pY&F+QEshzgyk6#shj^p3y7^~V%^E2|I@8FDXG zZxsQO@opQZ0#~Y_$z`1V#E+m_LY4TRQn773bWTiyZgFg?_n_+VXy_`8ts1I9>Lf9i zZnl`MF6stNc74akog{D5`fchz7uWQT47VbTHzq$fw|{r=(n+felYaK`jn#7xWoV!o4+JDES`aHII?Iv~HwiE0X1YDoz70T3fyxaS4McQ{~KoIRx ztvWc29)m^1X&d~xdjyqrOQ43U%BcN+L?(6p-o5?tjP5LyfP>hrco@rS<5*GcQbb{K z_@LinauB!{n#T9t$2lM+ky3}#}OARNB>`U z0$Q!aPw~`yOdiO_I&8qa?{Sgs*aR8#uT%F4diFWsHYY5-SEtxpNg>~{S~Wt$NJ5B* z*g)b!W|mINTPPw`VzT!L{j{e(<(6kK-705xqNp}CWZ~sILpFQ$nDMx|$v;!= zh5NTIG7y!VJ(S}ckOVg&sE>HsJVxQ~&r6nM6DtufDM$@I7}A-1^=dB8%c`*Q&n%Fn z^tE5P+}{z`Qq{${og(E4Fa@PyC#Kz{=s^tB!`Mna{$-~C1&r=h{phgn;EF3DRvBwA zWPd}G8cX7vJ^hWl=mY9U2`n~tXJWJm5snL`fCcOgs`X({6V%9Vi>%T$xUAShsb%Ct zGB3#jxfdlvAHDh)@|F?8vutINUPXrE4 z_{z-)Wvc5D$BRLXBKSH+MJ!s#ub=Go6)j&M9Oy_mx-Lx~y1<8QvXGVNPKX06{J6XS zv<2%0P}#=vk_o7uq>X1;-{v#kUl;fB*o!6x##JTTMCNL*&I@-v7}D=7ce?c!I`q#vru-#K~u0q1{A*@!uIBLVVH2EZ3^X(5Y+|kIU%yA=+BX# z12;Z{8PO3IPnKb8e9CmBH-hE>-d%)OQuLM&j-cnKZHnkUZkM^c!m2lcr9N!1#s8Ma zkqJ-uKaXDuWEt#bUgb|K`iyEA)$o_l*RV#H69h`Cj}#KAWtPTYQ$42)vvMMML24#{U zCJ1@)$tUelZ>v1%aNwMfWEIi(dkl(Z^P4E3PGIS-BOafjlV+848 zyZu_?P1nxGdW_QRZ}{WI;|J|m$pI}^U~k!07YDT z$&UL(Ya<|nhO(tRNq&9${rk5ioV0>=wy(^~Q3QEkZjvK{Dk`2GE|8RkOO9npJ+wXk zqyo=B`PG!A7$~5#8-9xfy=wvtJsbp)k_Rom*dEvRpct9Qj{Rddd$~O!%4Y7$U(wn_ zzq3=AB|sNeaIR#=W;aYsa|0x~cssuOOP;vmbEF!T9j}2;SM7N>?;; zLd8aO(+JeF>351eDxS+JcNpfGrSq5`(lO_Pjo`P-`luX6$g3iv$tq-UIJZ2Jp+_?_ zUM#z0;37TnW+$&PXS`Bp{Y|)%?oG42pPyz7@~kM)wbJF}{ne#a=N{ecz6SPV3Rk6u z!1w3jv|`CBLRo%>0}jP&%j<9Hvh6cPz7vp^1ux!+Pt^M%TU_!2AB6H%or5fz9*Q+% zXyOThASWx4Rq)wN03Rr}tkt%vT6_;J8cRQ~S$p~L^cmQE|Fe(Fj+Enz|Kc_|JD@|# zUn7&HyMfg(nT2JCxL65IOhiPFB$WA{o<4#TRMd_@s>Hd<3`k$ofM0A+`)zM&&PATx z7QIQyfQsPJKr(CA!53AINELOhGT$GNsyxmoG#b!DOtfEZF-g#4%P!)TN;km8WO34? zZhyS3$+-cyA@00BWNAkJb0=NIPTy;-f{~I0B`o}`#%)Begq8H!9xo$L9A;l-uACqj z*5j1GMq!=mR);RbD50{ro$1e~mmj@RXWEx=RHPmYhF(bqWK0>= za7j5{n2ZH`*!@eXEw>OCE&`A}rvHk6QD;E#Y3|PjRM&t+oY{rhlHQfsHZp>Judv_1 zf)4Y+J*|G52|=P0Jr%&Sd_)&ZGYV>jSiMXR6XNu-y@ep0Cd)QNQ@11XQ!Fm*MgF;B z(NbXM4)Nu-`GO5~SbKclyqrVtV6lLk>;m5h`ViJY_WLcLy4HGy8L_?A&wDjVXV-vQ zJj4D^cc@7549Nzk{eKA}64*KEqRZynrRy^IzYypgH)P-gU<2`ONe*WT@(vr!DtKxn zM9;b-T)37^K99yocZ?T~d%K>FFFgHc?V^I$=BXm+kzLSb{*uMVw`aM|{f<@t>gqa+ zxn+}Ho$X;oE0V10r5aygVBm8j2_rr}t(Aolot(y>l8p}7y!9^Qnq ze@?#knSiQRA5m(^u`XvBPQ~0-+VS@z=KH&rVUyG4?#BrhOI8+*2F^8A#pBl1zZSmi zyGx+=-}pv379jH8gW(1-SS7tGD470o`KCeL{Bl`t>!|kONq34GW8MN${B_n9ZoAn3w%%Owq5A;a8C3#fKsaiU!!iCjDn;MO{geU=Qx0j2CCDs zT9Z%$dd>Ej97@MFYEJLpt?09~s7~sm3dOtEV)%-;h_`kA_cIB#KI6F-qD3IxXDnbS zEMO2i@^guBLGwE2Tv+CeDrKJ>Wa##mTS#r_Xird4049fUIl#XCh^o}n`^T#qV*(BkC zGG3V!V@_B(^H&G*Z z?60D2N1s}1*(3R-4M<#)g-mjbp*<`tutb#YtGJSCMT_BMo!;elT_%s)C!O0~zc*wv z!8yyYc#;B$U_^o88>FJFd*KF`75xR+2;~=k0I4I#_LD`kD$&y$e6|Iz*iR%Kv-2WdE3`z`+t8C!owhy z0~x!~5wVbW(A4*Br^;YXIFAqrnJ+Z97)m!zI;(Va_pY`5cDV_gy+GKMFv=?)HR0gI z7g8Cob>7W9lJ@Ke%lEboe4cy37AkWF%33pG!}FF*Fm1Q3@IXhAfo86<>lN5^Ib1q6 z%87TnZI@2r4+Yrc-d0E0*V%ROS`8tz6+x4k1xM}!AoY&6<}m-vt~?S1`1bCNeI0y> zXmk{hZ{(z>7yj>nm;;&EYL&|*F5L{PoXjxPzy4(Z7`oK&E^`7qKV^B^2cKyPR z_msH(%V#FpyA@r|ieTmO#lwUY`J7KPw&6X?l}Odvntq$F-iLKmw6yhhhK6jIVkyYg zdF>mQbM0U=_fK0!Xd_g&C=gdMxW(88c#Y;KwY5UEwS2bhz4V^7wpG)56yeF|tTAjh zB4yDgOwYK3XW1Q^lkDx-VcXD)t~SXsvDVh57;2^J)_EC-VzRmtGdm-2qywX~O2a_e zVMy@}jTGHB=${vm1Nu=+3i4uT4me6x)Mb8B;sU%Y5oM7G$8ie)7kDxU3Smc&HQ3h-bZlhy=t&SSKD8&!m*CNg0j3_NjT zRy#n_`Yj4VxwLEj_dJrqf#Zn5I|RxckL=t>XdZ#Gt#5eel2c>LDdbuf4o^N;xDZw( z))7?U)f3c2e&*NnYU04dFz^5}YMof|;ISLHmqY&!R4eAS_k#3Dsl4Rkj&QT7(~N2< z+Q(J|MZbOWIC9RiO1zQ6MzE06)pz0#y35W@mG?y5qC@3b|KDza{{-OqnPiwn1^5h& zPwHfGZSphl#d?`h8Ru*Hv?j#zQ+}7mFM%((g2pyf(&oxfrp4uQt@`aS0$&pvOuB8K zP_r*^-N+}5Kop#i{X6ZnauTR9$$s%WonL49v|cvNUiS4}CaTJ1W)tHa7E>ln3@LNk z$_>`vM-sz%>&IHX6a?RTl>R8n)qaB}q-|&K( z13Xv$Dl+%GZG~qaM1>71an@2OZa48|tk8Di>-=|q|CkVE-e_^kzfTrj#d;sdlq>}V>1p34B^)EKp1drhMi z7F~ogFQ%FzM~$_$);g(OoZ$9a)z-8@Vr&t|g3yh`qfbXypiXCV^9_<&<>dE#QaLjqVCCQbI#7QG zSv-9$SdK-GXB|TXt8a8PPUQ|N>=$~Q+HJ#8sdq_5{C#*lD(Um5yYumX7Z6njXreOS zWb6wY`bAwKt19i2oIMwGNEzUbJ@wucgoFB9OQ!Q=wpmWO;sHwekLZmk>a=&J5WDiQ8|kEM}v2kCiCN$2Uo zkLQ#Biiu6x@(tuGA`C@O~52LcT8{fqJjxqr~0axm~&(UdY;LYQ1`-nI;0^ zh{mMX@Ml(>7E64eg&Kl1zxBi4h5>Oq55HD;R&v@g|D{x`q9FUEzW!J@(#sPS9YrfO zHvL7KPSlI;{vLEGST;I_=dY%_H5nBf(K6H~kXRXNuj8C4q=<4tG&xP?!6D?CwJl{ps+qeuXZCGBgv>)sJdw%7?c*=fQ{g^2a~{ zP81$ENcdY;xY^)o(DzLT#Zn~UW9fw*8}*If-%t7lgEd~~l%FeCfv z{S4d1dO^@XhSEk2wT;P`~+#a+5050;$4};uyyz05}zUc;b;J&Fz8THTmcD zgtdAz&`YJw`Z9UWQ85uyZ)_JXK)ll?aN{VFnE>j88S>guW<-A!F z)+buo6Y>nkyAC+-fObe|$Z|~r9;?-e+I;ZpZJ*=kPsc_Hl%;>tbS4yyOje-c!BcvHHvY~ppG+zViWd5!L$1@X}IJgz$_2g)pQH!PE=C)XN9BHce z&aH`JKU$XsI(j9>{CMd9&Lk?~`U7Ou00?7X7ABkuK=b%rvk+*3g6zgcW___u`wcvl zlz05I_C~l9z;Q64XZiufl2;hAo{~?e(a}S;Jcz3*jRUck$m>auPJ$Nl523QS_VMzs z-EK-s0Bese;xhwhUd3C5e-02Mqs2Z0AW$c}+$V$~PyV?bX<5LME%2(Zfjg|-E2$Wh zp%gROlx2cnG@C@!4j7Q3;wc*a(tdw=lcBumPkH}b-6*h;K_+i1)O%k~tq>MQfXC81 zwU%)b?C&@L8X7y>vrbT%%eL{Tws9v-pJYh*gZ96r`Clzh$jQLnN0>k_SQ%C@*pGXw zzU29U&QhTtiW(~_z5s2dc53b-hI0`eri1`qxS%}g;}G<}i?z5;8JJtSwav@MlIM2( zbePbv{J3HAO`AnU{y=3Vg!**lP)>u(Vb&Btqbh2eo5``zwA&8B??td1Ypx4gg=a}6 z!hiU0j&BAyzRz9{{9vE9jBpyegB!o`xtWh}{BZmMslc%E!*~#|EJ|+vT*n4l#)=<* zg^N8xPSNuY#h>AC&LBDoAZoHx1M>R6fdegsN}r3ccfiB)bkB2Fu~hh)rNp)ElBC-# zIil{U-Kza(z$h!xNT2@O57s+T5HLqiTVAHZztg_^IQxHJ0gUB;fW|9>fie;evE zuT)()61)pyQ6hG5#K}dG{6*kbbEd+d`bYUE`n8Hd5&;dIz_%NA4g03ywdR4yO9|G+ zG43IXHHj|_r3O{y>jLe79ULXb{Dbx$seB{upHFbXl|e*jJG?6rLnB(?&9FD;=`r+)bw_kS)_9!7M8k!a4_*` zOLr=F5`<*YPxG+-d>j;jvg@YT7>PP9X1nsGe+A1A0=Fc}ZImA1D0cY-v;ssqfW^?L zknV&?|NJxGSIXAW-PR6Q;i3XXPXGAY%~xs`R?D}74yiai0GfVOt(HSRP2Q>9N#c+A zko)D-L3^nljr)73p3A@Rze;>(pSbXUJMjBUec>m!fvruK<7N5+OUlfwm^V9SukTUf zsNFa7`|Q}%XItf&Kv1il%SmjvL`+s)>EeP{?dHbvR<)hZ`#nSB{yGv#(J%K$?qyLA zan+l3b5^5wLnCqpcAz#imv;d90PrPaKTI`i6#?#4xKmRQ`=l{)2+1M zN&`>r{P&9swo@*L%R``(E&>nxRmih?U*VwoRf1T_N$57KK|`ewfpB#8jD;2RAP$zK zv;8scfdW(iV5^WplZ+j9Za`+I{n~l^v7SU|9YmR>Z{@P}5sRdCRN?uFGuge4FWYk3 z_pd=zFp!K86h7My4gChRl1Ff|npeb8sTughP zc6kZlBIeOV8$a9pjsS9*f#tE!5kFrahd>{nLH(cPkHtL%wUfE)&qFI;Q{Jte^lr>{ z`=%!-W6<;}9S6DLw7={e&%$Z}4GLYR4HO{NNqOUaS0ta|DmGChBP)7x zeV(7ah;c}ob>Xh!va*Nv>7A z|0o@PlHwyb=tG_R{QD$NYw;M@+`}d-fX>FzF-c@x`oYplCT60Utz)@FyL!(R*>Iu) z@+`YkU0s7eYkg7jfqnD`-sPe*@#OiQd;zV3DW#TPm9@lc&}QhbLuD1QwNGY0WW>FO zDEM$&>p0B(diYrTTuo{TMO22#Z0eKITkFcaOMe15JGmnea-((TyLq3$ulXI_CpFW;8bS3vxDa3tyR@|dQ|h!tJ6%SP;p4AS?4B;iod+J&$Jq-htaG2-psPY?8#%9E z>;S-G2cT|ZUeX2Er(4>CbEXqI^14u?#2nGr6=5~_3+M$Wu9I?m+<#@Eueqjc*3*=_ z`ZOe?et(QrjZJcH^D-$-@!$;XbJ^VV%8oM=6K6t&yU99pW%ImB)>OYa{pM+eP(5o_r`W+ zD}*+;xQgTC`$A2P<@U!i=~t?zctQlogqW0RCNpXp5fP1DP3%Nrq}9c9-ZW{r7gUGX zVoiy5`nWou8m{(e5A?H-Y4-ThHbBaR{QzO&hxpy26%ChL`I84Mrs(_v@ zZm;IWP|F|?uD&9I+Ee3kOZ$(^8?6ia<9~g{fGIrqefW_R7LYLzKl5VW2KzqEpYNr! z*+TFkv#t~kZY`H4o3C%VUv5UL7!K<~7YivO%SB^2hW^QZGBT#oD!a5RpFoka1I?smNMXV9`b05V@Z?h_R z6TvQ)Ql|y|GXmRe>N13%eP7;sQhKHO2Hd`od|KD7dYrNb)=VtytM_XelN>Fu$A3W1 z1_KcLz8v%1PbJ`Vj*ivg%*>Nwn)V(X?yxk6hvgXZ1!RDmNCbPHdf zOF2`vXLXHd#!V~_eAZ_#;M{y)}S8 zB*2IWkk58|*?+m7Rj@*%Hq%PPm`L4~O=lVJ+RRi&TJWY3{^xl|UI)<4!(OAOMaJD7 zTUP1oCWA0%>F~FbY)Ax#(SIwGlY64&VwpS|Qv=fb?7DjS41_T85)Yu9n zbmt_1Cy0ik<)SSkh|6V9?3Xp{$~UxJrI4fL@^!1|Nb4A+&P%0+CeMJXiK2w*6>e*p zANS&2kc@{=TiyUmtLHhcEqKNlBS$7%BQ0__7g| zb96K*sa>+*RQ_p`j8uFD&gslEkxsrT?mYo^94wmY<>!A0{84?c;Www&9>?M`3Io6|C=N zF~>J!iv|z=+IE(FjV;fM`zgZB`qFtyeI#~cMm41{ubCy*7B+ey1S&z-zU_L*`MgOM$YajYu8%G`FwBm z=uzcFQ5rzQ2rr{HSqvceM3Rue-Zbi`2Lv}aI$fP$#uDVAc_MdPVG@|jE$$s4qNl_u zwmuq6F=l0UnG@C?kAz^v!{(BK#k>BZ_a3A<&&E|0s-eRZ00xthN}){~yS?Iow<^L2ir3f*ac#aqOW=I(sNdUSp{ z-x0{Fw-1qAW6>A*;W878UQ#g71t3H|;|tS2h$+^uZJ-%VOM-R_3f~>CZB}q2rIoTw z4cWjUCRKWY^m4uC7K5Gptjh%>e=*@JDf9|NC((4cjEcBqpQY{hb0?J6$K^3|Ja8OX zal$w}hzp+s8JFLIH@J5thYj6Pj`t2L<^g(ymV$hq`36C)b)*fxbMcABMAufjC&V7D zixwF#T%Sp!bhY}jX4;{u%B_w!_t@=u-cbAUH)w%XLmI4TTyTBOiTfpYJi9`!0sq^? z;rzS1<=>rr0mcOgYn}d1UuyH)YVrN>JOBVpyCx_(2+cWVI$pC3u*J;aL$d(0H9}Hl zbi&m}(D*N0Gbi%%*^y_3pnj>C5}rpGmI5|0=OHYZA`dX z1p)kPTpmJLscL*_iz^AP6eC#~_WoJhy|5us?ekMZPQzp;6W6b4s*s9Z%)%N~ zeQ6U@%86F%%`+*S3ZpCg&n@tQHYWV8PIt3L5ac>ZT3g#ua`WjWq%OA!^Qo@(n>gC* z<`42&m!Rxoh;>(F+WPfpzFVc7$z}qexxW@%iIdl`V_(_qtwn|5t6jLRT-H4w(i0(V zX1Sb+MITgT;3;ax*`h?7_o`n?E3Bxmm!>ubsFSG6{7&EZmkH#)@+@l30a$i1CVx4~ zqab%hgLJttbZm{Qd!gKe75J3wvi)Dznue*M$z6YfMs#ptNl${MHB3XS%v1mdy^CW$ z&W!9Kq+pS>kf>?jU5Ll^;=P@`y4Wc9V>9cp za&VO%)zXJ47arW$yWNZnT>iViM-d-kKY3+`oB;;!*H9mu&F@z z5LD<`E$A}I@A&@CoLa??8K+{nlblL6swhK_nY|*Z_-_5oHVlJPODtLOD9^JJ2+E#y z95j0y28~^T%fATRxr?-6zdfX*M;Cw9rW9Lho{VfOO1aJ}c1x8u1_4b!z_pDMg?Gr0 z=rE`_!s8x~u1(hUwHW?ckUi^%W~Kf1ptJ|BF07Qdx!RRZIt!#ZPzf@030jr z^6#+Jt+!x_=g&x7^FrPr;6)W+U+sN2W=6dDN7TUehG?C#0??H(HKdCt9p6q40_GmS zFh|$;4zQ%AGuG^zo0QWz6DvL_UMfoLu`A6qd&dg%kjk^>tn2>RH6^K7^ifun7_b6^ zaNLgv4EqrVdHo7wu2szD3I94svUQ^Z?Pk|uhjeW}k0c{_sMhUsNJmqt7gk)D#xr$@=0yT%d5t0=Y*DIU z7K9KPFVD|pnLLpl5)w!$4eeU1B4km+`Ah9*$q4!)rBb4*Pug=NnkiM7f8v@?RHs{E z`I$$5X~zxo7ZG}gZO{z&pe)OBiQYB&Xa9sxtY51k3HS6FHRQ=sY9prNvfc3;I%@|v zp(40#?8J7H@8XDn+a`3@kXx;*Q@mJys@bY#+H7*HL^FPX`8B1*7L}CR!vI2q%MUTa zXrPGP!O#GROL;XUw1DmktLw}5E>*liQdkaQVU2Z3Xd8d@7`)Lw|NF{es;7nD%nt3I z(Au6gd+w-V)a6BFwcQ1G3`b~M5#tz1PcZ?i%|xZ|WZI>4TE5=muKSjegi`8+)=JZr zKxx0@JT1*ov%I_< zvVQ?O52i}yCp#wcHK|OKQN_BK@oD~`eNz6ZM#Se+xLk3B!PaM>&25#hADw4I5mV4O z10+0>I50wPJ4FvL6&Tm1e|@(#9{gGVHBW5#!CB_+@)o$v698rT&(SC{abKwUYPc1KeA8~Uo%DC2m3VvkynE%oU25( z=}uFAjGeI6Y~FLQeq+_1^~+cz#9jjtzU}6noyQBX*n3pOqn7cs#3|+ut5xRaVoeCwD--mq^Qx@CB+fOE71h6yp`+o&!g@lexQC_r#>bWS9S1U zNI?}TE3H$kn$6=_UY|dExd%sb>+C~b?O#f$dqgJ6Z5QKBNWxf;-Hvw%ssz7kJhRA5 z>1}@*O=M;E(otc&pDBclv$(UsQS4+uuDU(As#9*72b3?lNolc3{}lyj1P+)DF;>kT z#Bx2zDjulRF7k!hI0qd^bVka{7a!X|;Rk*v%T+N_01O7D%byYzA4+KJ7MFpTwS8FZ zvtlIal~kDyQtC*Qnj#YeJ441g4|HEH$+uPUla3Zo9kNIMcmUO+)D}BWBVK#E4D@xl zQ{*I_GCh05!*hUbSf0Z;=WLbme9eJw0sVypy)X8UB3cUeo+9`4a&B-tj`4vuM>PWL zPFklB&E4kGx4k^5AJmoxiy`&l6)kT9XedIlDrYe%J+GD&SB3OY=4CP}FB&%03u%#E z03(ovYot`Ib`t09pHUOrNOm=}1CAnDhWKXhI7-XdNnx%0*;YBHks}UH7;~-WJmJJM zP8(P>K!@}OI)wh>7XsKaVAuS4&wMXK^4|+hP7+XtM`@(>0I)f}WpDQ3-a^nDHX=br znM&|};9+8H*`wIA`PL9awpDYF@#52aubQ-~b)BULr7^VyMJA`|g%FIeqBJm$pz-F8 zH32Fsv;GV`_@b|JUbbT#z2x^5#oz<#w6f$)EwJVoQ-z(WjP|8&d%}L#D&KH7N379| zw3lg&QE=ClB4fIs@<>{GI&ETNNy@+(sG%Jqe)aWD=?Rjm_F)lwPT>|mPi8{yHx?o%_ zurnxcU}xiVuC?{K3SUtV(S;`f3cab^+Wiw<&;nFhttuD4Baf2H^bO|Rvwi_rJbi$> zhZAMORI%H*Ql?tPqv%uIYPu;!`q~_43lUpSW;7=@4s`$w*W=uk*tqAjO==5~*WqWM z73I1ouAr&__mPKCtp@5{xW&UtwG^NOrJ`O}$F3w~23|tmcA@;nPd=W0+QMgd)>zP< z<>2u{gk33FZ&@=oO!@jLkrP#}c_>Uc-z8q-i&=e1s}0-w;mT^TYMBa+BpS5YvetQ~ zj+aFSkWDoFY&1278^MQl9pXoDsL@QQ{Gk<}Ml&j%w+>U+`YI@AulWjj#EfkN=GVJ0 z+dC}nAGSsR7=KM0PpsTmFjJltpCj$cM_XYTN$e{BHC`#qUdUd>kAdb{PTeuBg>e?w z9F|tZr_#sQ*bKCfN^%XT`CUD|g>g8ABxwSAsAD)0Cjcd8`TAl}9{`}^UhmmJq`|mS)-$%yYasfWc16X{)@2e;l zmdRO2=By0Ss7(kLJ#N``(c#juIuyRN!P0(q21=>UI;^%=@M=HSczFz2ubN~{y`fyT zd}!= z$EosglcyYtvAeBr zi;9p1SlZUmeqbKmow@P8tyyV3tAP?871d}9^y;K1{cXpE=;;{GD$r`<;amBfxtkmY zDs8uZLSo7XH+Aw(7d=Kt=WQPgYHa0}P?MuVk4F+RWCZ|y1EH!Zcm9_P;uss;)h`J{ zN9w{>$L_}KhknkL;|x3ewCUa{I(7I0_bNR>2ta3ECA4nmO|$LF(5|qKC00D3g-n)Q zsr0c9y}5wdHO&;{oi`hrLK>RIAeVyF5Kf*pTrd`vh{?I{)vGdXm4wd&@6DbHfaM3; z#79Suj@kjE?&eM9)?)Gk>Chkj+Wa9Drott&i3w1%)N4wN6?WmC}`NDDDb>$t4 z8;aF&c_2wI>W*bLut!Kif_Xppk3A1HwE*2EH_mqP;pCo!hbz0pqm3Rb)f+8Yh=-KP zkt<(Hh!Al%1x8F>{vDMn3U>LQusT#&+?P{Kq7HBEH>3!-^`S?mSMS$1y+XWE%sqkr z)Z*t4F;EE}6J@!@ z3XN^n1Q}LfvY&G~#11asRj8bU6W#M2o~royaZ3j!(>7{o8VjRv@8`hVgf8<ZXEIBV7)$?j>{O_ITo_m*wh(2ZqkcPE8px+IkjJJ z>8xME`lynVGwD#$=gjs`?t|5+v3L9V%yxj=>A8i*Q4rDhIxduKwwg8XuzOwz6fySf zc}S?e&mP1FDamsL)=3>dMAJ>Av6!s}Zf`EKi#YMyvVZWX-d=!6sMX7Z_EY4hRjX6- z!myX@J?oC)!P8-R{M2=%K@is5i_K$i+a>fV5hQi*0(o?>EWp_B}= zvWGz-Ob;$oRz0>JaZ@=uQW7FpOD@9l;;~aNBjXzOl_W4Z9eg{$^5;$ODCz63d5A0f z>>b%Q$(0lqTuN2q2PD{MdJ5hx&c&(NR;tje_rXnh$<(t{P$xQfb#SHk#U$5QC4QxL zdv=n@#ULGo&m2S%;W2cVz$?|oEj>3bk(zWT3osS>VATt zRf9#?w;$ES3?h9d5PHv?FBRGDTD^^W3y(Ut61++f+uM{K<1VpX=hJ_FZFXf})esr` z_42*o3v9D3L+?h>!Y{;lUdRaz~yXyk^!XL}jj&mx^JlttQkKf3ZNgAL!_z+;C2x@$rM+>^|vqYLgwO%oP)G z3sX79a%^$uYmndFiS%`R)Mzjfd9!iwy$CWArUPYjlNKyme!2)FSRSE`3CpLpk}d$+ zogr9t-a07&Zk4JwxgP$Oo2p)=Cp~a~7Lxe`16GVQ;W!dM?M<1illK>0eNpy~O1bQp zeoz}z?X3G$>_rka^r9GP{<28t!rHju$OH#Sm1}g=3mA^sp+cn>kgFxw0Rh#K1{fB0 z{>-d@dYVt@VeQFw{?QuFl&Rq6HpA+3XMq=oLM$d>9=t18e0hUG6*RBT#(37apyLLP z2tsI}RfT2{8cG0VHG=I&VDx;<7aVRh51|NAHba1vF^VLkcGWXIzdCP>TuWRV|9KUX zrwuywQm7ngGnvz!n1s>l%t%Ofeh~R1X!&E1_z3TS@vd3v0;9X~N)`_C45~2D1_#Mx zHggio?@jXhvO@WT$u>&>NtETF?*o=v1E`y`40n<&_`E?#rzw-Kqe|eTH*hbI&%e3uMa>+Zx z9tP7H!0igG_`YVO=+=^TnfCrwf0T;#_d>Qy+O_hU2`_O4T%;NJ$6&9?)f*N49+R$d zlR5Y+HTKF6(-OrQuL!;N#Lmoc&j%t_c#eO3Cq^`5!?^1S2&(Yw2^4F~R#kT}g49~S z(Ec>{8PGq-+flOR&8BO<{JIpYbJ)1>=<0`Vp^A9!qSmE}kSw(+4w46M-skODT}M|s zBfVF-Uj|}KmmWyTFEk0h2R1)5L`MoNmOdvQMSIZnvn?H$(IRx2P`IdhRJF;x=*L9neniZ5r?qFYKnaCX| zxMrQ~p`XSD>jP-eC4Px1b6FjK)qA%QJVLK8N;mT`evgeaQ{R z9yupQMo4cbcX4G(X(vovl@xdvGRd~Ui>w`fdnmfPCYWW?-=CY=)Q6?g-6oUVBJ5yx7y!CqpWZ7PU%jE%PJzg3``iJ@C?+UhJ~JpPpWBFU+JAJKXa<3B?ibget3&mtZZCzW3)nBq&s(xZF;e;jdF7=idJIL9Q%9Jv(eRVVdPpVPcu9 zpI9Xgk`Yto?tg+%P>{$xZc)D4~2l{dML6J}tD^QgtiTD|^fe#x3+lsYnjUtAk?@%uHxo&^;-ZKv()SVeKrJHODnFTJ zjWqwa`A6%7H9E8Jb}1rRVk=YKWyuwx7{2LoGc`8mwNU*Zn9Ona8NTx%8=nEVuwYA@ z-Jk1l79ZKQ(}#44CPpTNqys?S{odVN7VPP{bZp$hwb>CxkQw|oRhnRgX`4H7>E8oi zvR~IL)Dt>n%2zJ4e~NF^An>Ks0>~(6pdqZl}usw9Z!H1mmkAB_F zJL-!}@_`EKy6WT&SLqY0hv){a(VN;XJsR4{{Opq+rVcCba4N=Q#S+iJ4Q}b3Re4<} zF~et;G^?n!6vr%Wn-H;#Jqkw-WRg3bmR-re3FFAi>OAj~sep#e@_Y>zo))wF&B~Kg zS7105D$|)DE$rf%Rk6GT1`jQ##|A8DZ}j(&$D4!6uXncH_t6xmr#<3a(}V5DX-i;g z$>h^@eoV>MFo4z|8X{^SW`z8}8_VM0*<{k^S>ae2%!zup=z3)WAhl|KRoCiXqNx3p zol9|gAv;PfO*=ggF}&kmI`2}xg>XFNl?5J<%oC%gRDlZIDYn>xoK<#;U6xAF=I2v$ zvFFYS7tZ;~&SxtgIbP+golePd@$KHWMT4lhUR=hSW;)$BaxbF(qg^8*{E&8puqsYe zkL-TzuFOVE+f!BZGRhJ5g+^_7h!^PD2*Scypl3MBRKc7bvxt9#U7`wJshBnCaWKkCw8&37sASd4|Oh9wSK+JsmZwO8funZG8u zgZ{n)JNq5uo4V--*HD*VIJDU%d?=Z{1AiBJ85$r5Cz)~(|5>D;u?R7<1(l|Zd%gULA&sB8zKfw8rzr#7bkDUPJ&gq z#P6XxrX{xU8nkXw*?VOE)@bPk`MM7dbGw)aRE$s}@LVda6Wum(r;fTlnVQ9XIE{Q<(BiU+}Vm*xyp-YL6TwLu(?A zmIy1MDFm2FDHAqC3Z-hlPE$67?8N4*lNUJdB#z)B{L|i2CPIp>YYVugp=a~Zk~h%g z3vW3SWzAJ;qy>VdE+(WyQrl=~_!bAx*D;d^^*mMJ(`j*=y-`AUd(nC8H|xTVts3-B z+^f+sK0ZOkyPpkzEaha`q1A*S)f|1~zSY?(=}Edkx94Q_J6c;0&w974m-j&117wU( z>A!p`$CF5lj^D2JRDa(=6Uj*pdI|Ub7$1(fkGPnSEr~i!eiI_v{l1VkhTtxbX-3Mr z_(1LVnoZWbF5O_u{ZR#zTsr}8`4?im*AYzy$BLZcS!)eL0gJtqO{<`jA%gdzY8PlAdLP%s)^XW*I3+#3+0$)|hU%{7MgL3MIQ zE0pqRMT3qx9*uUWQygzA)(+bgVUoqdW zuBvSA>g+|Wre};=IxN};>#!u&4@F3n7V`3JT!AsX)juJ*)HWi)n9-HK11G8uYVI_U z{OddUbAF)7ILF#*ynz}f-t-!UDDu4ZBx}cTPwi@YP=D7JMFT? zdA+41lx9Apo3houGjoN#{UkWJ1bOo;qCZWp(*i~dp)Tai$XjJp`lvGMZh}*F-b|qs zN^sYz3i$&){EGRH)WdObzc7!Kk#Su)&$=Jqb1$T=`Ze(gmr^2tgA408)`R%7#fzyp zVyD3Y-5y=~M{au$>MSBf-JR}3LJX-|O|f_vcxCy$5t5!}C>zVw$mj8sm54F6@SlR|CZ4 zx=0gGJ1vOxpY=o0LB}jn$bgaSR7p*h-~^nUmyK{R&0E9Z6C=m<0j*HNqP(B+8F&|+ zAo<}wkG(N*O3w!B<3M5_1@`^>!BMY$+b@klG{&vnX$X>4;DTWF4_%{ig}Br|fh6W5 zT>@@!#NOY5SZ;%CD1Ty6aPZpM7cd`sH&av5vALiF}_4-m&vp?S+I{(QogOA3LQHLy?N zZQFIxshCACB*%n-sCGsbT;bfb&U*Q1*cW2~wJyV2U8AF)HO#x0=e3ZOI{E_1BBPAK zl>4}}Q=`pnCZieo46>#RA*-5joA{O;5nl1tyn`Olv1f-+NtfaIi}Gqkr>WRez5;>d zEta|YpX>PcRLZqoNf=oD;b?aC0YHXjiBH0fOyqjJ#tpg_ zL^1bF8}YAE9uxKmv1`PA2>R%XCt;k6%}wF7^tb*=VMn9!XnhrL)Cg|yUbX+Ypzzy> zWXQ^T&>GR;bBI|urU`*>y|-8K?zvDZIZl1I3Ev^w^Rjgb%>8JIAvd{GS{uePXY{$8 zS4l%T%V>Xd-#xA2lW=O!ZIIE(BB&3w-9#Ih-1?(o&6h)*+6l*;1SVq6)J&+obYOpCIk=qFIyp`Tx31 zt$KW*ZdH}0BsSwu*4y~tj??FA@k4NZY+T$J)^eer# ztM=b9o8eb40kml2-$BBgYAVgt+KK?EfBx>F_Hq@e!pF>?rjCbSTZ%|7GeM-RGFcOr zG)p{iB~+d)FPH=w-Pa^;XiA@) z_0slj9XUC<4g{34n9@1_ILreTYe9}gQut&hji%GoGOoWiS19H=b4ewK#)UC9X9jTb z$PsX(1R5kogILE5`k|mD0j0rw^3qrG(=U(~1MRu@AD)NazOFcxFA!D}|GS+}8_>d1 zb;X=x!#qFy;_EMG}q+GfA&;Hkbf5gdh>6mME>#+;fLx+>*y`26+e z7|sZP)KB<`*6zoA1tjA|ReZ2VPtDg zKKDu*xw0fCRQXGc$;Ex(Ow%*iZUNP@gH2L5j*&{_1B{B5T9ui+NKA`BExK|Zxmela zpNav!YG`~c%n^)C4mfcb!gxyCyST@EwZEp-_Wq-t%c@VmMhdGsS$yJylT_a8s{^M; zJ6+y37m0j@I?D{dhq%zZ{?9)4oDGGzHRg^Y(goUQKjz-oCa)PHqUGZJQ^U`FSF@vU zvFr8H`}qkv$~Ev&R!_md!y%JaRzF!jH3b%&4e`b&`T(J`XaAd(_P6DIts7E2 z|IdzxK1|(xr)b-W?};2;OD|turnRbe%g0~|!dGf$c3TJ24f|I0YDS#kb&>;b9!v}E zdzQ>zAmSap#0lry$sD46Pw)#9X{-+GR}0yJ{bq4Y!-x+|hOrk}ha+5UGKCqFoHO?x zuJ5w%uY+XGYE#C+- z*8V7`uU+BPu#;?NJv1;S)j&6A2-kbFMD>~re(@51@r31b!6AX^6)dpD_Ug>{lkVNA z!UN~^dA9Cj0YH^7u){WTYPUL|!$f(*=%m%SdkY717r~<7mQoBp^V)3(v1BWtzF3m) z1)^@MhEABcNwi(Q(_*LX4XdnLg}mBwDR@{sjBD z>)W{LC%ER)%NOpIC7$J-E5V?9X|0p(*3QuumymwnSH^_+PWD z%+tkCA(H?SrZw?5rIXW@=O*R0I_jHr&(AA^*N2gmOZNi{BwUWS9zbB@;Bz4$W=9n% z&XOHG#s1bhY^yv=!vt)h)5yirLVc-SrFocAvJfm#AB!a+x!A96DW{QhkZq6J_w!E; zXie4>F}-}7Bv$%hL^4@V;bDK5oYW=d-2F>~iG6WHN0hVsuYRKfO`1ul&-nQYrF5G- zz}dP`i;kn!pu$9$jJcp}`+eMekC|x|9wSf4hJO-q1#8VZ?^;S~-1DCwm7gmBrUC!) z2yhykeZ9qK9p=$NcR%z8#7;-epgw*70#%s0VJ8aXA>AyDWji9Gp_b|d-Ljsga%K&M zFc@GK95dvh;y5d>$;iC`%J2P$OfG<|6{d(qz!cy$?f=nOEsHC=!s#QxKD} z9GsrBucW5D)t#;teZ8q?qtHOcjKJ!)ui<%9?KYo6l8~*nbTWt?yfLn`uadJZHY;b| z-!5jVh#1J=%`;z|y);@+39BJDYM67#c;9!!7j*={B#P)ZJN&-n@C_qS@}u&~y4m!} zl~@+X`w<|0)=2s~e-qgn_EteJU&%FMNq`ncxqRDsw;1+*wtkd8X;a}98K;~-6gaz* zr>X%hc_-bH(5KU3R4O{1tg3rWF2lS!j%?pu&YoNSY?1l=hI)dH;C{$!-6BPC#?iqV z$lMAMe)5;P1+Gb+RJbNqqYDe#V=n9VpH=Q3px>5yIM1b*kh!~MplzYyY2^5xJw6Yc zkqg3q>lbErNe*7sc5rvl`FC0^RJUENnaKY_#?@JzXar<~Dtqj!uGR?$k$ODNgEbK9 zF7F>$-A!J@i*<8u?)Dt7oqkR4EQwLo1pRPs1oY+VoD?HVSmKHua?#_bwUoPlW9xfZ zIG*)ccRLTFgh){9YFY2@zyG%8y3IU8rdWB9czV9COL_DAhAV(eoemOxB2?zXC6=ww zcuixn5Ca{0Z7$f&WlU$~0TYWTnt%Viu011|A(bx9mc-Za5&f0m$Y(|Acjsct4+2R# zgV`|XUuoH{r@jM3h;$Rzd(y|a)UpWeZSJkt#!30#^zfJPAIzseJ7(hSEO8pVub~-T z%%_MJwY@6!|Cm5Gc$e(lWaz_6&t1sO-Zi>fDHv=KedHwKONF)lj+pqagBAllA1HQy z@TnBbj6|5g{D!{y`n>bGq6xXMd;lFDk|nA~kPb4^3B&uVmXbt5dhGs=Bdg6Tr!AyP z)U;F`GT5$&qUvoBM8ClR>4rFX%dI)^rFd6JgI+iax5|?6~8xiYF{B*8Q7MBY~6H-T00-brU2Ovz` zj!w?XR0Iu2Rxny?KAGR1^^Z-Xw)F9S%Bf8cD(;9o!H2wNA4C&3F!kN=w{MoA5?Pl? zx~Yn#T~>CaIK6cl@!$e67ih*lPz{M1H+2EG6UW&X?*vf`e7Qw&4S!x8p+sQXV9u16(sCBt7BV1kSxdft*qMejfqX3 zR>z2>JfmI<9NKpE9Ld* z3umqRhM{*arXFPmqzN1bX0{f^fW`PE+Wkr5HwW_Lzj4@$%o=+Dh0KrrtbDarppe<& zhyN1ybz2tN;Y@jJ5UM31;U2h1-A+ut6wXvkROs-7{@yQ;zIog6Sxm5ct&5vS{nM-2 zb8m{*9Gy=D*Twx86HjvYUbZ}XkNXWM;E1EY^sGD%KhvV)yH{yaQNzGIc}*;q_O<+; zjuXP(pD}*d{uPi~?qxfAZHS!Hn4MdoAE_S;HkP^W@KJ+b1n_!E#CuR3?s57JrCkhVFV@wd?$` zKGM}LhUNIF{@OyvT}8eyOugJ3tN&B^=W@9A;wZvUf&2_=4r)*1dVnJtB&y zH+1`mUuhSoZqRF*`Glc<9urEpwc>z#UUySjB!<}{1uH1_7SAAdqT~} zKyWXJhs@Rtpo6h@h^LRe>WyzAP)Hd+H7bg)^AW{eBrPivq-}ClZ^8q`j{R>{Pjm(`Qxt#NgX4S->~-DRp|O(EAUMS zxw^fmFZJ_m_UIP&fz3CO$JdiWWfGaALSByZ6^@Jhugx|{1(jz+F~WlO{KmBe{*t?J zOS^l-EgaNY523H?h~@5$Cs*uTJc<)Bmu&WunabpnPI9Hh3j2;%sA* zm*yrcigYrtD_Tf7G^B?N4jSYebO>mQ`iJm!d5f0>|G#KPDBxI@HEvz*!B?!Omrb7_ z8;7@bHg|e2{stn4Uy+zN)Fgs>0cJTZyv-{9m2IkebeQYYkmBq}HeQyOe{R z;g}fB&5~545TI3yE3@m0bN+hu?LOv8d<43Q%J64Dh2YB!Dw^H5K-tse_SUF+?G;v7 zdib_jEi>oqOdwDKq^^0H`MyQSD`?B8(qKtYyf^nmz|JBkGe)JJOS2AUR;r~xAqr>w z?c_V8B0Vicx7q5n-kC4#belxJs`s7VU_?U=wnOziBaC)BwP3x$dhsh)95v7r3+|1c zy+;^y#(%kM*R*kUD&-38kB!itoT>4CUc%=F z!$mEUgBngOzGnHA@V5{^dn3RtD+x4Jryut4fNOKH5pQ{sVw6>H1^=Nj#%#v)k^6#fWW#4$#S3 zB?{jp=@J1CBPN_q9%SY+xSPiQ*(%^{T zjO_l@ON@tu*`0pNb}mHu9dbmuZmPMp46P*e(>Z5`MLPZ-B9fKB$cZ!9$$l`~Rtb_h zX1RWF5&zpAp|D+EACBDPAJ^Q@j@h{Pxf|}res>{3Ndmm$*vv?ak@82YQi>+0CM3K0 z<~fNKT-+25gtL$pDE+l3U#AY17_#TzV(IWwz}c)3$&t!1y%Km98*!o&e7`f zbRNsOW7dFIGcJdh>ZM$Hk3Zvp2J32j_Ov&ATH(5TeGznA5VE9ErJL}P`vSumm z;$CCZFJ|`~o=G^n@fM*@zy89CIrbVr8guD-LlyomH|uFjr{0swvABO$L+#d8Smfgi zFgh5^ha0@S*^!S#GRIeY9%Bs5Z@rz_n3xb7TCFerktpdFeR!rF!SZ<|4eZH14P*8C zm~blE^&($eL5H=~&n%L##A0>WIu-kXsY>_w=mw z_~ai-8pWN?71?rtfG~Usb=HM#_iXA2_!~NBDWn)?Ech*-rDZ)en0pM`sc32HyAN}} zxLX)6#NIx_9^p+P@v61T6SrX_B|gBhUpK2&YJb-Rl2MF3`I9@o&Fep^>@bu0Ui7gKHQAISBA5WQeS9XIrhgwW-GqEL-s4@ z<<-egCKjV|R5~M(*K;_tZ<>nOC5>T4`?4b1|ImH`j_&~i3hJ>NLjrj`cs~gT*lfdG zJ=IzC_-d*NLjx2|`biTmhdRJXG9j;Kiq`Izh4qNGuGsfE9jpdtVp={$YLUklA%%Nc zFik7lWEpwl(TE(Lia|-M`p0|YE)61zsO^lAZZ&OPe?9{8s@P3oLLQ@<{ck9AE8*wR zyU`vLCbGQxc&hJ{sg|_#d@{W@U%OXS@+7(NF;w8$%D@{x!C03!@31yl16mXv97P=T zAC~Vc(%6`XH_@{pbXo8E!^8c8=ZL;c?L1uHP{0t&SlGjPvU4XfJU=s&NC1^)r4B;4 z+w#pc4Kx(|@b958x1|(c;H|WF&CK<-rm!FW$!{j^dZZc! z@ZCg6NbeKe-gAUi1v{qwH~Kxp4p|+Lpe!?3(KW%p_FcN!c7E2Z#$ftQf9+lor0Ldh z`x`$RY7-fr>hI~~i4OmPu9&M&=b}u%-^{Dgx&jm{-NVz{;2b|f`9qPyd=;m47A}e( zerou8sJp6YpIjOpeI!ib$XoE2Y>jC z`tT^-W(@pxzwZ@rIG#Y(h)%Z4pB}0C{%B#DhzZ}W#0QRY0!y!^rm+j3QvYwL%5gQ4 zH_CTL;aUI5yiqQX?hf~{*CV4l!}wBlLKFNT-xDsIfq|o>aS<$`i7f{BxFnZ3$)d%>zCFjzbl#Yv^Lz#JIFiif8kdfc1Dn`U2W%~b-r(44$+PU80l?? z>&9VqreEG;QUJxki#Ahvpf9|J)G#@iZF!#koq9`bM@NMYgvTl`{pt*C=r&rTnn9R7 zhP?UhT9=4%O20g1lb;%Qx$=khWzZ$Js{usJfAyo)zQp~l-M$qmhf2@8ddqlgAY*7` zgFZ;(bNr#G_~7t&I!ul23@~i_M#8<^p9JM6YUrW&m-m6ezEPvOA-pc$cF|eQq5S5Z zGVB$tvn)~CL$}dOzd`|@ym^V#dC$e+11&5c%IMcXt0wokOR|cHRGSX^CDbEOI zR;9$dIZFE&%N|MWN#w+{Ndri`Pa*tSD)Ad2Gc%#IRA141VQOx15~y&3kr(^T2(eso!oYoxEcN>*l2i&l&=*v+ z9C|XxLzcd;N83&nPKp)PB6YlKsH&_KDh2_cmR!%)< zYHmf}tcTFus>^A#hwSxdrluS-G$;){SE4h9)};3+VsouskTQlAY>mjXqXYK&D^@zb0tM<4bN^1ly zm<0KyL6RjY<^`{IR+c%L*RUHy3J>Ahe2Mnlvt}Au4e(w~F+n_3Xk5@A!hN}>n(WRv zFm{RwERU#2X3*3|*d0ToUJq$a)m@$S6k36_D=(W%$W9jNzXoDXF=IWZ z_0mwwdX)lwl_Go9R;A%$Sh}jn$?OriR|Lhs@ABZki?Ulkh|Pso3D~+Z88vMo223Jo zwhn$@$CvjAAfsp%dCk=(%m9pBNgC(;t)YZmO6KIV2YD*|i7!u{_E(FBO&k-V!E}Qi zC{-hWfpyndv-<1V^Px^;W%iS5gvhVSTp)-4o0L}}$coWt6r#n_q+?8y;K37B-C)BC zxn4)bLpp;r#gv5A{{IXpqC`1OxrRu*9SB@syN?)WzFiOWtBvbTf~LV}dYZPNgs#>D zslJ}uUTVkM#Zv7X-`>oRo?$+z(pLj~UI0Ku^vZL(+R1DpTsPH9tJ=?3Ee)3UK!2Mg zbxvfovIQaLA25^CMKR05Il<<9M>@E93jj+lGr@d9k5I|!Fbc3yweIm>RWMyF?etB9 zzeDP+TQC3j?(iX~A!>WK9~FKNfm^x}#^he-cKVG*^(U8$>nj}dWbhuVb>BUnBeXJ^ z&*-;BPhH_WwSb&Cg#VhotXQjLNfj1f^bIu0z8{~N4DCqg>W^2NF?#vKUI2qz(jA8> z??*ta5Or7Fgr*v2-iHXTE*M_5+!}Kj3oX)lhvM)YZSSsauk4oCwurUjiD*9TtEusC z;pO1i@EV?5-XtaKj?P9TguHTAc2IV?%hNs8f(%qD^A*x0@E(POaxXaGD*wx#0?P@Pr zDb8S`5!r3%VUbxp^&Xr*74z;izQ557Frd3#OTrpv)3;|JKk=Fa`P@&4uKWGwUD?=a zv!IKs+<;z&IWWj9%qC{a#MLZK@OMPn!DooC}rj#aqSiQn=y?n?o;*^Jw$PEi(i7-k0iy^1>SxRG*$%$ z1Qwg8uac?N;N~3p{!KkzGMJWjY3Cx^4hBXv&Vt?9H&)chAivR^A1RBFUXntN`m_%sJPX6ns4w2vSC{1Go%itu> zKkV8(^eO$;GX6N6dMwcg)*+<-8e&fPgB{$|U7x|8^!_WNgL}PNaJ@E#o;02j_oa~`d($Ku{Cg6Si#1550Q30(hj;LW z!G}^fsRii8#dC9X)Yi|Q;uO_P@1q|rmYE%U-8L1zeATHV$}sl z<(@~XIl`~8$X3Jo2tAyxAZE2Aw4I84DXeByI&E5otRiYNR54{e>o_`kd+xgXrze~g zFI;=hy|s}CfT}gYoXuFNcB~FX_PsJ_)8x#SVwI=MIXxFkD>>i$L%bO_wU-Rtw8gKV zijJi;OmQK%ILeJYX|}$e@u(P;O#^~~pU|HbaZf~x$Mjxjgq)3RcHy`|H~c8p}-v1PeR3@^ktQ)2Yu=(?tCj z^S=lXX9?+6leR`B$^b(SX)m2 zhO`*VvDcB`2LNB8jQ4yE*~@`L;x2_b=6s2lyoKXuCu;_p&sYJnSv0hUHz&qf*}omC zZ}Noo+m5eb{5aQF0_*_!luroyWAo9Z4A>ZL;^GH@{PXKT zYMw?J^NU1QJg7MX?R$%~TM17RQx_-Y#s0O}rN_y1Ta7c*hF^9kcJVu>B3T;>r9vNQ zigzs-cz+MEGx`t7t+NKU{Z&#jU6x}b^8267m@f>+i@_=VYws)2T$a@{S4D%BY&|@P zX60XxE|*4DH9;Cxt||i%P3E-kf22nhLt1XZ$|rMOnt^yW^h@_N1mwyc=n{~ zSjqdev%HPK+*_hP`byZ-tn>_}e>y`cMmy6G)on*N-QK>#iP|SXQOD76XECR4OoC2Y zx1W(Ir^gEX=D~FN2Y*oWQ6x-b(9ahWpLigU%<>t-G?U|PLQ4D&gjJPu%n0-j*qRla zLRi(Xop=ro&sfl^H$y2Edztksyf{9QPc78cqhLE{&Ek@dzkG{gM5gDTI?q#i1>xP& z()V)UVS6h^+6SAx5};9NVT1=8J=u)B2)2lQ2f9svf4RM?`1ybdgQwUVYgL6FsN+ZT zYfuy4A4ifil)mmuQcxh`?PuzKH*fLlR0d3>ar|;%5iA~eBBQ$(L%?Q|F}t~SY?JMD z(pKy}xH~*8Uw9;iD-BFOvKH1seH5o;F=`nEz5xG2rRsrsrSJVmPz5)QjZqA3Me*=b z@)w`rmEU!OT&iE_$He*N^&3~p!~ytEj64cHQZS^(h8YX={w!$Gfc3oZEda=MO`Ofo zG?|!zG9^*}a9O+Mvby1@bWMky(+}G$mr)+mgdfJySVz zvCQkonF<*9MB5sM(MZLU{7ScM5v2_NVG&2HrVzj3EskQ?_RZS$9P@QReR*keZq?qiB*OcR)w!DQG46mE-EjnqP9 zcEf)&fhya6e+b3uZO1b=f!RhNe}2w7QyP0}_qjBWbE=9#UW5{l_5S$vf&;&r_n|A6 zC6Ij-6%67<%`w~Ye-1z{zxBGVuAkUyxbEg~mAY?)zO~|3Zqz%3w^1>oPKkH7ClZ0Vk~7LyX-?L5(+(tBtBi+ylto&gd?a?B z$9bR`K~#)ST!m>4wNce=ED{y4-Pmker|7~8^2t{FHUjE;y7w)>5V(dXv7OGJbpN&o z9u=IpXj@$t5Ne;;hG6wS32uC;=RRqhy5k(xtT%Y7+o`ctz+z!Pr*68D!JAEbB_0=o zo)mb_W&y|VyC|*H!(@E(=v+ZkX>1ssJvwc>y*>N(l6!lq=}7|718WUI zH7R-BY&}`MT%|hmMX!7`*W%jrQ{$|@!z*e+3KZKX z?A!*$^8UfRhB&80^Dj;bxwFVi@$%EZsqEg#c;a#-13hK-Db|*$Y#`9dXQbZw`117L zyCE)H;%nsl880HR^(3TX1HoZ&pFZ|33(zMk@^h{BJp%k9qU+qg{F5pH6GA+?w=s;Si%H>m`8 z@wqlb*>jH1$b?m!;y8tP40CU4pNAcq@bV8)b9nPy=`8{Oj30(}A~lgCz%!lnUFIq; z0`K0-r~Wut+om2;=v`;c>f?jxUf52P4V=qGf=6agg;0yXc!+U=Btn7OTmcm+S#?T? zYoYMuTcDxnxg{gX$+#?k=C9siCV(=AME&pNv;gSF_6||B{V>}&>e>ml;h%1orhN^6 z_gOZ>ub$IndG>gi9$HZ6y`E*Pu6JNVK&q_JS~)u^KXfOac%JZ=5+Hwf9Ur{FQX~ZK zp?VHI>eayGcD)GYV5IHswB{Qge`37x2?NI6-F+N;w1KEk?TMLq&y*=-W#GQo7Ck!n z=WW$lLd2wuiQI8`>1{s4q5sXHY{7E_aet)~CSW%?s+#F#A&v-xeV7NfQ5U?w{*0Fb zb_Kk_Pt74_O11xw0gG~)NfONr>RSa1 zl}nqn&n6ak6_M?Ssrgg^Ew%+GG}D=3Ezoa-GlJ_fm9sXvJFM!*;fjIT=h!cFQ&01? z=;=+ZRDKOzxEuBTFl)p-;5I3)qYDNPd`Fa@bjZvLQw=D5GV%(^Ne8SmqyelE@@rng z;L}HmRE!p4UzMK#kwi?^Ogt^NKcI1@!8^YFK?Z<3y*AxnF z=S@6NJ4+PZPtM!M(|hNgGAR>szq<`8Ef|OC^m>McsI2jP(@8)4Z3EEhn1Zi!D}ZVL z=Iphl_aA^v1JmY&Fc~2%TO+`aFWZ9kRL-a&No-?AU}>&q`|@eNf~xO=)rRt7e8uNI zR^>AGh$hp0|1isDX!*Sjz(FSA?MwSz#NBj;cqpiGFNDg4mS`RWTx;t-Zb79aPIYxc z^A8fFzzLkL%^G85<46^wek~xC3d=7q%4ad+qT}sF+{^)OKE6<%Bh}d=xI(q8b+OE% z1YF)YXk9LH_GJ&+>peCpxmb32lhbGZ4T<)Tj=(ZcFT= zu#AaK4Z&;T+RUudEW28Un7F5!+`d2X;fs2oBY`M;2zabb!)hI@Pg9R4j3NvV6{Su(pcv;`uPNHg)Hve zkbDltc#cOZs+nU%VUTXqUphfB{+V1z;ulmlVT@ zy#rrV3ZL~aS4O^m3yoV;h`l46O&(wP1_0}}+}fk2=V;Ch9J79i#5t>O-xz9to0A$? z45Wfu&Swx<#XhGcdRP9vFGN|G7TeB=Xrj|eMPxD@{O9JcYu4`JY?#ga2Z4CNt0aDg z8_-fos5(Db^ripz02dmmE5TqP?UZ$X>PLF4wtLBla#MDpSy=bP}q zAK?LJEE|WLXXziYY}I;89==$O3BQrP|SOyNaC0B_Xz}qq38+|JuPRJhsjvo)7g^gq?zfD z@djBzC(22d@4h1Pk3|DvG(cDZAMG5PVM(+|U}S&jwZP|`q0&3s^@N2-f(rQSi)wUO zwxytc=ky@CA#Hv&VbC7~=mxu>T0OM9OvcGYSP>TR4gSa~*3-kYhW)LJR7lD@kWV@) zK>g;_f(u2OKimm@0oWuG1H>x0nis|?;G)5UC*bz8Q8w0+VBJTUnlYG|+j*&iB)dU> z?K71jy%vbXjztdJQN3Jut?uWc?fdR0e)B2+%&oawpGn2q(s_ zqrH}>@7WqK)+*JEZ5q5ECwy6Ziz-7ZoUMZdYdEsplut~v*$g_vSU!bldLV+*lPoOR}!7%v|&M5=}B`p2U{{!cq#y&c#*H`YMUZ~Yj=Da9a z_6ro)j*}~j5V$o4it}u$s`iZ+Bl};nz{~xVFMC1vEO_L;5gQw?mqE^e#Zww^@HSsW zb^&&9)6c@m0K!om4TL$_VCoYCZIP`H+&7))?2btVgwp9cyw5Et{3SckG{VB0RLoRz820|Ex98& zTF;tqc-Jjhh|o#z?>=2|VM!G)^=w4?n$9qtT^cld=4}{SSiI-t>khdip3fJ1t9lRm zcj$lG{4{j6Dh}L4R?0bEmDt-j|Go#P+x|~`SN;#>_x8=8lo3&u zR3uB;muzL3kg{)~>`OED>`Rknq%2voWEpEH*_rI7qOz13gG81Pl9Vi2%2v<02YsIZ z;QLGS<9W?}?sK1WuIs$7|F=$aEV=sb5{klKqdFYLcBy#DgpgfI{w-+^8#Ax1uXKXc=7SH1X zSY$?~zM3~Y1!2&t6uZ^Z#i7`VamC;r!_#b8sN*))0CdMu&wR1(m()}9+>%LHqoPEsbsqM6BlPw)h{PgVX+K^Yh-b%vl)mU)Chc5#1 z@rMtwiGT({=MQ6k%ySz3CY0XF!a=>>Eva=GS1pX0S+!l?-Lqv1ZNg4u)oiJ<`v&C+ z;F~y#WcAqq!3Y}6&*z4Y*v469=Fq|TuJ_B}5Ho49cyl^1H-O&A_1F8e;=eKd2r;M!ybw(kC|g&gwSxH4Qd^td>QQv>^3Zjb<5fpc1x~ zq4>~WKc-nYVV>zjQZZyv)lBQV(;>0I3*p&1Ud>j7^Zad4dPQ@i_HMQoj*hg@sgwo9 z0UwX5o1YMGrHSJz4M>&?G53V5 zvJQmMY5M{#X9Oy1E756t!uWcMST9ON<)`Vs&$K>yajik*W^qpT#C=a`J$a zVp3%vVTe~wK8a6B5q3^9jvsqu%-J?8HeBQ8-f3Hw9p-hy28y+-&+K~#`1CGaK?*yC ztG?*v#a|FgRlJ&$j2qXf7w2IqLAZu$9!NAOdllQ!qZcBzdtc(i61%A8g6u&N-VAeugB6bNw%!7 zH%wWp0WRa5%zFNMINS(?o(JE3xmXQ{GqIoKwxWw?-=GzkV}_*z?qDIn(l|fPr@KgO zA`sd~ddKGH=Dv5PfIy@-CMR;$ZP+}2%|O*Cw^!Xkkdwsfz1r9(Bz8q4<@L4UJ6l1J z)l?)5yo|{=8GQj&OWR>~okw_(zq)TaaAvZQU7~`tR&g+%Pv(KrZ-Ot%;`3u2{x`LD zS7)Z)%r3IL@Um33pZQ`ax%!i@pRZo%4p5(uJf?HM0>&LzI8Z}u8q7jTD67@(W1aj- zmm~Oy14p_1lj+EjOCk2!KS)_pCDI8}XD*QIGdeq$rcN~nvq``lDtMG*3yv|6cV z0a>ME*GG~J!{MQz=rw;v-;q<`%vJ#QmP_7L=W3j;p3BBFl|@$JlZ`yy>x#mBoRwh) ze3n2)W?sfbKqPu;O7Mwz@2H-TX|<{gB~>GHqNzmr%$F^$G8cIgBCl?OTC)w9^>u}b zt{A)@Fxu41pUg<*A^OI!V_>@^1+n$R)D9v_nV zEwL*9U%rss#t=0?oORAS;E?H|O&TIjNR!jDXMc#SNXY;Fh7E15rC-%rj z4){G<f--rJg(4T~6k4xei(ey&Kpp+@U+?_JiRq-tex9 zwcJ?Ge2MD>z7wY^GvS2xWTyQQoptlIhiZfRB$9{#A zQ=b`!ROn)c0kVKp;=+c+ap|oJX$u>fr#^4i9MB+>`-%xhUP$Uy1|4xX{vG*c0g8V! zpQiq~BQi1E4`@&g*_m;VqS;0>9aCmKeNBRuy>toU-ssz-Tj*nm!)Z}dM125h?Es_| zG!K>^4Pj6q4KGZsOx(=My3;biST|Qb>aGy{j&6ICF9d`p81n`XjaT-DgMdZfLU9?v zP;fQdQ#YgTds&fTzV`jxIBYJwie+y{N!r!oD-E-6*42PB8qKjJMvYMNZ9`~o@AG4{ zx|^1*4(OyCQ|r<~V!G%8SJ&i-RB16#7MJnYM(u1lF5ljJp>Q7!f+g*AZ#5KWOFwth zB*IKlV9(f~m}n{DPCi@hoD#vH%nQIuic&zjz{-MU?_#1A2Ynf0QCE!LHnL3$jfsa2 zMumY3w9(T3kUw-$+IFI3zP6Ulg5XP_`8LC1J`Ow)V1J3nLEg+2)@YRNqdiTW7lcY& z#FB4B1csUW<+PUK&Nq%Qg@OV-d%Bx7OA# zsr}9wUhPNZ@M876Xb}g~f&we^L<9tetMitl_{-!l8+$FREgGNRm8hi_fIB{l@q&&W zBvK^Qes2fkuv?1qKy~?MrWs19ICDG*J({}?5Ra_W+R^*RGO#D$Rg?26-U;JP05}#z z#D`e;HhL{*RtDi0KMHQES)><@+Wym~jasGreJ)qSdYWfDQWX32Tqqp?)G?3=v6fL@ zX$r&t8FEehy^M?fru6>Di<9nXjF|hNrBTt8x4xe%Je-bHd7s1FVSKx5aJFIQB%;;V z#z0tT>+5ol^mQ$UgJ}Q?2cK2!G%lX{9Kx4yT;>m_zjz*+axN^G!xTq5me)5|tEOFu zizWr0>e&+TsvaK>v*$PR9ug}-v^B%uc!lFJy*|tK@SE#sTh@AB*gP;LDh|kI%(ISO zzkd32=4S|7%qY1pds2o4MNA=JjI&vNH|XsWHs0-CJ6C=~Lgt7C?e+<9sl0j7|9$oo zv$7Jw_sKc$^Z4^Ohe}$}W-g*3T{PlMTxL)3tWLvmYPv+!aqF4rR(WfGmUVn-2X3MU| zshqLSf`u7wFOfCOGy6;`F#URUT}*^4j3&Rll$v%iUE2z7ORI)CT>Cnl!=l)!ABvN! zG`5?)+v_w9wse!i;0sxF`YHq&<1hQ=^*uLR-#6ndj1)4x!0JR8-rVO*P|rVGrjFv%p!Y)`H=kg?5g2MkfljN^5=GqB9sYD^cvtL#kdBzJH+&!8_(63v@qN?(~ z`)ve&`f*0vROty%I0Nba&|P0&sQUY21*2)FwqB}+orPV@#un@}6GC$Wll10Lmh{Oc zX=T~E5<=bk5xEgi#}g zQCfj<2gQX((E!MhC3gj%|O}(0Dub~&^=mO2>7^`WJ<3Zm(Z%*y!iMreg<>eil$qI4W+V; zi@4(pvEx8tEwevMxW1CZ>+!&^>b+Vj+z??&C7)a4Bz@jIX}R7(~iKy={1499vgbc zWCyHpGc{okQdecg^yK=wnDjvaXjA9z_XGHL*Vof77~qf)vLjHN0+$v=;;3M5v@z^y z#**p+HKUs$pDn%%hBSxRf*I6wi!#`u83+H3)M@qr`SGIm=-^=UnZygS_AcsyrcwDg za(0D?KwEG*HP_a+(9{oG_(s07P3?+SywoB#3N;OQo zU|RF_Bm9MOUq-3R?t-K(@SV>ZNGU-MdXOcp;OL?@pxqMe>3Ath;mOy#Jw^4gZnA z37b|w-A%TZqHX|q>3?{g^Lp}R9XN)c+Mfr^m}?-gwGnJu_n1&8YaZ8O!m}FJi5`x4 zpxv1p_GDK$^v$_ZaH&V*c4N4ffqQa`Z}IG`(XDI;BCBy3r%=&FBw z_w{CU4*`hgM+))qcxER4s`wT8NAPBQar}POXmH_jcYAgla-*oFL=5z0cAsOq6b=B% zwZci<-)-{oAh0yWg?C4T#hwS&DaXT;`V8A=ELcErV*_&T?HIZ2YQPtA{w%!jKcg3P zu;*U~|K{M|KA?hx>7Ok8n}dJ*0N|m2vhY8cgO7jq8mwDg*0GfGqyj&U3%Y9MDmJ(N E561!B@Bjb+ diff --git a/src/plugins/tile_map/public/__tests__/shaded_geohash_grid.png b/src/plugins/tile_map/public/__tests__/shaded_geohash_grid.png deleted file mode 100644 index e0b19dc61932346d404040124bcafa448f502f89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10196 zcmeI2eNYbR|*lU67oVraFcDv-M40b&b-Zi27^V#MT{Oq)&uQNxP?Oauf9B)JVF2J&*Vn;Y6~f9#x{{j+o2{Ud+; za_@O^@9%k@@8^4;+~0i?9kJSNgBuQqTfP6|eZR)x9I3XC>k8zX7ygmI$Kmj}{rlcO zoSmqaD|-}%1hE#%Op2)mx%z11tuNX#+UaMVSPgHg0>b2%`nSBbzC?HJ zq;rhNRUeZ}bJOVXe0!Z|o5xcc9|CGz}veTBH-xqQfJm!}7{cGcJ_NBhwt;=*d| z5Vjk(vcYPj2x|vS956k^=zwAr(ZggfDzMlEnAP_`TWH}a^z?2&@*cjafA;(N@1;{b z3NyXBaUftj)o7A+$Riox{Nw8}Q#l}b0M%31-G2`6CYriQw{ORvu2m}J3ZTD!PcKNy zTpTJ7D}27#!EY~^lbKBsmY~gQAS0Ddr{4qtL*G-rKDWR!|Hq*nduETC^X#lXwyC(0 zlBN4WQ^lO_Q`AhnwHclx5O$~O?&&&P3-rT2fOVLZ0Jia&Cw3Xkyf_#xV=2PAfjny% zzy8*!ROgMkVWPrBET!3>f8AxUhr&sr48-bsD@&*V& z>uhGOc-9e#s^iwd&+e@!*Tnl*wwK76Vs1ihaDM)6>zE(1R46pFW8yZ@`p6%!wsQ;8 zJG;BOs6K9TCeLZhyYwn$}ZIRPmoiyva%SxTDY5~QMC-s z%~cZkS!tI*h+(fWr{XNii%^-1Op|eHI9{@jDicxz3xcC$1h4jzNA8u0v0+Oba%8!0 zZfXSxjQ=>%BaRVkd`a_Fo27cn>Gv*nCFaZwY-3sqfJ#(B4tpniQ_0aWP3pb0Mj82O zjq{`uo)%?Tg#iUiXmPc2Eu*EhJ*;%&Q*SPJ5>nnuTTrP-HuDYjkom6lvp})Sv*oK> zfz*q`_+Pmm)H1wf6)Iw{#)h*4HzctG&+2xf&oRf2IZy_Z^C^R_kEQ72OmVSuNnE|Q zG;Yhsq`jyZukbqWE#K|*t0Z&tjSB7ha_izF+ENDC_9Rtd97{6)_@K!&1iyl&2v6)n0(A!`Bp_lK zk~?)UXga%J%^~s5oPiV>s?yd(&LjjH2(%&7W`0mYt(kCyx$38s<80ZyHzI2O;wMN= zxFL`l`9FsgLIM#NT!a}U!+lv#%RufLX|4ED^G&a#GFZ&oB+(j%T-H`tVXjpx0~R@e z+3W)-m2cS1%&dEWdpl@0Rg!|!RQLWgdAui1lv)7rcLfKt*Z776kl9a@2teW7G|4hY z;=L}JwHie3cG~;f7*rMn=4C=ZD5{uJU~b-4wI7F zI3vFRI`;;7H}j<@hc&uy8}TSeJ)i$#is*-qBL5SGFWDNtK)Lzp4k-gt zsifM5e}_T`N=4gvK$OyCGuK`mM&D9RFI78;y0X5F=HH^*^+{Yf`!|VFwS9&b{)Zys z#cJ7c`}nQ+0m7^K+|z#cw)@(tB(A?^lbu1XhY<)}9b$&sCDP+pc*)mOx>wPd;n%(` zB3{2!H?q1U8A$g@fZ&1ZR`_(P+C!?_25G{!K`j-L89lgZTBgTc@+^VekjS z*&p`Kyt905Cmkq9a>BaS+b4sEki?#fF1H(hr?(O3|6q<+i!$5e^K~B7L(E(|Ve!~4 zVp+rr73)QtQekp~DJljHJF_t^VqC Date: Mon, 10 Aug 2020 15:30:22 -0400 Subject: [PATCH 079/106] [Bug][Security_Solution][Telemetry] Capitalize S in macOS (#74688) --- .../plugins/security_solution/server/usage/endpoints/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/server/usage/endpoints/index.ts b/x-pack/plugins/security_solution/server/usage/endpoints/index.ts index 19beda4554d93..f1ce9d3ad6ff3 100644 --- a/x-pack/plugins/security_solution/server/usage/endpoints/index.ts +++ b/x-pack/plugins/security_solution/server/usage/endpoints/index.ts @@ -33,7 +33,7 @@ export interface EndpointUsage { policies: PoliciesTelemetry; } -type EndpointOSNames = 'Linux' | 'Windows' | 'macOs'; +type EndpointOSNames = 'Linux' | 'Windows' | 'macOS'; export interface AgentLocalMetadata extends AgentMetadata { elastic: { @@ -129,7 +129,7 @@ export const updateEndpointPolicyTelemetry = ( ): PoliciesTelemetry => { const policyHostTypeToPolicyType = { Linux: 'linux', - macOs: 'mac', + macOS: 'mac', Windows: 'windows', }; const enabledMalwarePolicyTypes = ['prevent', 'detect']; From 8f15621cbd4f5fb2c5af8d3972865ba5e0e44ed5 Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Mon, 10 Aug 2020 14:35:44 -0500 Subject: [PATCH 080/106] [Metrics UI] Fix No Data preview pluralization (#74399) Co-authored-by: Elastic Machine --- .../common/components/alert_preview.tsx | 17 +++++++++++++++-- .../translations/translations/ja-JP.json | 3 ++- .../translations/translations/zh-CN.json | 3 ++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/infra/public/alerting/common/components/alert_preview.tsx b/x-pack/plugins/infra/public/alerting/common/components/alert_preview.tsx index 9d28ef71a5518..877d047c941d4 100644 --- a/x-pack/plugins/infra/public/alerting/common/components/alert_preview.tsx +++ b/x-pack/plugins/infra/public/alerting/common/components/alert_preview.tsx @@ -186,9 +186,22 @@ export const AlertPreview: React.FC = (props) => { {showNoDataResults && previewResult.resultTotals.noData ? ( {previewResult.resultTotals.noData}, + boldedResultsNumber: ( + + {i18n.translate( + 'xpack.infra.metrics.alertFlyout.alertPreviewNoDataResultNumber', + { + defaultMessage: + '{noData, plural, one {was # result} other {were # results}}', + values: { + noData: previewResult.resultTotals.noData, + }, + } + )} + + ), }} /> ) : null}{' '} diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index c2f180f5268d4..05f709f04aa88 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -8830,7 +8830,8 @@ "xpack.infra.metrics.alertFlyout.alertPreviewErrorResult": "一部のデータを評価するときにエラーが発生しました。", "xpack.infra.metrics.alertFlyout.alertPreviewGroups": "{numberOfGroups} {groupName}", "xpack.infra.metrics.alertFlyout.alertPreviewGroupsAcross": "すべてを対象にする", - "xpack.infra.metrics.alertFlyout.alertPreviewNoDataResult": "データがない {noData}結果がありました。", + "xpack.infra.metrics.alertFlyout.alertPreviewNoDataResult": "データがない {boldedResultsNumber}結果がありました。", + "xpack.infra.metrics.alertFlyout.alertPreviewNoDataResultNumber": "{noData}", "xpack.infra.metrics.alertFlyout.alertPreviewResult": "このアラートは{firedTimes}回発生しました", "xpack.infra.metrics.alertFlyout.alertPreviewResultLookback": "過去{lookback}", "xpack.infra.metrics.alertFlyout.conditions": "条件", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 84c3eab8db9e7..bd0066eeb419f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -8832,7 +8832,8 @@ "xpack.infra.metrics.alertFlyout.alertPreviewErrorResult": "尝试评估部分数据时发生错误。", "xpack.infra.metrics.alertFlyout.alertPreviewGroups": "{numberOfGroups} 个{groupName}", "xpack.infra.metrics.alertFlyout.alertPreviewGroupsAcross": "在", - "xpack.infra.metrics.alertFlyout.alertPreviewNoDataResult": "存在 {noData} 个无数据结果。", + "xpack.infra.metrics.alertFlyout.alertPreviewNoDataResult": "存在 {boldedResultsNumber} 个无数据结果。", + "xpack.infra.metrics.alertFlyout.alertPreviewNoDataResultNumber": "{noData}", "xpack.infra.metrics.alertFlyout.alertPreviewResult": "此告警将发生 {firedTimes}", "xpack.infra.metrics.alertFlyout.alertPreviewResultLookback": "在过去 {lookback}。", "xpack.infra.metrics.alertFlyout.conditions": "条件", From 4ee483be235ce9a0105d95e22c392e8dded68d41 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Mon, 10 Aug 2020 17:18:36 -0400 Subject: [PATCH 081/106] [ML] ML on Kibana Management: Add ability to pass a group ID filter to job management page (#74533) * handle group id in url for anomaly detection * filter analytics list by group id. * handle list of groupIds * ensure analytics can handle jobid in url. rename util function * add tests for getSelectedIdFromUrl and getGroupQueryText * keep groupIds as array of strings and jobId as single string * fix tests and update types --- .../analytics_list/analytics_list.tsx | 25 ++++++---- .../components/analytics_list/use_columns.tsx | 4 +- .../job_filter_bar/job_filter_bar.js | 26 ++++++---- .../components/jobs_list/job_description.js | 17 +++++-- .../components/jobs_list/jobs_list.js | 8 ++-- .../jobs/jobs_list/components/utils.d.ts | 4 +- .../jobs/jobs_list/components/utils.js | 21 +++++++-- .../jobs/jobs_list/components/utils.test.ts | 47 +++++++++++++++++++ .../public/application/util/get_job_id_url.ts | 20 -------- .../application/util/get_selected_ids_url.ts | 39 +++++++++++++++ 10 files changed, 160 insertions(+), 51 deletions(-) create mode 100644 x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.test.ts delete mode 100644 x-pack/plugins/ml/public/application/util/get_job_id_url.ts create mode 100644 x-pack/plugins/ml/public/application/util/get_selected_ids_url.ts diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx index 90e24f6da5d0a..0652ec5f8acb1 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx @@ -38,7 +38,10 @@ import { getTaskStateBadge, getJobTypeBadge, useColumns } from './use_columns'; import { ExpandedRow } from './expanded_row'; import { AnalyticStatsBarStats, StatsBar } from '../../../../../components/stats_bar'; import { CreateAnalyticsButton } from '../create_analytics_button'; -import { getSelectedJobIdFromUrl } from '../../../../../jobs/jobs_list/components/utils'; +import { + getSelectedIdFromUrl, + getGroupQueryText, +} from '../../../../../jobs/jobs_list/components/utils'; import { SourceSelection } from '../source_selection'; function getItemIdToExpandedRowMap( @@ -99,16 +102,22 @@ export const DataFrameAnalyticsList: FC = ({ // Query text/job_id based on url but only after getAnalytics is done first // selectedJobIdFromUrlInitialized makes sure the query is only run once since analytics is being refreshed constantly - const [selectedJobIdFromUrlInitialized, setSelectedJobIdFromUrlInitialized] = useState(false); + const [selectedIdFromUrlInitialized, setSelectedIdFromUrlInitialized] = useState(false); useEffect(() => { - if (selectedJobIdFromUrlInitialized === false && analytics.length > 0) { - const selectedJobIdFromUrl = getSelectedJobIdFromUrl(window.location.href); - if (selectedJobIdFromUrl !== undefined) { - setSelectedJobIdFromUrlInitialized(true); - setSearchQueryText(selectedJobIdFromUrl); + if (selectedIdFromUrlInitialized === false && analytics.length > 0) { + const { jobId, groupIds } = getSelectedIdFromUrl(window.location.href); + let queryText = ''; + + if (groupIds !== undefined) { + queryText = getGroupQueryText(groupIds); + } else if (jobId !== undefined) { + queryText = jobId; } + + setSelectedIdFromUrlInitialized(true); + setSearchQueryText(queryText); } - }, [selectedJobIdFromUrlInitialized, analytics]); + }, [selectedIdFromUrlInitialized, analytics]); // Subscribe to the refresh observable to trigger reloading the analytics list. useRefreshAnalyticsList({ diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_columns.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_columns.tsx index 9ed87ff9f8312..7001681b6917a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_columns.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_columns.tsx @@ -19,7 +19,7 @@ import { EuiLink, RIGHT_ALIGNMENT, } from '@elastic/eui'; -import { getJobIdUrl } from '../../../../../util/get_job_id_url'; +import { getJobIdUrl, TAB_IDS } from '../../../../../util/get_selected_ids_url'; import { getAnalysisType, DataFrameAnalyticsId } from '../../../../common'; import { @@ -137,7 +137,7 @@ export const progressColumn = { }; export const getDFAnalyticsJobIdLink = (item: DataFrameAnalyticsListRow) => ( - {item.id} + {item.id} ); export const useColumns = ( diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_filter_bar/job_filter_bar.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_filter_bar/job_filter_bar.js index b274a8d572adb..6eb7b00e5620c 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_filter_bar/job_filter_bar.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_filter_bar/job_filter_bar.js @@ -9,7 +9,7 @@ import React, { Component, Fragment } from 'react'; import { ml } from '../../../../services/ml_api_service'; import { JobGroup } from '../job_group'; -import { getSelectedJobIdFromUrl, clearSelectedJobIdFromUrl } from '../utils'; +import { getGroupQueryText, getSelectedIdFromUrl, clearSelectedJobIdFromUrl } from '../utils'; import { EuiSearchBar, EuiFlexGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -54,15 +54,23 @@ export class JobFilterBar extends Component { componentDidMount() { // If job id is selected in url, filter table to that id - const selectedId = getSelectedJobIdFromUrl(window.location.href); - if (selectedId !== undefined) { + let defaultQueryText; + const { jobId, groupIds } = getSelectedIdFromUrl(window.location.href); + + if (groupIds !== undefined) { + defaultQueryText = getGroupQueryText(groupIds); + } else if (jobId !== undefined) { + defaultQueryText = jobId; + } + + if (defaultQueryText !== undefined) { this.setState( { - selectedId, + defaultQueryText, }, () => { // trigger onChange with query for job id to trigger table filter - const query = EuiSearchBar.Query.parse(selectedId); + const query = EuiSearchBar.Query.parse(defaultQueryText); this.onChange({ query }); } ); @@ -87,7 +95,7 @@ export class JobFilterBar extends Component { }; render() { - const { error, selectedId } = this.state; + const { error, defaultQueryText } = this.state; const filters = [ { type: 'field_value_toggle_group', @@ -147,7 +155,7 @@ export class JobFilterBar extends Component { return ( - {selectedId === undefined && ( + {defaultQueryText === undefined && ( )} - {selectedId !== undefined && ( + {defaultQueryText !== undefined && (

    ); } JobDescription.propTypes = { job: PropTypes.object.isRequired, + isManagementTable: PropTypes.bool, }; diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list/jobs_list.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list/jobs_list.js index 23b68551ca0f5..f90bbf3cf3fe6 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list/jobs_list.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list/jobs_list.js @@ -14,7 +14,7 @@ import { toLocaleString } from '../../../../util/string_utils'; import { ResultLinks, actionsMenuContent } from '../job_actions'; import { JobDescription } from './job_description'; import { JobIcon } from '../../../../components/job_message_icon'; -import { getJobIdUrl } from '../../../../util/get_job_id_url'; +import { getJobIdUrl, TAB_IDS } from '../../../../util/get_selected_ids_url'; import { TIME_FORMAT } from '../../../../../../common/constants/time_format'; import { EuiBadge, EuiBasicTable, EuiButtonIcon, EuiLink, EuiScreenReaderOnly } from '@elastic/eui'; @@ -71,7 +71,7 @@ export class JobsList extends Component { return id; } - return {id}; + return {id}; } getPageOfJobs(index, size, sortField, sortDirection) { @@ -189,7 +189,9 @@ export class JobsList extends Component { sortable: true, field: 'description', 'data-test-subj': 'mlJobListColumnDescription', - render: (description, item) => , + render: (description, item) => ( + + ), textOnly: true, width: '20%', }, diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.d.ts b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.d.ts index 5f72d155cbd5a..cf4fad9513de5 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.d.ts +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.d.ts @@ -3,5 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -export function getSelectedJobIdFromUrl(str: string): string; + +export function getSelectedIdFromUrl(str: string): { groupIds?: string[]; jobId?: string }; +export function getGroupQueryText(arr: string[]): string; export function clearSelectedJobIdFromUrl(str: string): void; diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js index 6fabd0299a936..913727bda67df 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js @@ -370,21 +370,34 @@ function getUrlVars(url) { return vars; } -export function getSelectedJobIdFromUrl(url) { +export function getSelectedIdFromUrl(url) { + const result = {}; if (typeof url === 'string') { + const isGroup = url.includes('groupIds'); url = decodeURIComponent(url); - if (url.includes('mlManagement') && url.includes('jobId')) { + + if (url.includes('mlManagement')) { const urlParams = getUrlVars(url); const decodedJson = rison.decode(urlParams.mlManagement); - return decodedJson.jobId; + + if (isGroup) { + result.groupIds = decodedJson.groupIds; + } else { + result.jobId = decodedJson.jobId; + } } } + return result; +} + +export function getGroupQueryText(groupIds) { + return `groups:(${groupIds.join(' or ')})`; } export function clearSelectedJobIdFromUrl(url) { if (typeof url === 'string') { url = decodeURIComponent(url); - if (url.includes('mlManagement') && url.includes('jobId')) { + if (url.includes('mlManagement') && (url.includes('jobId') || url.includes('groupIds'))) { const urlParams = getUrlVars(url); const clearedParams = `ml#/jobs?_g=${urlParams._g}`; window.history.replaceState({}, document.title, clearedParams); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.test.ts b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.test.ts new file mode 100644 index 0000000000000..e4c3c21c5a54a --- /dev/null +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.test.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getGroupQueryText, getSelectedIdFromUrl } from './utils'; + +describe('ML - Jobs List utils', () => { + const jobId = 'test_job_id_1'; + const jobIdUrl = `http://localhost:5601/aql/app/ml#/jobs?mlManagement=(jobId:${jobId})`; + const groupIdOne = 'test_group_id_1'; + const groupIdTwo = 'test_group_id_2'; + const groupIdsUrl = `http://localhost:5601/aql/app/ml#/jobs?mlManagement=(groupIds:!(${groupIdOne},${groupIdTwo}))`; + const groupIdUrl = `http://localhost:5601/aql/app/ml#/jobs?mlManagement=(groupIds:!(${groupIdOne}))`; + + describe('getSelectedIdFromUrl', () => { + it('should get selected job id from the url', () => { + const actual = getSelectedIdFromUrl(jobIdUrl); + expect(actual).toStrictEqual({ jobId }); + }); + + it('should get selected group ids from the url', () => { + const expected = { groupIds: [groupIdOne, groupIdTwo] }; + const actual = getSelectedIdFromUrl(groupIdsUrl); + expect(actual).toStrictEqual(expected); + }); + + it('should get selected group id from the url', () => { + const expected = { groupIds: [groupIdOne] }; + const actual = getSelectedIdFromUrl(groupIdUrl); + expect(actual).toStrictEqual(expected); + }); + }); + + describe('getGroupQueryText', () => { + it('should get query string for selected group ids', () => { + const actual = getGroupQueryText([groupIdOne, groupIdTwo]); + expect(actual).toBe(`groups:(${groupIdOne} or ${groupIdTwo})`); + }); + + it('should get query string for selected group id', () => { + const actual = getGroupQueryText([groupIdOne]); + expect(actual).toBe(`groups:(${groupIdOne})`); + }); + }); +}); diff --git a/x-pack/plugins/ml/public/application/util/get_job_id_url.ts b/x-pack/plugins/ml/public/application/util/get_job_id_url.ts deleted file mode 100644 index a6ca575f21b50..0000000000000 --- a/x-pack/plugins/ml/public/application/util/get_job_id_url.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import rison from 'rison-node'; - -import { getBasePath } from './dependency_cache'; - -export function getJobIdUrl(tabId: string, jobId: string): string { - // Create url for filtering by job id for kibana management table - const settings = { - jobId, - }; - const encoded = rison.encode(settings); - const url = `?mlManagement=${encoded}`; - const basePath = getBasePath(); - - return `${basePath.get()}/app/ml#/${tabId}${url}`; -} diff --git a/x-pack/plugins/ml/public/application/util/get_selected_ids_url.ts b/x-pack/plugins/ml/public/application/util/get_selected_ids_url.ts new file mode 100644 index 0000000000000..806626577008e --- /dev/null +++ b/x-pack/plugins/ml/public/application/util/get_selected_ids_url.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import rison from 'rison-node'; +import { getBasePath } from './dependency_cache'; + +export enum TAB_IDS { + DATA_FRAME_ANALYTICS = 'data_frame_analytics', + ANOMALY_DETECTION = 'jobs', +} + +function getSelectedIdsUrl(tabId: TAB_IDS, settings: { [key: string]: string | string[] }): string { + // Create url for filtering by job id or group ids for kibana management table + const encoded = rison.encode(settings); + const url = `?mlManagement=${encoded}`; + const basePath = getBasePath(); + + return `${basePath.get()}/app/ml#/${tabId}${url}`; +} + +// Create url for filtering by group ids for kibana management table +export function getGroupIdsUrl(tabId: TAB_IDS, ids: string[]): string { + const settings = { + groupIds: ids, + }; + + return getSelectedIdsUrl(tabId, settings); +} + +// Create url for filtering by job id for kibana management table +export function getJobIdUrl(tabId: TAB_IDS, id: string): string { + const settings = { + jobId: id, + }; + + return getSelectedIdsUrl(tabId, settings); +} From ae529879f26e415794e5f82bbfac7199b2f7fa55 Mon Sep 17 00:00:00 2001 From: Joel Griffith Date: Mon, 10 Aug 2020 16:07:12 -0700 Subject: [PATCH 082/106] Allow any hostname for chromium proxy bypass (#74693) * Allow any hostname for chromium proxy bypass * Adds a test for the proxy bypass config * Add wildcard to test --- .../reporting/server/config/schema.test.ts | 28 +++++++++++++++++++ .../plugins/reporting/server/config/schema.ts | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/reporting/server/config/schema.test.ts b/x-pack/plugins/reporting/server/config/schema.test.ts index ddd5491b661bc..69e4d443cf040 100644 --- a/x-pack/plugins/reporting/server/config/schema.test.ts +++ b/x-pack/plugins/reporting/server/config/schema.test.ts @@ -126,6 +126,34 @@ describe('Reporting Config Schema', () => { ).toMatchObject({ hostname: 'Frodo' }); }); + it('allows setting a wildcard for chrome proxy bypass', () => { + expect( + ConfigSchema.validate({ + capture: { + browser: { + chromium: { + proxy: { + enabled: true, + server: 'http://example.com:8080', + bypass: ['*.example.com', '*bar.example.com', 'bats.example.com'], + }, + }, + }, + }, + }).capture.browser.chromium.proxy + ).toMatchInlineSnapshot(` + Object { + "bypass": Array [ + "*.example.com", + "*bar.example.com", + "bats.example.com", + ], + "enabled": true, + "server": "http://example.com:8080", + } + `); + }); + it(`logs the proper validation messages`, () => { // kibanaServer const throwValidationErr = () => ConfigSchema.validate({ kibanaServer: { hostname: '0' } }); diff --git a/x-pack/plugins/reporting/server/config/schema.ts b/x-pack/plugins/reporting/server/config/schema.ts index 2f77aff0020d5..33249f20757e2 100644 --- a/x-pack/plugins/reporting/server/config/schema.ts +++ b/x-pack/plugins/reporting/server/config/schema.ts @@ -97,7 +97,7 @@ const CaptureSchema = schema.object({ bypass: schema.conditional( schema.siblingRef('enabled'), true, - schema.arrayOf(schema.string({ hostname: true })), + schema.arrayOf(schema.string()), schema.maybe(schema.never()) ), }), From 6bea373e8f61ca7ecf7cd81e93f7204a4173f015 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 11 Aug 2020 08:47:26 +0100 Subject: [PATCH 083/106] [ML] Adding initial file analysis overrides (#74376) * [ML] Adding initial file analysis overrides * using common default sample lines * correcting bottom padding * adding missed padding * code clean up * fixing translations Co-authored-by: Elastic Machine --- .../file_datavisualizer_view.js | 73 +++++++++++-------- .../file_error_callouts.tsx | 69 ++++++++++++------ .../file_based/components/utils/index.ts | 1 + .../file_based/components/utils/utils.ts | 2 +- 4 files changed, 91 insertions(+), 54 deletions(-) diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_datavisualizer_view.js b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_datavisualizer_view.js index 7cb545cd5a776..56b81e36f1e92 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_datavisualizer_view.js +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_datavisualizer_view.js @@ -20,6 +20,7 @@ import { EditFlyout } from '../edit_flyout'; import { ExplanationFlyout } from '../explanation_flyout'; import { ImportView } from '../import_view'; import { + DEFAULT_LINES_TO_SAMPLE, getMaxBytes, readFile, createUrlOverrides, @@ -55,7 +56,9 @@ export class FileDataVisualizerView extends Component { this.overrides = {}; this.previousOverrides = {}; - this.originalSettings = {}; + this.originalSettings = { + linesToSample: DEFAULT_LINES_TO_SAMPLE, + }; this.maxFileUploadBytes = getMaxBytes(); } @@ -129,7 +132,7 @@ export class FileDataVisualizerView extends Component { const serverSettings = processResults(resp); const serverOverrides = resp.overrides; - this.previousOverrides = this.overrides; + this.previousOverrides = overrides; this.overrides = {}; if (serverSettings.format === 'xml') { @@ -185,9 +188,8 @@ export class FileDataVisualizerView extends Component { serverError: error, }); - // as long as the previous overrides are different to the current overrides, // reload the results with the previous overrides - if (overrides !== undefined && isEqual(this.previousOverrides, overrides) === false) { + if (isRetry === false) { this.setState({ loading: true, loaded: false, @@ -244,6 +246,11 @@ export class FileDataVisualizerView extends Component { }; onCancel = () => { + this.overrides = {}; + this.previousOverrides = {}; + this.originalSettings = { + linesToSample: DEFAULT_LINES_TO_SAMPLE, + }; this.changeMode(MODE.READ); this.onFilePickerChange([]); }; @@ -276,7 +283,7 @@ export class FileDataVisualizerView extends Component { return (
    {mode === MODE.READ && ( - + <> {!loading && !loaded && } {loading && } @@ -286,10 +293,14 @@ export class FileDataVisualizerView extends Component { )} {fileCouldNotBeRead && loading === false && ( - - + <> + - + )} {loaded && ( @@ -298,8 +309,8 @@ export class FileDataVisualizerView extends Component { explanation={explanation} fileName={fileName} data={fileContents} - showEditFlyout={() => this.showEditFlyout()} - showExplanationFlyout={() => this.showExplanationFlyout()} + showEditFlyout={this.showEditFlyout} + showExplanationFlyout={this.showExplanationFlyout} disableButtons={isEditFlyoutVisible || isExplanationFlyoutVisible} /> )} @@ -317,19 +328,20 @@ export class FileDataVisualizerView extends Component { )} {bottomBarVisible && loaded && ( - + <> + + + )} - - - + )} {mode === MODE.IMPORT && ( - + <> {bottomBarVisible && ( - + <> + + + )} - - - + )}
    ); @@ -360,10 +373,10 @@ export class FileDataVisualizerView extends Component { function BottomPadding() { // padding for the BottomBar return ( - + <> - + ); } diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_error_callouts.tsx b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_error_callouts.tsx index 7333c96a0d8ea..d869676e48827 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_error_callouts.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_error_callouts.tsx @@ -7,7 +7,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React, { FC } from 'react'; -import { EuiCallOut, EuiSpacer } from '@elastic/eui'; +import { EuiCallOut, EuiSpacer, EuiButtonEmpty, EuiHorizontalRule } from '@elastic/eui'; import numeral from '@elastic/numeral'; import { ErrorResponse } from '../../../../../../common/types/errors'; @@ -77,34 +77,57 @@ export const FileTooLarge: FC = ({ fileSize, maxFileSize }) = interface FileCouldNotBeReadProps { error: ErrorResponse; loaded: boolean; + showEditFlyout(): void; } -export const FileCouldNotBeRead: FC = ({ error, loaded }) => { +export const FileCouldNotBeRead: FC = ({ + error, + loaded, + showEditFlyout, +}) => { const message = error?.body?.message || ''; return ( - - } - color="danger" - iconType="cross" - data-test-subj="mlFileUploadErrorCallout fileCouldNotBeRead" - > - {message} - - {loaded && ( - <> - + <> + - - )} - + } + color="danger" + iconType="cross" + data-test-subj="mlFileUploadErrorCallout fileCouldNotBeRead" + > + {loaded === false && ( + <> + +
    + + + + + + )} + {message} + + {loaded && ( + <> + + + + )} +
    + ); }; diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/index.ts b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/index.ts index 492a797f7a2f2..67d5b1176459b 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/index.ts +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/index.ts @@ -11,4 +11,5 @@ export { readFile, getMaxBytes, getMaxBytesFormatted, + DEFAULT_LINES_TO_SAMPLE, } from './utils'; diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts index 49ee5ec6b90b0..781f400180b10 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts @@ -18,7 +18,7 @@ import { import { getUiSettings } from '../../../../util/dependency_cache'; import { FILE_DATA_VISUALIZER_MAX_FILE_SIZE } from '../../../../../../common/constants/settings'; -const DEFAULT_LINES_TO_SAMPLE = 1000; +export const DEFAULT_LINES_TO_SAMPLE = 1000; const UPLOAD_SIZE_MB = 5; const overrideDefaults = { From 01d8f00b50fdb1ec48df9f5ffa48b6c9c18f6c18 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 11 Aug 2020 08:53:16 +0100 Subject: [PATCH 084/106] [ML] Refactor in preparation for new es client (#74552) * [ML] Refactor in preparation for new es client * removing commented out code Co-authored-by: Elastic Machine --- .../server/lib/license/ml_server_license.ts | 29 ++++- .../plugins/ml/server/routes/annotations.ts | 20 ++- .../ml/server/routes/anomaly_detectors.ts | 76 ++++++------ x-pack/plugins/ml/server/routes/calendars.ts | 52 ++++---- .../ml/server/routes/data_frame_analytics.ts | 115 +++++++----------- .../ml/server/routes/data_visualizer.ts | 26 ++-- x-pack/plugins/ml/server/routes/datafeeds.ts | 40 +++--- .../ml/server/routes/fields_service.ts | 18 +-- .../ml/server/routes/file_data_visualizer.ts | 22 ++-- x-pack/plugins/ml/server/routes/filters.ts | 54 ++++---- x-pack/plugins/ml/server/routes/indices.ts | 4 +- .../ml/server/routes/job_audit_messages.ts | 8 +- .../plugins/ml/server/routes/job_service.ts | 80 ++++++------ .../ml/server/routes/job_validation.ts | 22 ++-- x-pack/plugins/ml/server/routes/modules.ts | 62 +++++++--- .../ml/server/routes/notification_settings.ts | 4 +- .../ml/server/routes/results_service.ts | 46 +++---- x-pack/plugins/ml/server/routes/system.ts | 30 ++--- 18 files changed, 369 insertions(+), 339 deletions(-) diff --git a/x-pack/plugins/ml/server/lib/license/ml_server_license.ts b/x-pack/plugins/ml/server/lib/license/ml_server_license.ts index 382e785b39ca3..bd0a29721248a 100644 --- a/x-pack/plugins/ml/server/lib/license/ml_server_license.ts +++ b/x-pack/plugins/ml/server/lib/license/ml_server_license.ts @@ -6,30 +6,47 @@ import { KibanaRequest, KibanaResponseFactory, - RequestHandler, RequestHandlerContext, + ILegacyScopedClusterClient, + IScopedClusterClient, + RequestHandler, } from 'kibana/server'; import { MlLicense } from '../../../common/license'; +type Handler = (handlerParams: { + legacyClient: ILegacyScopedClusterClient; + client: IScopedClusterClient; + request: KibanaRequest; + response: KibanaResponseFactory; + context: RequestHandlerContext; +}) => ReturnType; + export class MlServerLicense extends MlLicense { - public fullLicenseAPIGuard(handler: RequestHandler) { + public fullLicenseAPIGuard(handler: Handler) { return guard(() => this.isFullLicense(), handler); } - public basicLicenseAPIGuard(handler: RequestHandler) { + public basicLicenseAPIGuard(handler: Handler) { return guard(() => this.isMinimumLicense(), handler); } } -function guard(check: () => boolean, handler: RequestHandler) { +function guard(check: () => boolean, handler: Handler) { return ( context: RequestHandlerContext, - request: KibanaRequest, + request: KibanaRequest, response: KibanaResponseFactory ) => { if (check() === false) { return response.forbidden(); } - return handler(context, request, response); + + return handler({ + legacyClient: context.ml!.mlClient, + client: context.core.elasticsearch.client, + request, + response, + context, + }); }; } diff --git a/x-pack/plugins/ml/server/routes/annotations.ts b/x-pack/plugins/ml/server/routes/annotations.ts index 3e496eb31dcc5..a6de80bb7e5e2 100644 --- a/x-pack/plugins/ml/server/routes/annotations.ts +++ b/x-pack/plugins/ml/server/routes/annotations.ts @@ -58,9 +58,9 @@ export function annotationRoutes( tags: ['access:ml:canGetAnnotations'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { getAnnotations } = annotationServiceProvider(context.ml!.mlClient); + const { getAnnotations } = annotationServiceProvider(legacyClient); const resp = await getAnnotations(request.body); return response.ok({ @@ -91,16 +91,14 @@ export function annotationRoutes( tags: ['access:ml:canCreateAnnotation'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const annotationsFeatureAvailable = await isAnnotationsFeatureAvailable( - context.ml!.mlClient - ); + const annotationsFeatureAvailable = await isAnnotationsFeatureAvailable(legacyClient); if (annotationsFeatureAvailable === false) { throw getAnnotationsFeatureUnavailableErrorMessage(); } - const { indexAnnotation } = annotationServiceProvider(context.ml!.mlClient); + const { indexAnnotation } = annotationServiceProvider(legacyClient); const currentUser = securityPlugin !== undefined ? securityPlugin.authc.getCurrentUser(request) : {}; @@ -136,17 +134,15 @@ export function annotationRoutes( tags: ['access:ml:canDeleteAnnotation'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const annotationsFeatureAvailable = await isAnnotationsFeatureAvailable( - context.ml!.mlClient - ); + const annotationsFeatureAvailable = await isAnnotationsFeatureAvailable(legacyClient); if (annotationsFeatureAvailable === false) { throw getAnnotationsFeatureUnavailableErrorMessage(); } const annotationId = request.params.annotationId; - const { deleteAnnotation } = annotationServiceProvider(context.ml!.mlClient); + const { deleteAnnotation } = annotationServiceProvider(legacyClient); const resp = await deleteAnnotation(annotationId); return response.ok({ diff --git a/x-pack/plugins/ml/server/routes/anomaly_detectors.ts b/x-pack/plugins/ml/server/routes/anomaly_detectors.ts index 8a59c174eb8e7..c6bdb32b262e4 100644 --- a/x-pack/plugins/ml/server/routes/anomaly_detectors.ts +++ b/x-pack/plugins/ml/server/routes/anomaly_detectors.ts @@ -43,9 +43,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.jobs'); + const results = await legacyClient.callAsInternalUser('ml.jobs'); return response.ok({ body: results, }); @@ -74,10 +74,10 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { jobId } = request.params; - const results = await context.ml!.mlClient.callAsInternalUser('ml.jobs', { jobId }); + const results = await legacyClient.callAsInternalUser('ml.jobs', { jobId }); return response.ok({ body: results, }); @@ -105,9 +105,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.jobStats'); + const results = await legacyClient.callAsInternalUser('ml.jobStats'); return response.ok({ body: results, }); @@ -136,10 +136,10 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { jobId } = request.params; - const results = await context.ml!.mlClient.callAsInternalUser('ml.jobStats', { jobId }); + const results = await legacyClient.callAsInternalUser('ml.jobStats', { jobId }); return response.ok({ body: results, }); @@ -172,10 +172,10 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { jobId } = request.params; - const results = await context.ml!.mlClient.callAsInternalUser('ml.addJob', { + const results = await legacyClient.callAsInternalUser('ml.addJob', { jobId, body: request.body, }); @@ -209,10 +209,10 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canUpdateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { jobId } = request.params; - const results = await context.ml!.mlClient.callAsInternalUser('ml.updateJob', { + const results = await legacyClient.callAsInternalUser('ml.updateJob', { jobId, body: request.body, }); @@ -244,10 +244,10 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canOpenJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { jobId } = request.params; - const results = await context.ml!.mlClient.callAsInternalUser('ml.openJob', { + const results = await legacyClient.callAsInternalUser('ml.openJob', { jobId, }); return response.ok({ @@ -278,7 +278,7 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCloseJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const options: { jobId: string; force?: boolean } = { jobId: request.params.jobId, @@ -287,7 +287,7 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { if (force !== undefined) { options.force = force; } - const results = await context.ml!.mlClient.callAsInternalUser('ml.closeJob', options); + const results = await legacyClient.callAsInternalUser('ml.closeJob', options); return response.ok({ body: results, }); @@ -316,7 +316,7 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canDeleteJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const options: { jobId: string; force?: boolean } = { jobId: request.params.jobId, @@ -325,7 +325,7 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { if (force !== undefined) { options.force = force; } - const results = await context.ml!.mlClient.callAsInternalUser('ml.deleteJob', options); + const results = await legacyClient.callAsInternalUser('ml.deleteJob', options); return response.ok({ body: results, }); @@ -352,9 +352,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.validateDetector', { + const results = await legacyClient.callAsInternalUser('ml.validateDetector', { body: request.body, }); return response.ok({ @@ -387,11 +387,11 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canForecastJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const jobId = request.params.jobId; const duration = request.body.duration; - const results = await context.ml!.mlClient.callAsInternalUser('ml.forecast', { + const results = await legacyClient.callAsInternalUser('ml.forecast', { jobId, duration, }); @@ -428,9 +428,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.records', { + const results = await legacyClient.callAsInternalUser('ml.records', { jobId: request.params.jobId, body: request.body, }); @@ -467,9 +467,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.buckets', { + const results = await legacyClient.callAsInternalUser('ml.buckets', { jobId: request.params.jobId, timestamp: request.params.timestamp, body: request.body, @@ -507,9 +507,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.overallBuckets', { + const results = await legacyClient.callAsInternalUser('ml.overallBuckets', { jobId: request.params.jobId, top_n: request.body.topN, bucket_span: request.body.bucketSpan, @@ -544,9 +544,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.categories', { + const results = await legacyClient.callAsInternalUser('ml.categories', { jobId: request.params.jobId, categoryId: request.params.categoryId, }); @@ -578,9 +578,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.modelSnapshots', { + const results = await legacyClient.callAsInternalUser('ml.modelSnapshots', { jobId: request.params.jobId, }); return response.ok({ @@ -611,9 +611,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.modelSnapshots', { + const results = await legacyClient.callAsInternalUser('ml.modelSnapshots', { jobId: request.params.jobId, snapshotId: request.params.snapshotId, }); @@ -647,9 +647,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.updateModelSnapshot', { + const results = await legacyClient.callAsInternalUser('ml.updateModelSnapshot', { jobId: request.params.jobId, snapshotId: request.params.snapshotId, body: request.body, @@ -682,9 +682,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.deleteModelSnapshot', { + const results = await legacyClient.callAsInternalUser('ml.deleteModelSnapshot', { jobId: request.params.jobId, snapshotId: request.params.snapshotId, }); diff --git a/x-pack/plugins/ml/server/routes/calendars.ts b/x-pack/plugins/ml/server/routes/calendars.ts index f5d129abd515e..3beb6e437b2ee 100644 --- a/x-pack/plugins/ml/server/routes/calendars.ts +++ b/x-pack/plugins/ml/server/routes/calendars.ts @@ -4,39 +4,43 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'kibana/server'; +import { ILegacyScopedClusterClient } from 'kibana/server'; import { wrapError } from '../client/error_wrapper'; import { RouteInitialization } from '../types'; import { calendarSchema, calendarIdSchema, calendarIdsSchema } from './schemas/calendars_schema'; import { CalendarManager, Calendar, FormCalendar } from '../models/calendar'; -function getAllCalendars(context: RequestHandlerContext) { - const cal = new CalendarManager(context.ml!.mlClient); +function getAllCalendars(legacyClient: ILegacyScopedClusterClient) { + const cal = new CalendarManager(legacyClient); return cal.getAllCalendars(); } -function getCalendar(context: RequestHandlerContext, calendarId: string) { - const cal = new CalendarManager(context.ml!.mlClient); +function getCalendar(legacyClient: ILegacyScopedClusterClient, calendarId: string) { + const cal = new CalendarManager(legacyClient); return cal.getCalendar(calendarId); } -function newCalendar(context: RequestHandlerContext, calendar: FormCalendar) { - const cal = new CalendarManager(context.ml!.mlClient); +function newCalendar(legacyClient: ILegacyScopedClusterClient, calendar: FormCalendar) { + const cal = new CalendarManager(legacyClient); return cal.newCalendar(calendar); } -function updateCalendar(context: RequestHandlerContext, calendarId: string, calendar: Calendar) { - const cal = new CalendarManager(context.ml!.mlClient); +function updateCalendar( + legacyClient: ILegacyScopedClusterClient, + calendarId: string, + calendar: Calendar +) { + const cal = new CalendarManager(legacyClient); return cal.updateCalendar(calendarId, calendar); } -function deleteCalendar(context: RequestHandlerContext, calendarId: string) { - const cal = new CalendarManager(context.ml!.mlClient); +function deleteCalendar(legacyClient: ILegacyScopedClusterClient, calendarId: string) { + const cal = new CalendarManager(legacyClient); return cal.deleteCalendar(calendarId); } -function getCalendarsByIds(context: RequestHandlerContext, calendarIds: string) { - const cal = new CalendarManager(context.ml!.mlClient); +function getCalendarsByIds(legacyClient: ILegacyScopedClusterClient, calendarIds: string) { + const cal = new CalendarManager(legacyClient); return cal.getCalendarsByIds(calendarIds); } @@ -56,9 +60,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetCalendars'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { - const resp = await getAllCalendars(context); + const resp = await getAllCalendars(legacyClient); return response.ok({ body: resp, @@ -88,15 +92,15 @@ export function calendars({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetCalendars'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { let returnValue; try { const calendarIds = request.params.calendarIds.split(','); if (calendarIds.length === 1) { - returnValue = await getCalendar(context, calendarIds[0]); + returnValue = await getCalendar(legacyClient, calendarIds[0]); } else { - returnValue = await getCalendarsByIds(context, calendarIds); + returnValue = await getCalendarsByIds(legacyClient, calendarIds); } return response.ok({ @@ -127,10 +131,10 @@ export function calendars({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateCalendar'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const body = request.body; - const resp = await newCalendar(context, body); + const resp = await newCalendar(legacyClient, body); return response.ok({ body: resp, @@ -162,11 +166,11 @@ export function calendars({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateCalendar'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { calendarId } = request.params; const body = request.body; - const resp = await updateCalendar(context, calendarId, body); + const resp = await updateCalendar(legacyClient, calendarId, body); return response.ok({ body: resp, @@ -196,10 +200,10 @@ export function calendars({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canDeleteCalendar'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { calendarId } = request.params; - const resp = await deleteCalendar(context, calendarId); + const resp = await deleteCalendar(legacyClient, calendarId); return response.ok({ body: resp, diff --git a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts index 94feb21a6b5fb..3b964588bef19 100644 --- a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts +++ b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'kibana/server'; +import { RequestHandlerContext, ILegacyScopedClusterClient } from 'kibana/server'; import { wrapError } from '../client/error_wrapper'; import { analyticsAuditMessagesProvider } from '../models/data_frame_analytics/analytics_audit_messages'; import { RouteInitialization } from '../types'; @@ -36,13 +36,13 @@ function deleteDestIndexPatternById(context: RequestHandlerContext, indexPattern */ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitialization) { async function userCanDeleteIndex( - context: RequestHandlerContext, + legacyClient: ILegacyScopedClusterClient, destinationIndex: string ): Promise { if (!mlLicense.isSecurityEnabled()) { return true; } - const privilege = await context.ml!.mlClient.callAsCurrentUser('ml.privilegeCheck', { + const privilege = await legacyClient.callAsCurrentUser('ml.privilegeCheck', { body: { index: [ { @@ -76,9 +76,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canGetDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser('ml.getDataFrameAnalytics'); + const results = await legacyClient.callAsInternalUser('ml.getDataFrameAnalytics'); return response.ok({ body: results, }); @@ -107,10 +107,10 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canGetDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { analyticsId } = request.params; - const results = await context.ml!.mlClient.callAsInternalUser('ml.getDataFrameAnalytics', { + const results = await legacyClient.callAsInternalUser('ml.getDataFrameAnalytics', { analyticsId, }); return response.ok({ @@ -137,11 +137,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canGetDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser( - 'ml.getDataFrameAnalyticsStats' - ); + const results = await legacyClient.callAsInternalUser('ml.getDataFrameAnalyticsStats'); return response.ok({ body: results, }); @@ -170,15 +168,12 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canGetDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { analyticsId } = request.params; - const results = await context.ml!.mlClient.callAsInternalUser( - 'ml.getDataFrameAnalyticsStats', - { - analyticsId, - } - ); + const results = await legacyClient.callAsInternalUser('ml.getDataFrameAnalyticsStats', { + analyticsId, + }); return response.ok({ body: results, }); @@ -210,17 +205,14 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canCreateDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { analyticsId } = request.params; - const results = await context.ml!.mlClient.callAsInternalUser( - 'ml.createDataFrameAnalytics', - { - body: request.body, - analyticsId, - ...getAuthorizationHeader(request), - } - ); + const results = await legacyClient.callAsInternalUser('ml.createDataFrameAnalytics', { + body: request.body, + analyticsId, + ...getAuthorizationHeader(request), + }); return response.ok({ body: results, }); @@ -249,15 +241,12 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canGetDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser( - 'ml.evaluateDataFrameAnalytics', - { - body: request.body, - ...getAuthorizationHeader(request), - } - ); + const results = await legacyClient.callAsInternalUser('ml.evaluateDataFrameAnalytics', { + body: request.body, + ...getAuthorizationHeader(request), + }); return response.ok({ body: results, }); @@ -287,14 +276,11 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canCreateDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const results = await context.ml!.mlClient.callAsInternalUser( - 'ml.explainDataFrameAnalytics', - { - body: request.body, - } - ); + const results = await legacyClient.callAsInternalUser('ml.explainDataFrameAnalytics', { + body: request.body, + }); return response.ok({ body: results, }); @@ -324,7 +310,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canDeleteDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response, context }) => { try { const { analyticsId } = request.params; const { deleteDestIndex, deleteDestIndexPattern } = request.query; @@ -338,7 +324,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat // Check if analyticsId is valid and get destination index if (deleteDestIndex || deleteDestIndexPattern) { try { - const dfa = await context.ml!.mlClient.callAsInternalUser('ml.getDataFrameAnalytics', { + const dfa = await legacyClient.callAsInternalUser('ml.getDataFrameAnalytics', { analyticsId, }); if (Array.isArray(dfa.data_frame_analytics) && dfa.data_frame_analytics.length > 0) { @@ -351,11 +337,11 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat // If user checks box to delete the destinationIndex associated with the job if (destinationIndex && deleteDestIndex) { // Verify if user has privilege to delete the destination index - const userCanDeleteDestIndex = await userCanDeleteIndex(context, destinationIndex); + const userCanDeleteDestIndex = await userCanDeleteIndex(legacyClient, destinationIndex); // If user does have privilege to delete the index, then delete the index if (userCanDeleteDestIndex) { try { - await context.ml!.mlClient.callAsCurrentUser('indices.delete', { + await legacyClient.callAsCurrentUser('indices.delete', { index: destinationIndex, }); destIndexDeleted.success = true; @@ -384,7 +370,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat // Delete the data frame analytics try { - await context.ml!.mlClient.callAsInternalUser('ml.deleteDataFrameAnalytics', { + await legacyClient.callAsInternalUser('ml.deleteDataFrameAnalytics', { analyticsId, }); analyticsJobDeleted.success = true; @@ -427,15 +413,12 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canStartStopDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { analyticsId } = request.params; - const results = await context.ml!.mlClient.callAsInternalUser( - 'ml.startDataFrameAnalytics', - { - analyticsId, - } - ); + const results = await legacyClient.callAsInternalUser('ml.startDataFrameAnalytics', { + analyticsId, + }); return response.ok({ body: results, }); @@ -466,7 +449,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canStartStopDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const options: { analyticsId: string; force?: boolean | undefined } = { analyticsId: request.params.analyticsId, @@ -477,10 +460,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat options.force = request.url.query.force; } - const results = await context.ml!.mlClient.callAsInternalUser( - 'ml.stopDataFrameAnalytics', - options - ); + const results = await legacyClient.callAsInternalUser('ml.stopDataFrameAnalytics', options); return response.ok({ body: results, }); @@ -510,16 +490,13 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canCreateDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { analyticsId } = request.params; - const results = await context.ml!.mlClient.callAsInternalUser( - 'ml.updateDataFrameAnalytics', - { - body: request.body, - analyticsId, - } - ); + const results = await legacyClient.callAsInternalUser('ml.updateDataFrameAnalytics', { + body: request.body, + analyticsId, + }); return response.ok({ body: results, }); @@ -548,10 +525,10 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canGetDataFrameAnalytics'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { analyticsId } = request.params; - const { getAnalyticsAuditMessages } = analyticsAuditMessagesProvider(context.ml!.mlClient); + const { getAnalyticsAuditMessages } = analyticsAuditMessagesProvider(legacyClient); const results = await getAnalyticsAuditMessages(analyticsId); return response.ok({ diff --git a/x-pack/plugins/ml/server/routes/data_visualizer.ts b/x-pack/plugins/ml/server/routes/data_visualizer.ts index 818e981835ced..6355285127f06 100644 --- a/x-pack/plugins/ml/server/routes/data_visualizer.ts +++ b/x-pack/plugins/ml/server/routes/data_visualizer.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'kibana/server'; +import { ILegacyScopedClusterClient } from 'kibana/server'; import { wrapError } from '../client/error_wrapper'; import { DataVisualizer } from '../models/data_visualizer'; import { Field, HistogramField } from '../models/data_visualizer/data_visualizer'; @@ -17,7 +17,7 @@ import { import { RouteInitialization } from '../types'; function getOverallStats( - context: RequestHandlerContext, + legacyClient: ILegacyScopedClusterClient, indexPatternTitle: string, query: object, aggregatableFields: string[], @@ -27,7 +27,7 @@ function getOverallStats( earliestMs: number, latestMs: number ) { - const dv = new DataVisualizer(context.ml!.mlClient); + const dv = new DataVisualizer(legacyClient); return dv.getOverallStats( indexPatternTitle, query, @@ -41,7 +41,7 @@ function getOverallStats( } function getStatsForFields( - context: RequestHandlerContext, + legacyClient: ILegacyScopedClusterClient, indexPatternTitle: string, query: any, fields: Field[], @@ -52,7 +52,7 @@ function getStatsForFields( interval: number, maxExamples: number ) { - const dv = new DataVisualizer(context.ml!.mlClient); + const dv = new DataVisualizer(legacyClient); return dv.getStatsForFields( indexPatternTitle, query, @@ -67,13 +67,13 @@ function getStatsForFields( } function getHistogramsForFields( - context: RequestHandlerContext, + legacyClient: ILegacyScopedClusterClient, indexPatternTitle: string, query: any, fields: HistogramField[], samplerShardSize: number ) { - const dv = new DataVisualizer(context.ml!.mlClient); + const dv = new DataVisualizer(legacyClient); return dv.getHistogramsForFields(indexPatternTitle, query, fields, samplerShardSize); } @@ -104,7 +104,7 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization) tags: ['access:ml:canAccessML'], }, }, - mlLicense.basicLicenseAPIGuard(async (context, request, response) => { + mlLicense.basicLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { params: { indexPatternTitle }, @@ -112,7 +112,7 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization) } = request; const results = await getHistogramsForFields( - context, + legacyClient, indexPatternTitle, query, fields, @@ -151,7 +151,7 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization) tags: ['access:ml:canAccessML'], }, }, - mlLicense.basicLicenseAPIGuard(async (context, request, response) => { + mlLicense.basicLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { params: { indexPatternTitle }, @@ -168,7 +168,7 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization) } = request; const results = await getStatsForFields( - context, + legacyClient, indexPatternTitle, query, fields, @@ -216,7 +216,7 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization) tags: ['access:ml:canAccessML'], }, }, - mlLicense.basicLicenseAPIGuard(async (context, request, response) => { + mlLicense.basicLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { params: { indexPatternTitle }, @@ -232,7 +232,7 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization) } = request; const results = await getOverallStats( - context, + legacyClient, indexPatternTitle, query, aggregatableFields, diff --git a/x-pack/plugins/ml/server/routes/datafeeds.ts b/x-pack/plugins/ml/server/routes/datafeeds.ts index 855b64b0ffed0..47a9afc2244d9 100644 --- a/x-pack/plugins/ml/server/routes/datafeeds.ts +++ b/x-pack/plugins/ml/server/routes/datafeeds.ts @@ -33,9 +33,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetDatafeeds'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await context.ml!.mlClient.callAsInternalUser('ml.datafeeds'); + const resp = await legacyClient.callAsInternalUser('ml.datafeeds'); return response.ok({ body: resp, @@ -65,10 +65,10 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetDatafeeds'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const resp = await context.ml!.mlClient.callAsInternalUser('ml.datafeeds', { datafeedId }); + const resp = await legacyClient.callAsInternalUser('ml.datafeeds', { datafeedId }); return response.ok({ body: resp, @@ -94,9 +94,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetDatafeeds'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await context.ml!.mlClient.callAsInternalUser('ml.datafeedStats'); + const resp = await legacyClient.callAsInternalUser('ml.datafeedStats'); return response.ok({ body: resp, @@ -126,10 +126,10 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetDatafeeds'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const resp = await context.ml!.mlClient.callAsInternalUser('ml.datafeedStats', { + const resp = await legacyClient.callAsInternalUser('ml.datafeedStats', { datafeedId, }); @@ -163,10 +163,10 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateDatafeed'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const resp = await context.ml!.mlClient.callAsInternalUser('ml.addDatafeed', { + const resp = await legacyClient.callAsInternalUser('ml.addDatafeed', { datafeedId, body: request.body, ...getAuthorizationHeader(request), @@ -202,10 +202,10 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canUpdateDatafeed'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const resp = await context.ml!.mlClient.callAsInternalUser('ml.updateDatafeed', { + const resp = await legacyClient.callAsInternalUser('ml.updateDatafeed', { datafeedId, body: request.body, ...getAuthorizationHeader(request), @@ -241,7 +241,7 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canDeleteDatafeed'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const options: { datafeedId: string; force?: boolean } = { datafeedId: request.params.jobId, @@ -251,7 +251,7 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { options.force = force; } - const resp = await context.ml!.mlClient.callAsInternalUser('ml.deleteDatafeed', options); + const resp = await legacyClient.callAsInternalUser('ml.deleteDatafeed', options); return response.ok({ body: resp, @@ -283,12 +283,12 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canStartStopDatafeed'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const datafeedId = request.params.datafeedId; const { start, end } = request.body; - const resp = await context.ml!.mlClient.callAsInternalUser('ml.startDatafeed', { + const resp = await legacyClient.callAsInternalUser('ml.startDatafeed', { datafeedId, start, end, @@ -322,11 +322,11 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canStartStopDatafeed'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const resp = await context.ml!.mlClient.callAsInternalUser('ml.stopDatafeed', { + const resp = await legacyClient.callAsInternalUser('ml.stopDatafeed', { datafeedId, }); @@ -358,10 +358,10 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canPreviewDatafeed'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const resp = await context.ml!.mlClient.callAsInternalUser('ml.datafeedPreview', { + const resp = await legacyClient.callAsInternalUser('ml.datafeedPreview', { datafeedId, ...getAuthorizationHeader(request), }); diff --git a/x-pack/plugins/ml/server/routes/fields_service.ts b/x-pack/plugins/ml/server/routes/fields_service.ts index b83f846b1685d..0595b31d5bbbc 100644 --- a/x-pack/plugins/ml/server/routes/fields_service.ts +++ b/x-pack/plugins/ml/server/routes/fields_service.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'kibana/server'; +import { ILegacyScopedClusterClient } from 'kibana/server'; import { wrapError } from '../client/error_wrapper'; import { RouteInitialization } from '../types'; import { @@ -13,14 +13,14 @@ import { } from './schemas/fields_service_schema'; import { fieldsServiceProvider } from '../models/fields_service'; -function getCardinalityOfFields(context: RequestHandlerContext, payload: any) { - const fs = fieldsServiceProvider(context.ml!.mlClient); +function getCardinalityOfFields(legacyClient: ILegacyScopedClusterClient, payload: any) { + const fs = fieldsServiceProvider(legacyClient); const { index, fieldNames, query, timeFieldName, earliestMs, latestMs } = payload; return fs.getCardinalityOfFields(index, fieldNames, query, timeFieldName, earliestMs, latestMs); } -function getTimeFieldRange(context: RequestHandlerContext, payload: any) { - const fs = fieldsServiceProvider(context.ml!.mlClient); +function getTimeFieldRange(legacyClient: ILegacyScopedClusterClient, payload: any) { + const fs = fieldsServiceProvider(legacyClient); const { index, timeFieldName, query } = payload; return fs.getTimeFieldRange(index, timeFieldName, query); } @@ -50,9 +50,9 @@ export function fieldsService({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canAccessML'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await getCardinalityOfFields(context, request.body); + const resp = await getCardinalityOfFields(legacyClient, request.body); return response.ok({ body: resp, @@ -85,9 +85,9 @@ export function fieldsService({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canAccessML'], }, }, - mlLicense.basicLicenseAPIGuard(async (context, request, response) => { + mlLicense.basicLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await getTimeFieldRange(context, request.body); + const resp = await getTimeFieldRange(legacyClient, request.body); return response.ok({ body: resp, diff --git a/x-pack/plugins/ml/server/routes/file_data_visualizer.ts b/x-pack/plugins/ml/server/routes/file_data_visualizer.ts index b57eda5ad56a1..88949fecbc7df 100644 --- a/x-pack/plugins/ml/server/routes/file_data_visualizer.ts +++ b/x-pack/plugins/ml/server/routes/file_data_visualizer.ts @@ -5,7 +5,7 @@ */ import { schema } from '@kbn/config-schema'; -import { RequestHandlerContext } from 'kibana/server'; +import { ILegacyScopedClusterClient } from 'kibana/server'; import { MAX_FILE_SIZE_BYTES } from '../../common/constants/file_datavisualizer'; import { InputOverrides, @@ -28,13 +28,17 @@ import { importFileQuerySchema, } from './schemas/file_data_visualizer_schema'; -function analyzeFiles(context: RequestHandlerContext, data: InputData, overrides: InputOverrides) { - const { analyzeFile } = fileDataVisualizerProvider(context.ml!.mlClient); +function analyzeFiles( + legacyClient: ILegacyScopedClusterClient, + data: InputData, + overrides: InputOverrides +) { + const { analyzeFile } = fileDataVisualizerProvider(legacyClient); return analyzeFile(data, overrides); } function importData( - context: RequestHandlerContext, + legacyClient: ILegacyScopedClusterClient, id: string, index: string, settings: Settings, @@ -42,7 +46,7 @@ function importData( ingestPipeline: IngestPipelineWrapper, data: InputData ) { - const { importData: importDataFunc } = importDataProvider(context.ml!.mlClient); + const { importData: importDataFunc } = importDataProvider(legacyClient); return importDataFunc(id, index, settings, mappings, ingestPipeline, data); } @@ -74,9 +78,9 @@ export function fileDataVisualizerRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canFindFileStructure'], }, }, - mlLicense.basicLicenseAPIGuard(async (context, request, response) => { + mlLicense.basicLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const result = await analyzeFiles(context, request.body, request.query); + const result = await analyzeFiles(legacyClient, request.body, request.query); return response.ok({ body: result }); } catch (e) { return response.customError(wrapError(e)); @@ -109,7 +113,7 @@ export function fileDataVisualizerRoutes({ router, mlLicense }: RouteInitializat tags: ['access:ml:canFindFileStructure'], }, }, - mlLicense.basicLicenseAPIGuard(async (context, request, response) => { + mlLicense.basicLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { id } = request.query; const { index, data, settings, mappings, ingestPipeline } = request.body; @@ -122,7 +126,7 @@ export function fileDataVisualizerRoutes({ router, mlLicense }: RouteInitializat } const result = await importData( - context, + legacyClient, id, index, settings, diff --git a/x-pack/plugins/ml/server/routes/filters.ts b/x-pack/plugins/ml/server/routes/filters.ts index dcdb4caa6cd3b..bb4f8a2bebaa9 100644 --- a/x-pack/plugins/ml/server/routes/filters.ts +++ b/x-pack/plugins/ml/server/routes/filters.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'kibana/server'; +import { ILegacyScopedClusterClient } from 'kibana/server'; import { wrapError } from '../client/error_wrapper'; import { RouteInitialization } from '../types'; import { createFilterSchema, filterIdSchema, updateFilterSchema } from './schemas/filters_schema'; @@ -12,33 +12,37 @@ import { FilterManager, FormFilter } from '../models/filter'; // TODO - add function for returning a list of just the filter IDs. // TODO - add function for returning a list of filter IDs plus item count. -function getAllFilters(context: RequestHandlerContext) { - const mgr = new FilterManager(context.ml!.mlClient); +function getAllFilters(legacyClient: ILegacyScopedClusterClient) { + const mgr = new FilterManager(legacyClient); return mgr.getAllFilters(); } -function getAllFilterStats(context: RequestHandlerContext) { - const mgr = new FilterManager(context.ml!.mlClient); +function getAllFilterStats(legacyClient: ILegacyScopedClusterClient) { + const mgr = new FilterManager(legacyClient); return mgr.getAllFilterStats(); } -function getFilter(context: RequestHandlerContext, filterId: string) { - const mgr = new FilterManager(context.ml!.mlClient); +function getFilter(legacyClient: ILegacyScopedClusterClient, filterId: string) { + const mgr = new FilterManager(legacyClient); return mgr.getFilter(filterId); } -function newFilter(context: RequestHandlerContext, filter: FormFilter) { - const mgr = new FilterManager(context.ml!.mlClient); +function newFilter(legacyClient: ILegacyScopedClusterClient, filter: FormFilter) { + const mgr = new FilterManager(legacyClient); return mgr.newFilter(filter); } -function updateFilter(context: RequestHandlerContext, filterId: string, filter: FormFilter) { - const mgr = new FilterManager(context.ml!.mlClient); +function updateFilter( + legacyClient: ILegacyScopedClusterClient, + filterId: string, + filter: FormFilter +) { + const mgr = new FilterManager(legacyClient); return mgr.updateFilter(filterId, filter); } -function deleteFilter(context: RequestHandlerContext, filterId: string) { - const mgr = new FilterManager(context.ml!.mlClient); +function deleteFilter(legacyClient: ILegacyScopedClusterClient, filterId: string) { + const mgr = new FilterManager(legacyClient); return mgr.deleteFilter(filterId); } @@ -61,9 +65,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetFilters'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { - const resp = await getAllFilters(context); + const resp = await getAllFilters(legacyClient); return response.ok({ body: resp, @@ -96,9 +100,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetFilters'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await getFilter(context, request.params.filterId); + const resp = await getFilter(legacyClient, request.params.filterId); return response.ok({ body: resp, }); @@ -130,10 +134,10 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateFilter'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const body = request.body; - const resp = await newFilter(context, body); + const resp = await newFilter(legacyClient, body); return response.ok({ body: resp, @@ -168,11 +172,11 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateFilter'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { filterId } = request.params; const body = request.body; - const resp = await updateFilter(context, filterId, body); + const resp = await updateFilter(legacyClient, filterId, body); return response.ok({ body: resp, @@ -202,10 +206,10 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canDeleteFilter'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { filterId } = request.params; - const resp = await deleteFilter(context, filterId); + const resp = await deleteFilter(legacyClient, filterId); return response.ok({ body: resp, @@ -235,9 +239,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetFilters'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { - const resp = await getAllFilterStats(context); + const resp = await getAllFilterStats(legacyClient); return response.ok({ body: resp, diff --git a/x-pack/plugins/ml/server/routes/indices.ts b/x-pack/plugins/ml/server/routes/indices.ts index fb3ef7fc41c76..6a759cb97f308 100644 --- a/x-pack/plugins/ml/server/routes/indices.ts +++ b/x-pack/plugins/ml/server/routes/indices.ts @@ -31,7 +31,7 @@ export function indicesRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canAccessML'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { body: { index, fields: requestFields }, @@ -40,7 +40,7 @@ export function indicesRoutes({ router, mlLicense }: RouteInitialization) { requestFields !== undefined && Array.isArray(requestFields) ? requestFields.join(',') : '*'; - const result = await context.ml!.mlClient.callAsCurrentUser('fieldCaps', { index, fields }); + const result = await legacyClient.callAsCurrentUser('fieldCaps', { index, fields }); return response.ok({ body: result }); } catch (e) { return response.customError(wrapError(e)); diff --git a/x-pack/plugins/ml/server/routes/job_audit_messages.ts b/x-pack/plugins/ml/server/routes/job_audit_messages.ts index d4840ed650a32..2313decfabd5b 100644 --- a/x-pack/plugins/ml/server/routes/job_audit_messages.ts +++ b/x-pack/plugins/ml/server/routes/job_audit_messages.ts @@ -37,9 +37,9 @@ export function jobAuditMessagesRoutes({ router, mlLicense }: RouteInitializatio tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { getJobAuditMessages } = jobAuditMessagesProvider(context.ml!.mlClient); + const { getJobAuditMessages } = jobAuditMessagesProvider(legacyClient); const { jobId } = request.params; const { from } = request.query; const resp = await getJobAuditMessages(jobId, from); @@ -72,9 +72,9 @@ export function jobAuditMessagesRoutes({ router, mlLicense }: RouteInitializatio tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { getJobAuditMessages } = jobAuditMessagesProvider(context.ml!.mlClient); + const { getJobAuditMessages } = jobAuditMessagesProvider(legacyClient); const { from } = request.query; const resp = await getJobAuditMessages(undefined, from); diff --git a/x-pack/plugins/ml/server/routes/job_service.ts b/x-pack/plugins/ml/server/routes/job_service.ts index e03dbb40d623a..3d560fc857e95 100644 --- a/x-pack/plugins/ml/server/routes/job_service.ts +++ b/x-pack/plugins/ml/server/routes/job_service.ts @@ -48,9 +48,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canStartStopDatafeed'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { forceStartDatafeeds } = jobServiceProvider(context.ml!.mlClient); + const { forceStartDatafeeds } = jobServiceProvider(legacyClient); const { datafeedIds, start, end } = request.body; const resp = await forceStartDatafeeds(datafeedIds, start, end); @@ -82,9 +82,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canStartStopDatafeed'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { stopDatafeeds } = jobServiceProvider(context.ml!.mlClient); + const { stopDatafeeds } = jobServiceProvider(legacyClient); const { datafeedIds } = request.body; const resp = await stopDatafeeds(datafeedIds); @@ -116,9 +116,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canDeleteJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { deleteJobs } = jobServiceProvider(context.ml!.mlClient); + const { deleteJobs } = jobServiceProvider(legacyClient); const { jobIds } = request.body; const resp = await deleteJobs(jobIds); @@ -150,9 +150,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCloseJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { closeJobs } = jobServiceProvider(context.ml!.mlClient); + const { closeJobs } = jobServiceProvider(legacyClient); const { jobIds } = request.body; const resp = await closeJobs(jobIds); @@ -184,9 +184,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCloseJob', 'access:ml:canStartStopDatafeed'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { forceStopAndCloseJob } = jobServiceProvider(context.ml!.mlClient); + const { forceStopAndCloseJob } = jobServiceProvider(legacyClient); const { jobId } = request.body; const resp = await forceStopAndCloseJob(jobId); @@ -223,9 +223,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { jobsSummary } = jobServiceProvider(context.ml!.mlClient); + const { jobsSummary } = jobServiceProvider(legacyClient); const { jobIds } = request.body; const resp = await jobsSummary(jobIds); @@ -257,9 +257,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { - const { jobsWithTimerange } = jobServiceProvider(context.ml!.mlClient); + const { jobsWithTimerange } = jobServiceProvider(legacyClient); const resp = await jobsWithTimerange(); return response.ok({ @@ -290,9 +290,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { createFullJobsList } = jobServiceProvider(context.ml!.mlClient); + const { createFullJobsList } = jobServiceProvider(legacyClient); const { jobIds } = request.body; const resp = await createFullJobsList(jobIds); @@ -320,9 +320,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { - const { getAllGroups } = jobServiceProvider(context.ml!.mlClient); + const { getAllGroups } = jobServiceProvider(legacyClient); const resp = await getAllGroups(); return response.ok({ @@ -353,9 +353,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canUpdateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { updateGroups } = jobServiceProvider(context.ml!.mlClient); + const { updateGroups } = jobServiceProvider(legacyClient); const { jobs } = request.body; const resp = await updateGroups(jobs); @@ -383,9 +383,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { - const { deletingJobTasks } = jobServiceProvider(context.ml!.mlClient); + const { deletingJobTasks } = jobServiceProvider(legacyClient); const resp = await deletingJobTasks(); return response.ok({ @@ -416,9 +416,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { jobsExist } = jobServiceProvider(context.ml!.mlClient); + const { jobsExist } = jobServiceProvider(legacyClient); const { jobIds } = request.body; const resp = await jobsExist(jobIds); @@ -449,12 +449,12 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response, context }) => { try { const { indexPattern } = request.params; const isRollup = request.query.rollup === 'true'; const savedObjectsClient = context.core.savedObjects.client; - const { newJobCaps } = jobServiceProvider(context.ml!.mlClient); + const { newJobCaps } = jobServiceProvider(legacyClient); const resp = await newJobCaps(indexPattern, isRollup, savedObjectsClient); return response.ok({ @@ -485,7 +485,7 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { indexPatternTitle, @@ -499,7 +499,7 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { splitFieldValue, } = request.body; - const { newJobLineChart } = jobServiceProvider(context.ml!.mlClient); + const { newJobLineChart } = jobServiceProvider(legacyClient); const resp = await newJobLineChart( indexPatternTitle, timeField, @@ -540,7 +540,7 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { indexPatternTitle, @@ -553,7 +553,7 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { splitFieldName, } = request.body; - const { newJobPopulationChart } = jobServiceProvider(context.ml!.mlClient); + const { newJobPopulationChart } = jobServiceProvider(legacyClient); const resp = await newJobPopulationChart( indexPatternTitle, timeField, @@ -589,9 +589,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { - const { getAllJobAndGroupIds } = jobServiceProvider(context.ml!.mlClient); + const { getAllJobAndGroupIds } = jobServiceProvider(legacyClient); const resp = await getAllJobAndGroupIds(); return response.ok({ @@ -622,9 +622,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { getLookBackProgress } = jobServiceProvider(context.ml!.mlClient); + const { getLookBackProgress } = jobServiceProvider(legacyClient); const { jobId, start, end } = request.body; const resp = await getLookBackProgress(jobId, start, end); @@ -656,9 +656,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { validateCategoryExamples } = categorizationExamplesProvider(context.ml!.mlClient); + const { validateCategoryExamples } = categorizationExamplesProvider(legacyClient); const { indexPatternTitle, timeField, @@ -709,9 +709,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { topCategories } = jobServiceProvider(context.ml!.mlClient); + const { topCategories } = jobServiceProvider(legacyClient); const { jobId, count } = request.body; const resp = await topCategories(jobId, count); @@ -743,9 +743,9 @@ export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateJob', 'access:ml:canStartStopDatafeed'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { revertModelSnapshot } = jobServiceProvider(context.ml!.mlClient); + const { revertModelSnapshot } = jobServiceProvider(legacyClient); const { jobId, snapshotId, diff --git a/x-pack/plugins/ml/server/routes/job_validation.ts b/x-pack/plugins/ml/server/routes/job_validation.ts index e52c6b76e918b..6da052663a002 100644 --- a/x-pack/plugins/ml/server/routes/job_validation.ts +++ b/x-pack/plugins/ml/server/routes/job_validation.ts @@ -5,7 +5,7 @@ */ import Boom from 'boom'; -import { RequestHandlerContext } from 'kibana/server'; +import { ILegacyScopedClusterClient } from 'kibana/server'; import { TypeOf } from '@kbn/config-schema'; import { AnalysisConfig } from '../../common/types/anomaly_detection_jobs'; import { wrapError } from '../client/error_wrapper'; @@ -27,12 +27,12 @@ type CalculateModelMemoryLimitPayload = TypeOf; */ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization, version: string) { function calculateModelMemoryLimit( - context: RequestHandlerContext, + legacyClient: ILegacyScopedClusterClient, payload: CalculateModelMemoryLimitPayload ) { const { analysisConfig, indexPattern, query, timeFieldName, earliestMs, latestMs } = payload; - return calculateModelMemoryLimitProvider(context.ml!.mlClient)( + return calculateModelMemoryLimitProvider(legacyClient)( analysisConfig as AnalysisConfig, indexPattern, query, @@ -61,10 +61,10 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization, tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { let errorResp; - const resp = await estimateBucketSpanFactory(context.ml!.mlClient)(request.body) + const resp = await estimateBucketSpanFactory(legacyClient)(request.body) // this catch gets triggered when the estimation code runs without error // but isn't able to come up with a bucket span estimation. // this doesn't return a HTTP error but an object with an error message @@ -109,9 +109,9 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization, tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await calculateModelMemoryLimit(context, request.body); + const resp = await calculateModelMemoryLimit(legacyClient, request.body); return response.ok({ body: resp, @@ -141,9 +141,9 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization, tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await validateCardinality(context.ml!.mlClient, request.body); + const resp = await validateCardinality(legacyClient, request.body); return response.ok({ body: resp, @@ -173,11 +173,11 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization, tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { // version corresponds to the version used in documentation links. const resp = await validateJob( - context.ml!.mlClient, + legacyClient, request.body, version, mlLicense.isSecurityEnabled() === false diff --git a/x-pack/plugins/ml/server/routes/modules.ts b/x-pack/plugins/ml/server/routes/modules.ts index 463babb86304f..23e37d2213029 100644 --- a/x-pack/plugins/ml/server/routes/modules.ts +++ b/x-pack/plugins/ml/server/routes/modules.ts @@ -6,7 +6,11 @@ import { TypeOf } from '@kbn/config-schema'; -import { RequestHandlerContext, KibanaRequest } from 'kibana/server'; +import { + ILegacyScopedClusterClient, + KibanaRequest, + SavedObjectsClientContract, +} from 'kibana/server'; import { DatafeedOverride, JobOverride } from '../../common/types/modules'; import { wrapError } from '../client/error_wrapper'; import { DataRecognizer } from '../models/data_recognizer'; @@ -19,16 +23,22 @@ import { import { RouteInitialization } from '../types'; function recognize( - context: RequestHandlerContext, + legacyClient: ILegacyScopedClusterClient, + savedObjectsClient: SavedObjectsClientContract, request: KibanaRequest, indexPatternTitle: string ) { - const dr = new DataRecognizer(context.ml!.mlClient, context.core.savedObjects.client, request); + const dr = new DataRecognizer(legacyClient, savedObjectsClient, request); return dr.findMatches(indexPatternTitle); } -function getModule(context: RequestHandlerContext, request: KibanaRequest, moduleId: string) { - const dr = new DataRecognizer(context.ml!.mlClient, context.core.savedObjects.client, request); +function getModule( + legacyClient: ILegacyScopedClusterClient, + savedObjectsClient: SavedObjectsClientContract, + request: KibanaRequest, + moduleId: string +) { + const dr = new DataRecognizer(legacyClient, savedObjectsClient, request); if (moduleId === undefined) { return dr.listModules(); } else { @@ -37,7 +47,8 @@ function getModule(context: RequestHandlerContext, request: KibanaRequest, modul } function setup( - context: RequestHandlerContext, + legacyClient: ILegacyScopedClusterClient, + savedObjectsClient: SavedObjectsClientContract, request: KibanaRequest, moduleId: string, prefix?: string, @@ -52,7 +63,7 @@ function setup( datafeedOverrides?: DatafeedOverride | DatafeedOverride[], estimateModelMemory?: boolean ) { - const dr = new DataRecognizer(context.ml!.mlClient, context.core.savedObjects.client, request); + const dr = new DataRecognizer(legacyClient, savedObjectsClient, request); return dr.setup( moduleId, prefix, @@ -70,11 +81,12 @@ function setup( } function dataRecognizerJobsExist( - context: RequestHandlerContext, + legacyClient: ILegacyScopedClusterClient, + savedObjectsClient: SavedObjectsClientContract, request: KibanaRequest, moduleId: string ) { - const dr = new DataRecognizer(context.ml!.mlClient, context.core.savedObjects.client, request); + const dr = new DataRecognizer(legacyClient, savedObjectsClient, request); return dr.dataRecognizerJobsExist(moduleId); } @@ -119,10 +131,15 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response, context }) => { try { const { indexPatternTitle } = request.params; - const results = await recognize(context, request, indexPatternTitle); + const results = await recognize( + legacyClient, + context.core.savedObjects.client, + request, + indexPatternTitle + ); return response.ok({ body: results }); } catch (e) { @@ -249,7 +266,7 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response, context }) => { try { let { moduleId } = request.params; if (moduleId === '') { @@ -257,7 +274,12 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { // the moduleId will be an empty string. moduleId = undefined; } - const results = await getModule(context, request, moduleId); + const results = await getModule( + legacyClient, + context.core.savedObjects.client, + request, + moduleId + ); return response.ok({ body: results }); } catch (e) { @@ -417,7 +439,7 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canCreateJob'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response, context }) => { try { const { moduleId } = request.params; @@ -436,7 +458,8 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { } = request.body as TypeOf; const result = await setup( - context, + legacyClient, + context.core.savedObjects.client, request, moduleId, prefix, @@ -521,10 +544,15 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response, context }) => { try { const { moduleId } = request.params; - const result = await dataRecognizerJobsExist(context, request, moduleId); + const result = await dataRecognizerJobsExist( + legacyClient, + context.core.savedObjects.client, + request, + moduleId + ); return response.ok({ body: result }); } catch (e) { diff --git a/x-pack/plugins/ml/server/routes/notification_settings.ts b/x-pack/plugins/ml/server/routes/notification_settings.ts index e4a9abb0784be..09c145d6257a8 100644 --- a/x-pack/plugins/ml/server/routes/notification_settings.ts +++ b/x-pack/plugins/ml/server/routes/notification_settings.ts @@ -26,13 +26,13 @@ export function notificationRoutes({ router, mlLicense }: RouteInitialization) { tags: ['access:ml:canAccessML'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, response }) => { try { const params = { includeDefaults: true, filterPath: '**.xpack.notification', }; - const resp = await context.ml!.mlClient.callAsCurrentUser('cluster.getSettings', params); + const resp = await legacyClient.callAsCurrentUser('cluster.getSettings', params); return response.ok({ body: resp, diff --git a/x-pack/plugins/ml/server/routes/results_service.ts b/x-pack/plugins/ml/server/routes/results_service.ts index c9370362816fa..0d619bf63b8e7 100644 --- a/x-pack/plugins/ml/server/routes/results_service.ts +++ b/x-pack/plugins/ml/server/routes/results_service.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'kibana/server'; +import { ILegacyScopedClusterClient } from 'kibana/server'; import { schema } from '@kbn/config-schema'; import { wrapError } from '../client/error_wrapper'; import { RouteInitialization } from '../types'; @@ -18,8 +18,8 @@ import { import { resultsServiceProvider } from '../models/results_service'; import { ML_RESULTS_INDEX_PATTERN } from '../../common/constants/index_patterns'; -function getAnomaliesTableData(context: RequestHandlerContext, payload: any) { - const rs = resultsServiceProvider(context.ml!.mlClient); +function getAnomaliesTableData(legacyClient: ILegacyScopedClusterClient, payload: any) { + const rs = resultsServiceProvider(legacyClient); const { jobIds, criteriaFields, @@ -48,25 +48,25 @@ function getAnomaliesTableData(context: RequestHandlerContext, payload: any) { ); } -function getCategoryDefinition(context: RequestHandlerContext, payload: any) { - const rs = resultsServiceProvider(context.ml!.mlClient); +function getCategoryDefinition(legacyClient: ILegacyScopedClusterClient, payload: any) { + const rs = resultsServiceProvider(legacyClient); return rs.getCategoryDefinition(payload.jobId, payload.categoryId); } -function getCategoryExamples(context: RequestHandlerContext, payload: any) { - const rs = resultsServiceProvider(context.ml!.mlClient); +function getCategoryExamples(legacyClient: ILegacyScopedClusterClient, payload: any) { + const rs = resultsServiceProvider(legacyClient); const { jobId, categoryIds, maxExamples } = payload; return rs.getCategoryExamples(jobId, categoryIds, maxExamples); } -function getMaxAnomalyScore(context: RequestHandlerContext, payload: any) { - const rs = resultsServiceProvider(context.ml!.mlClient); +function getMaxAnomalyScore(legacyClient: ILegacyScopedClusterClient, payload: any) { + const rs = resultsServiceProvider(legacyClient); const { jobIds, earliestMs, latestMs } = payload; return rs.getMaxAnomalyScore(jobIds, earliestMs, latestMs); } -function getPartitionFieldsValues(context: RequestHandlerContext, payload: any) { - const rs = resultsServiceProvider(context.ml!.mlClient); +function getPartitionFieldsValues(legacyClient: ILegacyScopedClusterClient, payload: any) { + const rs = resultsServiceProvider(legacyClient); const { jobId, searchTerm, criteriaFields, earliestMs, latestMs } = payload; return rs.getPartitionFieldsValues(jobId, searchTerm, criteriaFields, earliestMs, latestMs); } @@ -94,9 +94,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await getAnomaliesTableData(context, request.body); + const resp = await getAnomaliesTableData(legacyClient, request.body); return response.ok({ body: resp, @@ -126,9 +126,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await getCategoryDefinition(context, request.body); + const resp = await getCategoryDefinition(legacyClient, request.body); return response.ok({ body: resp, @@ -158,9 +158,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await getMaxAnomalyScore(context, request.body); + const resp = await getMaxAnomalyScore(legacyClient, request.body); return response.ok({ body: resp, @@ -190,9 +190,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await getCategoryExamples(context, request.body); + const resp = await getCategoryExamples(legacyClient, request.body); return response.ok({ body: resp, @@ -222,9 +222,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const resp = await getPartitionFieldsValues(context, request.body); + const resp = await getPartitionFieldsValues(legacyClient, request.body); return response.ok({ body: resp, @@ -251,14 +251,14 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { const body = { ...request.body, index: ML_RESULTS_INDEX_PATTERN, }; try { return response.ok({ - body: await context.ml!.mlClient.callAsInternalUser('search', body), + body: await legacyClient.callAsInternalUser('search', body), }); } catch (error) { return response.customError(wrapError(error)); diff --git a/x-pack/plugins/ml/server/routes/system.ts b/x-pack/plugins/ml/server/routes/system.ts index f2d8c89046178..99ba9519b6a34 100644 --- a/x-pack/plugins/ml/server/routes/system.ts +++ b/x-pack/plugins/ml/server/routes/system.ts @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; import { Request } from 'hapi'; -import { RequestHandlerContext } from 'kibana/server'; +import { ILegacyScopedClusterClient } from 'kibana/server'; import { wrapError } from '../client/error_wrapper'; import { mlLog } from '../client/log'; import { capabilitiesProvider } from '../lib/capabilities'; @@ -21,9 +21,9 @@ export function systemRoutes( { router, mlLicense }: RouteInitialization, { spaces, cloud, resolveMlCapabilities }: SystemRouteDeps ) { - async function getNodeCount(context: RequestHandlerContext) { + async function getNodeCount(legacyClient: ILegacyScopedClusterClient) { const filterPath = 'nodes.*.attributes'; - const resp = await context.ml!.mlClient.callAsInternalUser('nodes.info', { + const resp = await legacyClient.callAsInternalUser('nodes.info', { filterPath, }); @@ -58,9 +58,9 @@ export function systemRoutes( tags: ['access:ml:canAccessML'], }, }, - mlLicense.basicLicenseAPIGuard(async (context, request, response) => { + mlLicense.basicLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const { callAsCurrentUser, callAsInternalUser } = context.ml!.mlClient; + const { callAsCurrentUser, callAsInternalUser } = legacyClient; let upgradeInProgress = false; try { const info = await callAsInternalUser('ml.info'); @@ -115,7 +115,7 @@ export function systemRoutes( path: '/api/ml/ml_capabilities', validate: false, }, - mlLicense.basicLicenseAPIGuard(async (context, request, response) => { + mlLicense.basicLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { // if spaces is disabled force isMlEnabledInSpace to be true const { isMlEnabledInSpace } = @@ -129,7 +129,7 @@ export function systemRoutes( } const { getCapabilities } = capabilitiesProvider( - context.ml!.mlClient, + legacyClient, mlCapabilities, mlLicense, isMlEnabledInSpace @@ -159,10 +159,10 @@ export function systemRoutes( }, }, - mlLicense.basicLicenseAPIGuard(async (context, request, response) => { + mlLicense.basicLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { return response.ok({ - body: await getNodeCount(context), + body: await getNodeCount(legacyClient), }); } catch (e) { return response.customError(wrapError(e)); @@ -185,9 +185,9 @@ export function systemRoutes( tags: ['access:ml:canAccessML'], }, }, - mlLicense.basicLicenseAPIGuard(async (context, request, response) => { + mlLicense.basicLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { - const info = await context.ml!.mlClient.callAsInternalUser('ml.info'); + const info = await legacyClient.callAsInternalUser('ml.info'); const cloudId = cloud && cloud.cloudId; return response.ok({ body: { ...info, cloudId }, @@ -216,10 +216,10 @@ export function systemRoutes( tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { return response.ok({ - body: await context.ml!.mlClient.callAsCurrentUser('search', request.body), + body: await legacyClient.callAsCurrentUser('search', request.body), }); } catch (error) { return response.customError(wrapError(error)); @@ -243,7 +243,7 @@ export function systemRoutes( tags: ['access:ml:canGetJobs'], }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { + mlLicense.fullLicenseAPIGuard(async ({ legacyClient, request, response }) => { try { const { index } = request.body; @@ -255,7 +255,7 @@ export function systemRoutes( ignore: 404, }; - const fieldsResult = await context.ml!.mlClient.callAsCurrentUser('fieldCaps', options); + const fieldsResult = await legacyClient.callAsCurrentUser('fieldCaps', options); const result = { exists: false }; if (Array.isArray(fieldsResult.indices) && fieldsResult.indices.length !== 0) { From 8d9bafeb579208edcde6e9906718cd57286bfcf2 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 11 Aug 2020 09:01:19 +0100 Subject: [PATCH 085/106] [ML] Fixing schema for custom rule conditions (#74676) Co-authored-by: Elastic Machine --- .../ml/server/routes/schemas/anomaly_detectors_schema.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/ml/server/routes/schemas/anomaly_detectors_schema.ts b/x-pack/plugins/ml/server/routes/schemas/anomaly_detectors_schema.ts index 196e17d0984f9..9203c7cf997a6 100644 --- a/x-pack/plugins/ml/server/routes/schemas/anomaly_detectors_schema.ts +++ b/x-pack/plugins/ml/server/routes/schemas/anomaly_detectors_schema.ts @@ -11,7 +11,7 @@ const customRulesSchema = schema.maybe( schema.maybe( schema.object({ actions: schema.arrayOf(schema.string()), - conditions: schema.arrayOf(schema.any()), + conditions: schema.maybe(schema.arrayOf(schema.any())), scope: schema.maybe(schema.any()), }) ) From ce6011e4d5aad67ec4cd22c28920fe6bac57bb8b Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Tue, 11 Aug 2020 10:05:44 +0200 Subject: [PATCH 086/106] Bump angular dependency from 1.7.9 to 1.8.0 (#74482) --- package.json | 8 ++--- packages/kbn-ui-shared-deps/package.json | 2 +- x-pack/package.json | 6 ++-- yarn.lock | 40 ++++++++++++------------ 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 0b5a6822e6afa..becd670e4ddcf 100644 --- a/package.json +++ b/package.json @@ -147,12 +147,12 @@ "JSONStream": "1.3.5", "abortcontroller-polyfill": "^1.4.0", "accept": "3.0.2", - "angular": "^1.7.9", - "angular-aria": "^1.7.9", + "angular": "^1.8.0", + "angular-aria": "^1.8.0", "angular-elastic": "^2.5.1", "angular-recursion": "^1.0.5", - "angular-route": "^1.7.9", - "angular-sanitize": "^1.7.9", + "angular-route": "^1.8.0", + "angular-sanitize": "^1.8.0", "angular-sortable-view": "^0.0.17", "autoprefixer": "^9.7.4", "babel-loader": "^8.0.6", diff --git a/packages/kbn-ui-shared-deps/package.json b/packages/kbn-ui-shared-deps/package.json index 3c03a52383f77..ae14777e8b44a 100644 --- a/packages/kbn-ui-shared-deps/package.json +++ b/packages/kbn-ui-shared-deps/package.json @@ -15,7 +15,7 @@ "@kbn/i18n": "1.0.0", "@kbn/monaco": "1.0.0", "abortcontroller-polyfill": "^1.4.0", - "angular": "^1.7.9", + "angular": "^1.8.0", "compression-webpack-plugin": "^4.0.0", "core-js": "^3.6.4", "custom-event-polyfill": "^0.3.0", diff --git a/x-pack/package.json b/x-pack/package.json index 83eb0910add11..7533741391f8e 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -227,9 +227,9 @@ "@turf/circle": "6.0.1", "@turf/distance": "6.0.1", "@turf/helpers": "6.0.1", - "angular": "^1.7.9", - "angular-resource": "1.7.9", - "angular-sanitize": "1.7.9", + "angular": "^1.8.0", + "angular-resource": "1.8.0", + "angular-sanitize": "1.8.0", "angular-ui-ace": "0.2.3", "apollo-cache-inmemory": "1.6.2", "apollo-client": "^2.3.8", diff --git a/yarn.lock b/yarn.lock index 7c397c33ad8a8..6f82c8126ac06 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6466,10 +6466,10 @@ ammo@3.x.x: dependencies: hoek "5.x.x" -angular-aria@^1.7.9: - version "1.7.9" - resolved "https://registry.yarnpkg.com/angular-aria/-/angular-aria-1.7.9.tgz#90c61895ffbd876e95915222b32a7bd0070af7e3" - integrity sha512-luI3Jemd1AbOQW0krdzfEG3fM0IFtLY0bSSqIDEx3POE0XjKIC1MkrO8Csyq9PPgueLphyAPofzUwZ8YeZ88SA== +angular-aria@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/angular-aria/-/angular-aria-1.8.0.tgz#97aec9b1e8bafd07d5fab30f98d8ec832e18e25d" + integrity sha512-eCQI6EwgY6bYHdzIUfDABHnZjoZ3bNYpCsnceQF4bLfbq1QtZ7raRPNca45sj6C9Pfjde6PNcEDvuLozFPYnrQ== angular-elastic@^2.5.1: version "2.5.1" @@ -6488,20 +6488,20 @@ angular-recursion@^1.0.5: resolved "https://registry.yarnpkg.com/angular-recursion/-/angular-recursion-1.0.5.tgz#cd405428a0bf55faf52eaa7988c1fe69cd930543" integrity sha1-zUBUKKC/Vfr1Lqp5iMH+ac2TBUM= -angular-resource@1.7.9: - version "1.7.9" - resolved "https://registry.yarnpkg.com/angular-resource/-/angular-resource-1.7.9.tgz#fa53623fae2c60debe2410d692447dcb0ba02396" - integrity sha512-rXXhCE2qT31Pn4Sl+2XL+ntv4zxnA2OzY+clCl8/pOp/s/gIzxpQlEtXipo3QK8Qur3glbIkeF/bJw+gjVAdUw== +angular-resource@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/angular-resource/-/angular-resource-1.8.0.tgz#578ef122e7cb7bcc6c0ad6c2451dc3d27fd570ba" + integrity sha512-9woUq3kDwoT7R6SjKX8vaJMhOplYBm9sqRAxKgDhDIdPyA8iBowqQIusf9+8Q+z/HlXb8ZXvKspJyKXrxmKdvg== -angular-route@^1.7.9: - version "1.7.9" - resolved "https://registry.yarnpkg.com/angular-route/-/angular-route-1.7.9.tgz#f9910a2af0ba3ad7a969c5dd369b8360d0d5e4ef" - integrity sha512-vRoj5hzdQtWbODhWJqDzD1iNOEfCKshO6GFBuPVV7RHlPjzIc4R2dHCc7Qiv/8F3LDxJDohc6vSnTDMLHuaqeA== +angular-route@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/angular-route/-/angular-route-1.8.0.tgz#cb8066c5d34284ffd6a15ac7be1b3d51c5ad7bb2" + integrity sha512-ORvXAdVfCCA6XFwyjSkVQFFGufj0mNGiCvBR93Qsii8+7t/6Ioy6wheUoCj1x4NWUv7hAq3nYYGCVO6QEKb1BQ== -angular-sanitize@1.7.9, angular-sanitize@^1.7.9: - version "1.7.9" - resolved "https://registry.yarnpkg.com/angular-sanitize/-/angular-sanitize-1.7.9.tgz#6b4d5e826abdabd352b13a7c65c8c74daf6a7b15" - integrity sha512-nB/xe7JQWF9nLvhHommAICQ3eWrfRETo0EVGFESi952CDzDa+GAJ/2BFBNw44QqQPxj1Xua/uYKrbLsOGWZdbQ== +angular-sanitize@1.8.0, angular-sanitize@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/angular-sanitize/-/angular-sanitize-1.8.0.tgz#9f80782d3afeec3bcc0bb92b3ca6f1f421cfbca6" + integrity sha512-j5GiOPCvfcDWK5svEOVoPb11X3UDVy/mdHPRWuy14Iyw86xaq+Bb+x/em2sAOa5MQQeY5ciLXbF3RRp8iCKcNg== angular-sortable-view@^0.0.17: version "0.0.17" @@ -6513,10 +6513,10 @@ angular-ui-ace@0.2.3: resolved "https://registry.yarnpkg.com/angular-ui-ace/-/angular-ui-ace-0.2.3.tgz#3cb903428100621a367fc7f641440e97a42a26d0" integrity sha1-PLkDQoEAYho2f8f2QUQOl6QqJtA= -angular@>=1.0.6, angular@^1.7.9: - version "1.7.9" - resolved "https://registry.yarnpkg.com/angular/-/angular-1.7.9.tgz#e52616e8701c17724c3c238cfe4f9446fd570bc4" - integrity sha512-5se7ZpcOtu0MBFlzGv5dsM1quQDoDeUTwZrWjGtTNA7O88cD8TEk5IEKCTDa3uECV9XnvKREVUr7du1ACiWGFQ== +angular@>=1.0.6, angular@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/angular/-/angular-1.8.0.tgz#b1ec179887869215cab6dfd0df2e42caa65b1b51" + integrity sha512-VdaMx+Qk0Skla7B5gw77a8hzlcOakwF8mjlW13DpIWIDlfqwAbSSLfd8N/qZnzEmQF4jC4iofInd3gE7vL8ZZg== ansi-align@^2.0.0: version "2.0.0" From 92289b63ef1d3960f49bcd22eedca442ac230c7c Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Tue, 11 Aug 2020 10:05:54 +0200 Subject: [PATCH 087/106] [Ingest Node Pipelines] Sentence-case processor names (#74645) * wip on fixing processor names * added comment * fix Jest test element selector Co-authored-by: Elastic Machine --- .../pipeline_processors_editor.helpers.tsx | 4 +- .../pipeline_processors_editor_item.tsx | 4 +- .../processor_settings_form.tsx | 7 +- .../common_fields/processor_type_field.tsx | 116 +++++++++++++++--- .../components/shared/index.ts | 11 ++ .../map_processor_type_to_form.tsx | 16 +-- 6 files changed, 126 insertions(+), 32 deletions(-) create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/index.ts rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => shared}/map_processor_type_to_form.tsx (95%) diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx index 227513dcdaacc..5ac43953e79bc 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.helpers.tsx @@ -89,7 +89,7 @@ const createActions = (testBed: TestBed) => { async addProcessor(processorsSelector: string, type: string, options: Record) { find(`${processorsSelector}.addProcessorButton`).simulate('click'); await act(async () => { - find('processorTypeSelector').simulate('change', [{ value: type, label: type }]); + find('processorTypeSelector.input').simulate('change', [{ value: type, label: type }]); }); component.update(); await act(async () => { @@ -129,7 +129,7 @@ const createActions = (testBed: TestBed) => { find(`${processorSelector}.moreMenu.button`).simulate('click'); find(`${processorSelector}.moreMenu.addOnFailureButton`).simulate('click'); await act(async () => { - find('processorTypeSelector').simulate('change', [{ value: type, label: type }]); + find('processorTypeSelector.input').simulate('change', [{ value: type, label: type }]); }); component.update(); await act(async () => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx index b43e2bc1342c3..edabbe277e5d9 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx @@ -22,6 +22,8 @@ import { ProcessorsDispatch } from '../../processors_reducer'; import { ProcessorInfo } from '../processors_tree'; +import { getProcessorDescriptor } from '../shared'; + import './pipeline_processors_editor_item.scss'; import { InlineTextInput } from './inline_text_input'; @@ -139,7 +141,7 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( className="pipelineProcessorsEditor__item__processorTypeLabel" color={isDimmed ? 'subdued' : undefined} > - {processor.type} + {getProcessorDescriptor(processor.type)?.label ?? processor.type} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.tsx index 015adae83e71e..b5b3a38bb6a6c 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.tsx @@ -23,8 +23,9 @@ import { import { Form, FormDataProvider, FormHook } from '../../../../../shared_imports'; import { ProcessorInternal } from '../../types'; +import { getProcessorDescriptor } from '../shared'; + import { DocumentationButton } from './documentation_button'; -import { getProcessorFormDescriptor } from './map_processor_type_to_form'; import { CommonProcessorFields, ProcessorTypeField } from './processors/common_fields'; import { Custom } from './processors/custom'; @@ -88,7 +89,7 @@ export const ProcessorSettingsForm: FunctionComponent = memo( {({ type }) => { - const formDescriptor = getProcessorFormDescriptor(type as any); + const formDescriptor = getProcessorDescriptor(type as any); if (formDescriptor) { return ( @@ -114,7 +115,7 @@ export const ProcessorSettingsForm: FunctionComponent = memo( const { type } = arg; if (type?.length) { - const formDescriptor = getProcessorFormDescriptor(type as any); + const formDescriptor = getProcessorDescriptor(type as any); if (formDescriptor?.FieldsComponent) { return ( diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/processor_type_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/processor_type_field.tsx index 4b82fbfad9b52..71ee4a714a28e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/processor_type_field.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/processor_type_field.tsx @@ -3,16 +3,42 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { FunctionComponent } from 'react'; +import { flow } from 'fp-ts/lib/function'; +import { map } from 'fp-ts/lib/Array'; + import { FIELD_TYPES, FieldConfig, UseField, fieldValidators, - ComboBoxField, } from '../../../../../../../shared_imports'; -import { types } from '../../map_processor_type_to_form'; + +import { getProcessorDescriptor, mapProcessorTypeToDescriptor } from '../../../shared'; +import { + FieldValidateResponse, + VALIDATION_TYPES, +} from '../../../../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; + +const extractProcessorTypesAndLabels = flow( + Object.entries, + map(([type, { label }]) => ({ + label, + value: type, + })), + (arr) => arr.sort((a, b) => a.label.localeCompare(b.label)) +); + +interface ProcessorTypeAndLabel { + value: string; + label: string; +} + +const processorTypesAndLabels: ProcessorTypeAndLabel[] = extractProcessorTypesAndLabels( + mapProcessorTypeToDescriptor +); interface Props { initialType?: string; @@ -47,22 +73,76 @@ const typeConfig: FieldConfig = { export const ProcessorTypeField: FunctionComponent = ({ initialType }) => { return ( - ({ label: type, value: type })), - noSuggestions: false, - singleSelection: { - asPlainText: true, - }, - }, + + {(typeField) => { + let selectedOptions: ProcessorTypeAndLabel[]; + if ((typeField.value as string[]).length) { + const [type] = typeField.value as string[]; + const descriptor = getProcessorDescriptor(type); + selectedOptions = descriptor + ? [{ label: descriptor.label, value: type }] + : // If there is no label for this processor type, just use the type as the label + [{ label: type, value: type }]; + } else { + selectedOptions = []; + } + + const error = typeField.getErrorsMessages(); + const isInvalid = error ? Boolean(error.length) : false; + + const onCreateComboOption = (value: string) => { + // Note: for now, all validations for a comboBox array item have to be synchronous + // If there is a need to support asynchronous validation, we'll work on it (and will need to update the logic). + const { isValid } = typeField.validate({ + value, + validationType: VALIDATION_TYPES.ARRAY_ITEM, + }) as FieldValidateResponse; + + if (!isValid) { + // Return false to explicitly reject the user's input. + return false; + } + + const newValue = [...(typeField.value as string[]), value]; + + typeField.setValue(newValue); + }; + + return ( + + { + typeField.setValue(options.map(({ value }) => value)); + }} + noSuggestions={false} + singleSelection={{ + asPlainText: true, + }} + data-test-subj="input" + /> + + ); }} - /> + ); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/index.ts new file mode 100644 index 0000000000000..1b4b975b5305e --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { + getProcessorDescriptor, + mapProcessorTypeToDescriptor, + ProcessorType, +} from './map_processor_type_to_form'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/map_processor_type_to_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx similarity index 95% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/map_processor_type_to_form.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx index 5993d7fb3f87a..7055721fc8b07 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/map_processor_type_to_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx @@ -10,7 +10,7 @@ import { FunctionComponent } from 'react'; // import { SetProcessor } from './processors/set'; // import { Gsub } from './processors/gsub'; -interface FieldsFormDescriptor { +interface FieldDescriptor { FieldsComponent?: FunctionComponent; docLinkPath: string; /** @@ -19,7 +19,9 @@ interface FieldsFormDescriptor { label: string; } -const mapProcessorTypeToFormDescriptor: Record = { +type MapProcessorTypeToDescriptor = Record; + +export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { append: { FieldsComponent: undefined, // TODO: Implement docLinkPath: '/append-processor.html', @@ -262,12 +264,10 @@ const mapProcessorTypeToFormDescriptor: Record = { }, }; -export const types = Object.keys(mapProcessorTypeToFormDescriptor).sort(); - -export type ProcessorType = keyof typeof mapProcessorTypeToFormDescriptor; +export type ProcessorType = keyof typeof mapProcessorTypeToDescriptor; -export const getProcessorFormDescriptor = ( +export const getProcessorDescriptor = ( type: ProcessorType | string -): FieldsFormDescriptor | undefined => { - return mapProcessorTypeToFormDescriptor[type as ProcessorType]; +): FieldDescriptor | undefined => { + return mapProcessorTypeToDescriptor[type as ProcessorType]; }; From a4ec4332c665956727ec264c171ef5f4c48dbb9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Tue, 11 Aug 2020 11:32:05 +0200 Subject: [PATCH 088/106] [ILM] Convert node details flyout to TS (#73707) * [ILM] Convert node allocation component to TS and use hooks * [ILM] Fix jest tests * [ILM] Fix i18n check * [ILM] Implement code review suggestions * [ILM] Fix type check, docs link and button maxWidth in NodeAllocation component * Fix internaliation error * [ILM] Convert node details flyout to TS * [ILM] Fix useState declaration * [ILM] Fix useState declaration * [ILM] Fix jest test * [ILM] Change error message when unable to load node attributes * [ILM] Change error message when unable to load node details * [ILM] Delete a period in error callout * [ILM] Delete a period in error callout * [ILM] Convert node details flyout to TS * [ILM] Fix i18n check * [ILM] Fix useState declaration * [ILM] Fix useState declaration * [ILM] Fix jest test * [ILM] Change error message when unable to load node details * [ILM] Delete a period in error callout Co-authored-by: Elastic Machine --- .../__jest__/components/edit_policy.test.js | 14 ++- .../components/helpers/http_requests.ts | 9 ++ .../components/cold_phase/cold_phase.js | 3 - .../node_allocation/node_allocation.tsx | 18 ++- .../node_attrs_details/{index.js => index.ts} | 2 +- .../node_attrs_details.container.js | 18 --- .../node_attrs_details/node_attrs_details.js | 81 ------------- .../node_attrs_details/node_attrs_details.tsx | 106 ++++++++++++++++++ .../components/warm_phase/warm_phase.js | 3 - .../sections/edit_policy/edit_policy.js | 16 --- .../public/application/services/api.ts | 9 +- .../public/application/store/actions/nodes.js | 24 ---- .../application/store/reducers/nodes.js | 23 +--- .../application/store/selectors/nodes.js | 14 --- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 16 files changed, 149 insertions(+), 193 deletions(-) rename x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/{index.js => index.ts} (78%) delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.js create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.tsx diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js index c6da347ed8cfe..4fe3d5c66696e 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js +++ b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js @@ -253,6 +253,9 @@ describe('edit policy', () => { beforeEach(() => { server.respondImmediately = true; httpRequestsMockHelpers.setNodesListResponse({}); + httpRequestsMockHelpers.setNodesDetailsResponse('attribute:true', [ + { nodeId: 'testNodeId', stats: { name: 'testNodeName', host: 'testHost' } }, + ]); }); test('should show number required error when trying to save empty warm phase', async () => { @@ -395,7 +398,9 @@ describe('edit policy', () => { rendered.update(); const flyoutButton = findTestSubject(rendered, 'warm-viewNodeDetailsFlyoutButton'); expect(flyoutButton.exists()).toBeTruthy(); - flyoutButton.simulate('click'); + await act(async () => { + await flyoutButton.simulate('click'); + }); rendered.update(); expect(rendered.find('.euiFlyout').exists()).toBeTruthy(); }); @@ -404,6 +409,9 @@ describe('edit policy', () => { beforeEach(() => { server.respondImmediately = true; httpRequestsMockHelpers.setNodesListResponse({}); + httpRequestsMockHelpers.setNodesDetailsResponse('attribute:true', [ + { nodeId: 'testNodeId', stats: { name: 'testNodeName', host: 'testHost' } }, + ]); }); test('should allow 0 for phase timing', async () => { const rendered = mountWithIntl(component); @@ -470,7 +478,9 @@ describe('edit policy', () => { rendered.update(); const flyoutButton = findTestSubject(rendered, 'cold-viewNodeDetailsFlyoutButton'); expect(flyoutButton.exists()).toBeTruthy(); - flyoutButton.simulate('click'); + await act(async () => { + await flyoutButton.simulate('click'); + }); rendered.update(); expect(rendered.find('.euiFlyout').exists()).toBeTruthy(); }); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/components/helpers/http_requests.ts b/x-pack/plugins/index_lifecycle_management/__jest__/components/helpers/http_requests.ts index b5c941beef181..668cbedbf0c95 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/components/helpers/http_requests.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/components/helpers/http_requests.ts @@ -25,9 +25,18 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { ]); }; + const setNodesDetailsResponse = (nodeAttributes: string, response: HttpResponse = []) => { + server.respondWith(`/api/index_lifecycle_management/nodes/${nodeAttributes}/details`, [ + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify(response), + ]); + }; + return { setPoliciesResponse, setNodesListResponse, + setNodesDetailsResponse, }; }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/cold_phase/cold_phase.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/cold_phase/cold_phase.js index d5c0744e5eb07..200bf0e767d9d 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/cold_phase/cold_phase.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/cold_phase/cold_phase.js @@ -34,7 +34,6 @@ import { SetPriorityInput } from '../set_priority_input'; export class ColdPhase extends PureComponent { static propTypes = { setPhaseData: PropTypes.func.isRequired, - showNodeDetailsFlyout: PropTypes.func.isRequired, isShowingErrors: PropTypes.bool.isRequired, errors: PropTypes.object.isRequired, @@ -42,7 +41,6 @@ export class ColdPhase extends PureComponent { render() { const { setPhaseData, - showNodeDetailsFlyout, phaseData, errors, isShowingErrors, @@ -114,7 +112,6 @@ export class ColdPhase extends PureComponent { void; - showNodeDetailsFlyout: (nodeAttrs: any) => void; errors: any; phaseData: any; isShowingErrors: boolean; @@ -48,13 +48,16 @@ const learnMoreLink = ( export const NodeAllocation: React.FunctionComponent = ({ phase, setPhaseData, - showNodeDetailsFlyout, errors, phaseData, isShowingErrors, }) => { const { isLoading, data: nodes, error, sendRequest } = useLoadNodes(); + const [selectedNodeAttrsForDetails, setSelectedNodeAttrsForDetails] = useState( + null + ); + if (isLoading) { return ( @@ -162,7 +165,7 @@ export const NodeAllocation: React.FunctionComponent = ({ data-test-subj={`${phase}-viewNodeDetailsFlyoutButton`} flush="left" iconType="eye" - onClick={() => showNodeDetailsFlyout(phaseData[PHASE_NODE_ATTRS])} + onClick={() => setSelectedNodeAttrsForDetails(phaseData[PHASE_NODE_ATTRS])} > = ({ ) : null} {learnMoreLink} + + {selectedNodeAttrsForDetails ? ( + setSelectedNodeAttrsForDetails(null)} + /> + ) : null} ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/index.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/index.ts similarity index 78% rename from x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/index.js rename to x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/index.ts index 885e965c46c4b..056d2f2f600f3 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/index.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { NodeAttrsDetails } from './node_attrs_details.container'; +export { NodeAttrsDetails } from './node_attrs_details'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js deleted file mode 100644 index ca7c310723b62..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { connect } from 'react-redux'; - -import { getNodeDetails } from '../../../../store/selectors'; -import { fetchNodeDetails } from '../../../../store/actions'; -import { NodeAttrsDetails as PresentationComponent } from './node_attrs_details'; - -export const NodeAttrsDetails = connect( - (state, ownProps) => ({ - details: getNodeDetails(state, ownProps.selectedNodeAttrs), - }), - { fetchNodeDetails } -)(PresentationComponent); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.js deleted file mode 100644 index 67bc8f0386abf..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.js +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; - -import { - EuiFlyoutBody, - EuiFlyout, - EuiTitle, - EuiInMemoryTable, - EuiSpacer, - EuiPortal, -} from '@elastic/eui'; - -export class NodeAttrsDetails extends PureComponent { - static propTypes = { - fetchNodeDetails: PropTypes.func.isRequired, - close: PropTypes.func.isRequired, - - details: PropTypes.array, - selectedNodeAttrs: PropTypes.string.isRequired, - }; - - UNSAFE_componentWillMount() { - this.props.fetchNodeDetails(this.props.selectedNodeAttrs); - } - - render() { - const { selectedNodeAttrs, details, close } = this.props; - - return ( - - - - -

    - -

    -
    - - -
    -
    -
    - ); - } -} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.tsx new file mode 100644 index 0000000000000..6fcbd94dc5e9a --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.tsx @@ -0,0 +1,106 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { + EuiFlyoutBody, + EuiFlyout, + EuiTitle, + EuiInMemoryTable, + EuiSpacer, + EuiPortal, + EuiLoadingContent, + EuiCallOut, + EuiButton, +} from '@elastic/eui'; + +import { useLoadNodeDetails } from '../../../../services/api'; + +interface Props { + close: () => void; + selectedNodeAttrs: string; +} + +export const NodeAttrsDetails: React.FunctionComponent = ({ close, selectedNodeAttrs }) => { + const { data, isLoading, error, sendRequest } = useLoadNodeDetails(selectedNodeAttrs); + let content; + if (isLoading) { + content = ; + } else if (error) { + const { statusCode, message } = error; + content = ( + + } + color="danger" + > +

    + {message} ({statusCode}) +

    + + + +
    + ); + } else { + content = ( + + ); + } + return ( + + + + +

    + +

    +
    + + {content} +
    +
    +
    + ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/warm_phase/warm_phase.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/warm_phase/warm_phase.js index 55aec88c8bcab..60b5ab4781b6d 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/warm_phase/warm_phase.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/warm_phase/warm_phase.js @@ -38,7 +38,6 @@ import { MinAgeInput } from '../min_age_input'; export class WarmPhase extends PureComponent { static propTypes = { setPhaseData: PropTypes.func.isRequired, - showNodeDetailsFlyout: PropTypes.func.isRequired, isShowingErrors: PropTypes.bool.isRequired, errors: PropTypes.object.isRequired, @@ -47,7 +46,6 @@ export class WarmPhase extends PureComponent { render() { const { setPhaseData, - showNodeDetailsFlyout, phaseData, errors, isShowingErrors, @@ -152,7 +150,6 @@ export class WarmPhase extends PureComponent { { - this.setState({ isShowingNodeDetailsFlyout: true, selectedNodeAttrsForDetails }); - }; - togglePolicyJsonFlyout = () => { this.setState(({ isShowingPolicyJsonFlyout }) => ({ isShowingPolicyJsonFlyout: !isShowingPolicyJsonFlyout, @@ -291,7 +284,6 @@ export class EditPolicy extends Component { @@ -299,7 +291,6 @@ export class EditPolicy extends Component { @@ -370,13 +361,6 @@ export class EditPolicy extends Component {
    - {this.state.isShowingNodeDetailsFlyout ? ( - this.setState({ isShowingNodeDetailsFlyout: false })} - /> - ) : null} - {this.state.isShowingPolicyJsonFlyout ? ( { }); }; -export async function loadNodeDetails(selectedNodeAttrs: string) { - return await sendGet(`nodes/${selectedNodeAttrs}/details`); -} +export const useLoadNodeDetails = (selectedNodeAttrs: string) => { + return useRequest({ + path: `nodes/${selectedNodeAttrs}/details`, + method: 'get', + }); +}; export async function loadIndexTemplates() { return await sendGet(`templates`); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/store/actions/nodes.js b/x-pack/plugins/index_lifecycle_management/public/application/store/actions/nodes.js index 0b4026f019210..3f1c00db621a7 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/store/actions/nodes.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/store/actions/nodes.js @@ -3,33 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { i18n } from '@kbn/i18n'; import { createAction } from 'redux-actions'; -import { showApiError } from '../../services/api_errors'; -import { loadNodeDetails } from '../../services/api'; import { SET_SELECTED_NODE_ATTRS } from '../../constants'; export const setSelectedNodeAttrs = createAction(SET_SELECTED_NODE_ATTRS); export const setSelectedPrimaryShardCount = createAction('SET_SELECTED_PRIMARY_SHARED_COUNT'); export const setSelectedReplicaCount = createAction('SET_SELECTED_REPLICA_COUNT'); - -export const fetchedNodeDetails = createAction( - 'FETCHED_NODE_DETAILS', - (selectedNodeAttrs, details) => ({ - selectedNodeAttrs, - details, - }) -); -export const fetchNodeDetails = (selectedNodeAttrs) => async (dispatch) => { - let details; - try { - details = await loadNodeDetails(selectedNodeAttrs); - } catch (err) { - const title = i18n.translate('xpack.indexLifecycleMgmt.editPolicy.nodeDetailErrorMessage', { - defaultMessage: 'Error loading node attribute details', - }); - showApiError(err, title); - return false; - } - dispatch(fetchedNodeDetails(selectedNodeAttrs, details)); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/store/reducers/nodes.js b/x-pack/plugins/index_lifecycle_management/public/application/store/reducers/nodes.js index 06d173e9901f8..383e61b5aacde 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/store/reducers/nodes.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/store/reducers/nodes.js @@ -5,12 +5,7 @@ */ import { handleActions } from 'redux-actions'; -import { - setSelectedNodeAttrs, - setSelectedPrimaryShardCount, - setSelectedReplicaCount, - fetchedNodeDetails, -} from '../actions/nodes'; +import { setSelectedPrimaryShardCount, setSelectedReplicaCount } from '../actions'; const defaultState = { isLoading: false, @@ -23,22 +18,6 @@ const defaultState = { export const nodes = handleActions( { - [fetchedNodeDetails](state, { payload }) { - const { selectedNodeAttrs, details } = payload; - return { - ...state, - details: { - ...state.details, - [selectedNodeAttrs]: details, - }, - }; - }, - [setSelectedNodeAttrs](state, { payload: selectedNodeAttrs }) { - return { - ...state, - selectedNodeAttrs, - }; - }, [setSelectedPrimaryShardCount](state, { payload }) { let selectedPrimaryShardCount = parseInt(payload); if (isNaN(selectedPrimaryShardCount)) { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/nodes.js b/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/nodes.js index 561681bf7d93d..72bfd4b15a78a 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/nodes.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/nodes.js @@ -10,17 +10,3 @@ export const getSelectedPrimaryShardCount = (state) => state.nodes.selectedPrima export const getSelectedReplicaCount = (state) => state.nodes.selectedReplicaCount !== undefined ? state.nodes.selectedReplicaCount : 1; - -export const getSelectedNodeAttrs = (state) => state.nodes.selectedNodeAttrs; - -export const getNodesFromSelectedNodeAttrs = (state) => { - const nodes = getNodes(state)[getSelectedNodeAttrs(state)]; - if (nodes) { - return nodes.length; - } - return null; -}; - -export const getNodeDetails = (state, selectedNodeAttrs) => { - return state.nodes.details[selectedNodeAttrs]; -}; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 05f709f04aa88..c796aacda10a0 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -8206,7 +8206,6 @@ "xpack.indexLifecycleMgmt.editPolicy.nodeAllocationLabel": "シャードの割当をコントロールするノード属性を選択", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingDescription": "ノード属性なしではシャードの割り当てをコントロールできません。", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingLabel": "elasticsearch.yml でノード属性が構成されていません", - "xpack.indexLifecycleMgmt.editPolicy.nodeDetailErrorMessage": "ノード属性の詳細の読み込み中にエラーが発生しました", "xpack.indexLifecycleMgmt.editPolicy.numberRequiredError": "数字が必要です。", "xpack.indexLifecycleMgmt.editPolicy.phaseCold.minimumAgeLabel": "コールドフェーズのタイミング", "xpack.indexLifecycleMgmt.editPolicy.phaseCold.minimumAgeUnitsAriaLabel": "コールドフェーズのタイミングの単位", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index bd0066eeb419f..4c48a66b3c3c8 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -8208,7 +8208,6 @@ "xpack.indexLifecycleMgmt.editPolicy.nodeAllocationLabel": "选择节点属性来控制分片分配", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingDescription": "没有节点属性,将无法控制分片分配。", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingLabel": "elasticsearch.yml 中未配置任何节点属性", - "xpack.indexLifecycleMgmt.editPolicy.nodeDetailErrorMessage": "加载节点属性详细信息时出错", "xpack.indexLifecycleMgmt.editPolicy.numberRequiredError": "数字必填。", "xpack.indexLifecycleMgmt.editPolicy.phaseCold.minimumAgeLabel": "冷阶段计时", "xpack.indexLifecycleMgmt.editPolicy.phaseCold.minimumAgeUnitsAriaLabel": "冷阶段计时单位", From 0c16ca464936547f83b770dc630de20a9f1652e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Tue, 11 Aug 2020 10:44:32 +0100 Subject: [PATCH 089/106] [Telemetry][API Integration] size_in_bytes to be a number (#74664) --- test/api_integration/apis/telemetry/telemetry_local.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/api_integration/apis/telemetry/telemetry_local.js b/test/api_integration/apis/telemetry/telemetry_local.js index 88e6b3a29052e..8b10f412fae27 100644 --- a/test/api_integration/apis/telemetry/telemetry_local.js +++ b/test/api_integration/apis/telemetry/telemetry_local.js @@ -90,7 +90,7 @@ export default function ({ getService }) { expect(stats.stack_stats.data[0].index_count).to.be(1); expect(stats.stack_stats.data[0].doc_count).to.be(0); expect(stats.stack_stats.data[0].ecs_index_count).to.be(0); - expect(stats.stack_stats.data[0].size_in_bytes).to.be.greaterThan(0); + expect(stats.stack_stats.data[0].size_in_bytes).to.be.a('number'); }); it('should pull local stats and validate fields', async () => { From 5665ce2cd2773f7db83d1de7d4b362470e9f8840 Mon Sep 17 00:00:00 2001 From: igoristic Date: Tue, 11 Aug 2020 06:40:22 -0400 Subject: [PATCH 090/106] Fixed grammar (#74725) --- TYPESCRIPT.md | 2 +- rfcs/text/0001_lifecycle_setup.md | 2 +- src/plugins/data/public/search/search_interceptor.ts | 2 +- .../plugins/data_enhanced/public/search/search_interceptor.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TYPESCRIPT.md b/TYPESCRIPT.md index 7be9a5e4f3b17..ae23768558f9d 100644 --- a/TYPESCRIPT.md +++ b/TYPESCRIPT.md @@ -62,7 +62,7 @@ declare module '@elastic/eui' { 1. Open up the file and see how easy it would be to convert to TypeScript. 2. If it's very straightforward, go for it. 3. If it's not and you wish to stay focused on your own PR, get around the error by adding a type definition file in the same folder as the dependency, with the same name. -4. Minimally you will need to type what you are using in your PR. No need to go crazy to fully type the thing or you might be there for awhile depending on what's available. +4. Minimally you will need to type what you are using in your PR. No need to go crazy to fully type the thing or you might be there for a while depending on what's available. For example: diff --git a/rfcs/text/0001_lifecycle_setup.md b/rfcs/text/0001_lifecycle_setup.md index 01343b42f9a2d..bff200ca76472 100644 --- a/rfcs/text/0001_lifecycle_setup.md +++ b/rfcs/text/0001_lifecycle_setup.md @@ -124,7 +124,7 @@ all services and plugins, and then adding an empty `start` where it is necessary. Functionality can then be moved from `setup`->`start` on a case-by-case. -If this change doesn't happen for awhile, then it might make sense to follow +If this change doesn't happen for a while, then it might make sense to follow the reverse process to ensure the least impact. The migration guide will be updated to reflect the `setup` and `start` diff --git a/src/plugins/data/public/search/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor.ts index e6eca16c5ca4b..677ad0ccea677 100644 --- a/src/plugins/data/public/search/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor.ts @@ -170,7 +170,7 @@ export class SearchInterceptor { if (this.longRunningToast) return; this.longRunningToast = this.deps.toasts.addInfo( { - title: 'Your query is taking awhile', + title: 'Your query is taking a while', text: getLongQueryNotification({ application: this.deps.application, }), diff --git a/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts b/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts index 927dc91f365b7..9662b9e17248b 100644 --- a/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts +++ b/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts @@ -51,7 +51,7 @@ export class EnhancedSearchInterceptor extends SearchInterceptor { if (this.longRunningToast) return; this.longRunningToast = this.deps.toasts.addInfo( { - title: 'Your query is taking awhile', + title: 'Your query is taking a while', text: getLongQueryNotification({ cancel: this.cancelPending, runBeyondTimeout: this.runBeyondTimeout, From 53828dab35a95191ffb3467c33f5731847bb22f2 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Tue, 11 Aug 2020 15:24:21 +0300 Subject: [PATCH 091/106] [telemetry] update README to downplay ui_metrics (#74635) Co-authored-by: Elastic Machine --- src/plugins/usage_collection/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/usage_collection/README.md b/src/plugins/usage_collection/README.md index a828096f86042..4f0f10703c5e9 100644 --- a/src/plugins/usage_collection/README.md +++ b/src/plugins/usage_collection/README.md @@ -10,8 +10,6 @@ To integrate with the telemetry services for usage collection of your feature, t All you need to provide is a `type` for organizing your fields, `schema` field to define the expected types of usage fields reported, and a `fetch` method for returning your usage data. Then you need to make the Telemetry service aware of the collector by registering it. -### New Platform - 1. Make sure `usageCollection` is in your optional Plugins: ```json @@ -205,6 +203,10 @@ There are a few ways you can test that your usage collector is working properly. # UI Metric app +The UI metrics implementation in its current state is not useful. We are working on improving the implementation to enable teams to use the data to visualize and gather information from what is being reported. Please refer to the telemetry team if you are interested in adding ui_metrics to your plugin. + +**Until a better implementation is introduced, please defer from adding any new ui metrics.** + ## Purpose The purpose of the UI Metric app is to provide a tool for gathering data on how users interact with From d91e024f66b4a8c71749f599e392b8de7a5cd6e7 Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Date: Tue, 11 Aug 2020 08:52:38 -0400 Subject: [PATCH 092/106] [SECURITY] Bugs css/inspect (#74711) * Fix inspection button when using topN * css left over --- .../components/configure_cases/index.tsx | 3 +++ .../common/components/header_global/index.tsx | 6 ++++-- .../public/common/components/top_n/index.tsx | 2 +- .../containers/use_global_time/index.test.tsx | 21 ++++++++++++++++++- .../containers/use_global_time/index.tsx | 8 ++++--- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx index e2e3a600a95ff..63b271b8cce78 100644 --- a/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx @@ -42,6 +42,9 @@ const FormWrapper = styled.div` padding-top: ${theme.eui.paddingSizes.xl}; padding-bottom: ${theme.eui.paddingSizes.xl}; + .euiFlyout { + z-index: ${theme.eui.euiZNavigation + 1}; + } `} `; diff --git a/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx b/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx index fbc3d62768d00..e05e3c2e9aeb1 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx @@ -41,14 +41,15 @@ const FlexItem = styled(EuiFlexItem)` `; FlexItem.displayName = 'FlexItem'; -const FlexGroup = styled(EuiFlexGroup)<{ $globalFullScreen: boolean }>` - ${({ $globalFullScreen, theme }) => ` +const FlexGroup = styled(EuiFlexGroup)<{ $globalFullScreen: boolean; $hasSibling: boolean }>` + ${({ $globalFullScreen, $hasSibling, theme }) => ` border-bottom: ${theme.eui.euiBorderThin}; margin-bottom: 1px; padding-bottom: 4px; padding-left: ${theme.eui.paddingSizes.l}; padding-right: ${gutterTimeline}; ${$globalFullScreen ? 'display: none;' : ''} + ${$hasSibling ? `border-bottom: ${theme.eui.euiBorderThin};` : 'border-bottom-width: 0px;'} `} `; FlexGroup.displayName = 'FlexGroup'; @@ -75,6 +76,7 @@ export const HeaderGlobal = React.memo(({ hideDetectionEngine diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/index.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/index.tsx index 807f1839973fa..d71242329bcda 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/index.tsx @@ -104,7 +104,7 @@ const StatefulTopNComponent: React.FC = ({ value, }) => { const kibana = useKibana(); - const { from, deleteQuery, setQuery, to } = useGlobalTime(); + const { from, deleteQuery, setQuery, to } = useGlobalTime(false); const options = getOptions( timelineId === TimelineId.active ? activeTimelineEventType : undefined diff --git a/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.test.tsx b/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.test.tsx index 9d5f1740b0276..07ce3551e3289 100644 --- a/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.test.tsx @@ -8,17 +8,22 @@ import { act, renderHook } from '@testing-library/react-hooks'; import { useGlobalTime } from '.'; +const mockDispatch = jest.fn(); + jest.mock('react-redux', () => { const originalModule = jest.requireActual('react-redux'); return { ...originalModule, - useDispatch: jest.fn().mockReturnValue(jest.fn()), + useDispatch: () => mockDispatch, useSelector: jest.fn().mockReturnValue({ from: 0, to: 0 }), }; }); describe('useGlobalTime', () => { + beforeEach(() => { + mockDispatch.mockReset(); + }); test('returns memoized value', () => { const { result, rerender } = renderHook(() => useGlobalTime()); @@ -30,4 +35,18 @@ describe('useGlobalTime', () => { expect(result1.from).toBe(0); expect(result1.to).toBe(0); }); + + test('clear all queries at unmount', () => { + const { rerender } = renderHook(() => useGlobalTime()); + act(() => rerender()); + expect(mockDispatch.mock.calls[0][0].type).toEqual( + 'x-pack/security_solution/local/inputs/DELETE_ALL_QUERY' + ); + }); + + test('do NOT clear all queries at unmount', () => { + const { rerender } = renderHook(() => useGlobalTime(false)); + act(() => rerender()); + expect(mockDispatch.mock.calls.length).toBe(0); + }); }); diff --git a/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx b/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx index b63616ecbcf56..52825caf9ce74 100644 --- a/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx @@ -11,7 +11,7 @@ import { inputsSelectors } from '../../store'; import { inputsActions } from '../../store/actions'; import { SetQuery, DeleteQuery } from './types'; -export const useGlobalTime = () => { +export const useGlobalTime = (clearAllQuery: boolean = true) => { const dispatch = useDispatch(); const { from, to } = useSelector(inputsSelectors.globalTimeRangeSelector); const [isInitializing, setIsInitializing] = useState(true); @@ -32,9 +32,11 @@ export const useGlobalTime = () => { setIsInitializing(false); } return () => { - dispatch(inputsActions.deleteAllQuery({ id: 'global' })); + if (clearAllQuery) { + dispatch(inputsActions.deleteAllQuery({ id: 'global' })); + } }; - }, [dispatch, isInitializing]); + }, [clearAllQuery, dispatch, isInitializing]); const memoizedReturn = useMemo( () => ({ From 6c63b0d40b2a83ba07822790622769bfd2f56d8d Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Tue, 11 Aug 2020 07:54:58 -0500 Subject: [PATCH 093/106] Index pattern field list - transition away from extending array - introduce and use getAll() (#74718) - Introduce `indexPattern.fields.getAll()` and use where possible - Rename `index_patterns/fields/fields.mocks.ts.ts => index_patterns/fields/fields.mocks.ts` - FieldSpec - make `count` and `scripted` fields optional - use `indexPattern.fields.getByName` instead of filter where possible --- ...in-plugins-data-public.fieldlist.getall.md | 11 ++ ...na-plugin-plugins-data-public.fieldlist.md | 1 + ...ta-public.iindexpatternfieldlist.getall.md | 15 +++ ...gins-data-public.iindexpatternfieldlist.md | 1 + .../es_query/filters/exists_filter.test.ts | 2 +- .../es_query/filters/get_filter_field.test.ts | 2 +- .../es_query/filters/phrases_filter.test.ts | 2 +- .../index_patterns/fields/field_list.ts | 2 + .../{fields.mocks.ts.ts => fields.mocks.ts} | 0 .../fields/index_pattern_field.ts | 4 +- .../index_patterns/index_pattern.ts | 4 +- .../data/common/index_patterns/mocks.ts | 2 +- .../data/common/index_patterns/types.ts | 4 +- src/plugins/data/public/public.api.md | 4 + .../lib/get_index_pattern_field_list.ts | 6 +- .../components/table/table.test.tsx | 68 ++++++------ .../application/components/table/table.tsx | 8 +- .../edit_index_pattern/edit_index_pattern.tsx | 6 +- .../edit_index_pattern/tabs/tabs.tsx | 2 +- .../edit_index_pattern/tabs/utils.ts | 4 +- .../__snapshots__/field_editor.test.tsx.snap | 101 ++++-------------- .../components/scripting_help/test_script.tsx | 1 + .../field_editor/field_editor.test.tsx | 21 ++-- .../components/field_editor/field_editor.tsx | 8 +- .../public/control/list_control_factory.ts | 2 +- .../public/test_utils/get_deps_mock.tsx | 1 + .../public/helpers/arg_value_suggestions.ts | 3 + .../components/autocomplete/field.test.tsx | 2 +- .../autocomplete/field_value_lists.test.tsx | 2 +- .../autocomplete/field_value_match.test.tsx | 2 +- .../field_value_match_any.test.tsx | 2 +- .../components/autocomplete/helpers.test.ts | 2 +- .../use_field_value_autocomplete.test.ts | 2 +- .../components/autocomplete/operator.test.tsx | 2 +- .../exceptions/builder/entry_item.test.tsx | 2 +- .../builder/exception_item.test.tsx | 2 +- .../exceptions/builder/helpers.test.tsx | 2 +- .../exceptions/builder/index.test.tsx | 2 +- 38 files changed, 143 insertions(+), 164 deletions(-) create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getall.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md rename src/plugins/data/common/index_patterns/fields/{fields.mocks.ts.ts => fields.mocks.ts} (100%) diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getall.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getall.md new file mode 100644 index 0000000000000..da29a4de9acc8 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.getall.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) > [getAll](./kibana-plugin-plugins-data-public.fieldlist.getall.md) + +## FieldList.getAll property + +Signature: + +```typescript +readonly getAll: () => IndexPatternField[]; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.md index ef740575dff4e..012b069430290 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldlist.md @@ -21,6 +21,7 @@ export declare class FieldList extends Array implements IInde | Property | Modifiers | Type | Description | | --- | --- | --- | --- | | [add](./kibana-plugin-plugins-data-public.fieldlist.add.md) | | (field: FieldSpec) => void | | +| [getAll](./kibana-plugin-plugins-data-public.fieldlist.getall.md) | | () => IndexPatternField[] | | | [getByName](./kibana-plugin-plugins-data-public.fieldlist.getbyname.md) | | (name: IndexPatternField['name']) => IndexPatternField | undefined | | | [getByType](./kibana-plugin-plugins-data-public.fieldlist.getbytype.md) | | (type: IndexPatternField['type']) => any[] | | | [remove](./kibana-plugin-plugins-data-public.fieldlist.remove.md) | | (field: IFieldType) => void | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md new file mode 100644 index 0000000000000..070e36e303a80 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [getAll](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md) + +## IIndexPatternFieldList.getAll() method + +Signature: + +```typescript +getAll(): IndexPatternField[]; +``` +Returns: + +`IndexPatternField[]` + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md index 4ab012a2601d2..b068c4804c0dd 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md @@ -15,6 +15,7 @@ export interface IIndexPatternFieldList extends Array | Method | Description | | --- | --- | | [add(field)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.add.md) | | +| [getAll()](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md) | | | [getByName(name)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md) | | | [getByType(type)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md) | | | [remove(field)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.remove.md) | | diff --git a/src/plugins/data/common/es_query/filters/exists_filter.test.ts b/src/plugins/data/common/es_query/filters/exists_filter.test.ts index 065301986726d..298ea7f49da5e 100644 --- a/src/plugins/data/common/es_query/filters/exists_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/exists_filter.test.ts @@ -19,7 +19,7 @@ import { buildExistsFilter, getExistsFilterField } from './exists_filter'; import { IIndexPattern } from '../../index_patterns'; -import { fields } from '../../index_patterns/fields/fields.mocks.ts'; +import { fields } from '../../index_patterns/fields/fields.mocks'; describe('exists filter', function () { const indexPattern: IIndexPattern = ({ diff --git a/src/plugins/data/common/es_query/filters/get_filter_field.test.ts b/src/plugins/data/common/es_query/filters/get_filter_field.test.ts index 4329a45f84ef9..3b27aa98cf5f6 100644 --- a/src/plugins/data/common/es_query/filters/get_filter_field.test.ts +++ b/src/plugins/data/common/es_query/filters/get_filter_field.test.ts @@ -21,7 +21,7 @@ import { buildPhraseFilter } from './phrase_filter'; import { buildQueryFilter } from './query_string_filter'; import { getFilterField } from './get_filter_field'; import { IIndexPattern } from '../../index_patterns'; -import { fields } from '../../index_patterns/fields/fields.mocks.ts'; +import { fields } from '../../index_patterns/fields/fields.mocks'; describe('getFilterField', function () { const indexPattern: IIndexPattern = ({ diff --git a/src/plugins/data/common/es_query/filters/phrases_filter.test.ts b/src/plugins/data/common/es_query/filters/phrases_filter.test.ts index 7fbab263ac040..ed42b63be7ecc 100644 --- a/src/plugins/data/common/es_query/filters/phrases_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/phrases_filter.test.ts @@ -19,7 +19,7 @@ import { buildPhrasesFilter, getPhrasesFilterField } from './phrases_filter'; import { IIndexPattern } from '../../index_patterns'; -import { fields } from '../../index_patterns/fields/fields.mocks.ts'; +import { fields } from '../../index_patterns/fields/fields.mocks'; describe('phrases filter', function () { const indexPattern: IIndexPattern = ({ diff --git a/src/plugins/data/common/index_patterns/fields/field_list.ts b/src/plugins/data/common/index_patterns/fields/field_list.ts index 207002f42bbce..172da9f9ca43f 100644 --- a/src/plugins/data/common/index_patterns/fields/field_list.ts +++ b/src/plugins/data/common/index_patterns/fields/field_list.ts @@ -27,6 +27,7 @@ type FieldMap = Map; export interface IIndexPatternFieldList extends Array { add(field: FieldSpec): void; + getAll(): IndexPatternField[]; getByName(name: IndexPatternField['name']): IndexPatternField | undefined; getByType(type: IndexPatternField['type']): IndexPatternField[]; remove(field: IFieldType): void; @@ -72,6 +73,7 @@ export class FieldList extends Array implements IIndexPattern specs.map((field) => this.add(field)); } + public readonly getAll = () => [...this.byName.values()]; public readonly getByName = (name: IndexPatternField['name']) => this.byName.get(name); public readonly getByType = (type: IndexPatternField['type']) => [ ...(this.groups.get(type) || new Map()).values(), diff --git a/src/plugins/data/common/index_patterns/fields/fields.mocks.ts.ts b/src/plugins/data/common/index_patterns/fields/fields.mocks.ts similarity index 100% rename from src/plugins/data/common/index_patterns/fields/fields.mocks.ts.ts rename to src/plugins/data/common/index_patterns/fields/fields.mocks.ts diff --git a/src/plugins/data/common/index_patterns/fields/index_pattern_field.ts b/src/plugins/data/common/index_patterns/fields/index_pattern_field.ts index 4e22332bef141..679de103f8019 100644 --- a/src/plugins/data/common/index_patterns/fields/index_pattern_field.ts +++ b/src/plugins/data/common/index_patterns/fields/index_pattern_field.ts @@ -62,7 +62,7 @@ export class IndexPatternField implements IFieldType { // writable attrs public get count() { - return this.spec.count; + return this.spec.count || 0; } public set count(count) { @@ -107,7 +107,7 @@ export class IndexPatternField implements IFieldType { } public get scripted() { - return this.spec.scripted; + return !!this.spec.scripted; } public get searchable() { diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts index 211919e8e6b53..4e484dce7826f 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts @@ -403,11 +403,11 @@ export class IndexPattern implements IIndexPattern { } getNonScriptedFields() { - return [...this.fields.filter((field) => !field.scripted)]; + return [...this.fields.getAll().filter((field) => !field.scripted)]; } getScriptedFields() { - return [...this.fields.filter((field) => field.scripted)]; + return [...this.fields.getAll().filter((field) => field.scripted)]; } isTimeBased(): boolean { diff --git a/src/plugins/data/common/index_patterns/mocks.ts b/src/plugins/data/common/index_patterns/mocks.ts index 6036c08fa2b10..faf1b8307ea2e 100644 --- a/src/plugins/data/common/index_patterns/mocks.ts +++ b/src/plugins/data/common/index_patterns/mocks.ts @@ -17,4 +17,4 @@ * under the License. */ -export * from './fields/fields.mocks.ts'; +export * from './fields/fields.mocks'; diff --git a/src/plugins/data/common/index_patterns/types.ts b/src/plugins/data/common/index_patterns/types.ts index 3a7cf54843dfc..a771113acd231 100644 --- a/src/plugins/data/common/index_patterns/types.ts +++ b/src/plugins/data/common/index_patterns/types.ts @@ -149,7 +149,7 @@ export interface FieldSpecExportFmt { } export interface FieldSpec { - count: number; + count?: number; script?: string; lang?: string; conflictDescriptions?: Record; @@ -158,7 +158,7 @@ export interface FieldSpec { name: string; type: string; esTypes?: string[]; - scripted: boolean; + scripted?: boolean; searchable: boolean; aggregatable: boolean; readFromDocValues?: boolean; diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 76f88df4dd6fc..adff7b205b931 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -585,6 +585,8 @@ export class FieldList extends Array implements IIndexPattern // (undocumented) readonly add: (field: FieldSpec) => void; // (undocumented) + readonly getAll: () => IndexPatternField[]; + // (undocumented) readonly getByName: (name: IndexPatternField['name']) => IndexPatternField | undefined; // (undocumented) readonly getByType: (type: IndexPatternField['type']) => any[]; @@ -879,6 +881,8 @@ export interface IIndexPatternFieldList extends Array { // (undocumented) add(field: FieldSpec): void; // (undocumented) + getAll(): IndexPatternField[]; + // (undocumented) getByName(name: IndexPatternField['name']): IndexPatternField | undefined; // (undocumented) getByType(type: IndexPatternField['type']): IndexPatternField[]; diff --git a/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts b/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts index 751a59d982153..00e00aa8e2991 100644 --- a/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts +++ b/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { difference, map } from 'lodash'; +import { difference } from 'lodash'; import { IndexPattern, IndexPatternField } from 'src/plugins/data/public'; export function getIndexPatternFieldList( @@ -26,7 +26,7 @@ export function getIndexPatternFieldList( if (!indexPattern || !fieldCounts) return []; const fieldNamesInDocs = Object.keys(fieldCounts); - const fieldNamesInIndexPattern = map(indexPattern.fields, 'name'); + const fieldNamesInIndexPattern = indexPattern.fields.getAll().map((fld) => fld.name); const unknownTypes: IndexPatternField[] = []; difference(fieldNamesInDocs, fieldNamesInIndexPattern).forEach((unknownFieldName) => { @@ -36,5 +36,5 @@ export function getIndexPatternFieldList( } as IndexPatternField); }); - return [...indexPattern.fields, ...unknownTypes]; + return [...indexPattern.fields.getAll(), ...unknownTypes]; } diff --git a/src/plugins/discover/public/application/components/table/table.test.tsx b/src/plugins/discover/public/application/components/table/table.test.tsx index 0793072fd0cf4..29659b3969365 100644 --- a/src/plugins/discover/public/application/components/table/table.test.tsx +++ b/src/plugins/discover/public/application/components/table/table.test.tsx @@ -24,45 +24,47 @@ import { DocViewTable } from './table'; import { indexPatterns, IndexPattern } from '../../../../../data/public'; const indexPattern = { - fields: [ - { - name: '_index', - type: 'string', - scripted: false, - filterable: true, - }, - { - name: 'message', - type: 'string', - scripted: false, - filterable: false, - }, - { - name: 'extension', - type: 'string', - scripted: false, - filterable: true, - }, - { - name: 'bytes', - type: 'number', - scripted: false, - filterable: true, - }, - { - name: 'scripted', - type: 'number', - scripted: true, - filterable: false, - }, - ], + fields: { + getAll: () => [ + { + name: '_index', + type: 'string', + scripted: false, + filterable: true, + }, + { + name: 'message', + type: 'string', + scripted: false, + filterable: false, + }, + { + name: 'extension', + type: 'string', + scripted: false, + filterable: true, + }, + { + name: 'bytes', + type: 'number', + scripted: false, + filterable: true, + }, + { + name: 'scripted', + type: 'number', + scripted: true, + filterable: false, + }, + ], + }, metaFields: ['_index', '_score'], flattenHit: undefined, formatHit: jest.fn((hit) => hit._source), } as IndexPattern; indexPattern.fields.getByName = (name: string) => { - return indexPattern.fields.find((field) => field.name === name); + return indexPattern.fields.getAll().find((field) => field.name === name); }; indexPattern.flattenHit = indexPatterns.flattenHitWrapper(indexPattern, indexPattern.metaFields); diff --git a/src/plugins/discover/public/application/components/table/table.tsx b/src/plugins/discover/public/application/components/table/table.tsx index 9b95f2fc6bd27..628045bd32f61 100644 --- a/src/plugins/discover/public/application/components/table/table.tsx +++ b/src/plugins/discover/public/application/components/table/table.tsx @@ -104,15 +104,13 @@ export function DocViewTable({ // to the index pattern, but that has its own complications which you can read more about in the following // issue: https://github.com/elastic/kibana/issues/54957 const isNestedField = - !indexPattern.fields.find((patternField) => patternField.name === field) && - !!indexPattern.fields.find((patternField) => { + !indexPattern.fields.getByName(field) && + !!indexPattern.fields.getAll().find((patternField) => { // We only want to match a full path segment const nestedRootRegex = new RegExp(escapeRegExp(field) + '(\\.|$)'); return nestedRootRegex.test(patternField.subType?.nested?.path ?? ''); }); - const fieldType = isNestedField - ? 'nested' - : indexPattern.fields.find((patternField) => patternField.name === field)?.type; + const fieldType = isNestedField ? 'nested' : indexPattern.fields.getByName(field)?.type; return ( ().services; const [fields, setFields] = useState(indexPattern.getNonScriptedFields()); const [conflictedFields, setConflictedFields] = useState( - indexPattern.fields.filter((field) => field.type === 'conflict') + indexPattern.fields.getAll().filter((field) => field.type === 'conflict') ); const [defaultIndex, setDefaultIndex] = useState(uiSettings.get('defaultIndex')); const [tags, setTags] = useState([]); useEffect(() => { setFields(indexPattern.getNonScriptedFields()); - setConflictedFields(indexPattern.fields.filter((field) => field.type === 'conflict')); + setConflictedFields( + indexPattern.fields.getAll().filter((field) => field.type === 'conflict') + ); }, [indexPattern]); useEffect(() => { diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx index a59dca80a3684..f32eb63ad04b4 100644 --- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx @@ -87,7 +87,7 @@ export function Tabs({ indexPattern, fields, history, location }: TabsProps) { const refreshFilters = useCallback(() => { const tempIndexedFieldTypes: string[] = []; const tempScriptedFieldLanguages: string[] = []; - indexPattern.fields.forEach((field) => { + indexPattern.fields.getAll().forEach((field) => { if (field.scripted) { if (field.lang) { tempScriptedFieldLanguages.push(field.lang); diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts index 5ab9c695caaa0..b422de93de7a9 100644 --- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts @@ -84,9 +84,9 @@ export function getTabs( fieldFilter: string, indexPatternListProvider: IndexPatternManagementStart['list'] ) { - const totalCount = getCounts(indexPattern.fields, indexPattern.getSourceFiltering()); + const totalCount = getCounts(indexPattern.fields.getAll(), indexPattern.getSourceFiltering()); const filteredCount = getCounts( - indexPattern.fields, + indexPattern.fields.getAll(), indexPattern.getSourceFiltering(), fieldFilter ); diff --git a/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap index c22160bc4036d..3f4190eed9170 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/__snapshots__/field_editor.test.tsx.snap @@ -25,11 +25,10 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = ` executeScript={[Function]} indexPattern={ Object { - "fields": Array [ - Object { - "name": "foobar", - }, - ], + "fields": Object { + "getAll": [Function], + "getByName": [Function], + }, "getFormatterForField": [Function], } } @@ -261,19 +260,10 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = ` executeScript={[Function]} indexPattern={ Object { - "fields": Array [ - Object { - "name": "foobar", - }, - Object { - "format": Format {}, - "lang": "painless", - "name": "test", - "script": "doc.test.value", - "scripted": true, - "type": "number", - }, - ], + "fields": Object { + "getAll": [Function], + "getByName": [Function], + }, "getFormatterForField": [Function], } } @@ -504,27 +494,10 @@ exports[`FieldEditor should show conflict field warning 1`] = ` executeScript={[Function]} indexPattern={ Object { - "fields": Array [ - Object { - "name": "foobar", - }, - Object { - "format": Format {}, - "lang": "painless", - "name": "test", - "script": "doc.test.value", - "scripted": true, - "type": "number", - }, - Object { - "format": Format {}, - "lang": "testlang", - "name": "test", - "script": "doc.test.value", - "scripted": true, - "type": "number", - }, - ], + "fields": Object { + "getAll": [Function], + "getByName": [Function], + }, "getFormatterForField": [Function], } } @@ -784,27 +757,10 @@ exports[`FieldEditor should show deprecated lang warning 1`] = ` executeScript={[Function]} indexPattern={ Object { - "fields": Array [ - Object { - "name": "foobar", - }, - Object { - "format": Format {}, - "lang": "painless", - "name": "test", - "script": "doc.test.value", - "scripted": true, - "type": "number", - }, - Object { - "format": Format {}, - "lang": "testlang", - "name": "test", - "script": "doc.test.value", - "scripted": true, - "type": "number", - }, - ], + "fields": Object { + "getAll": [Function], + "getByName": [Function], + }, "getFormatterForField": [Function], } } @@ -1116,27 +1072,10 @@ exports[`FieldEditor should show multiple type field warning with a table contai executeScript={[Function]} indexPattern={ Object { - "fields": Array [ - Object { - "name": "foobar", - }, - Object { - "format": Format {}, - "lang": "painless", - "name": "test", - "script": "doc.test.value", - "scripted": true, - "type": "number", - }, - Object { - "format": Format {}, - "lang": "testlang", - "name": "test", - "script": "doc.test.value", - "scripted": true, - "type": "number", - }, - ], + "fields": Object { + "getAll": [Function], + "getByName": [Function], + }, "getFormatterForField": [Function], } } diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx index cb1d5a25c01ae..77c6698fdc337 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx @@ -188,6 +188,7 @@ export class TestScript extends Component { const fields: EuiComboBoxOptionOption[] = []; this.props.indexPattern.fields + .getAll() .filter((field) => { const isMultiField = field.subType && field.subType.multi; return !field.name.startsWith('_') && !isMultiField && !field.scripted; diff --git a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx index ba1f2ff4b665d..96d3fc549ece0 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.test.tsx @@ -17,12 +17,7 @@ * under the License. */ -import { - IndexPattern, - IndexPatternField, - IIndexPatternFieldList, - FieldFormatInstanceType, -} from 'src/plugins/data/public'; +import { IndexPattern, IndexPatternField, FieldFormatInstanceType } from 'src/plugins/data/public'; jest.mock('brace/mode/groovy', () => ({})); @@ -71,15 +66,19 @@ jest.mock('./components/field_format_editor', () => ({ FieldFormatEditor: 'field-format-editor', })); -const fields: IndexPatternField[] = [ +const fieldList = [ { name: 'foobar', } as IndexPatternField, ]; +const fields = { + getAll: () => fieldList, +}; + // @ts-ignore fields.getByName = (name: string) => { - return fields.find((field) => field.name === name); + return fields.getAll().find((field) => field.name === name); }; class Format { @@ -112,7 +111,7 @@ describe('FieldEditor', () => { beforeEach(() => { indexPattern = ({ - fields: fields as IIndexPatternFieldList, + fields, getFormatterForField: () => ({ params: () => ({}) }), } as unknown) as IndexPattern; }); @@ -139,7 +138,7 @@ describe('FieldEditor', () => { name: 'test', script: 'doc.test.value', }; - indexPattern.fields.push(testField as IndexPatternField); + fieldList.push(testField as IndexPatternField); indexPattern.fields.getByName = (name) => { const flds = { [testField.name]: testField, @@ -169,7 +168,7 @@ describe('FieldEditor', () => { script: 'doc.test.value', lang: 'testlang', }; - indexPattern.fields.push((testField as unknown) as IndexPatternField); + fieldList.push((testField as unknown) as IndexPatternField); indexPattern.fields.getByName = (name) => { const flds = { [testField.name]: testField, diff --git a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx index d78e1e1014581..6a3f632a9582e 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx @@ -155,7 +155,7 @@ export class FieldEditor extends PureComponent f.name), + existingFieldNames: indexPattern.fields.getAll().map((f: IFieldType) => f.name), fieldFormatId: undefined, fieldFormatParams: {}, showScriptingHelp: false, @@ -197,7 +197,7 @@ export class FieldEditor extends PureComponent f.name === spec.name), + isCreating: !indexPattern.fields.getByName(spec.name), isDeprecatedLang: this.deprecatedLangs.includes(spec.lang || ''), errors: [], scriptingLangs, @@ -804,11 +804,11 @@ export class FieldEditor extends PureComponent f.name === field.name); + const fieldExists = !!indexPattern.fields.getByName(field.name); let oldField: IndexPatternField['spec']; - if (index > -1) { + if (fieldExists) { oldField = indexPattern.fields.getByName(field.name)!.spec; indexPattern.fields.update(field); } else { diff --git a/src/plugins/input_control_vis/public/control/list_control_factory.ts b/src/plugins/input_control_vis/public/control/list_control_factory.ts index 65a3e37a93edf..acbbf08c7d004 100644 --- a/src/plugins/input_control_vis/public/control/list_control_factory.ts +++ b/src/plugins/input_control_vis/public/control/list_control_factory.ts @@ -216,7 +216,7 @@ export async function listControlFactory( // dynamic options are only allowed on String fields but the setting defaults to true so it could // be enabled for non-string fields (since UI input is hidden for non-string fields). // If field is not string, then disable dynamic options. - const field = indexPattern.fields.find(({ name }) => name === controlParams.fieldName); + const field = indexPattern.fields.getAll().find(({ name }) => name === controlParams.fieldName); if (field && field.type !== 'string') { controlParams.options.dynamicOptions = false; } diff --git a/src/plugins/input_control_vis/public/test_utils/get_deps_mock.tsx b/src/plugins/input_control_vis/public/test_utils/get_deps_mock.tsx index feedcab1850eb..f72bc96f9e7c1 100644 --- a/src/plugins/input_control_vis/public/test_utils/get_deps_mock.tsx +++ b/src/plugins/input_control_vis/public/test_utils/get_deps_mock.tsx @@ -26,6 +26,7 @@ fields.push({ name: 'myField' } as any); fields.getByName = (name: any) => { return fields.find(({ name: n }: { name: string }) => n === name); }; +fields.getAll = () => [...fields]; export const getDepsMock = ({ searchSource = { diff --git a/src/plugins/vis_type_timelion/public/helpers/arg_value_suggestions.ts b/src/plugins/vis_type_timelion/public/helpers/arg_value_suggestions.ts index 19ec46bd7f659..85d41aab5859d 100644 --- a/src/plugins/vis_type_timelion/public/helpers/arg_value_suggestions.ts +++ b/src/plugins/vis_type_timelion/public/helpers/arg_value_suggestions.ts @@ -117,6 +117,7 @@ export function getArgValueSuggestions() { const valueSplit = partial.split(':'); return indexPattern.fields + .getAll() .filter((field) => { return ( field.aggregatable && @@ -136,6 +137,7 @@ export function getArgValueSuggestions() { } return indexPattern.fields + .getAll() .filter((field) => { return ( field.aggregatable && @@ -155,6 +157,7 @@ export function getArgValueSuggestions() { } return indexPattern.fields + .getAll() .filter((field) => { return ( 'date' === field.type && diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field.test.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field.test.tsx index 30864f246071b..a678deae41542 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field.test.tsx @@ -12,7 +12,7 @@ import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; import { fields, getField, -} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { FieldComponent } from './field'; describe('FieldComponent', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx index eca38b9effe1b..eef6e09d496db 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx @@ -11,7 +11,7 @@ import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; // we don't have the types for waitFor just yet, so using "as waitFor" until when we do import { wait as waitFor } from '@testing-library/react'; -import { getField } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +import { getField } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { ListSchema } from '../../../lists_plugin_deps'; import { getFoundListSchemaMock } from '../../../../../lists/common/schemas/response/found_list_schema.mock'; import { getListResponseMock } from '../../../../../lists/common/schemas/response/list_schema.mock'; diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.test.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.test.tsx index 998ed1f3351c8..94040ccb639be 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.test.tsx @@ -12,7 +12,7 @@ import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; import { fields, getField, -} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { AutocompleteFieldMatchComponent } from './field_value_match'; import { useFieldValueAutocomplete } from './hooks/use_field_value_autocomplete'; jest.mock('./hooks/use_field_value_autocomplete'); diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.test.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.test.tsx index 0a0281a9c4a51..4074150f76d06 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.test.tsx @@ -12,7 +12,7 @@ import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; import { fields, getField, -} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { AutocompleteFieldMatchAnyComponent } from './field_value_match_any'; import { useFieldValueAutocomplete } from './hooks/use_field_value_autocomplete'; jest.mock('./hooks/use_field_value_autocomplete'); diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts index 289cdd5e87c00..bbcbcbcf928b3 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts @@ -5,7 +5,7 @@ */ import '../../../common/mock/match_media'; -import { getField } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +import { getField } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { EXCEPTION_OPERATORS, diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.test.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.test.ts index a76b50d11a875..82e9c21f6b839 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/hooks/use_field_value_autocomplete.test.ts @@ -13,7 +13,7 @@ import { } from './use_field_value_autocomplete'; import { useKibana } from '../../../../common/lib/kibana'; import { stubIndexPatternWithFields } from '../../../../../../../../src/plugins/data/common/index_patterns/index_pattern.stub'; -import { getField } from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +import { getField } from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { OperatorTypeEnum } from '../../../../lists_plugin_deps'; jest.mock('../../../../common/lib/kibana'); diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/operator.test.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/operator.test.tsx index 737be199e2481..e6f6227811085 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/operator.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/operator.test.tsx @@ -9,7 +9,7 @@ import { mount } from 'enzyme'; import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; -import { getField } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +import { getField } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { OperatorComponent } from './operator'; import { isOperator, isNotOperator } from './operators'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.test.tsx index 2a116c4cd8acf..59a5db2a09779 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.test.tsx @@ -22,7 +22,7 @@ import { import { fields, getField, -} from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +} from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { getFoundListSchemaMock } from '../../../../../../lists/common/schemas/response/found_list_schema.mock'; import { getEmptyValue } from '../../empty_value'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.test.tsx index e90639a2c0285..0f9be25e046b2 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.test.tsx @@ -10,7 +10,7 @@ import { mount } from 'enzyme'; import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; import { useKibana } from '../../../../common/lib/kibana'; -import { fields } from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +import { fields } from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { getExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; import { getEntryMatchMock } from '../../../../../../lists/common/schemas/types/entry_match.mock'; import { getEntryMatchAnyMock } from '../../../../../../lists/common/schemas/types/entry_match_any.mock'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx index 04ab9ee7216f7..9bfd04cc19d72 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx @@ -6,7 +6,7 @@ import { fields, getField, -} from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +} from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { getEntryNestedMock } from '../../../../../../lists/common/schemas/types/entry_nested.mock'; import { getEntryMatchMock } from '../../../../../../lists/common/schemas/types/entry_match.mock'; import { getEntryMatchAnyMock } from '../../../../../../lists/common/schemas/types/entry_match_any.mock'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.test.tsx index 3fa0e59f9acb0..2d389a7dbcee1 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.test.tsx @@ -13,7 +13,7 @@ import { wait as waitFor } from '@testing-library/react'; import { fields, getField, -} from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +} from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { getExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; import { getEntryMatchAnyMock } from '../../../../../../lists/common/schemas/types/entry_match_any.mock'; From 9782ac4b7ff9374e32500afcf6c25470b7b4b00f Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Tue, 11 Aug 2020 06:47:33 -0700 Subject: [PATCH 094/106] Bump chalk to 4.1.0 (#73397) https://github.com/chalk/chalk/releases Signed-off-by: Tyler Smalley Co-authored-by: Elastic Machine --- packages/kbn-dev-utils/package.json | 2 +- packages/kbn-es/package.json | 2 +- packages/kbn-plugin-generator/package.json | 2 +- packages/kbn-pm/dist/index.js | 20099 +++++++++++-------- packages/kbn-pm/package.json | 2 +- packages/kbn-test/package.json | 2 +- packages/kbn-ui-framework/package.json | 2 +- src/dev/typescript/exec_in_projects.ts | 2 +- x-pack/package.json | 2 +- yarn.lock | 8 +- 10 files changed, 11448 insertions(+), 8675 deletions(-) diff --git a/packages/kbn-dev-utils/package.json b/packages/kbn-dev-utils/package.json index 83a7a7607816c..7ce433f80bed0 100644 --- a/packages/kbn-dev-utils/package.json +++ b/packages/kbn-dev-utils/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "axios": "^0.19.0", - "chalk": "^2.4.2", + "chalk": "^4.1.0", "dedent": "^0.7.0", "execa": "^4.0.2", "exit-hook": "^2.2.0", diff --git a/packages/kbn-es/package.json b/packages/kbn-es/package.json index f53eb694ec712..c3670f648d309 100644 --- a/packages/kbn-es/package.json +++ b/packages/kbn-es/package.json @@ -8,7 +8,7 @@ "@elastic/elasticsearch": "7.9.0-rc.1", "@kbn/dev-utils": "1.0.0", "abort-controller": "^2.0.3", - "chalk": "^2.4.2", + "chalk": "^4.1.0", "dedent": "^0.7.0", "del": "^5.1.0", "execa": "^4.0.2", diff --git a/packages/kbn-plugin-generator/package.json b/packages/kbn-plugin-generator/package.json index 5c1e98cd869de..0803e498279f3 100644 --- a/packages/kbn-plugin-generator/package.json +++ b/packages/kbn-plugin-generator/package.json @@ -4,7 +4,7 @@ "private": true, "version": "1.0.0", "dependencies": { - "chalk": "^2.4.2", + "chalk": "^4.1.0", "dedent": "^0.7.0", "execa": "^4.0.2", "getopts": "^2.2.4", diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index b8794124ad197..ee141e1d8ab7a 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -94,21 +94,21 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _cli__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "run", function() { return _cli__WEBPACK_IMPORTED_MODULE_0__["run"]; }); -/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(498); +/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(511); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["buildProductionProjects"]; }); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getProjects", function() { return _utils_projects__WEBPACK_IMPORTED_MODULE_2__["getProjects"]; }); -/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(162); +/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(163); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Project", function() { return _utils_project__WEBPACK_IMPORTED_MODULE_3__["Project"]; }); -/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(271); +/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(287); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__["copyWorkspacePackages"]; }); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(272); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(288); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getProjectPaths", function() { return _config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"]; }); /* @@ -151,9 +151,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5); /* harmony import */ var _kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(126); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(490); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(142); +/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(127); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(503); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(143); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -568,10 +568,10 @@ var tooling_log_1 = __webpack_require__(6); Object.defineProperty(exports, "ToolingLog", { enumerable: true, get: function () { return tooling_log_1.ToolingLog; } }); var tooling_log_text_writer_1 = __webpack_require__(110); Object.defineProperty(exports, "ToolingLogTextWriter", { enumerable: true, get: function () { return tooling_log_text_writer_1.ToolingLogTextWriter; } }); -var log_levels_1 = __webpack_require__(124); +var log_levels_1 = __webpack_require__(125); Object.defineProperty(exports, "pickLevelFromFlags", { enumerable: true, get: function () { return log_levels_1.pickLevelFromFlags; } }); Object.defineProperty(exports, "parseLogLevel", { enumerable: true, get: function () { return log_levels_1.parseLogLevel; } }); -var tooling_log_collecting_writer_1 = __webpack_require__(125); +var tooling_log_collecting_writer_1 = __webpack_require__(126); Object.defineProperty(exports, "ToolingLogCollectingWriter", { enumerable: true, get: function () { return tooling_log_collecting_writer_1.ToolingLogCollectingWriter; } }); @@ -6594,7 +6594,7 @@ exports.ToolingLogTextWriter = void 0; const tslib_1 = __webpack_require__(7); const util_1 = __webpack_require__(111); const chalk_1 = tslib_1.__importDefault(__webpack_require__(112)); -const log_levels_1 = __webpack_require__(124); +const log_levels_1 = __webpack_require__(125); const { magentaBright, yellow, red, blue, green, dim } = chalk_1.default; const PREFIX_INDENT = ' '.repeat(6); const MSG_PREFIXES = { @@ -6672,233 +6672,234 @@ module.exports = require("util"); "use strict"; -const escapeStringRegexp = __webpack_require__(113); -const ansiStyles = __webpack_require__(114); -const stdoutColor = __webpack_require__(120).stdout; - -const template = __webpack_require__(123); +const ansiStyles = __webpack_require__(113); +const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(119); +const { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex +} = __webpack_require__(123); -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); +const {isArray} = Array; // `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; - -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); +const levelMapping = [ + 'ansi', + 'ansi', + 'ansi256', + 'ansi16m' +]; const styles = Object.create(null); -function applyOptions(obj, options) { - options = options || {}; +const applyOptions = (object, options = {}) => { + if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { + throw new Error('The `level` option should be an integer from 0 to 3'); + } // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; + const colorLevel = stdoutColor ? stdoutColor.level : 0; + object.level = options.level === undefined ? colorLevel : options.level; +}; + +class ChalkClass { + constructor(options) { + // eslint-disable-next-line no-constructor-return + return chalkFactory(options); + } } -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); +const chalkFactory = options => { + const chalk = {}; + applyOptions(chalk, options); - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; + chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); - chalk.template.constructor = Chalk; + chalk.template.constructor = () => { + throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); + }; - return chalk.template; - } + chalk.template.Instance = ChalkClass; - applyOptions(this, options); -} + return chalk.template; +}; -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; +function Chalk(options) { + return chalkFactory(options); } -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - - styles[key] = { +for (const [styleName, style] of Object.entries(ansiStyles)) { + styles[styleName] = { get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); + Object.defineProperty(this, styleName, {value: builder}); + return builder; } }; } styles.visible = { get() { - return build.call(this, this._styles || [], true, 'visible'); + const builder = createBuilder(this, this._styler, true); + Object.defineProperty(this, 'visible', {value: builder}); + return builder; } }; -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } +const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; +for (const model of usedModels) { styles[model] = { get() { - const level = this.level; - return function () { - const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.color.close, - closeRe: ansiStyles.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + const {level} = this; + return function (...arguments_) { + const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler); + return createBuilder(this, styler, this._isEmpty); }; } }; } -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } - +for (const model of usedModels) { const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); styles[bgModel] = { get() { - const level = this.level; - return function () { - const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.bgColor.close, - closeRe: ansiStyles.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + const {level} = this; + return function (...arguments_) { + const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler); + return createBuilder(this, styler, this._isEmpty); }; } }; } -const proto = Object.defineProperties(() => {}, styles); - -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; - - builder._styles = _styles; - builder._empty = _empty; - - const self = this; - - Object.defineProperty(builder, 'level', { +const proto = Object.defineProperties(() => {}, { + ...styles, + level: { enumerable: true, get() { - return self.level; + return this._generator.level; }, set(level) { - self.level = level; + this._generator.level = level; } - }); + } +}); - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; +const createStyler = (open, close, parent) => { + let openAll; + let closeAll; + if (parent === undefined) { + openAll = open; + closeAll = close; + } else { + openAll = parent.openAll + open; + closeAll = close + parent.closeAll; + } + + return { + open, + close, + openAll, + closeAll, + parent + }; +}; + +const createBuilder = (self, _styler, _isEmpty) => { + const builder = (...arguments_) => { + if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) { + // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}` + return applyStyle(builder, chalkTag(builder, ...arguments_)); } - }); - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; + // Single argument is hot path, implicit coercion is faster than anything + // eslint-disable-next-line no-implicit-coercion + return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); + }; - // `__proto__` is used because we must return a function, but there is + // We alter the prototype because we must return a function, but there is // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto + Object.setPrototypeOf(builder, proto); - return builder; -} + builder._generator = self; + builder._styler = _styler; + builder._isEmpty = _isEmpty; -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); + return builder; +}; - if (argsLen === 0) { - return ''; +const applyStyle = (self, string) => { + if (self.level <= 0 || !string) { + return self._isEmpty ? '' : string; } - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } + let styler = self._styler; - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; + if (styler === undefined) { + return string; } - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles.dim.open = ''; - } + const {openAll, closeAll} = styler; + if (string.indexOf('\u001B') !== -1) { + while (styler !== undefined) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + string = stringReplaceAll(string, styler.close, styler.open); - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; + styler = styler.parent; + } + } - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); + // We can move both next actions out of loop, because remaining actions in loop won't have + // any/visible effect on parts we add here. Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 + const lfIndex = string.indexOf('\n'); + if (lfIndex !== -1) { + string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); } - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; + return openAll + string + closeAll; +}; - return str; -} +let template; +const chalkTag = (chalk, ...strings) => { + const [firstString] = strings; -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { + if (!isArray(firstString) || !isArray(firstString.raw)) { // If chalk() was called by itself or with a string, // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); + return strings.join(' '); } - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; + const arguments_ = strings.slice(1); + const parts = [firstString.raw[0]]; - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); + for (let i = 1; i < firstString.length; i++) { + parts.push( + String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), + String(firstString.raw[i]) + ); + } + + if (template === undefined) { + template = __webpack_require__(124); } return template(chalk, parts.join('')); -} +}; Object.defineProperties(Chalk.prototype, styles); -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript +const chalk = Chalk(); // eslint-disable-line new-cap +chalk.supportsColor = stdoutColor; +chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap +chalk.stderr.supportsColor = stderrColor; + +module.exports = chalk; /***/ }), @@ -6906,40 +6907,64 @@ module.exports.default = module.exports; // For TypeScript /***/ (function(module, exports, __webpack_require__) { "use strict"; +/* WEBPACK VAR INJECTION */(function(module) { +const wrapAnsi16 = (fn, offset) => (...args) => { + const code = fn(...args); + return `\u001B[${code + offset}m`; +}; -var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; - -module.exports = function (str) { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } +const wrapAnsi256 = (fn, offset) => (...args) => { + const code = fn(...args); + return `\u001B[${38 + offset};5;${code}m`; +}; - return str.replace(matchOperatorsRe, '\\$&'); +const wrapAnsi16m = (fn, offset) => (...args) => { + const rgb = fn(...args); + return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; }; +const ansi2ansi = n => n; +const rgb2rgb = (r, g, b) => [r, g, b]; -/***/ }), -/* 114 */ -/***/ (function(module, exports, __webpack_require__) { +const setLazyProperty = (object, property, get) => { + Object.defineProperty(object, property, { + get: () => { + const value = get(); -"use strict"; -/* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(116); + Object.defineProperty(object, property, { + value, + enumerable: true, + configurable: true + }); -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${code + offset}m`; + return value; + }, + enumerable: true, + configurable: true + }); }; -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};5;${code}m`; -}; +/** @type {typeof import('color-convert')} */ +let colorConvert; +const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { + if (colorConvert === undefined) { + colorConvert = __webpack_require__(115); + } -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; + const offset = isBackground ? 10 : 0; + const styles = {}; + + for (const [sourceSpace, suite] of Object.entries(colorConvert)) { + const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace; + if (sourceSpace === targetSpace) { + styles[name] = wrap(identity, offset); + } else if (typeof suite === 'object') { + styles[name] = wrap(suite[targetSpace], offset); + } + } + + return styles; }; function assembleStyles() { @@ -6965,9 +6990,9 @@ function assembleStyles() { magenta: [35, 39], cyan: [36, 39], white: [37, 39], - gray: [90, 39], // Bright color + blackBright: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], @@ -6998,15 +7023,14 @@ function assembleStyles() { } }; - // Fix humans - styles.color.grey = styles.color.gray; - - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; - - for (const styleName of Object.keys(group)) { - const style = group[styleName]; + // Alias bright black as gray (and grey) + styles.color.gray = styles.color.blackBright; + styles.bgColor.bgGray = styles.bgColor.bgBlackBright; + styles.color.grey = styles.color.blackBright; + styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; + for (const [groupName, group] of Object.entries(styles)) { + for (const [styleName, style] of Object.entries(group)) { styles[styleName] = { open: `\u001B[${style[0]}m`, close: `\u001B[${style[1]}m` @@ -7021,65 +7045,22 @@ function assembleStyles() { value: group, enumerable: false }); - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); } - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false + }); styles.color.close = '\u001B[39m'; styles.bgColor.close = '\u001B[49m'; - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; - - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; - - for (let key of Object.keys(colorConvert)) { - if (typeof colorConvert[key] !== 'object') { - continue; - } - - const suite = colorConvert[key]; - - if (key === 'ansi16') { - key = 'ansi'; - } - - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } - - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } - - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); - } - } + setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false)); + setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false)); + setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false)); + setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true)); + setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true)); + setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true)); return styles; } @@ -7090,10 +7071,10 @@ Object.defineProperty(module, 'exports', { get: assembleStyles }); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 115 */ +/* 114 */ /***/ (function(module, exports) { module.exports = function(module) { @@ -7121,30 +7102,31 @@ module.exports = function(module) { /***/ }), -/* 116 */ +/* 115 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(117); -var route = __webpack_require__(119); +const conversions = __webpack_require__(116); +const route = __webpack_require__(118); -var convert = {}; +const convert = {}; -var models = Object.keys(conversions); +const models = Object.keys(conversions); function wrapRaw(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; + const wrappedFn = function (...args) { + const arg0 = args[0]; + if (arg0 === undefined || arg0 === null) { + return arg0; } - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); + if (arg0.length > 1) { + args = arg0; } return fn(args); }; - // preserve .conversion property if there is one + // Preserve .conversion property if there is one if ('conversion' in fn) { wrappedFn.conversion = fn.conversion; } @@ -7153,22 +7135,24 @@ function wrapRaw(fn) { } function wrapRounded(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; + const wrappedFn = function (...args) { + const arg0 = args[0]; + + if (arg0 === undefined || arg0 === null) { + return arg0; } - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); + if (arg0.length > 1) { + args = arg0; } - var result = fn(args); + const result = fn(args); - // we're assuming the result is an array here. + // We're assuming the result is an array here. // see notice in conversions.js; don't use box types // in conversion functions. if (typeof result === 'object') { - for (var len = result.length, i = 0; i < len; i++) { + for (let len = result.length, i = 0; i < len; i++) { result[i] = Math.round(result[i]); } } @@ -7176,7 +7160,7 @@ function wrapRounded(fn) { return result; }; - // preserve .conversion property if there is one + // Preserve .conversion property if there is one if ('conversion' in fn) { wrappedFn.conversion = fn.conversion; } @@ -7184,17 +7168,17 @@ function wrapRounded(fn) { return wrappedFn; } -models.forEach(function (fromModel) { +models.forEach(fromModel => { convert[fromModel] = {}; Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); - var routes = route(fromModel); - var routeModels = Object.keys(routes); + const routes = route(fromModel); + const routeModels = Object.keys(routes); - routeModels.forEach(function (toModel) { - var fn = routes[toModel]; + routeModels.forEach(toModel => { + const fn = routes[toModel]; convert[fromModel][toModel] = wrapRounded(fn); convert[fromModel][toModel].raw = wrapRaw(fn); @@ -7205,24 +7189,23 @@ module.exports = convert; /***/ }), -/* 117 */ +/* 116 */ /***/ (function(module, exports, __webpack_require__) { /* MIT license */ -var cssKeywords = __webpack_require__(118); +/* eslint-disable no-mixed-operators */ +const cssKeywords = __webpack_require__(117); // NOTE: conversions should only return primitive values (i.e. arrays, or // values that give correct `typeof` results). // do not use box values types (i.e. Number(), String(), etc.) -var reverseKeywords = {}; -for (var key in cssKeywords) { - if (cssKeywords.hasOwnProperty(key)) { - reverseKeywords[cssKeywords[key]] = key; - } +const reverseKeywords = {}; +for (const key of Object.keys(cssKeywords)) { + reverseKeywords[cssKeywords[key]] = key; } -var convert = module.exports = { +const convert = { rgb: {channels: 3, labels: 'rgb'}, hsl: {channels: 3, labels: 'hsl'}, hsv: {channels: 3, labels: 'hsv'}, @@ -7240,40 +7223,38 @@ var convert = module.exports = { gray: {channels: 1, labels: ['gray']} }; -// hide .channels and .labels properties -for (var model in convert) { - if (convert.hasOwnProperty(model)) { - if (!('channels' in convert[model])) { - throw new Error('missing channels property: ' + model); - } +module.exports = convert; - if (!('labels' in convert[model])) { - throw new Error('missing channel labels property: ' + model); - } +// Hide .channels and .labels properties +for (const model of Object.keys(convert)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } - if (convert[model].labels.length !== convert[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } - var channels = convert[model].channels; - var labels = convert[model].labels; - delete convert[model].channels; - delete convert[model].labels; - Object.defineProperty(convert[model], 'channels', {value: channels}); - Object.defineProperty(convert[model], 'labels', {value: labels}); + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); } + + const {channels, labels} = convert[model]; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); } convert.rgb.hsl = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var min = Math.min(r, g, b); - var max = Math.max(r, g, b); - var delta = max - min; - var h; - var s; - var l; + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const min = Math.min(r, g, b); + const max = Math.max(r, g, b); + const delta = max - min; + let h; + let s; if (max === min) { h = 0; @@ -7291,7 +7272,7 @@ convert.rgb.hsl = function (rgb) { h += 360; } - l = (min + max) / 2; + const l = (min + max) / 2; if (max === min) { s = 0; @@ -7305,49 +7286,58 @@ convert.rgb.hsl = function (rgb) { }; convert.rgb.hsv = function (rgb) { - var r = rgb[0]; - var g = rgb[1]; - var b = rgb[2]; - var min = Math.min(r, g, b); - var max = Math.max(r, g, b); - var delta = max - min; - var h; - var s; - var v; + let rdif; + let gdif; + let bdif; + let h; + let s; + + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const v = Math.max(r, g, b); + const diff = v - Math.min(r, g, b); + const diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; + }; - if (max === 0) { + if (diff === 0) { + h = 0; s = 0; } else { - s = (delta / max * 1000) / 10; - } - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } - - h = Math.min(h * 60, 360); + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); + + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } - if (h < 0) { - h += 360; + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } } - v = ((max / 255) * 1000) / 10; - - return [h, s, v]; + return [ + h * 360, + s * 100, + v * 100 + ]; }; convert.rgb.hwb = function (rgb) { - var r = rgb[0]; - var g = rgb[1]; - var b = rgb[2]; - var h = convert.rgb.hsl(rgb)[0]; - var w = 1 / 255 * Math.min(r, Math.min(g, b)); + const r = rgb[0]; + const g = rgb[1]; + let b = rgb[2]; + const h = convert.rgb.hsl(rgb)[0]; + const w = 1 / 255 * Math.min(r, Math.min(g, b)); b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); @@ -7355,54 +7345,48 @@ convert.rgb.hwb = function (rgb) { }; convert.rgb.cmyk = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var c; - var m; - var y; - var k; + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; - k = Math.min(1 - r, 1 - g, 1 - b); - c = (1 - r - k) / (1 - k) || 0; - m = (1 - g - k) / (1 - k) || 0; - y = (1 - b - k) / (1 - k) || 0; + const k = Math.min(1 - r, 1 - g, 1 - b); + const c = (1 - r - k) / (1 - k) || 0; + const m = (1 - g - k) / (1 - k) || 0; + const y = (1 - b - k) / (1 - k) || 0; return [c * 100, m * 100, y * 100, k * 100]; }; -/** - * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - * */ function comparativeDistance(x, y) { + /* + See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + */ return ( - Math.pow(x[0] - y[0], 2) + - Math.pow(x[1] - y[1], 2) + - Math.pow(x[2] - y[2], 2) + ((x[0] - y[0]) ** 2) + + ((x[1] - y[1]) ** 2) + + ((x[2] - y[2]) ** 2) ); } convert.rgb.keyword = function (rgb) { - var reversed = reverseKeywords[rgb]; + const reversed = reverseKeywords[rgb]; if (reversed) { return reversed; } - var currentClosestDistance = Infinity; - var currentClosestKeyword; + let currentClosestDistance = Infinity; + let currentClosestKeyword; - for (var keyword in cssKeywords) { - if (cssKeywords.hasOwnProperty(keyword)) { - var value = cssKeywords[keyword]; + for (const keyword of Object.keys(cssKeywords)) { + const value = cssKeywords[keyword]; - // Compute comparative distance - var distance = comparativeDistance(rgb, value); + // Compute comparative distance + const distance = comparativeDistance(rgb, value); - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; } } @@ -7414,55 +7398,50 @@ convert.keyword.rgb = function (keyword) { }; convert.rgb.xyz = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; + let r = rgb[0] / 255; + let g = rgb[1] / 255; + let b = rgb[2] / 255; - // assume sRGB - r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); - g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); - b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); + // Assume sRGB + r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92); + g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92); + b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92); - var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); + const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); return [x * 100, y * 100, z * 100]; }; convert.rgb.lab = function (rgb) { - var xyz = convert.rgb.xyz(rgb); - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; + const xyz = convert.rgb.xyz(rgb); + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; x /= 95.047; y /= 100; z /= 108.883; - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); + x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); + const l = (116 * y) - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); return [l, a, b]; }; convert.hsl.rgb = function (hsl) { - var h = hsl[0] / 360; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var t1; - var t2; - var t3; - var rgb; - var val; + const h = hsl[0] / 360; + const s = hsl[1] / 100; + const l = hsl[2] / 100; + let t2; + let t3; + let val; if (s === 0) { val = l * 255; @@ -7475,14 +7454,15 @@ convert.hsl.rgb = function (hsl) { t2 = l + s - l * s; } - t1 = 2 * l - t2; + const t1 = 2 * l - t2; - rgb = [0, 0, 0]; - for (var i = 0; i < 3; i++) { + const rgb = [0, 0, 0]; + for (let i = 0; i < 3; i++) { t3 = h + 1 / 3 * -(i - 1); if (t3 < 0) { t3++; } + if (t3 > 1) { t3--; } @@ -7504,33 +7484,31 @@ convert.hsl.rgb = function (hsl) { }; convert.hsl.hsv = function (hsl) { - var h = hsl[0]; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var smin = s; - var lmin = Math.max(l, 0.01); - var sv; - var v; + const h = hsl[0]; + let s = hsl[1] / 100; + let l = hsl[2] / 100; + let smin = s; + const lmin = Math.max(l, 0.01); l *= 2; s *= (l <= 1) ? l : 2 - l; smin *= lmin <= 1 ? lmin : 2 - lmin; - v = (l + s) / 2; - sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); + const v = (l + s) / 2; + const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); return [h, sv * 100, v * 100]; }; convert.hsv.rgb = function (hsv) { - var h = hsv[0] / 60; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var hi = Math.floor(h) % 6; - - var f = h - Math.floor(h); - var p = 255 * v * (1 - s); - var q = 255 * v * (1 - (s * f)); - var t = 255 * v * (1 - (s * (1 - f))); + const h = hsv[0] / 60; + const s = hsv[1] / 100; + let v = hsv[2] / 100; + const hi = Math.floor(h) % 6; + + const f = h - Math.floor(h); + const p = 255 * v * (1 - s); + const q = 255 * v * (1 - (s * f)); + const t = 255 * v * (1 - (s * (1 - f))); v *= 255; switch (hi) { @@ -7550,16 +7528,15 @@ convert.hsv.rgb = function (hsv) { }; convert.hsv.hsl = function (hsv) { - var h = hsv[0]; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var vmin = Math.max(v, 0.01); - var lmin; - var sl; - var l; + const h = hsv[0]; + const s = hsv[1] / 100; + const v = hsv[2] / 100; + const vmin = Math.max(v, 0.01); + let sl; + let l; l = (2 - s) * v; - lmin = (2 - s) * vmin; + const lmin = (2 - s) * vmin; sl = s * vmin; sl /= (lmin <= 1) ? lmin : 2 - lmin; sl = sl || 0; @@ -7570,87 +7547,83 @@ convert.hsv.hsl = function (hsv) { // http://dev.w3.org/csswg/css-color/#hwb-to-rgb convert.hwb.rgb = function (hwb) { - var h = hwb[0] / 360; - var wh = hwb[1] / 100; - var bl = hwb[2] / 100; - var ratio = wh + bl; - var i; - var v; - var f; - var n; + const h = hwb[0] / 360; + let wh = hwb[1] / 100; + let bl = hwb[2] / 100; + const ratio = wh + bl; + let f; - // wh + bl cant be > 1 + // Wh + bl cant be > 1 if (ratio > 1) { wh /= ratio; bl /= ratio; } - i = Math.floor(6 * h); - v = 1 - bl; + const i = Math.floor(6 * h); + const v = 1 - bl; f = 6 * h - i; if ((i & 0x01) !== 0) { f = 1 - f; } - n = wh + f * (v - wh); // linear interpolation + const n = wh + f * (v - wh); // Linear interpolation - var r; - var g; - var b; + let r; + let g; + let b; + /* eslint-disable max-statements-per-line,no-multi-spaces */ switch (i) { default: case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; } + /* eslint-enable max-statements-per-line,no-multi-spaces */ return [r * 255, g * 255, b * 255]; }; convert.cmyk.rgb = function (cmyk) { - var c = cmyk[0] / 100; - var m = cmyk[1] / 100; - var y = cmyk[2] / 100; - var k = cmyk[3] / 100; - var r; - var g; - var b; + const c = cmyk[0] / 100; + const m = cmyk[1] / 100; + const y = cmyk[2] / 100; + const k = cmyk[3] / 100; - r = 1 - Math.min(1, c * (1 - k) + k); - g = 1 - Math.min(1, m * (1 - k) + k); - b = 1 - Math.min(1, y * (1 - k) + k); + const r = 1 - Math.min(1, c * (1 - k) + k); + const g = 1 - Math.min(1, m * (1 - k) + k); + const b = 1 - Math.min(1, y * (1 - k) + k); return [r * 255, g * 255, b * 255]; }; convert.xyz.rgb = function (xyz) { - var x = xyz[0] / 100; - var y = xyz[1] / 100; - var z = xyz[2] / 100; - var r; - var g; - var b; + const x = xyz[0] / 100; + const y = xyz[1] / 100; + const z = xyz[2] / 100; + let r; + let g; + let b; r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - // assume sRGB + // Assume sRGB r = r > 0.0031308 - ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) + ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055) : r * 12.92; g = g > 0.0031308 - ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) + ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055) : g * 12.92; b = b > 0.0031308 - ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) + ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055) : b * 12.92; r = Math.min(Math.max(0, r), 1); @@ -7661,43 +7634,40 @@ convert.xyz.rgb = function (xyz) { }; convert.xyz.lab = function (xyz) { - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; x /= 95.047; y /= 100; z /= 108.883; - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); + x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); + const l = (116 * y) - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); return [l, a, b]; }; convert.lab.xyz = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var x; - var y; - var z; + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let x; + let y; + let z; y = (l + 16) / 116; x = a / 500 + y; z = y - b / 200; - var y2 = Math.pow(y, 3); - var x2 = Math.pow(x, 3); - var z2 = Math.pow(z, 3); + const y2 = y ** 3; + const x2 = x ** 3; + const z2 = z ** 3; y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; @@ -7710,45 +7680,38 @@ convert.lab.xyz = function (lab) { }; convert.lab.lch = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var hr; - var h; - var c; + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let h; - hr = Math.atan2(b, a); + const hr = Math.atan2(b, a); h = hr * 360 / 2 / Math.PI; if (h < 0) { h += 360; } - c = Math.sqrt(a * a + b * b); + const c = Math.sqrt(a * a + b * b); return [l, c, h]; }; convert.lch.lab = function (lch) { - var l = lch[0]; - var c = lch[1]; - var h = lch[2]; - var a; - var b; - var hr; + const l = lch[0]; + const c = lch[1]; + const h = lch[2]; - hr = h / 360 * 2 * Math.PI; - a = c * Math.cos(hr); - b = c * Math.sin(hr); + const hr = h / 360 * 2 * Math.PI; + const a = c * Math.cos(hr); + const b = c * Math.sin(hr); return [l, a, b]; }; -convert.rgb.ansi16 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization +convert.rgb.ansi16 = function (args, saturation = null) { + const [r, g, b] = args; + let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization value = Math.round(value / 50); @@ -7756,7 +7719,7 @@ convert.rgb.ansi16 = function (args) { return 30; } - var ansi = 30 + let ansi = 30 + ((Math.round(b / 255) << 2) | (Math.round(g / 255) << 1) | Math.round(r / 255)); @@ -7769,17 +7732,17 @@ convert.rgb.ansi16 = function (args) { }; convert.hsv.ansi16 = function (args) { - // optimization here; we already know the value and don't need to get + // Optimization here; we already know the value and don't need to get // it converted for us. return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); }; convert.rgb.ansi256 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; + const r = args[0]; + const g = args[1]; + const b = args[2]; - // we use the extended greyscale palette here, with the exception of + // We use the extended greyscale palette here, with the exception of // black and white. normal palette only has 4 greyscale shades. if (r === g && g === b) { if (r < 8) { @@ -7793,7 +7756,7 @@ convert.rgb.ansi256 = function (args) { return Math.round(((r - 8) / 247) * 24) + 232; } - var ansi = 16 + const ansi = 16 + (36 * Math.round(r / 255 * 5)) + (6 * Math.round(g / 255 * 5)) + Math.round(b / 255 * 5); @@ -7802,9 +7765,9 @@ convert.rgb.ansi256 = function (args) { }; convert.ansi16.rgb = function (args) { - var color = args % 10; + let color = args % 10; - // handle greyscale + // Handle greyscale if (color === 0 || color === 7) { if (args > 50) { color += 3.5; @@ -7815,71 +7778,71 @@ convert.ansi16.rgb = function (args) { return [color, color, color]; } - var mult = (~~(args > 50) + 1) * 0.5; - var r = ((color & 1) * mult) * 255; - var g = (((color >> 1) & 1) * mult) * 255; - var b = (((color >> 2) & 1) * mult) * 255; + const mult = (~~(args > 50) + 1) * 0.5; + const r = ((color & 1) * mult) * 255; + const g = (((color >> 1) & 1) * mult) * 255; + const b = (((color >> 2) & 1) * mult) * 255; return [r, g, b]; }; convert.ansi256.rgb = function (args) { - // handle greyscale + // Handle greyscale if (args >= 232) { - var c = (args - 232) * 10 + 8; + const c = (args - 232) * 10 + 8; return [c, c, c]; } args -= 16; - var rem; - var r = Math.floor(args / 36) / 5 * 255; - var g = Math.floor((rem = args % 36) / 6) / 5 * 255; - var b = (rem % 6) / 5 * 255; + let rem; + const r = Math.floor(args / 36) / 5 * 255; + const g = Math.floor((rem = args % 36) / 6) / 5 * 255; + const b = (rem % 6) / 5 * 255; return [r, g, b]; }; convert.rgb.hex = function (args) { - var integer = ((Math.round(args[0]) & 0xFF) << 16) + const integer = ((Math.round(args[0]) & 0xFF) << 16) + ((Math.round(args[1]) & 0xFF) << 8) + (Math.round(args[2]) & 0xFF); - var string = integer.toString(16).toUpperCase(); + const string = integer.toString(16).toUpperCase(); return '000000'.substring(string.length) + string; }; convert.hex.rgb = function (args) { - var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); if (!match) { return [0, 0, 0]; } - var colorString = match[0]; + let colorString = match[0]; if (match[0].length === 3) { - colorString = colorString.split('').map(function (char) { + colorString = colorString.split('').map(char => { return char + char; }).join(''); } - var integer = parseInt(colorString, 16); - var r = (integer >> 16) & 0xFF; - var g = (integer >> 8) & 0xFF; - var b = integer & 0xFF; + const integer = parseInt(colorString, 16); + const r = (integer >> 16) & 0xFF; + const g = (integer >> 8) & 0xFF; + const b = integer & 0xFF; return [r, g, b]; }; convert.rgb.hcg = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var max = Math.max(Math.max(r, g), b); - var min = Math.min(Math.min(r, g), b); - var chroma = (max - min); - var grayscale; - var hue; + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const max = Math.max(Math.max(r, g), b); + const min = Math.min(Math.min(r, g), b); + const chroma = (max - min); + let grayscale; + let hue; if (chroma < 1) { grayscale = min / (1 - chroma); @@ -7896,7 +7859,7 @@ convert.rgb.hcg = function (rgb) { if (max === g) { hue = 2 + (b - r) / chroma; } else { - hue = 4 + (r - g) / chroma + 4; + hue = 4 + (r - g) / chroma; } hue /= 6; @@ -7906,17 +7869,12 @@ convert.rgb.hcg = function (rgb) { }; convert.hsl.hcg = function (hsl) { - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var c = 1; - var f = 0; + const s = hsl[1] / 100; + const l = hsl[2] / 100; - if (l < 0.5) { - c = 2.0 * s * l; - } else { - c = 2.0 * s * (1.0 - l); - } + const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l)); + let f = 0; if (c < 1.0) { f = (l - 0.5 * c) / (1.0 - c); } @@ -7925,11 +7883,11 @@ convert.hsl.hcg = function (hsl) { }; convert.hsv.hcg = function (hsv) { - var s = hsv[1] / 100; - var v = hsv[2] / 100; + const s = hsv[1] / 100; + const v = hsv[2] / 100; - var c = s * v; - var f = 0; + const c = s * v; + let f = 0; if (c < 1.0) { f = (v - c) / (1 - c); @@ -7939,20 +7897,21 @@ convert.hsv.hcg = function (hsv) { }; convert.hcg.rgb = function (hcg) { - var h = hcg[0] / 360; - var c = hcg[1] / 100; - var g = hcg[2] / 100; + const h = hcg[0] / 360; + const c = hcg[1] / 100; + const g = hcg[2] / 100; if (c === 0.0) { return [g * 255, g * 255, g * 255]; } - var pure = [0, 0, 0]; - var hi = (h % 1) * 6; - var v = hi % 1; - var w = 1 - v; - var mg = 0; + const pure = [0, 0, 0]; + const hi = (h % 1) * 6; + const v = hi % 1; + const w = 1 - v; + let mg = 0; + /* eslint-disable max-statements-per-line */ switch (Math.floor(hi)) { case 0: pure[0] = 1; pure[1] = v; pure[2] = 0; break; @@ -7967,6 +7926,7 @@ convert.hcg.rgb = function (hcg) { default: pure[0] = 1; pure[1] = 0; pure[2] = w; } + /* eslint-enable max-statements-per-line */ mg = (1.0 - c) * g; @@ -7978,11 +7938,11 @@ convert.hcg.rgb = function (hcg) { }; convert.hcg.hsv = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; + const c = hcg[1] / 100; + const g = hcg[2] / 100; - var v = c + g * (1.0 - c); - var f = 0; + const v = c + g * (1.0 - c); + let f = 0; if (v > 0.0) { f = c / v; @@ -7992,11 +7952,11 @@ convert.hcg.hsv = function (hcg) { }; convert.hcg.hsl = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; + const c = hcg[1] / 100; + const g = hcg[2] / 100; - var l = g * (1.0 - c) + 0.5 * c; - var s = 0; + const l = g * (1.0 - c) + 0.5 * c; + let s = 0; if (l > 0.0 && l < 0.5) { s = c / (2 * l); @@ -8009,18 +7969,18 @@ convert.hcg.hsl = function (hcg) { }; convert.hcg.hwb = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - var v = c + g * (1.0 - c); + const c = hcg[1] / 100; + const g = hcg[2] / 100; + const v = c + g * (1.0 - c); return [hcg[0], (v - c) * 100, (1 - v) * 100]; }; convert.hwb.hcg = function (hwb) { - var w = hwb[1] / 100; - var b = hwb[2] / 100; - var v = 1 - b; - var c = v - w; - var g = 0; + const w = hwb[1] / 100; + const b = hwb[2] / 100; + const v = 1 - b; + const c = v - w; + let g = 0; if (c < 1) { g = (v - c) / (1 - c); @@ -8041,10 +8001,12 @@ convert.gray.rgb = function (args) { return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; }; -convert.gray.hsl = convert.gray.hsv = function (args) { +convert.gray.hsl = function (args) { return [0, 0, args[0]]; }; +convert.gray.hsv = convert.gray.hsl; + convert.gray.hwb = function (gray) { return [0, 100, gray[0]]; }; @@ -8058,21 +8020,21 @@ convert.gray.lab = function (gray) { }; convert.gray.hex = function (gray) { - var val = Math.round(gray[0] / 100 * 255) & 0xFF; - var integer = (val << 16) + (val << 8) + val; + const val = Math.round(gray[0] / 100 * 255) & 0xFF; + const integer = (val << 16) + (val << 8) + val; - var string = integer.toString(16).toUpperCase(); + const string = integer.toString(16).toUpperCase(); return '000000'.substring(string.length) + string; }; convert.rgb.gray = function (rgb) { - var val = (rgb[0] + rgb[1] + rgb[2]) / 3; + const val = (rgb[0] + rgb[1] + rgb[2]) / 3; return [val / 255 * 100]; }; /***/ }), -/* 118 */ +/* 117 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -8231,13 +8193,13 @@ module.exports = { /***/ }), -/* 119 */ +/* 118 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(117); +const conversions = __webpack_require__(116); /* - this function routes a model to all other models. + This function routes a model to all other models. all functions that are routed have a property `.conversion` attached to the returned synthetic function. This property is an array @@ -8248,11 +8210,11 @@ var conversions = __webpack_require__(117); */ function buildGraph() { - var graph = {}; + const graph = {}; // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - var models = Object.keys(conversions); + const models = Object.keys(conversions); - for (var len = models.length, i = 0; i < len; i++) { + for (let len = models.length, i = 0; i < len; i++) { graph[models[i]] = { // http://jsperf.com/1-vs-infinity // micro-opt, but this is simple. @@ -8266,18 +8228,18 @@ function buildGraph() { // https://en.wikipedia.org/wiki/Breadth-first_search function deriveBFS(fromModel) { - var graph = buildGraph(); - var queue = [fromModel]; // unshift -> queue -> pop + const graph = buildGraph(); + const queue = [fromModel]; // Unshift -> queue -> pop graph[fromModel].distance = 0; while (queue.length) { - var current = queue.pop(); - var adjacents = Object.keys(conversions[current]); + const current = queue.pop(); + const adjacents = Object.keys(conversions[current]); - for (var len = adjacents.length, i = 0; i < len; i++) { - var adjacent = adjacents[i]; - var node = graph[adjacent]; + for (let len = adjacents.length, i = 0; i < len; i++) { + const adjacent = adjacents[i]; + const node = graph[adjacent]; if (node.distance === -1) { node.distance = graph[current].distance + 1; @@ -8297,10 +8259,10 @@ function link(from, to) { } function wrapConversion(toModel, graph) { - var path = [graph[toModel].parent, toModel]; - var fn = conversions[graph[toModel].parent][toModel]; + const path = [graph[toModel].parent, toModel]; + let fn = conversions[graph[toModel].parent][toModel]; - var cur = graph[toModel].parent; + let cur = graph[toModel].parent; while (graph[cur].parent) { path.unshift(graph[cur].parent); fn = link(conversions[graph[cur].parent][cur], fn); @@ -8312,16 +8274,16 @@ function wrapConversion(toModel, graph) { } module.exports = function (fromModel) { - var graph = deriveBFS(fromModel); - var conversion = {}; + const graph = deriveBFS(fromModel); + const conversion = {}; - var models = Object.keys(graph); - for (var len = models.length, i = 0; i < len; i++) { - var toModel = models[i]; - var node = graph[toModel]; + const models = Object.keys(graph); + for (let len = models.length, i = 0; i < len; i++) { + const toModel = models[i]; + const node = graph[toModel]; if (node.parent === null) { - // no possible conversion, or this node is the source model. + // No possible conversion, or this node is the source model. continue; } @@ -8334,29 +8296,38 @@ module.exports = function (fromModel) { /***/ }), -/* 120 */ +/* 119 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(121); +const os = __webpack_require__(120); +const tty = __webpack_require__(121); const hasFlag = __webpack_require__(122); -const env = process.env; +const {env} = process; let forceColor; if (hasFlag('no-color') || hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; + hasFlag('color=false') || + hasFlag('color=never')) { + forceColor = 0; } else if (hasFlag('color') || hasFlag('colors') || hasFlag('color=true') || hasFlag('color=always')) { - forceColor = true; + forceColor = 1; } + if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; + if (env.FORCE_COLOR === 'true') { + forceColor = 1; + } else if (env.FORCE_COLOR === 'false') { + forceColor = 0; + } else { + forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); + } } function translateLevel(level) { @@ -8372,8 +8343,8 @@ function translateLevel(level) { }; } -function supportsColor(stream) { - if (forceColor === false) { +function supportsColor(haveStream, streamIsTTY) { + if (forceColor === 0) { return 0; } @@ -8387,26 +8358,21 @@ function supportsColor(stream) { return 2; } - if (stream && !stream.isTTY && forceColor !== true) { - // VS code debugger doesn't have isTTY set - if (env.VSCODE_PID) { - return 1; - } + if (haveStream && !streamIsTTY && forceColor === undefined) { return 0; } - const min = forceColor ? 1 : 0; + const min = forceColor || 0; + + if (env.TERM === 'dumb') { + return min; + } if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. + // Windows 10 build 10586 is the first Windows release that supports 256 colors. + // Windows 10 build 14931 is the first release that supports 16m/TrueColor. const osRelease = os.release().split('.'); if ( - Number(process.versions.node.split('.')[0]) >= 8 && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586 ) { @@ -8428,6 +8394,10 @@ function supportsColor(stream) { return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; } + if ('GITHUB_ACTIONS' in env) { + return 1; + } + if (env.COLORTERM === 'truecolor') { return 3; } @@ -8448,7 +8418,7 @@ function supportsColor(stream) { return 2; } - if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { return 1; } @@ -8456,43 +8426,45 @@ function supportsColor(stream) { return 1; } - if (env.TERM === 'dumb') { - return min; - } - return min; } function getSupportLevel(stream) { - const level = supportsColor(stream); + const level = supportsColor(stream, stream && stream.isTTY); return translateLevel(level); } module.exports = { supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) + stdout: translateLevel(supportsColor(true, tty.isatty(1))), + stderr: translateLevel(supportsColor(true, tty.isatty(2))) }; /***/ }), -/* 121 */ +/* 120 */ /***/ (function(module, exports) { module.exports = require("os"); +/***/ }), +/* 121 */ +/***/ (function(module, exports) { + +module.exports = require("tty"); + /***/ }), /* 122 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = (flag, argv) => { - argv = argv || process.argv; + +module.exports = (flag, argv = process.argv) => { const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const pos = argv.indexOf(prefix + flag); - const terminatorPos = argv.indexOf('--'); - return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf('--'); + return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); }; @@ -8502,10 +8474,56 @@ module.exports = (flag, argv) => { "use strict"; -const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; + +const stringReplaceAll = (string, substring, replacer) => { + let index = string.indexOf(substring); + if (index === -1) { + return string; + } + + const substringLength = substring.length; + let endIndex = 0; + let returnValue = ''; + do { + returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; + endIndex = index + substringLength; + index = string.indexOf(substring, endIndex); + } while (index !== -1); + + returnValue += string.substr(endIndex); + return returnValue; +}; + +const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { + let endIndex = 0; + let returnValue = ''; + do { + const gotCR = string[index - 1] === '\r'; + returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; + endIndex = index + 1; + index = string.indexOf('\n', endIndex); + } while (index !== -1); + + returnValue += string.substr(endIndex); + return returnValue; +}; + +module.exports = { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex +}; + + +/***/ }), +/* 124 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; +const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi; const ESCAPES = new Map([ ['n', '\n'], @@ -8521,23 +8539,31 @@ const ESCAPES = new Map([ ]); function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { + const u = c[0] === 'u'; + const bracket = c[1] === '{'; + + if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { return String.fromCharCode(parseInt(c.slice(1), 16)); } + if (u && bracket) { + return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); + } + return ESCAPES.get(c) || c; } -function parseArguments(name, args) { +function parseArguments(name, arguments_) { const results = []; - const chunks = args.trim().split(/\s*,\s*/g); + const chunks = arguments_.trim().split(/\s*,\s*/g); let matches; for (const chunk of chunks) { - if (!isNaN(chunk)) { - results.push(Number(chunk)); + const number = Number(chunk); + if (!Number.isNaN(number)) { + results.push(number); } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); } else { throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); } @@ -8576,36 +8602,34 @@ function buildStyle(chalk, styles) { } let current = chalk; - for (const styleName of Object.keys(enabled)) { - if (Array.isArray(enabled[styleName])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } + for (const [styleName, styles] of Object.entries(enabled)) { + if (!Array.isArray(styles)) { + continue; + } - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); } + + current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; } return current; } -module.exports = (chalk, tmp) => { +module.exports = (chalk, temporary) => { const styles = []; const chunks = []; let chunk = []; // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); + temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { + if (escapeCharacter) { + chunk.push(unescape(escapeCharacter)); } else if (style) { - const str = chunk.join(''); + const string = chunk.join(''); chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); + chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); styles.push({inverse, styles: parseStyle(style)}); } else if (close) { if (styles.length === 0) { @@ -8616,15 +8640,15 @@ module.exports = (chalk, tmp) => { chunk = []; styles.pop(); } else { - chunk.push(chr); + chunk.push(character); } }); chunks.push(chunk.join('')); if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); + const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errMessage); } return chunks.join(''); @@ -8632,7 +8656,7 @@ module.exports = (chalk, tmp) => { /***/ }), -/* 124 */ +/* 125 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -8689,7 +8713,7 @@ exports.parseLogLevel = parseLogLevel; /***/ }), -/* 125 */ +/* 126 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -8733,16 +8757,16 @@ exports.ToolingLogCollectingWriter = ToolingLogCollectingWriter; /***/ }), -/* 126 */ +/* 127 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "commands", function() { return commands; }); -/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(127); -/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(280); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(389); -/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(390); +/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(128); +/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(295); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(402); +/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(403); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8773,18 +8797,18 @@ const commands = { }; /***/ }), -/* 127 */ +/* 128 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BootstrapCommand", function() { return BootstrapCommand; }); -/* harmony import */ var _utils_link_project_executables__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(128); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(142); -/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(143); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144); -/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(273); -/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(279); +/* harmony import */ var _utils_link_project_executables__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(129); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); +/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(289); +/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(294); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8887,7 +8911,7 @@ const BootstrapCommand = { }; /***/ }), -/* 128 */ +/* 129 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -8895,8 +8919,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "linkProjectExecutables", function() { return linkProjectExecutables; }); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(129); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(142); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(130); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(143); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8958,7 +8982,7 @@ async function linkProjectExecutables(projectsByName, projectGraph) { } /***/ }), -/* 129 */ +/* 130 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -8972,11 +8996,11 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDirectory", function() { return isDirectory; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFile", function() { return isFile; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createSymlink", function() { return createSymlink; }); -/* harmony import */ var cmd_shim__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(130); +/* harmony import */ var cmd_shim__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(131); /* harmony import */ var cmd_shim__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cmd_shim__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(132); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(133); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(141); +/* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(142); /* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ncp__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); @@ -9092,7 +9116,7 @@ async function forceCreate(src, dest, type) { } /***/ }), -/* 130 */ +/* 131 */ /***/ (function(module, exports, __webpack_require__) { // On windows, create a .cmd file. @@ -9108,11 +9132,11 @@ async function forceCreate(src, dest, type) { module.exports = cmdShim cmdShim.ifExists = cmdShimIfExists -var fs = __webpack_require__(131) +var fs = __webpack_require__(132) -var mkdir = __webpack_require__(139) +var mkdir = __webpack_require__(140) , path = __webpack_require__(4) - , toBatchSyntax = __webpack_require__(140) + , toBatchSyntax = __webpack_require__(141) , shebangExpr = /^#\!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+=[^ \t]+\s+)*\s*([^ \t]+)(.*)$/ function cmdShimIfExists (from, to, cb) { @@ -9345,13 +9369,13 @@ function times(n, ok, cb) { /***/ }), -/* 131 */ +/* 132 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(132) -var polyfills = __webpack_require__(133) -var legacy = __webpack_require__(135) -var clone = __webpack_require__(137) +var fs = __webpack_require__(133) +var polyfills = __webpack_require__(134) +var legacy = __webpack_require__(136) +var clone = __webpack_require__(138) var util = __webpack_require__(111) @@ -9430,7 +9454,7 @@ if (!global[gracefulQueue]) { if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { process.on('exit', function() { debug(global[gracefulQueue]) - __webpack_require__(138).equal(global[gracefulQueue].length, 0) + __webpack_require__(139).equal(global[gracefulQueue].length, 0) }) } } @@ -9697,16 +9721,16 @@ function retry () { /***/ }), -/* 132 */ +/* 133 */ /***/ (function(module, exports) { module.exports = require("fs"); /***/ }), -/* 133 */ +/* 134 */ /***/ (function(module, exports, __webpack_require__) { -var constants = __webpack_require__(134) +var constants = __webpack_require__(135) var origCwd = process.cwd var cwd = null @@ -10051,16 +10075,16 @@ function patch (fs) { /***/ }), -/* 134 */ +/* 135 */ /***/ (function(module, exports) { module.exports = require("constants"); /***/ }), -/* 135 */ +/* 136 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(136).Stream +var Stream = __webpack_require__(137).Stream module.exports = legacy @@ -10181,13 +10205,13 @@ function legacy (fs) { /***/ }), -/* 136 */ +/* 137 */ /***/ (function(module, exports) { module.exports = require("stream"); /***/ }), -/* 137 */ +/* 138 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -10213,17 +10237,17 @@ function clone (obj) { /***/ }), -/* 138 */ +/* 139 */ /***/ (function(module, exports) { module.exports = require("assert"); /***/ }), -/* 139 */ +/* 140 */ /***/ (function(module, exports, __webpack_require__) { var path = __webpack_require__(4); -var fs = __webpack_require__(132); +var fs = __webpack_require__(133); var _0777 = parseInt('0777', 8); module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; @@ -10324,7 +10348,7 @@ mkdirP.sync = function sync (p, opts, made) { /***/ }), -/* 140 */ +/* 141 */ /***/ (function(module, exports) { exports.replaceDollarWithPercentPair = replaceDollarWithPercentPair @@ -10382,10 +10406,10 @@ function replaceDollarWithPercentPair(value) { /***/ }), -/* 141 */ +/* 142 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(132), +var fs = __webpack_require__(133), path = __webpack_require__(4); module.exports = ncp; @@ -10649,7 +10673,7 @@ function ncp (source, dest, options, callback) { /***/ }), -/* 142 */ +/* 143 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -10709,7 +10733,7 @@ const log = new Log(); /***/ }), -/* 143 */ +/* 144 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -10775,7 +10799,7 @@ async function parallelize(items, fn, concurrency = 4) { } /***/ }), -/* 144 */ +/* 145 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -10784,15 +10808,15 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProjectGraph", function() { return buildProjectGraph; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "topologicallyBatchProjects", function() { return topologicallyBatchProjects; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "includeTransitiveProjects", function() { return includeTransitiveProjects; }); -/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(145); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(146); /* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(111); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(161); -/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(162); -/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(271); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(162); +/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(163); +/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(287); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -10991,7 +11015,7 @@ function includeTransitiveProjects(subsetOfProjects, allProjects, { } /***/ }), -/* 145 */ +/* 146 */ /***/ (function(module, exports, __webpack_require__) { // Approach: @@ -11036,27 +11060,27 @@ function includeTransitiveProjects(subsetOfProjects, allProjects, { module.exports = glob -var fs = __webpack_require__(132) -var rp = __webpack_require__(146) -var minimatch = __webpack_require__(148) +var fs = __webpack_require__(133) +var rp = __webpack_require__(147) +var minimatch = __webpack_require__(149) var Minimatch = minimatch.Minimatch -var inherits = __webpack_require__(152) -var EE = __webpack_require__(154).EventEmitter +var inherits = __webpack_require__(153) +var EE = __webpack_require__(155).EventEmitter var path = __webpack_require__(4) -var assert = __webpack_require__(138) -var isAbsolute = __webpack_require__(155) -var globSync = __webpack_require__(156) -var common = __webpack_require__(157) +var assert = __webpack_require__(139) +var isAbsolute = __webpack_require__(156) +var globSync = __webpack_require__(157) +var common = __webpack_require__(158) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts var ownProp = common.ownProp -var inflight = __webpack_require__(158) +var inflight = __webpack_require__(159) var util = __webpack_require__(111) var childrenIgnored = common.childrenIgnored var isIgnored = common.isIgnored -var once = __webpack_require__(160) +var once = __webpack_require__(161) function glob (pattern, options, cb) { if (typeof options === 'function') cb = options, options = {} @@ -11787,7 +11811,7 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) { /***/ }), -/* 146 */ +/* 147 */ /***/ (function(module, exports, __webpack_require__) { module.exports = realpath @@ -11797,13 +11821,13 @@ realpath.realpathSync = realpathSync realpath.monkeypatch = monkeypatch realpath.unmonkeypatch = unmonkeypatch -var fs = __webpack_require__(132) +var fs = __webpack_require__(133) var origRealpath = fs.realpath var origRealpathSync = fs.realpathSync var version = process.version var ok = /^v[0-5]\./.test(version) -var old = __webpack_require__(147) +var old = __webpack_require__(148) function newError (er) { return er && er.syscall === 'realpath' && ( @@ -11859,7 +11883,7 @@ function unmonkeypatch () { /***/ }), -/* 147 */ +/* 148 */ /***/ (function(module, exports, __webpack_require__) { // Copyright Joyent, Inc. and other Node contributors. @@ -11885,7 +11909,7 @@ function unmonkeypatch () { var pathModule = __webpack_require__(4); var isWindows = process.platform === 'win32'; -var fs = __webpack_require__(132); +var fs = __webpack_require__(133); // JavaScript implementation of realpath, ported from node pre-v6 @@ -12168,7 +12192,7 @@ exports.realpath = function realpath(p, cache, cb) { /***/ }), -/* 148 */ +/* 149 */ /***/ (function(module, exports, __webpack_require__) { module.exports = minimatch @@ -12180,7 +12204,7 @@ try { } catch (er) {} var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = __webpack_require__(149) +var expand = __webpack_require__(150) var plTypes = { '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, @@ -13097,11 +13121,11 @@ function regExpEscape (s) { /***/ }), -/* 149 */ +/* 150 */ /***/ (function(module, exports, __webpack_require__) { -var concatMap = __webpack_require__(150); -var balanced = __webpack_require__(151); +var concatMap = __webpack_require__(151); +var balanced = __webpack_require__(152); module.exports = expandTop; @@ -13304,7 +13328,7 @@ function expand(str, isTop) { /***/ }), -/* 150 */ +/* 151 */ /***/ (function(module, exports) { module.exports = function (xs, fn) { @@ -13323,7 +13347,7 @@ var isArray = Array.isArray || function (xs) { /***/ }), -/* 151 */ +/* 152 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -13389,7 +13413,7 @@ function range(a, b, str) { /***/ }), -/* 152 */ +/* 153 */ /***/ (function(module, exports, __webpack_require__) { try { @@ -13399,12 +13423,12 @@ try { module.exports = util.inherits; } catch (e) { /* istanbul ignore next */ - module.exports = __webpack_require__(153); + module.exports = __webpack_require__(154); } /***/ }), -/* 153 */ +/* 154 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -13437,13 +13461,13 @@ if (typeof Object.create === 'function') { /***/ }), -/* 154 */ +/* 155 */ /***/ (function(module, exports) { module.exports = require("events"); /***/ }), -/* 155 */ +/* 156 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -13470,22 +13494,22 @@ module.exports.win32 = win32; /***/ }), -/* 156 */ +/* 157 */ /***/ (function(module, exports, __webpack_require__) { module.exports = globSync globSync.GlobSync = GlobSync -var fs = __webpack_require__(132) -var rp = __webpack_require__(146) -var minimatch = __webpack_require__(148) +var fs = __webpack_require__(133) +var rp = __webpack_require__(147) +var minimatch = __webpack_require__(149) var Minimatch = minimatch.Minimatch -var Glob = __webpack_require__(145).Glob +var Glob = __webpack_require__(146).Glob var util = __webpack_require__(111) var path = __webpack_require__(4) -var assert = __webpack_require__(138) -var isAbsolute = __webpack_require__(155) -var common = __webpack_require__(157) +var assert = __webpack_require__(139) +var isAbsolute = __webpack_require__(156) +var common = __webpack_require__(158) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts @@ -13962,7 +13986,7 @@ GlobSync.prototype._makeAbs = function (f) { /***/ }), -/* 157 */ +/* 158 */ /***/ (function(module, exports, __webpack_require__) { exports.alphasort = alphasort @@ -13980,8 +14004,8 @@ function ownProp (obj, field) { } var path = __webpack_require__(4) -var minimatch = __webpack_require__(148) -var isAbsolute = __webpack_require__(155) +var minimatch = __webpack_require__(149) +var isAbsolute = __webpack_require__(156) var Minimatch = minimatch.Minimatch function alphasorti (a, b) { @@ -14208,12 +14232,12 @@ function childrenIgnored (self, path) { /***/ }), -/* 158 */ +/* 159 */ /***/ (function(module, exports, __webpack_require__) { -var wrappy = __webpack_require__(159) +var wrappy = __webpack_require__(160) var reqs = Object.create(null) -var once = __webpack_require__(160) +var once = __webpack_require__(161) module.exports = wrappy(inflight) @@ -14268,7 +14292,7 @@ function slice (args) { /***/ }), -/* 159 */ +/* 160 */ /***/ (function(module, exports) { // Returns a wrapper function that returns a wrapped callback @@ -14307,10 +14331,10 @@ function wrappy (fn, cb) { /***/ }), -/* 160 */ +/* 161 */ /***/ (function(module, exports, __webpack_require__) { -var wrappy = __webpack_require__(159) +var wrappy = __webpack_require__(160) module.exports = wrappy(once) module.exports.strict = wrappy(onceStrict) @@ -14355,7 +14379,7 @@ function onceStrict (fn) { /***/ }), -/* 161 */ +/* 162 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -14388,22 +14412,22 @@ class CliError extends Error { } /***/ }), -/* 162 */ +/* 163 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Project", function() { return Project; }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(132); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(133); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(111); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(161); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(142); -/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(163); -/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(226); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(162); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); +/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(164); +/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(233); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -14640,7 +14664,7 @@ function normalizePath(path) { } /***/ }), -/* 163 */ +/* 164 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -14648,9 +14672,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readPackageJson", function() { return readPackageJson; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "writePackageJson", function() { return writePackageJson; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isLinkDependency", function() { return isLinkDependency; }); -/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(164); +/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(165); /* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(read_pkg__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(206); +/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(213); /* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(write_pkg__WEBPACK_IMPORTED_MODULE_1__); /* * Licensed to Elasticsearch B.V. under one or more contributor @@ -14684,15 +14708,15 @@ function writePackageJson(path, json) { const isLinkDependency = depVersion => depVersion.startsWith('link:'); /***/ }), -/* 164 */ +/* 165 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(132); +const fs = __webpack_require__(133); const path = __webpack_require__(4); -const parseJson = __webpack_require__(165); +const parseJson = __webpack_require__(166); const readFileAsync = promisify(fs.readFile); @@ -14707,7 +14731,7 @@ module.exports = async options => { const json = parseJson(await readFileAsync(filePath, 'utf8')); if (options.normalize) { - __webpack_require__(180)(json); + __webpack_require__(187)(json); } return json; @@ -14724,7 +14748,7 @@ module.exports.sync = options => { const json = parseJson(fs.readFileSync(filePath, 'utf8')); if (options.normalize) { - __webpack_require__(180)(json); + __webpack_require__(187)(json); } return json; @@ -14732,15 +14756,15 @@ module.exports.sync = options => { /***/ }), -/* 165 */ +/* 166 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const errorEx = __webpack_require__(166); -const fallback = __webpack_require__(168); -const {default: LinesAndColumns} = __webpack_require__(169); -const {codeFrameColumns} = __webpack_require__(170); +const errorEx = __webpack_require__(167); +const fallback = __webpack_require__(169); +const {default: LinesAndColumns} = __webpack_require__(170); +const {codeFrameColumns} = __webpack_require__(171); const JSONError = errorEx('JSONError', { fileName: errorEx.append('in %s'), @@ -14789,14 +14813,14 @@ module.exports = (string, reviver, filename) => { /***/ }), -/* 166 */ +/* 167 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(111); -var isArrayish = __webpack_require__(167); +var isArrayish = __webpack_require__(168); var errorEx = function errorEx(name, properties) { if (!name || name.constructor !== String) { @@ -14929,7 +14953,7 @@ module.exports = errorEx; /***/ }), -/* 167 */ +/* 168 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -14946,7 +14970,7 @@ module.exports = function isArrayish(obj) { /***/ }), -/* 168 */ +/* 169 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -14985,7 +15009,7 @@ function parseJson (txt, reviver, context) { /***/ }), -/* 169 */ +/* 170 */ /***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { "use strict"; @@ -15049,7 +15073,7 @@ var LinesAndColumns = (function () { /***/ }), -/* 170 */ +/* 171 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15061,7 +15085,7 @@ Object.defineProperty(exports, "__esModule", { exports.codeFrameColumns = codeFrameColumns; exports.default = _default; -var _highlight = _interopRequireWildcard(__webpack_require__(171)); +var _highlight = _interopRequireWildcard(__webpack_require__(172)); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } @@ -15222,7 +15246,7 @@ function _default(rawLines, lineNumber, colNumber, opts = {}) { } /***/ }), -/* 171 */ +/* 172 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15235,11 +15259,11 @@ exports.shouldHighlight = shouldHighlight; exports.getChalk = getChalk; exports.default = highlight; -var _jsTokens = _interopRequireWildcard(__webpack_require__(172)); +var _jsTokens = _interopRequireWildcard(__webpack_require__(173)); -var _helperValidatorIdentifier = __webpack_require__(173); +var _helperValidatorIdentifier = __webpack_require__(174); -var _chalk = _interopRequireDefault(__webpack_require__(176)); +var _chalk = _interopRequireDefault(__webpack_require__(177)); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -15335,7 +15359,7 @@ function highlight(code, options = {}) { } /***/ }), -/* 172 */ +/* 173 */ /***/ (function(module, exports) { // Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell @@ -15364,7 +15388,7 @@ exports.matchToToken = function(match) { /***/ }), -/* 173 */ +/* 174 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15422,12 +15446,12 @@ Object.defineProperty(exports, "isKeyword", { } }); -var _identifier = __webpack_require__(174); +var _identifier = __webpack_require__(175); -var _keyword = __webpack_require__(175); +var _keyword = __webpack_require__(176); /***/ }), -/* 174 */ +/* 175 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15510,7 +15534,7 @@ function isIdentifierName(name) { } /***/ }), -/* 175 */ +/* 176 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15554,16 +15578,16 @@ function isKeyword(word) { } /***/ }), -/* 176 */ +/* 177 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const escapeStringRegexp = __webpack_require__(113); -const ansiStyles = __webpack_require__(177); -const stdoutColor = __webpack_require__(178).stdout; +const escapeStringRegexp = __webpack_require__(178); +const ansiStyles = __webpack_require__(179); +const stdoutColor = __webpack_require__(184).stdout; -const template = __webpack_require__(179); +const template = __webpack_require__(186); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -15789,12 +15813,30 @@ module.exports.default = module.exports; // For TypeScript /***/ }), -/* 177 */ +/* 178 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; + +module.exports = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + + return str.replace(matchOperatorsRe, '\\$&'); +}; + + +/***/ }), +/* 179 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(116); +const colorConvert = __webpack_require__(180); const wrapAnsi16 = (fn, offset) => function () { const code = fn.apply(colorConvert, arguments); @@ -15959,3021 +16001,4252 @@ Object.defineProperty(module, 'exports', { get: assembleStyles }); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 178 */ +/* 180 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var conversions = __webpack_require__(181); +var route = __webpack_require__(183); -const os = __webpack_require__(121); -const hasFlag = __webpack_require__(122); +var convert = {}; -const env = process.env; +var models = Object.keys(conversions); -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; -} +function wrapRaw(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } -function translateLevel(level) { - if (level === 0) { - return false; - } + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 + return fn(args); }; -} - -function supportsColor(stream) { - if (forceColor === false) { - return 0; - } - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; } - if (hasFlag('color=256')) { - return 2; - } + return wrappedFn; +} - if (stream && !stream.isTTY && forceColor !== true) { - // VS code debugger doesn't have isTTY set - if (env.VSCODE_PID) { - return 1; +function wrapRounded(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; } - return 0; - } - - const min = forceColor ? 1 : 0; - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); } - return 1; - } + var result = fn(args); - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; + // we're assuming the result is an array here. + // see notice in conversions.js; don't use box types + // in conversion functions. + if (typeof result === 'object') { + for (var len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } } - return min; - } - - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + return result; + }; - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; } - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } + return wrappedFn; +} - if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } +models.forEach(function (fromModel) { + convert[fromModel] = {}; - if ('COLORTERM' in env) { - return 1; - } + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); - if (env.TERM === 'dumb') { - return min; - } + var routes = route(fromModel); + var routeModels = Object.keys(routes); - return min; -} + routeModels.forEach(function (toModel) { + var fn = routes[toModel]; -function getSupportLevel(stream) { - const level = supportsColor(stream); - return translateLevel(level); -} + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) -}; +module.exports = convert; /***/ }), -/* 179 */ +/* 181 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - -const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; +/* MIT license */ +var cssKeywords = __webpack_require__(182); -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); +// NOTE: conversions should only return primitive values (i.e. arrays, or +// values that give correct `typeof` results). +// do not use box values types (i.e. Number(), String(), etc.) -function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); +var reverseKeywords = {}; +for (var key in cssKeywords) { + if (cssKeywords.hasOwnProperty(key)) { + reverseKeywords[cssKeywords[key]] = key; } - - return ESCAPES.get(c) || c; } -function parseArguments(name, args) { - const results = []; - const chunks = args.trim().split(/\s*,\s*/g); - let matches; +var convert = module.exports = { + rgb: {channels: 3, labels: 'rgb'}, + hsl: {channels: 3, labels: 'hsl'}, + hsv: {channels: 3, labels: 'hsv'}, + hwb: {channels: 3, labels: 'hwb'}, + cmyk: {channels: 4, labels: 'cmyk'}, + xyz: {channels: 3, labels: 'xyz'}, + lab: {channels: 3, labels: 'lab'}, + lch: {channels: 3, labels: 'lch'}, + hex: {channels: 1, labels: ['hex']}, + keyword: {channels: 1, labels: ['keyword']}, + ansi16: {channels: 1, labels: ['ansi16']}, + ansi256: {channels: 1, labels: ['ansi256']}, + hcg: {channels: 3, labels: ['h', 'c', 'g']}, + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, + gray: {channels: 1, labels: ['gray']} +}; - for (const chunk of chunks) { - if (!isNaN(chunk)) { - results.push(Number(chunk)); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); +// hide .channels and .labels properties +for (var model in convert) { + if (convert.hasOwnProperty(model)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); } - } - - return results; -} - -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; - - const results = []; - let matches; - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); } - } - return results; + var channels = convert[model].channels; + var labels = convert[model].labels; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); + } } -function buildStyle(chalk, styles) { - const enabled = {}; +convert.rgb.hsl = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var min = Math.min(r, g, b); + var max = Math.max(r, g, b); + var delta = max - min; + var h; + var s; + var l; - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; } - let current = chalk; - for (const styleName of Object.keys(enabled)) { - if (Array.isArray(enabled[styleName])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } + h = Math.min(h * 60, 360); - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } + if (h < 0) { + h += 360; } - return current; -} + l = (min + max) / 2; -module.exports = (chalk, tmp) => { - const styles = []; - const chunks = []; - let chunk = []; + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } - // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); - } else if (style) { - const str = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } + return [h, s * 100, l * 100]; +}; - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(chr); - } - }); +convert.rgb.hsv = function (rgb) { + var rdif; + var gdif; + var bdif; + var h; + var s; - chunks.push(chunk.join('')); + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var v = Math.max(r, g, b); + var diff = v - Math.min(r, g, b); + var diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; + }; - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); + if (diff === 0) { + h = s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); + + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } } - return chunks.join(''); + return [ + h * 360, + s * 100, + v * 100 + ]; }; +convert.rgb.hwb = function (rgb) { + var r = rgb[0]; + var g = rgb[1]; + var b = rgb[2]; + var h = convert.rgb.hsl(rgb)[0]; + var w = 1 / 255 * Math.min(r, Math.min(g, b)); -/***/ }), -/* 180 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = normalize + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); -var fixer = __webpack_require__(181) -normalize.fixer = fixer + return [h, w * 100, b * 100]; +}; -var makeWarning = __webpack_require__(204) +convert.rgb.cmyk = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var c; + var m; + var y; + var k; -var fieldsToFix = ['name','version','description','repository','modules','scripts' - ,'files','bin','man','bugs','keywords','readme','homepage','license'] -var otherThingsToFix = ['dependencies','people', 'typos'] + k = Math.min(1 - r, 1 - g, 1 - b); + c = (1 - r - k) / (1 - k) || 0; + m = (1 - g - k) / (1 - k) || 0; + y = (1 - b - k) / (1 - k) || 0; -var thingsToFix = fieldsToFix.map(function(fieldName) { - return ucFirst(fieldName) + "Field" -}) -// two ways to do this in CoffeeScript on only one line, sub-70 chars: -// thingsToFix = fieldsToFix.map (name) -> ucFirst(name) + "Field" -// thingsToFix = (ucFirst(name) + "Field" for name in fieldsToFix) -thingsToFix = thingsToFix.concat(otherThingsToFix) + return [c * 100, m * 100, y * 100, k * 100]; +}; -function normalize (data, warn, strict) { - if(warn === true) warn = null, strict = true - if(!strict) strict = false - if(!warn || data.private) warn = function(msg) { /* noop */ } - - if (data.scripts && - data.scripts.install === "node-gyp rebuild" && - !data.scripts.preinstall) { - data.gypfile = true - } - fixer.warn = function() { warn(makeWarning.apply(null, arguments)) } - thingsToFix.forEach(function(thingName) { - fixer["fix" + ucFirst(thingName)](data, strict) - }) - data._id = data.name + "@" + data.version +/** + * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + * */ +function comparativeDistance(x, y) { + return ( + Math.pow(x[0] - y[0], 2) + + Math.pow(x[1] - y[1], 2) + + Math.pow(x[2] - y[2], 2) + ); } -function ucFirst (string) { - return string.charAt(0).toUpperCase() + string.slice(1); -} +convert.rgb.keyword = function (rgb) { + var reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } + var currentClosestDistance = Infinity; + var currentClosestKeyword; -/***/ }), -/* 181 */ -/***/ (function(module, exports, __webpack_require__) { + for (var keyword in cssKeywords) { + if (cssKeywords.hasOwnProperty(keyword)) { + var value = cssKeywords[keyword]; -var semver = __webpack_require__(182) -var validateLicense = __webpack_require__(183); -var hostedGitInfo = __webpack_require__(188) -var isBuiltinModule = __webpack_require__(192).isCore -var depTypes = ["dependencies","devDependencies","optionalDependencies"] -var extractDescription = __webpack_require__(202) -var url = __webpack_require__(189) -var typos = __webpack_require__(203) + // Compute comparative distance + var distance = comparativeDistance(rgb, value); -var fixer = module.exports = { - // default warning function - warn: function() {}, + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } + } - fixRepositoryField: function(data) { - if (data.repositories) { - this.warn("repositories"); - data.repository = data.repositories[0] - } - if (!data.repository) return this.warn("missingRepository") - if (typeof data.repository === "string") { - data.repository = { - type: "git", - url: data.repository - } - } - var r = data.repository.url || "" - if (r) { - var hosted = hostedGitInfo.fromUrl(r) - if (hosted) { - r = data.repository.url - = hosted.getDefaultRepresentation() == "shortcut" ? hosted.https() : hosted.toString() - } - } + return currentClosestKeyword; +}; - if (r.match(/github.com\/[^\/]+\/[^\/]+\.git\.git$/)) { - this.warn("brokenGitUrl", r) - } - } +convert.keyword.rgb = function (keyword) { + return cssKeywords[keyword]; +}; -, fixTypos: function(data) { - Object.keys(typos.topLevel).forEach(function (d) { - if (data.hasOwnProperty(d)) { - this.warn("typo", d, typos.topLevel[d]) - } - }, this) - } +convert.rgb.xyz = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; -, fixScriptsField: function(data) { - if (!data.scripts) return - if (typeof data.scripts !== "object") { - this.warn("nonObjectScripts") - delete data.scripts - return - } - Object.keys(data.scripts).forEach(function (k) { - if (typeof data.scripts[k] !== "string") { - this.warn("nonStringScript") - delete data.scripts[k] - } else if (typos.script[k] && !data.scripts[typos.script[k]]) { - this.warn("typo", k, typos.script[k], "scripts") - } - }, this) - } + // assume sRGB + r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); + g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); + b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); -, fixFilesField: function(data) { - var files = data.files - if (files && !Array.isArray(files)) { - this.warn("nonArrayFiles") - delete data.files - } else if (data.files) { - data.files = data.files.filter(function(file) { - if (!file || typeof file !== "string") { - this.warn("invalidFilename", file) - return false - } else { - return true - } - }, this) - } - } + var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); -, fixBinField: function(data) { - if (!data.bin) return; - if (typeof data.bin === "string") { - var b = {} - var match - if (match = data.name.match(/^@[^/]+[/](.*)$/)) { - b[match[1]] = data.bin - } else { - b[data.name] = data.bin - } - data.bin = b - } - } + return [x * 100, y * 100, z * 100]; +}; -, fixManField: function(data) { - if (!data.man) return; - if (typeof data.man === "string") { - data.man = [ data.man ] - } - } -, fixBundleDependenciesField: function(data) { - var bdd = "bundledDependencies" - var bd = "bundleDependencies" - if (data[bdd] && !data[bd]) { - data[bd] = data[bdd] - delete data[bdd] - } - if (data[bd] && !Array.isArray(data[bd])) { - this.warn("nonArrayBundleDependencies") - delete data[bd] - } else if (data[bd]) { - data[bd] = data[bd].filter(function(bd) { - if (!bd || typeof bd !== 'string') { - this.warn("nonStringBundleDependency", bd) - return false - } else { - if (!data.dependencies) { - data.dependencies = {} - } - if (!data.dependencies.hasOwnProperty(bd)) { - this.warn("nonDependencyBundleDependency", bd) - data.dependencies[bd] = "*" - } - return true - } - }, this) - } - } +convert.rgb.lab = function (rgb) { + var xyz = convert.rgb.xyz(rgb); + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; -, fixDependencies: function(data, strict) { - var loose = !strict - objectifyDeps(data, this.warn) - addOptionalDepsToDeps(data, this.warn) - this.fixBundleDependenciesField(data) + x /= 95.047; + y /= 100; + z /= 108.883; - ;['dependencies','devDependencies'].forEach(function(deps) { - if (!(deps in data)) return - if (!data[deps] || typeof data[deps] !== "object") { - this.warn("nonObjectDependencies", deps) - delete data[deps] - return - } - Object.keys(data[deps]).forEach(function (d) { - var r = data[deps][d] - if (typeof r !== 'string') { - this.warn("nonStringDependency", d, JSON.stringify(r)) - delete data[deps][d] - } - var hosted = hostedGitInfo.fromUrl(data[deps][d]) - if (hosted) data[deps][d] = hosted.toString() - }, this) - }, this) - } + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); -, fixModulesField: function (data) { - if (data.modules) { - this.warn("deprecatedModules") - delete data.modules - } - } + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); -, fixKeywordsField: function (data) { - if (typeof data.keywords === "string") { - data.keywords = data.keywords.split(/,\s+/) - } - if (data.keywords && !Array.isArray(data.keywords)) { - delete data.keywords - this.warn("nonArrayKeywords") - } else if (data.keywords) { - data.keywords = data.keywords.filter(function(kw) { - if (typeof kw !== "string" || !kw) { - this.warn("nonStringKeyword"); - return false - } else { - return true - } - }, this) - } - } + return [l, a, b]; +}; -, fixVersionField: function(data, strict) { - // allow "loose" semver 1.0 versions in non-strict mode - // enforce strict semver 2.0 compliance in strict mode - var loose = !strict - if (!data.version) { - data.version = "" - return true - } - if (!semver.valid(data.version, loose)) { - throw new Error('Invalid version: "'+ data.version + '"') - } - data.version = semver.clean(data.version, loose) - return true - } +convert.hsl.rgb = function (hsl) { + var h = hsl[0] / 360; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var t1; + var t2; + var t3; + var rgb; + var val; -, fixPeople: function(data) { - modifyPeople(data, unParsePerson) - modifyPeople(data, parsePerson) - } + if (s === 0) { + val = l * 255; + return [val, val, val]; + } -, fixNameField: function(data, options) { - if (typeof options === "boolean") options = {strict: options} - else if (typeof options === "undefined") options = {} - var strict = options.strict - if (!data.name && !strict) { - data.name = "" - return - } - if (typeof data.name !== "string") { - throw new Error("name field must be a string.") - } - if (!strict) - data.name = data.name.trim() - ensureValidName(data.name, strict, options.allowLegacyCase) - if (isBuiltinModule(data.name)) - this.warn("conflictingName", data.name) - } + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; + } + t1 = 2 * l - t2; -, fixDescriptionField: function (data) { - if (data.description && typeof data.description !== 'string') { - this.warn("nonStringDescription") - delete data.description - } - if (data.readme && !data.description) - data.description = extractDescription(data.readme) - if(data.description === undefined) delete data.description; - if (!data.description) this.warn("missingDescription") - } + rgb = [0, 0, 0]; + for (var i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } + if (t3 > 1) { + t3--; + } -, fixReadmeField: function (data) { - if (!data.readme) { - this.warn("missingReadme") - data.readme = "ERROR: No README data found!" - } - } + if (6 * t3 < 1) { + val = t1 + (t2 - t1) * 6 * t3; + } else if (2 * t3 < 1) { + val = t2; + } else if (3 * t3 < 2) { + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + } else { + val = t1; + } -, fixBugsField: function(data) { - if (!data.bugs && data.repository && data.repository.url) { - var hosted = hostedGitInfo.fromUrl(data.repository.url) - if(hosted && hosted.bugs()) { - data.bugs = {url: hosted.bugs()} - } - } - else if(data.bugs) { - var emailRe = /^.+@.*\..+$/ - if(typeof data.bugs == "string") { - if(emailRe.test(data.bugs)) - data.bugs = {email:data.bugs} - else if(url.parse(data.bugs).protocol) - data.bugs = {url: data.bugs} - else - this.warn("nonEmailUrlBugsString") - } - else { - bugsTypos(data.bugs, this.warn) - var oldBugs = data.bugs - data.bugs = {} - if(oldBugs.url) { - if(typeof(oldBugs.url) == "string" && url.parse(oldBugs.url).protocol) - data.bugs.url = oldBugs.url - else - this.warn("nonUrlBugsUrlField") - } - if(oldBugs.email) { - if(typeof(oldBugs.email) == "string" && emailRe.test(oldBugs.email)) - data.bugs.email = oldBugs.email - else - this.warn("nonEmailBugsEmailField") - } - } - if(!data.bugs.email && !data.bugs.url) { - delete data.bugs - this.warn("emptyNormalizedBugs") - } - } - } + rgb[i] = val * 255; + } -, fixHomepageField: function(data) { - if (!data.homepage && data.repository && data.repository.url) { - var hosted = hostedGitInfo.fromUrl(data.repository.url) - if (hosted && hosted.docs()) data.homepage = hosted.docs() - } - if (!data.homepage) return + return rgb; +}; - if(typeof data.homepage !== "string") { - this.warn("nonUrlHomepage") - return delete data.homepage - } - if(!url.parse(data.homepage).protocol) { - data.homepage = "http://" + data.homepage - } - } +convert.hsl.hsv = function (hsl) { + var h = hsl[0]; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var smin = s; + var lmin = Math.max(l, 0.01); + var sv; + var v; -, fixLicenseField: function(data) { - if (!data.license) { - return this.warn("missingLicense") - } else{ - if ( - typeof(data.license) !== 'string' || - data.license.length < 1 || - data.license.trim() === '' - ) { - this.warn("invalidLicense") - } else { - if (!validateLicense(data.license).validForNewPackages) - this.warn("invalidLicense") - } - } - } -} + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + v = (l + s) / 2; + sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); -function isValidScopedPackageName(spec) { - if (spec.charAt(0) !== '@') return false + return [h, sv * 100, v * 100]; +}; - var rest = spec.slice(1).split('/') - if (rest.length !== 2) return false +convert.hsv.rgb = function (hsv) { + var h = hsv[0] / 60; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var hi = Math.floor(h) % 6; - return rest[0] && rest[1] && - rest[0] === encodeURIComponent(rest[0]) && - rest[1] === encodeURIComponent(rest[1]) -} + var f = h - Math.floor(h); + var p = 255 * v * (1 - s); + var q = 255 * v * (1 - (s * f)); + var t = 255 * v * (1 - (s * (1 - f))); + v *= 255; -function isCorrectlyEncodedName(spec) { - return !spec.match(/[\/@\s\+%:]/) && - spec === encodeURIComponent(spec) -} + switch (hi) { + case 0: + return [v, t, p]; + case 1: + return [q, v, p]; + case 2: + return [p, v, t]; + case 3: + return [p, q, v]; + case 4: + return [t, p, v]; + case 5: + return [v, p, q]; + } +}; -function ensureValidName (name, strict, allowLegacyCase) { - if (name.charAt(0) === "." || - !(isValidScopedPackageName(name) || isCorrectlyEncodedName(name)) || - (strict && (!allowLegacyCase) && name !== name.toLowerCase()) || - name.toLowerCase() === "node_modules" || - name.toLowerCase() === "favicon.ico") { - throw new Error("Invalid name: " + JSON.stringify(name)) - } -} +convert.hsv.hsl = function (hsv) { + var h = hsv[0]; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var vmin = Math.max(v, 0.01); + var lmin; + var sl; + var l; -function modifyPeople (data, fn) { - if (data.author) data.author = fn(data.author) - ;["maintainers", "contributors"].forEach(function (set) { - if (!Array.isArray(data[set])) return; - data[set] = data[set].map(fn) - }) - return data -} + l = (2 - s) * v; + lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; -function unParsePerson (person) { - if (typeof person === "string") return person - var name = person.name || "" - var u = person.url || person.web - var url = u ? (" ("+u+")") : "" - var e = person.email || person.mail - var email = e ? (" <"+e+">") : "" - return name+email+url -} + return [h, sl * 100, l * 100]; +}; -function parsePerson (person) { - if (typeof person !== "string") return person - var name = person.match(/^([^\(<]+)/) - var url = person.match(/\(([^\)]+)\)/) - var email = person.match(/<([^>]+)>/) - var obj = {} - if (name && name[0].trim()) obj.name = name[0].trim() - if (email) obj.email = email[1]; - if (url) obj.url = url[1]; - return obj -} +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +convert.hwb.rgb = function (hwb) { + var h = hwb[0] / 360; + var wh = hwb[1] / 100; + var bl = hwb[2] / 100; + var ratio = wh + bl; + var i; + var v; + var f; + var n; -function addOptionalDepsToDeps (data, warn) { - var o = data.optionalDependencies - if (!o) return; - var d = data.dependencies || {} - Object.keys(o).forEach(function (k) { - d[k] = o[k] - }) - data.dependencies = d -} + // wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; + } -function depObjectify (deps, type, warn) { - if (!deps) return {} - if (typeof deps === "string") { - deps = deps.trim().split(/[\n\r\s\t ,]+/) - } - if (!Array.isArray(deps)) return deps - warn("deprecatedArrayDependencies", type) - var o = {} - deps.filter(function (d) { - return typeof d === "string" - }).forEach(function(d) { - d = d.trim().split(/(:?[@\s><=])/) - var dn = d.shift() - var dv = d.join("") - dv = dv.trim() - dv = dv.replace(/^@/, "") - o[dn] = dv - }) - return o -} + i = Math.floor(6 * h); + v = 1 - bl; + f = 6 * h - i; -function objectifyDeps (data, warn) { - depTypes.forEach(function (type) { - if (!data[type]) return; - data[type] = depObjectify(data[type], type, warn) - }) -} + if ((i & 0x01) !== 0) { + f = 1 - f; + } -function bugsTypos(bugs, warn) { - if (!bugs) return - Object.keys(bugs).forEach(function (k) { - if (typos.bugs[k]) { - warn("typo", k, typos.bugs[k], "bugs") - bugs[typos.bugs[k]] = bugs[k] - delete bugs[k] - } - }) -} + n = wh + f * (v - wh); // linear interpolation + var r; + var g; + var b; + switch (i) { + default: + case 6: + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; + } -/***/ }), -/* 182 */ -/***/ (function(module, exports) { + return [r * 255, g * 255, b * 255]; +}; -exports = module.exports = SemVer +convert.cmyk.rgb = function (cmyk) { + var c = cmyk[0] / 100; + var m = cmyk[1] / 100; + var y = cmyk[2] / 100; + var k = cmyk[3] / 100; + var r; + var g; + var b; -var debug -/* istanbul ignore next */ -if (typeof process === 'object' && - process.env && - process.env.NODE_DEBUG && - /\bsemver\b/i.test(process.env.NODE_DEBUG)) { - debug = function () { - var args = Array.prototype.slice.call(arguments, 0) - args.unshift('SEMVER') - console.log.apply(console, args) - } -} else { - debug = function () {} -} + r = 1 - Math.min(1, c * (1 - k) + k); + g = 1 - Math.min(1, m * (1 - k) + k); + b = 1 - Math.min(1, y * (1 - k) + k); -// Note: this is the semver.org version of the spec that it implements -// Not necessarily the package version of this code. -exports.SEMVER_SPEC_VERSION = '2.0.0' + return [r * 255, g * 255, b * 255]; +}; -var MAX_LENGTH = 256 -var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || - /* istanbul ignore next */ 9007199254740991 +convert.xyz.rgb = function (xyz) { + var x = xyz[0] / 100; + var y = xyz[1] / 100; + var z = xyz[2] / 100; + var r; + var g; + var b; -// Max safe segment length for coercion. -var MAX_SAFE_COMPONENT_LENGTH = 16 + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); -// The actual regexps go on exports.re -var re = exports.re = [] -var src = exports.src = [] -var R = 0 + // assume sRGB + r = r > 0.0031308 + ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) + : r * 12.92; -// The following Regular Expressions can be used for tokenizing, -// validating, and parsing SemVer version strings. + g = g > 0.0031308 + ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) + : g * 12.92; -// ## Numeric Identifier -// A single `0`, or a non-zero digit followed by zero or more digits. + b = b > 0.0031308 + ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) + : b * 12.92; -var NUMERICIDENTIFIER = R++ -src[NUMERICIDENTIFIER] = '0|[1-9]\\d*' -var NUMERICIDENTIFIERLOOSE = R++ -src[NUMERICIDENTIFIERLOOSE] = '[0-9]+' + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); -// ## Non-numeric Identifier -// Zero or more digits, followed by a letter or hyphen, and then zero or -// more letters, digits, or hyphens. + return [r * 255, g * 255, b * 255]; +}; -var NONNUMERICIDENTIFIER = R++ -src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' +convert.xyz.lab = function (xyz) { + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; -// ## Main Version -// Three dot-separated numeric identifiers. + x /= 95.047; + y /= 100; + z /= 108.883; -var MAINVERSION = R++ -src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + - '(' + src[NUMERICIDENTIFIER] + ')\\.' + - '(' + src[NUMERICIDENTIFIER] + ')' + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); -var MAINVERSIONLOOSE = R++ -src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + - '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + - '(' + src[NUMERICIDENTIFIERLOOSE] + ')' + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); -// ## Pre-release Version Identifier -// A numeric identifier, or a non-numeric identifier. + return [l, a, b]; +}; -var PRERELEASEIDENTIFIER = R++ -src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + - '|' + src[NONNUMERICIDENTIFIER] + ')' +convert.lab.xyz = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var x; + var y; + var z; -var PRERELEASEIDENTIFIERLOOSE = R++ -src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + - '|' + src[NONNUMERICIDENTIFIER] + ')' + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; -// ## Pre-release Version -// Hyphen, followed by one or more dot-separated pre-release version -// identifiers. + var y2 = Math.pow(y, 3); + var x2 = Math.pow(x, 3); + var z2 = Math.pow(z, 3); + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; -var PRERELEASE = R++ -src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + - '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))' + x *= 95.047; + y *= 100; + z *= 108.883; -var PRERELEASELOOSE = R++ -src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + - '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))' + return [x, y, z]; +}; -// ## Build Metadata Identifier -// Any combination of digits, letters, or hyphens. +convert.lab.lch = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var hr; + var h; + var c; -var BUILDIDENTIFIER = R++ -src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+' + hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; -// ## Build Metadata -// Plus sign, followed by one or more period-separated build metadata -// identifiers. + if (h < 0) { + h += 360; + } -var BUILD = R++ -src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + - '(?:\\.' + src[BUILDIDENTIFIER] + ')*))' + c = Math.sqrt(a * a + b * b); -// ## Full Version String -// A main version, followed optionally by a pre-release version and -// build metadata. + return [l, c, h]; +}; -// Note that the only major, minor, patch, and pre-release sections of -// the version string are capturing groups. The build metadata is not a -// capturing group, because it should not ever be used in version -// comparison. +convert.lch.lab = function (lch) { + var l = lch[0]; + var c = lch[1]; + var h = lch[2]; + var a; + var b; + var hr; -var FULL = R++ -var FULLPLAIN = 'v?' + src[MAINVERSION] + - src[PRERELEASE] + '?' + - src[BUILD] + '?' + hr = h / 360 * 2 * Math.PI; + a = c * Math.cos(hr); + b = c * Math.sin(hr); -src[FULL] = '^' + FULLPLAIN + '$' + return [l, a, b]; +}; -// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. -// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty -// common in the npm registry. -var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + - src[PRERELEASELOOSE] + '?' + - src[BUILD] + '?' +convert.rgb.ansi16 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization -var LOOSE = R++ -src[LOOSE] = '^' + LOOSEPLAIN + '$' + value = Math.round(value / 50); -var GTLT = R++ -src[GTLT] = '((?:<|>)?=?)' + if (value === 0) { + return 30; + } -// Something like "2.*" or "1.2.x". -// Note that "x.x" is a valid xRange identifer, meaning "any version" -// Only the first item is strictly required. -var XRANGEIDENTIFIERLOOSE = R++ -src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' -var XRANGEIDENTIFIER = R++ -src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*' + var ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); -var XRANGEPLAIN = R++ -src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + - '(?:' + src[PRERELEASE] + ')?' + - src[BUILD] + '?' + - ')?)?' + if (value === 2) { + ansi += 60; + } -var XRANGEPLAINLOOSE = R++ -src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + - '(?:' + src[PRERELEASELOOSE] + ')?' + - src[BUILD] + '?' + - ')?)?' + return ansi; +}; -var XRANGE = R++ -src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$' -var XRANGELOOSE = R++ -src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$' +convert.hsv.ansi16 = function (args) { + // optimization here; we already know the value and don't need to get + // it converted for us. + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); +}; -// Coercion. -// Extract anything that could conceivably be a part of a valid semver -var COERCE = R++ -src[COERCE] = '(?:^|[^\\d])' + - '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + - '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + - '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + - '(?:$|[^\\d])' +convert.rgb.ansi256 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; -// Tilde ranges. -// Meaning is "reasonably at or greater than" -var LONETILDE = R++ -src[LONETILDE] = '(?:~>?)' + // we use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (r === g && g === b) { + if (r < 8) { + return 16; + } -var TILDETRIM = R++ -src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+' -re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g') -var tildeTrimReplace = '$1~' + if (r > 248) { + return 231; + } -var TILDE = R++ -src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$' -var TILDELOOSE = R++ -src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$' + return Math.round(((r - 8) / 247) * 24) + 232; + } -// Caret ranges. -// Meaning is "at least and backwards compatible with" -var LONECARET = R++ -src[LONECARET] = '(?:\\^)' + var ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); -var CARETTRIM = R++ -src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+' -re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g') -var caretTrimReplace = '$1^' + return ansi; +}; -var CARET = R++ -src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$' -var CARETLOOSE = R++ -src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$' +convert.ansi16.rgb = function (args) { + var color = args % 10; -// A simple gt/lt/eq thing, or just "" to indicate "any version" -var COMPARATORLOOSE = R++ -src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$' -var COMPARATOR = R++ -src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$' + // handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } -// An expression to strip any whitespace between the gtlt and the thing -// it modifies, so that `> 1.2.3` ==> `>1.2.3` -var COMPARATORTRIM = R++ -src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + - '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')' + color = color / 10.5 * 255; -// this one has to use the /g flag -re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g') -var comparatorTrimReplace = '$1$2$3' + return [color, color, color]; + } -// Something like `1.2.3 - 1.2.4` -// Note that these all use the loose form, because they'll be -// checked against either the strict or loose comparator form -// later. -var HYPHENRANGE = R++ -src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + - '\\s+-\\s+' + - '(' + src[XRANGEPLAIN] + ')' + - '\\s*$' + var mult = (~~(args > 50) + 1) * 0.5; + var r = ((color & 1) * mult) * 255; + var g = (((color >> 1) & 1) * mult) * 255; + var b = (((color >> 2) & 1) * mult) * 255; -var HYPHENRANGELOOSE = R++ -src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + - '\\s+-\\s+' + - '(' + src[XRANGEPLAINLOOSE] + ')' + - '\\s*$' + return [r, g, b]; +}; -// Star ranges basically just allow anything at all. -var STAR = R++ -src[STAR] = '(<|>)?=?\\s*\\*' +convert.ansi256.rgb = function (args) { + // handle greyscale + if (args >= 232) { + var c = (args - 232) * 10 + 8; + return [c, c, c]; + } -// Compile to actual regexp objects. -// All are flag-free, unless they were created above with a flag. -for (var i = 0; i < R; i++) { - debug(i, src[i]) - if (!re[i]) { - re[i] = new RegExp(src[i]) - } -} + args -= 16; -exports.parse = parse -function parse (version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } + var rem; + var r = Math.floor(args / 36) / 5 * 255; + var g = Math.floor((rem = args % 36) / 6) / 5 * 255; + var b = (rem % 6) / 5 * 255; - if (version instanceof SemVer) { - return version - } + return [r, g, b]; +}; - if (typeof version !== 'string') { - return null - } +convert.rgb.hex = function (args) { + var integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); - if (version.length > MAX_LENGTH) { - return null - } + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; - var r = options.loose ? re[LOOSE] : re[FULL] - if (!r.test(version)) { - return null - } +convert.hex.rgb = function (args) { + var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; + } - try { - return new SemVer(version, options) - } catch (er) { - return null - } -} + var colorString = match[0]; -exports.valid = valid -function valid (version, options) { - var v = parse(version, options) - return v ? v.version : null -} + if (match[0].length === 3) { + colorString = colorString.split('').map(function (char) { + return char + char; + }).join(''); + } -exports.clean = clean -function clean (version, options) { - var s = parse(version.trim().replace(/^[=v]+/, ''), options) - return s ? s.version : null -} - -exports.SemVer = SemVer - -function SemVer (version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - if (version instanceof SemVer) { - if (version.loose === options.loose) { - return version - } else { - version = version.version - } - } else if (typeof version !== 'string') { - throw new TypeError('Invalid Version: ' + version) - } - - if (version.length > MAX_LENGTH) { - throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') - } - - if (!(this instanceof SemVer)) { - return new SemVer(version, options) - } + var integer = parseInt(colorString, 16); + var r = (integer >> 16) & 0xFF; + var g = (integer >> 8) & 0xFF; + var b = integer & 0xFF; - debug('SemVer', version, options) - this.options = options - this.loose = !!options.loose + return [r, g, b]; +}; - var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL]) +convert.rgb.hcg = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var max = Math.max(Math.max(r, g), b); + var min = Math.min(Math.min(r, g), b); + var chroma = (max - min); + var grayscale; + var hue; - if (!m) { - throw new TypeError('Invalid Version: ' + version) - } + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; + } - this.raw = version + if (chroma <= 0) { + hue = 0; + } else + if (max === r) { + hue = ((g - b) / chroma) % 6; + } else + if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma + 4; + } - // these are actually numbers - this.major = +m[1] - this.minor = +m[2] - this.patch = +m[3] + hue /= 6; + hue %= 1; - if (this.major > MAX_SAFE_INTEGER || this.major < 0) { - throw new TypeError('Invalid major version') - } + return [hue * 360, chroma * 100, grayscale * 100]; +}; - if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { - throw new TypeError('Invalid minor version') - } +convert.hsl.hcg = function (hsl) { + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var c = 1; + var f = 0; - if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { - throw new TypeError('Invalid patch version') - } + if (l < 0.5) { + c = 2.0 * s * l; + } else { + c = 2.0 * s * (1.0 - l); + } - // numberify any prerelease numeric ids - if (!m[4]) { - this.prerelease = [] - } else { - this.prerelease = m[4].split('.').map(function (id) { - if (/^[0-9]+$/.test(id)) { - var num = +id - if (num >= 0 && num < MAX_SAFE_INTEGER) { - return num - } - } - return id - }) - } + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); + } - this.build = m[5] ? m[5].split('.') : [] - this.format() -} + return [hsl[0], c * 100, f * 100]; +}; -SemVer.prototype.format = function () { - this.version = this.major + '.' + this.minor + '.' + this.patch - if (this.prerelease.length) { - this.version += '-' + this.prerelease.join('.') - } - return this.version -} +convert.hsv.hcg = function (hsv) { + var s = hsv[1] / 100; + var v = hsv[2] / 100; -SemVer.prototype.toString = function () { - return this.version -} + var c = s * v; + var f = 0; -SemVer.prototype.compare = function (other) { - debug('SemVer.compare', this.version, this.options, other) - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } + if (c < 1.0) { + f = (v - c) / (1 - c); + } - return this.compareMain(other) || this.comparePre(other) -} + return [hsv[0], c * 100, f * 100]; +}; -SemVer.prototype.compareMain = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } +convert.hcg.rgb = function (hcg) { + var h = hcg[0] / 360; + var c = hcg[1] / 100; + var g = hcg[2] / 100; - return compareIdentifiers(this.major, other.major) || - compareIdentifiers(this.minor, other.minor) || - compareIdentifiers(this.patch, other.patch) -} + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } -SemVer.prototype.comparePre = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } + var pure = [0, 0, 0]; + var hi = (h % 1) * 6; + var v = hi % 1; + var w = 1 - v; + var mg = 0; - // NOT having a prerelease is > having one - if (this.prerelease.length && !other.prerelease.length) { - return -1 - } else if (!this.prerelease.length && other.prerelease.length) { - return 1 - } else if (!this.prerelease.length && !other.prerelease.length) { - return 0 - } + switch (Math.floor(hi)) { + case 0: + pure[0] = 1; pure[1] = v; pure[2] = 0; break; + case 1: + pure[0] = w; pure[1] = 1; pure[2] = 0; break; + case 2: + pure[0] = 0; pure[1] = 1; pure[2] = v; break; + case 3: + pure[0] = 0; pure[1] = w; pure[2] = 1; break; + case 4: + pure[0] = v; pure[1] = 0; pure[2] = 1; break; + default: + pure[0] = 1; pure[1] = 0; pure[2] = w; + } - var i = 0 - do { - var a = this.prerelease[i] - var b = other.prerelease[i] - debug('prerelease compare', i, a, b) - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers(a, b) - } - } while (++i) -} + mg = (1.0 - c) * g; -// preminor will bump the version up to the next minor release, and immediately -// down to pre-release. premajor and prepatch work the same way. -SemVer.prototype.inc = function (release, identifier) { - switch (release) { - case 'premajor': - this.prerelease.length = 0 - this.patch = 0 - this.minor = 0 - this.major++ - this.inc('pre', identifier) - break - case 'preminor': - this.prerelease.length = 0 - this.patch = 0 - this.minor++ - this.inc('pre', identifier) - break - case 'prepatch': - // If this is already a prerelease, it will bump to the next version - // drop any prereleases that might already exist, since they are not - // relevant at this point. - this.prerelease.length = 0 - this.inc('patch', identifier) - this.inc('pre', identifier) - break - // If the input is a non-prerelease version, this acts the same as - // prepatch. - case 'prerelease': - if (this.prerelease.length === 0) { - this.inc('patch', identifier) - } - this.inc('pre', identifier) - break + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; - case 'major': - // If this is a pre-major version, bump up to the same major version. - // Otherwise increment major. - // 1.0.0-5 bumps to 1.0.0 - // 1.1.0 bumps to 2.0.0 - if (this.minor !== 0 || - this.patch !== 0 || - this.prerelease.length === 0) { - this.major++ - } - this.minor = 0 - this.patch = 0 - this.prerelease = [] - break - case 'minor': - // If this is a pre-minor version, bump up to the same minor version. - // Otherwise increment minor. - // 1.2.0-5 bumps to 1.2.0 - // 1.2.1 bumps to 1.3.0 - if (this.patch !== 0 || this.prerelease.length === 0) { - this.minor++ - } - this.patch = 0 - this.prerelease = [] - break - case 'patch': - // If this is not a pre-release version, it will increment the patch. - // If it is a pre-release it will bump up to the same patch version. - // 1.2.0-5 patches to 1.2.0 - // 1.2.0 patches to 1.2.1 - if (this.prerelease.length === 0) { - this.patch++ - } - this.prerelease = [] - break - // This probably shouldn't be used publicly. - // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. - case 'pre': - if (this.prerelease.length === 0) { - this.prerelease = [0] - } else { - var i = this.prerelease.length - while (--i >= 0) { - if (typeof this.prerelease[i] === 'number') { - this.prerelease[i]++ - i = -2 - } - } - if (i === -1) { - // didn't increment anything - this.prerelease.push(0) - } - } - if (identifier) { - // 1.2.0-beta.1 bumps to 1.2.0-beta.2, - // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 - if (this.prerelease[0] === identifier) { - if (isNaN(this.prerelease[1])) { - this.prerelease = [identifier, 0] - } - } else { - this.prerelease = [identifier, 0] - } - } - break +convert.hcg.hsv = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; - default: - throw new Error('invalid increment argument: ' + release) - } - this.format() - this.raw = this.version - return this -} + var v = c + g * (1.0 - c); + var f = 0; -exports.inc = inc -function inc (version, release, loose, identifier) { - if (typeof (loose) === 'string') { - identifier = loose - loose = undefined - } + if (v > 0.0) { + f = c / v; + } - try { - return new SemVer(version, loose).inc(release, identifier).version - } catch (er) { - return null - } -} + return [hcg[0], f * 100, v * 100]; +}; -exports.diff = diff -function diff (version1, version2) { - if (eq(version1, version2)) { - return null - } else { - var v1 = parse(version1) - var v2 = parse(version2) - var prefix = '' - if (v1.prerelease.length || v2.prerelease.length) { - prefix = 'pre' - var defaultResult = 'prerelease' - } - for (var key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return prefix + key - } - } - } - return defaultResult // may be undefined - } -} +convert.hcg.hsl = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; -exports.compareIdentifiers = compareIdentifiers + var l = g * (1.0 - c) + 0.5 * c; + var s = 0; -var numeric = /^[0-9]+$/ -function compareIdentifiers (a, b) { - var anum = numeric.test(a) - var bnum = numeric.test(b) + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); + } - if (anum && bnum) { - a = +a - b = +b - } + return [hcg[0], s * 100, l * 100]; +}; - return a === b ? 0 - : (anum && !bnum) ? -1 - : (bnum && !anum) ? 1 - : a < b ? -1 - : 1 -} +convert.hcg.hwb = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + var v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; -exports.rcompareIdentifiers = rcompareIdentifiers -function rcompareIdentifiers (a, b) { - return compareIdentifiers(b, a) -} +convert.hwb.hcg = function (hwb) { + var w = hwb[1] / 100; + var b = hwb[2] / 100; + var v = 1 - b; + var c = v - w; + var g = 0; -exports.major = major -function major (a, loose) { - return new SemVer(a, loose).major -} + if (c < 1) { + g = (v - c) / (1 - c); + } -exports.minor = minor -function minor (a, loose) { - return new SemVer(a, loose).minor -} + return [hwb[0], c * 100, g * 100]; +}; -exports.patch = patch -function patch (a, loose) { - return new SemVer(a, loose).patch -} +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; +}; -exports.compare = compare -function compare (a, b, loose) { - return new SemVer(a, loose).compare(new SemVer(b, loose)) -} +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; +}; -exports.compareLoose = compareLoose -function compareLoose (a, b) { - return compare(a, b, true) -} +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; -exports.rcompare = rcompare -function rcompare (a, b, loose) { - return compare(b, a, loose) -} +convert.gray.hsl = convert.gray.hsv = function (args) { + return [0, 0, args[0]]; +}; -exports.sort = sort -function sort (list, loose) { - return list.sort(function (a, b) { - return exports.compare(a, b, loose) - }) -} +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; +}; -exports.rsort = rsort -function rsort (list, loose) { - return list.sort(function (a, b) { - return exports.rcompare(a, b, loose) - }) -} +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; -exports.gt = gt -function gt (a, b, loose) { - return compare(a, b, loose) > 0 -} +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; +}; -exports.lt = lt -function lt (a, b, loose) { - return compare(a, b, loose) < 0 -} +convert.gray.hex = function (gray) { + var val = Math.round(gray[0] / 100 * 255) & 0xFF; + var integer = (val << 16) + (val << 8) + val; -exports.eq = eq -function eq (a, b, loose) { - return compare(a, b, loose) === 0 -} + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; -exports.neq = neq -function neq (a, b, loose) { - return compare(a, b, loose) !== 0 -} +convert.rgb.gray = function (rgb) { + var val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; +}; -exports.gte = gte -function gte (a, b, loose) { - return compare(a, b, loose) >= 0 -} -exports.lte = lte -function lte (a, b, loose) { - return compare(a, b, loose) <= 0 -} +/***/ }), +/* 182 */ +/***/ (function(module, exports, __webpack_require__) { -exports.cmp = cmp -function cmp (a, op, b, loose) { - switch (op) { - case '===': - if (typeof a === 'object') - a = a.version - if (typeof b === 'object') - b = b.version - return a === b +"use strict"; + + +module.exports = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] +}; - case '!==': - if (typeof a === 'object') - a = a.version - if (typeof b === 'object') - b = b.version - return a !== b - case '': - case '=': - case '==': - return eq(a, b, loose) +/***/ }), +/* 183 */ +/***/ (function(module, exports, __webpack_require__) { - case '!=': - return neq(a, b, loose) +var conversions = __webpack_require__(181); - case '>': - return gt(a, b, loose) +/* + this function routes a model to all other models. - case '>=': - return gte(a, b, loose) + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). - case '<': - return lt(a, b, loose) + conversions that are not possible simply are not included. +*/ - case '<=': - return lte(a, b, loose) +function buildGraph() { + var graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + var models = Object.keys(conversions); - default: - throw new TypeError('Invalid operator: ' + op) - } + for (var len = models.length, i = 0; i < len; i++) { + graph[models[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; + } + + return graph; } -exports.Comparator = Comparator -function Comparator (comp, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + var graph = buildGraph(); + var queue = [fromModel]; // unshift -> queue -> pop - if (comp instanceof Comparator) { - if (comp.loose === !!options.loose) { - return comp - } else { - comp = comp.value - } - } + graph[fromModel].distance = 0; - if (!(this instanceof Comparator)) { - return new Comparator(comp, options) - } + while (queue.length) { + var current = queue.pop(); + var adjacents = Object.keys(conversions[current]); - debug('comparator', comp, options) - this.options = options - this.loose = !!options.loose - this.parse(comp) + for (var len = adjacents.length, i = 0; i < len; i++) { + var adjacent = adjacents[i]; + var node = graph[adjacent]; - if (this.semver === ANY) { - this.value = '' - } else { - this.value = this.operator + this.semver.version - } + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } + } - debug('comp', this) + return graph; } -var ANY = {} -Comparator.prototype.parse = function (comp) { - var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR] - var m = comp.match(r) +function link(from, to) { + return function (args) { + return to(from(args)); + }; +} - if (!m) { - throw new TypeError('Invalid comparator: ' + comp) - } +function wrapConversion(toModel, graph) { + var path = [graph[toModel].parent, toModel]; + var fn = conversions[graph[toModel].parent][toModel]; - this.operator = m[1] - if (this.operator === '=') { - this.operator = '' - } + var cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions[graph[cur].parent][cur], fn); + cur = graph[cur].parent; + } - // if it literally is just '>' or '' then allow anything. - if (!m[2]) { - this.semver = ANY - } else { - this.semver = new SemVer(m[2], this.options.loose) - } + fn.conversion = path; + return fn; } -Comparator.prototype.toString = function () { - return this.value -} +module.exports = function (fromModel) { + var graph = deriveBFS(fromModel); + var conversion = {}; -Comparator.prototype.test = function (version) { - debug('Comparator.test', version, this.options.loose) + var models = Object.keys(graph); + for (var len = models.length, i = 0; i < len; i++) { + var toModel = models[i]; + var node = graph[toModel]; - if (this.semver === ANY) { - return true - } + if (node.parent === null) { + // no possible conversion, or this node is the source model. + continue; + } - if (typeof version === 'string') { - version = new SemVer(version, this.options) - } + conversion[toModel] = wrapConversion(toModel, graph); + } - return cmp(version, this.operator, this.semver, this.options) -} + return conversion; +}; -Comparator.prototype.intersects = function (comp, options) { - if (!(comp instanceof Comparator)) { - throw new TypeError('a Comparator is required') - } - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - var rangeTmp +/***/ }), +/* 184 */ +/***/ (function(module, exports, __webpack_require__) { - if (this.operator === '') { - rangeTmp = new Range(comp.value, options) - return satisfies(this.value, rangeTmp, options) - } else if (comp.operator === '') { - rangeTmp = new Range(this.value, options) - return satisfies(comp.semver, rangeTmp, options) - } +"use strict"; - var sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>') - var sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<') - var sameSemVer = this.semver.version === comp.semver.version - var differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<=') - var oppositeDirectionsLessThan = - cmp(this.semver, '<', comp.semver, options) && - ((this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<')) - var oppositeDirectionsGreaterThan = - cmp(this.semver, '>', comp.semver, options) && - ((this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>')) +const os = __webpack_require__(120); +const hasFlag = __webpack_require__(185); - return sameDirectionIncreasing || sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || oppositeDirectionsGreaterThan +const env = process.env; + +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + forceColor = false; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = true; +} +if ('FORCE_COLOR' in env) { + forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; } -exports.Range = Range -function Range (range, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } +function translateLevel(level) { + if (level === 0) { + return false; + } - if (range instanceof Range) { - if (range.loose === !!options.loose && - range.includePrerelease === !!options.includePrerelease) { - return range - } else { - return new Range(range.raw, options) - } - } + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +} - if (range instanceof Comparator) { - return new Range(range.value, options) - } +function supportsColor(stream) { + if (forceColor === false) { + return 0; + } - if (!(this instanceof Range)) { - return new Range(range, options) - } + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } - this.options = options - this.loose = !!options.loose - this.includePrerelease = !!options.includePrerelease + if (hasFlag('color=256')) { + return 2; + } - // First, split based on boolean or || - this.raw = range - this.set = range.split(/\s*\|\|\s*/).map(function (range) { - return this.parseRange(range.trim()) - }, this).filter(function (c) { - // throw out any that are not relevant for whatever reason - return c.length - }) + if (stream && !stream.isTTY && forceColor !== true) { + return 0; + } - if (!this.set.length) { - throw new TypeError('Invalid SemVer Range: ' + range) - } + const min = forceColor ? 1 : 0; - this.format() -} + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows + // release that supports 256 colors. Windows 10 build 14931 is the first release + // that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(process.versions.node.split('.')[0]) >= 8 && + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } -Range.prototype.format = function () { - this.range = this.set.map(function (comps) { - return comps.join(' ').trim() - }).join('||').trim() - return this.range -} + return 1; + } -Range.prototype.toString = function () { - return this.range -} + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } -Range.prototype.parseRange = function (range) { - var loose = this.options.loose - range = range.trim() - // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` - var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE] - range = range.replace(hr, hyphenReplace) - debug('hyphen replace', range) - // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` - range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace) - debug('comparator trim', range, re[COMPARATORTRIM]) + return min; + } - // `~ 1.2.3` => `~1.2.3` - range = range.replace(re[TILDETRIM], tildeTrimReplace) + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } - // `^ 1.2.3` => `^1.2.3` - range = range.replace(re[CARETTRIM], caretTrimReplace) + if (env.COLORTERM === 'truecolor') { + return 3; + } - // normalize spaces - range = range.split(/\s+/).join(' ') + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - // At this point, the range is completely trimmed and - // ready to be split into comparators. + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } - var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR] - var set = range.split(' ').map(function (comp) { - return parseComparator(comp, this.options) - }, this).join(' ').split(/\s+/) - if (this.options.loose) { - // in loose mode, throw out any that are not valid comparators - set = set.filter(function (comp) { - return !!comp.match(compRe) - }) - } - set = set.map(function (comp) { - return new Comparator(comp, this.options) - }, this) + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } - return set -} + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } -Range.prototype.intersects = function (range, options) { - if (!(range instanceof Range)) { - throw new TypeError('a Range is required') - } + if ('COLORTERM' in env) { + return 1; + } - return this.set.some(function (thisComparators) { - return thisComparators.every(function (thisComparator) { - return range.set.some(function (rangeComparators) { - return rangeComparators.every(function (rangeComparator) { - return thisComparator.intersects(rangeComparator, options) - }) - }) - }) - }) -} + if (env.TERM === 'dumb') { + return min; + } -// Mostly just for testing and legacy API reasons -exports.toComparators = toComparators -function toComparators (range, options) { - return new Range(range, options).set.map(function (comp) { - return comp.map(function (c) { - return c.value - }).join(' ').trim().split(' ') - }) + return min; } -// comprised of xranges, tildes, stars, and gtlt's at this point. -// already replaced the hyphen ranges -// turn into a set of JUST comparators. -function parseComparator (comp, options) { - debug('comp', comp, options) - comp = replaceCarets(comp, options) - debug('caret', comp) - comp = replaceTildes(comp, options) - debug('tildes', comp) - comp = replaceXRanges(comp, options) - debug('xrange', comp) - comp = replaceStars(comp, options) - debug('stars', comp) - return comp +function getSupportLevel(stream) { + const level = supportsColor(stream); + return translateLevel(level); } -function isX (id) { - return !id || id.toLowerCase() === 'x' || id === '*' -} +module.exports = { + supportsColor: getSupportLevel, + stdout: getSupportLevel(process.stdout), + stderr: getSupportLevel(process.stderr) +}; -// ~, ~> --> * (any, kinda silly) -// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 -// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 -// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 -// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 -// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 -function replaceTildes (comp, options) { - return comp.trim().split(/\s+/).map(function (comp) { - return replaceTilde(comp, options) - }).join(' ') -} -function replaceTilde (comp, options) { - var r = options.loose ? re[TILDELOOSE] : re[TILDE] - return comp.replace(r, function (_, M, m, p, pr) { - debug('tilde', comp, _, M, m, p, pr) - var ret +/***/ }), +/* 185 */ +/***/ (function(module, exports, __webpack_require__) { - if (isX(M)) { - ret = '' - } else if (isX(m)) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' - } else if (isX(p)) { - // ~1.2 == >=1.2.0 <1.3.0 - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' - } else if (pr) { - debug('replaceTilde pr', pr) - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + (+m + 1) + '.0' - } else { - // ~1.2.3 == >=1.2.3 <1.3.0 - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + (+m + 1) + '.0' - } +"use strict"; - debug('tilde return', ret) - return ret - }) -} +module.exports = (flag, argv) => { + argv = argv || process.argv; + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const pos = argv.indexOf(prefix + flag); + const terminatorPos = argv.indexOf('--'); + return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); +}; -// ^ --> * (any, kinda silly) -// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 -// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 -// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 -// ^1.2.3 --> >=1.2.3 <2.0.0 -// ^1.2.0 --> >=1.2.0 <2.0.0 -function replaceCarets (comp, options) { - return comp.trim().split(/\s+/).map(function (comp) { - return replaceCaret(comp, options) - }).join(' ') -} -function replaceCaret (comp, options) { - debug('caret', comp, options) - var r = options.loose ? re[CARETLOOSE] : re[CARET] - return comp.replace(r, function (_, M, m, p, pr) { - debug('caret', comp, _, M, m, p, pr) - var ret +/***/ }), +/* 186 */ +/***/ (function(module, exports, __webpack_require__) { - if (isX(M)) { - ret = '' - } else if (isX(m)) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' - } else if (isX(p)) { - if (M === '0') { - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' - } else { - ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' - } - } else if (pr) { - debug('replaceCaret pr', pr) - if (M === '0') { - if (m === '0') { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + m + '.' + (+p + 1) - } else { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + (+m + 1) + '.0' - } - } else { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + (+M + 1) + '.0.0' - } - } else { - debug('no pr') - if (M === '0') { - if (m === '0') { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + m + '.' + (+p + 1) - } else { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + (+m + 1) + '.0' - } - } else { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + (+M + 1) + '.0.0' - } - } +"use strict"; - debug('caret return', ret) - return ret - }) -} +const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; +const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; +const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; +const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; -function replaceXRanges (comp, options) { - debug('replaceXRanges', comp, options) - return comp.split(/\s+/).map(function (comp) { - return replaceXRange(comp, options) - }).join(' ') +const ESCAPES = new Map([ + ['n', '\n'], + ['r', '\r'], + ['t', '\t'], + ['b', '\b'], + ['f', '\f'], + ['v', '\v'], + ['0', '\0'], + ['\\', '\\'], + ['e', '\u001B'], + ['a', '\u0007'] +]); + +function unescape(c) { + if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { + return String.fromCharCode(parseInt(c.slice(1), 16)); + } + + return ESCAPES.get(c) || c; } -function replaceXRange (comp, options) { - comp = comp.trim() - var r = options.loose ? re[XRANGELOOSE] : re[XRANGE] - return comp.replace(r, function (ret, gtlt, M, m, p, pr) { - debug('xRange', comp, ret, gtlt, M, m, p, pr) - var xM = isX(M) - var xm = xM || isX(m) - var xp = xm || isX(p) - var anyX = xp +function parseArguments(name, args) { + const results = []; + const chunks = args.trim().split(/\s*,\s*/g); + let matches; - if (gtlt === '=' && anyX) { - gtlt = '' - } + for (const chunk of chunks) { + if (!isNaN(chunk)) { + results.push(Number(chunk)); + } else if ((matches = chunk.match(STRING_REGEX))) { + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); + } else { + throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); + } + } - if (xM) { - if (gtlt === '>' || gtlt === '<') { - // nothing is allowed - ret = '<0.0.0' - } else { - // nothing is forbidden - ret = '*' - } - } else if (gtlt && anyX) { - // we know patch is an x, because we have any x at all. - // replace X with 0 - if (xm) { - m = 0 - } - p = 0 + return results; +} - if (gtlt === '>') { - // >1 => >=2.0.0 - // >1.2 => >=1.3.0 - // >1.2.3 => >= 1.2.4 - gtlt = '>=' - if (xm) { - M = +M + 1 - m = 0 - p = 0 - } else { - m = +m + 1 - p = 0 - } - } else if (gtlt === '<=') { - // <=0.7.x is actually <0.8.0, since any 0.7.x should - // pass. Similarly, <=7.x is actually <8.0.0, etc. - gtlt = '<' - if (xm) { - M = +M + 1 - } else { - m = +m + 1 - } - } +function parseStyle(style) { + STYLE_REGEX.lastIndex = 0; - ret = gtlt + M + '.' + m + '.' + p - } else if (xm) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' - } else if (xp) { - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' - } + const results = []; + let matches; - debug('xRange return', ret) + while ((matches = STYLE_REGEX.exec(style)) !== null) { + const name = matches[1]; - return ret - }) -} + if (matches[2]) { + const args = parseArguments(name, matches[2]); + results.push([name].concat(args)); + } else { + results.push([name]); + } + } -// Because * is AND-ed with everything else in the comparator, -// and '' means "any version", just remove the *s entirely. -function replaceStars (comp, options) { - debug('replaceStars', comp, options) - // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(re[STAR], '') + return results; } -// This function is passed to string.replace(re[HYPHENRANGE]) -// M, m, patch, prerelease, build -// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 -// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do -// 1.2 - 3.4 => >=1.2.0 <3.5.0 -function hyphenReplace ($0, - from, fM, fm, fp, fpr, fb, - to, tM, tm, tp, tpr, tb) { - if (isX(fM)) { - from = '' - } else if (isX(fm)) { - from = '>=' + fM + '.0.0' - } else if (isX(fp)) { - from = '>=' + fM + '.' + fm + '.0' - } else { - from = '>=' + from - } +function buildStyle(chalk, styles) { + const enabled = {}; - if (isX(tM)) { - to = '' - } else if (isX(tm)) { - to = '<' + (+tM + 1) + '.0.0' - } else if (isX(tp)) { - to = '<' + tM + '.' + (+tm + 1) + '.0' - } else if (tpr) { - to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr - } else { - to = '<=' + to - } + for (const layer of styles) { + for (const style of layer.styles) { + enabled[style[0]] = layer.inverse ? null : style.slice(1); + } + } - return (from + ' ' + to).trim() + let current = chalk; + for (const styleName of Object.keys(enabled)) { + if (Array.isArray(enabled[styleName])) { + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); + } + + if (enabled[styleName].length > 0) { + current = current[styleName].apply(current, enabled[styleName]); + } else { + current = current[styleName]; + } + } + } + + return current; } -// if ANY of the sets match ALL of its comparators, then pass -Range.prototype.test = function (version) { - if (!version) { - return false - } +module.exports = (chalk, tmp) => { + const styles = []; + const chunks = []; + let chunk = []; - if (typeof version === 'string') { - version = new SemVer(version, this.options) - } + // eslint-disable-next-line max-params + tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { + if (escapeChar) { + chunk.push(unescape(escapeChar)); + } else if (style) { + const str = chunk.join(''); + chunk = []; + chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); + styles.push({inverse, styles: parseStyle(style)}); + } else if (close) { + if (styles.length === 0) { + throw new Error('Found extraneous } in Chalk template literal'); + } - for (var i = 0; i < this.set.length; i++) { - if (testSet(this.set[i], version, this.options)) { - return true - } - } - return false -} + chunks.push(buildStyle(chalk, styles)(chunk.join(''))); + chunk = []; + styles.pop(); + } else { + chunk.push(chr); + } + }); -function testSet (set, version, options) { - for (var i = 0; i < set.length; i++) { - if (!set[i].test(version)) { - return false - } - } + chunks.push(chunk.join('')); - if (version.prerelease.length && !options.includePrerelease) { - // Find the set of versions that are allowed to have prereleases - // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 - // That should allow `1.2.3-pr.2` to pass. - // However, `1.2.4-alpha.notready` should NOT be allowed, - // even though it's within the range set by the comparators. - for (i = 0; i < set.length; i++) { - debug(set[i].semver) - if (set[i].semver === ANY) { - continue - } + if (styles.length > 0) { + const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errMsg); + } - if (set[i].semver.prerelease.length > 0) { - var allowed = set[i].semver - if (allowed.major === version.major && - allowed.minor === version.minor && - allowed.patch === version.patch) { - return true - } - } - } + return chunks.join(''); +}; - // Version has a -pre, but it's not one of the ones we like. - return false - } - return true -} +/***/ }), +/* 187 */ +/***/ (function(module, exports, __webpack_require__) { -exports.satisfies = satisfies -function satisfies (version, range, options) { - try { - range = new Range(range, options) - } catch (er) { - return false - } - return range.test(version) -} +module.exports = normalize -exports.maxSatisfying = maxSatisfying -function maxSatisfying (versions, range, options) { - var max = null - var maxSV = null - try { - var rangeObj = new Range(range, options) - } catch (er) { - return null +var fixer = __webpack_require__(188) +normalize.fixer = fixer + +var makeWarning = __webpack_require__(211) + +var fieldsToFix = ['name','version','description','repository','modules','scripts' + ,'files','bin','man','bugs','keywords','readme','homepage','license'] +var otherThingsToFix = ['dependencies','people', 'typos'] + +var thingsToFix = fieldsToFix.map(function(fieldName) { + return ucFirst(fieldName) + "Field" +}) +// two ways to do this in CoffeeScript on only one line, sub-70 chars: +// thingsToFix = fieldsToFix.map (name) -> ucFirst(name) + "Field" +// thingsToFix = (ucFirst(name) + "Field" for name in fieldsToFix) +thingsToFix = thingsToFix.concat(otherThingsToFix) + +function normalize (data, warn, strict) { + if(warn === true) warn = null, strict = true + if(!strict) strict = false + if(!warn || data.private) warn = function(msg) { /* noop */ } + + if (data.scripts && + data.scripts.install === "node-gyp rebuild" && + !data.scripts.preinstall) { + data.gypfile = true } - versions.forEach(function (v) { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!max || maxSV.compare(v) === -1) { - // compare(max, v, true) - max = v - maxSV = new SemVer(max, options) - } - } + fixer.warn = function() { warn(makeWarning.apply(null, arguments)) } + thingsToFix.forEach(function(thingName) { + fixer["fix" + ucFirst(thingName)](data, strict) }) - return max + data._id = data.name + "@" + data.version } -exports.minSatisfying = minSatisfying -function minSatisfying (versions, range, options) { - var min = null - var minSV = null - try { - var rangeObj = new Range(range, options) - } catch (er) { - return null - } - versions.forEach(function (v) { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!min || minSV.compare(v) === 1) { - // compare(min, v, true) - min = v - minSV = new SemVer(min, options) - } - } - }) - return min +function ucFirst (string) { + return string.charAt(0).toUpperCase() + string.slice(1); } -exports.minVersion = minVersion -function minVersion (range, loose) { - range = new Range(range, loose) - var minver = new SemVer('0.0.0') - if (range.test(minver)) { - return minver +/***/ }), +/* 188 */ +/***/ (function(module, exports, __webpack_require__) { + +var semver = __webpack_require__(189) +var validateLicense = __webpack_require__(190); +var hostedGitInfo = __webpack_require__(195) +var isBuiltinModule = __webpack_require__(199).isCore +var depTypes = ["dependencies","devDependencies","optionalDependencies"] +var extractDescription = __webpack_require__(209) +var url = __webpack_require__(196) +var typos = __webpack_require__(210) + +var fixer = module.exports = { + // default warning function + warn: function() {}, + + fixRepositoryField: function(data) { + if (data.repositories) { + this.warn("repositories"); + data.repository = data.repositories[0] + } + if (!data.repository) return this.warn("missingRepository") + if (typeof data.repository === "string") { + data.repository = { + type: "git", + url: data.repository + } + } + var r = data.repository.url || "" + if (r) { + var hosted = hostedGitInfo.fromUrl(r) + if (hosted) { + r = data.repository.url + = hosted.getDefaultRepresentation() == "shortcut" ? hosted.https() : hosted.toString() + } + } + + if (r.match(/github.com\/[^\/]+\/[^\/]+\.git\.git$/)) { + this.warn("brokenGitUrl", r) + } } - minver = new SemVer('0.0.0-0') - if (range.test(minver)) { - return minver +, fixTypos: function(data) { + Object.keys(typos.topLevel).forEach(function (d) { + if (data.hasOwnProperty(d)) { + this.warn("typo", d, typos.topLevel[d]) + } + }, this) } - minver = null - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i] +, fixScriptsField: function(data) { + if (!data.scripts) return + if (typeof data.scripts !== "object") { + this.warn("nonObjectScripts") + delete data.scripts + return + } + Object.keys(data.scripts).forEach(function (k) { + if (typeof data.scripts[k] !== "string") { + this.warn("nonStringScript") + delete data.scripts[k] + } else if (typos.script[k] && !data.scripts[typos.script[k]]) { + this.warn("typo", k, typos.script[k], "scripts") + } + }, this) + } - comparators.forEach(function (comparator) { - // Clone to avoid manipulating the comparator's semver object. - var compver = new SemVer(comparator.semver.version) - switch (comparator.operator) { - case '>': - if (compver.prerelease.length === 0) { - compver.patch++ - } else { - compver.prerelease.push(0) - } - compver.raw = compver.format() - /* fallthrough */ - case '': - case '>=': - if (!minver || gt(minver, compver)) { - minver = compver - } - break - case '<': - case '<=': - /* Ignore maximum versions */ - break - /* istanbul ignore next */ - default: - throw new Error('Unexpected operation: ' + comparator.operator) +, fixFilesField: function(data) { + var files = data.files + if (files && !Array.isArray(files)) { + this.warn("nonArrayFiles") + delete data.files + } else if (data.files) { + data.files = data.files.filter(function(file) { + if (!file || typeof file !== "string") { + this.warn("invalidFilename", file) + return false + } else { + return true + } + }, this) + } + } + +, fixBinField: function(data) { + if (!data.bin) return; + if (typeof data.bin === "string") { + var b = {} + var match + if (match = data.name.match(/^@[^/]+[/](.*)$/)) { + b[match[1]] = data.bin + } else { + b[data.name] = data.bin } - }) + data.bin = b + } } - if (minver && range.test(minver)) { - return minver +, fixManField: function(data) { + if (!data.man) return; + if (typeof data.man === "string") { + data.man = [ data.man ] + } + } +, fixBundleDependenciesField: function(data) { + var bdd = "bundledDependencies" + var bd = "bundleDependencies" + if (data[bdd] && !data[bd]) { + data[bd] = data[bdd] + delete data[bdd] + } + if (data[bd] && !Array.isArray(data[bd])) { + this.warn("nonArrayBundleDependencies") + delete data[bd] + } else if (data[bd]) { + data[bd] = data[bd].filter(function(bd) { + if (!bd || typeof bd !== 'string') { + this.warn("nonStringBundleDependency", bd) + return false + } else { + if (!data.dependencies) { + data.dependencies = {} + } + if (!data.dependencies.hasOwnProperty(bd)) { + this.warn("nonDependencyBundleDependency", bd) + data.dependencies[bd] = "*" + } + return true + } + }, this) + } } - return null -} +, fixDependencies: function(data, strict) { + var loose = !strict + objectifyDeps(data, this.warn) + addOptionalDepsToDeps(data, this.warn) + this.fixBundleDependenciesField(data) -exports.validRange = validRange -function validRange (range, options) { - try { - // Return '*' instead of '' so that truthiness works. - // This will throw if it's invalid anyway - return new Range(range, options).range || '*' - } catch (er) { - return null + ;['dependencies','devDependencies'].forEach(function(deps) { + if (!(deps in data)) return + if (!data[deps] || typeof data[deps] !== "object") { + this.warn("nonObjectDependencies", deps) + delete data[deps] + return + } + Object.keys(data[deps]).forEach(function (d) { + var r = data[deps][d] + if (typeof r !== 'string') { + this.warn("nonStringDependency", d, JSON.stringify(r)) + delete data[deps][d] + } + var hosted = hostedGitInfo.fromUrl(data[deps][d]) + if (hosted) data[deps][d] = hosted.toString() + }, this) + }, this) } -} -// Determine if version is less than all the versions possible in the range -exports.ltr = ltr -function ltr (version, range, options) { - return outside(version, range, '<', options) -} +, fixModulesField: function (data) { + if (data.modules) { + this.warn("deprecatedModules") + delete data.modules + } + } -// Determine if version is greater than all the versions possible in the range. -exports.gtr = gtr -function gtr (version, range, options) { - return outside(version, range, '>', options) -} +, fixKeywordsField: function (data) { + if (typeof data.keywords === "string") { + data.keywords = data.keywords.split(/,\s+/) + } + if (data.keywords && !Array.isArray(data.keywords)) { + delete data.keywords + this.warn("nonArrayKeywords") + } else if (data.keywords) { + data.keywords = data.keywords.filter(function(kw) { + if (typeof kw !== "string" || !kw) { + this.warn("nonStringKeyword"); + return false + } else { + return true + } + }, this) + } + } -exports.outside = outside -function outside (version, range, hilo, options) { - version = new SemVer(version, options) - range = new Range(range, options) +, fixVersionField: function(data, strict) { + // allow "loose" semver 1.0 versions in non-strict mode + // enforce strict semver 2.0 compliance in strict mode + var loose = !strict + if (!data.version) { + data.version = "" + return true + } + if (!semver.valid(data.version, loose)) { + throw new Error('Invalid version: "'+ data.version + '"') + } + data.version = semver.clean(data.version, loose) + return true + } - var gtfn, ltefn, ltfn, comp, ecomp - switch (hilo) { - case '>': - gtfn = gt - ltefn = lte - ltfn = lt - comp = '>' - ecomp = '>=' - break - case '<': - gtfn = lt - ltefn = gte - ltfn = gt - comp = '<' - ecomp = '<=' - break - default: - throw new TypeError('Must provide a hilo val of "<" or ">"') +, fixPeople: function(data) { + modifyPeople(data, unParsePerson) + modifyPeople(data, parsePerson) } - // If it satisifes the range it is not outside - if (satisfies(version, range, options)) { - return false +, fixNameField: function(data, options) { + if (typeof options === "boolean") options = {strict: options} + else if (typeof options === "undefined") options = {} + var strict = options.strict + if (!data.name && !strict) { + data.name = "" + return + } + if (typeof data.name !== "string") { + throw new Error("name field must be a string.") + } + if (!strict) + data.name = data.name.trim() + ensureValidName(data.name, strict, options.allowLegacyCase) + if (isBuiltinModule(data.name)) + this.warn("conflictingName", data.name) } - // From now on, variable terms are as if we're in "gtr" mode. - // but note that everything is flipped for the "ltr" function. - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i] +, fixDescriptionField: function (data) { + if (data.description && typeof data.description !== 'string') { + this.warn("nonStringDescription") + delete data.description + } + if (data.readme && !data.description) + data.description = extractDescription(data.readme) + if(data.description === undefined) delete data.description; + if (!data.description) this.warn("missingDescription") + } - var high = null - var low = null +, fixReadmeField: function (data) { + if (!data.readme) { + this.warn("missingReadme") + data.readme = "ERROR: No README data found!" + } + } - comparators.forEach(function (comparator) { - if (comparator.semver === ANY) { - comparator = new Comparator('>=0.0.0') +, fixBugsField: function(data) { + if (!data.bugs && data.repository && data.repository.url) { + var hosted = hostedGitInfo.fromUrl(data.repository.url) + if(hosted && hosted.bugs()) { + data.bugs = {url: hosted.bugs()} } - high = high || comparator - low = low || comparator - if (gtfn(comparator.semver, high.semver, options)) { - high = comparator - } else if (ltfn(comparator.semver, low.semver, options)) { - low = comparator + } + else if(data.bugs) { + var emailRe = /^.+@.*\..+$/ + if(typeof data.bugs == "string") { + if(emailRe.test(data.bugs)) + data.bugs = {email:data.bugs} + else if(url.parse(data.bugs).protocol) + data.bugs = {url: data.bugs} + else + this.warn("nonEmailUrlBugsString") } - }) + else { + bugsTypos(data.bugs, this.warn) + var oldBugs = data.bugs + data.bugs = {} + if(oldBugs.url) { + if(typeof(oldBugs.url) == "string" && url.parse(oldBugs.url).protocol) + data.bugs.url = oldBugs.url + else + this.warn("nonUrlBugsUrlField") + } + if(oldBugs.email) { + if(typeof(oldBugs.email) == "string" && emailRe.test(oldBugs.email)) + data.bugs.email = oldBugs.email + else + this.warn("nonEmailBugsEmailField") + } + } + if(!data.bugs.email && !data.bugs.url) { + delete data.bugs + this.warn("emptyNormalizedBugs") + } + } + } - // If the edge version comparator has a operator then our version - // isn't outside it - if (high.operator === comp || high.operator === ecomp) { - return false +, fixHomepageField: function(data) { + if (!data.homepage && data.repository && data.repository.url) { + var hosted = hostedGitInfo.fromUrl(data.repository.url) + if (hosted && hosted.docs()) data.homepage = hosted.docs() } + if (!data.homepage) return - // If the lowest version comparator has an operator and our version - // is less than it then it isn't higher than the range - if ((!low.operator || low.operator === comp) && - ltefn(version, low.semver)) { - return false - } else if (low.operator === ecomp && ltfn(version, low.semver)) { - return false + if(typeof data.homepage !== "string") { + this.warn("nonUrlHomepage") + return delete data.homepage + } + if(!url.parse(data.homepage).protocol) { + data.homepage = "http://" + data.homepage } } - return true -} -exports.prerelease = prerelease -function prerelease (version, options) { - var parsed = parse(version, options) - return (parsed && parsed.prerelease.length) ? parsed.prerelease : null +, fixLicenseField: function(data) { + if (!data.license) { + return this.warn("missingLicense") + } else{ + if ( + typeof(data.license) !== 'string' || + data.license.length < 1 || + data.license.trim() === '' + ) { + this.warn("invalidLicense") + } else { + if (!validateLicense(data.license).validForNewPackages) + this.warn("invalidLicense") + } + } + } } -exports.intersects = intersects -function intersects (r1, r2, options) { - r1 = new Range(r1, options) - r2 = new Range(r2, options) - return r1.intersects(r2) -} +function isValidScopedPackageName(spec) { + if (spec.charAt(0) !== '@') return false -exports.coerce = coerce -function coerce (version) { - if (version instanceof SemVer) { - return version - } + var rest = spec.slice(1).split('/') + if (rest.length !== 2) return false - if (typeof version !== 'string') { - return null - } + return rest[0] && rest[1] && + rest[0] === encodeURIComponent(rest[0]) && + rest[1] === encodeURIComponent(rest[1]) +} - var match = version.match(re[COERCE]) +function isCorrectlyEncodedName(spec) { + return !spec.match(/[\/@\s\+%:]/) && + spec === encodeURIComponent(spec) +} - if (match == null) { - return null +function ensureValidName (name, strict, allowLegacyCase) { + if (name.charAt(0) === "." || + !(isValidScopedPackageName(name) || isCorrectlyEncodedName(name)) || + (strict && (!allowLegacyCase) && name !== name.toLowerCase()) || + name.toLowerCase() === "node_modules" || + name.toLowerCase() === "favicon.ico") { + throw new Error("Invalid name: " + JSON.stringify(name)) } - - return parse(match[1] + - '.' + (match[2] || '0') + - '.' + (match[3] || '0')) } +function modifyPeople (data, fn) { + if (data.author) data.author = fn(data.author) + ;["maintainers", "contributors"].forEach(function (set) { + if (!Array.isArray(data[set])) return; + data[set] = data[set].map(fn) + }) + return data +} -/***/ }), -/* 183 */ -/***/ (function(module, exports, __webpack_require__) { - -var parse = __webpack_require__(184); -var correct = __webpack_require__(186); - -var genericWarning = ( - 'license should be ' + - 'a valid SPDX license expression (without "LicenseRef"), ' + - '"UNLICENSED", or ' + - '"SEE LICENSE IN "' -); +function unParsePerson (person) { + if (typeof person === "string") return person + var name = person.name || "" + var u = person.url || person.web + var url = u ? (" ("+u+")") : "" + var e = person.email || person.mail + var email = e ? (" <"+e+">") : "" + return name+email+url +} -var fileReferenceRE = /^SEE LICEN[CS]E IN (.+)$/; +function parsePerson (person) { + if (typeof person !== "string") return person + var name = person.match(/^([^\(<]+)/) + var url = person.match(/\(([^\)]+)\)/) + var email = person.match(/<([^>]+)>/) + var obj = {} + if (name && name[0].trim()) obj.name = name[0].trim() + if (email) obj.email = email[1]; + if (url) obj.url = url[1]; + return obj +} -function startsWith(prefix, string) { - return string.slice(0, prefix.length) === prefix; +function addOptionalDepsToDeps (data, warn) { + var o = data.optionalDependencies + if (!o) return; + var d = data.dependencies || {} + Object.keys(o).forEach(function (k) { + d[k] = o[k] + }) + data.dependencies = d } -function usesLicenseRef(ast) { - if (ast.hasOwnProperty('license')) { - var license = ast.license; - return ( - startsWith('LicenseRef', license) || - startsWith('DocumentRef', license) - ); - } else { - return ( - usesLicenseRef(ast.left) || - usesLicenseRef(ast.right) - ); +function depObjectify (deps, type, warn) { + if (!deps) return {} + if (typeof deps === "string") { + deps = deps.trim().split(/[\n\r\s\t ,]+/) } + if (!Array.isArray(deps)) return deps + warn("deprecatedArrayDependencies", type) + var o = {} + deps.filter(function (d) { + return typeof d === "string" + }).forEach(function(d) { + d = d.trim().split(/(:?[@\s><=])/) + var dn = d.shift() + var dv = d.join("") + dv = dv.trim() + dv = dv.replace(/^@/, "") + o[dn] = dv + }) + return o } -module.exports = function(argument) { - var ast; +function objectifyDeps (data, warn) { + depTypes.forEach(function (type) { + if (!data[type]) return; + data[type] = depObjectify(data[type], type, warn) + }) +} - try { - ast = parse(argument); - } catch (e) { - var match - if ( - argument === 'UNLICENSED' || - argument === 'UNLICENCED' - ) { - return { - validForOldPackages: true, - validForNewPackages: true, - unlicensed: true - }; - } else if (match = fileReferenceRE.exec(argument)) { - return { - validForOldPackages: true, - validForNewPackages: true, - inFile: match[1] - }; - } else { - var result = { - validForOldPackages: false, - validForNewPackages: false, - warnings: [genericWarning] - }; - var corrected = correct(argument); - if (corrected) { - result.warnings.push( - 'license is similar to the valid expression "' + corrected + '"' - ); - } - return result; +function bugsTypos(bugs, warn) { + if (!bugs) return + Object.keys(bugs).forEach(function (k) { + if (typos.bugs[k]) { + warn("typo", k, typos.bugs[k], "bugs") + bugs[typos.bugs[k]] = bugs[k] + delete bugs[k] } - } - - if (usesLicenseRef(ast)) { - return { - validForNewPackages: false, - validForOldPackages: false, - spdx: true, - warnings: [genericWarning] - }; - } else { - return { - validForNewPackages: true, - validForOldPackages: true, - spdx: true - }; - } -}; + }) +} /***/ }), -/* 184 */ -/***/ (function(module, exports, __webpack_require__) { +/* 189 */ +/***/ (function(module, exports) { -var parser = __webpack_require__(185).parser +exports = module.exports = SemVer -module.exports = function (argument) { - return parser.parse(argument) +var debug +/* istanbul ignore next */ +if (typeof process === 'object' && + process.env && + process.env.NODE_DEBUG && + /\bsemver\b/i.test(process.env.NODE_DEBUG)) { + debug = function () { + var args = Array.prototype.slice.call(arguments, 0) + args.unshift('SEMVER') + console.log.apply(console, args) + } +} else { + debug = function () {} } +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0' -/***/ }), -/* 185 */ -/***/ (function(module, exports, __webpack_require__) { +var MAX_LENGTH = 256 +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || + /* istanbul ignore next */ 9007199254740991 -/* WEBPACK VAR INJECTION */(function(module) {/* parser generated by jison 0.4.17 */ -/* - Returns a Parser object of the following structure: +// Max safe segment length for coercion. +var MAX_SAFE_COMPONENT_LENGTH = 16 - Parser: { - yy: {} - } +// The actual regexps go on exports.re +var re = exports.re = [] +var src = exports.src = [] +var R = 0 - Parser.prototype: { - yy: {}, - trace: function(), - symbols_: {associative list: name ==> number}, - terminals_: {associative list: number ==> name}, - productions_: [...], - performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), - table: [...], - defaultActions: {...}, - parseError: function(str, hash), - parse: function(input), +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. - lexer: { - EOF: 1, - parseError: function(str, hash), - setInput: function(input), - input: function(), - unput: function(str), - more: function(), - less: function(n), - pastInput: function(), - upcomingInput: function(), - showPosition: function(), - test_match: function(regex_match_array, rule_index), - next: function(), - lex: function(), - begin: function(condition), - popState: function(), - _currentRules: function(), - topState: function(), - pushState: function(condition), +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. - options: { - ranges: boolean (optional: true ==> token location info will include a .range[] member) - flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) - backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) - }, +var NUMERICIDENTIFIER = R++ +src[NUMERICIDENTIFIER] = '0|[1-9]\\d*' +var NUMERICIDENTIFIERLOOSE = R++ +src[NUMERICIDENTIFIERLOOSE] = '[0-9]+' - performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), - rules: [...], - conditions: {associative list: name ==> set}, - } - } +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. +var NONNUMERICIDENTIFIER = R++ +src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' - token location info (@$, _$, etc.): { - first_line: n, - last_line: n, - first_column: n, - last_column: n, - range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) - } +// ## Main Version +// Three dot-separated numeric identifiers. +var MAINVERSION = R++ +src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')' - the parseError function receives a 'hash' object with these members for lexer and parser errors: { - text: (matched text) - token: (the produced terminal token, if any) - line: (yylineno) - } - while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { - loc: (yylloc) - expected: (string describing the set of expected tokens) - recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) - } -*/ -var spdxparse = (function(){ -var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,6],$V2=[1,7],$V3=[1,4],$V4=[1,9],$V5=[1,10],$V6=[5,14,15,17],$V7=[5,12,14,15,17]; -var parser = {trace: function trace() { }, -yy: {}, -symbols_: {"error":2,"start":3,"expression":4,"EOS":5,"simpleExpression":6,"LICENSE":7,"PLUS":8,"LICENSEREF":9,"DOCUMENTREF":10,"COLON":11,"WITH":12,"EXCEPTION":13,"AND":14,"OR":15,"OPEN":16,"CLOSE":17,"$accept":0,"$end":1}, -terminals_: {2:"error",5:"EOS",7:"LICENSE",8:"PLUS",9:"LICENSEREF",10:"DOCUMENTREF",11:"COLON",12:"WITH",13:"EXCEPTION",14:"AND",15:"OR",16:"OPEN",17:"CLOSE"}, -productions_: [0,[3,2],[6,1],[6,2],[6,1],[6,3],[4,1],[4,3],[4,3],[4,3],[4,3]], -performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { -/* this == yyval */ +var MAINVERSIONLOOSE = R++ +src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')' -var $0 = $$.length - 1; -switch (yystate) { -case 1: -return this.$ = $$[$0-1] -break; -case 2: case 4: case 5: -this.$ = {license: yytext} -break; -case 3: -this.$ = {license: $$[$0-1], plus: true} -break; -case 6: -this.$ = $$[$0] -break; -case 7: -this.$ = {exception: $$[$0]} -this.$.license = $$[$0-2].license -if ($$[$0-2].hasOwnProperty('plus')) { - this.$.plus = $$[$0-2].plus -} -break; -case 8: -this.$ = {conjunction: 'and', left: $$[$0-2], right: $$[$0]} -break; -case 9: -this.$ = {conjunction: 'or', left: $$[$0-2], right: $$[$0]} -break; -case 10: -this.$ = $$[$0-1] -break; -} -}, -table: [{3:1,4:2,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{1:[3]},{5:[1,8],14:$V4,15:$V5},o($V6,[2,6],{12:[1,11]}),{4:12,6:3,7:$V0,9:$V1,10:$V2,16:$V3},o($V7,[2,2],{8:[1,13]}),o($V7,[2,4]),{11:[1,14]},{1:[2,1]},{4:15,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{4:16,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{13:[1,17]},{14:$V4,15:$V5,17:[1,18]},o($V7,[2,3]),{9:[1,19]},o($V6,[2,8]),o([5,15,17],[2,9],{14:$V4}),o($V6,[2,7]),o($V6,[2,10]),o($V7,[2,5])], -defaultActions: {8:[2,1]}, -parseError: function parseError(str, hash) { - if (hash.recoverable) { - this.trace(str); - } else { - function _parseError (msg, hash) { - this.message = msg; - this.hash = hash; - } - _parseError.prototype = Error; +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. - throw new _parseError(str, hash); - } -}, -parse: function parse(input) { - var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; - var args = lstack.slice.call(arguments, 1); - var lexer = Object.create(this.lexer); - var sharedState = { yy: {} }; - for (var k in this.yy) { - if (Object.prototype.hasOwnProperty.call(this.yy, k)) { - sharedState.yy[k] = this.yy[k]; - } - } - lexer.setInput(input, sharedState.yy); - sharedState.yy.lexer = lexer; - sharedState.yy.parser = this; - if (typeof lexer.yylloc == 'undefined') { - lexer.yylloc = {}; - } - var yyloc = lexer.yylloc; - lstack.push(yyloc); - var ranges = lexer.options && lexer.options.ranges; - if (typeof sharedState.yy.parseError === 'function') { - this.parseError = sharedState.yy.parseError; - } else { - this.parseError = Object.getPrototypeOf(this).parseError; - } - function popStack(n) { - stack.length = stack.length - 2 * n; - vstack.length = vstack.length - n; - lstack.length = lstack.length - n; - } - _token_stack: - var lex = function () { - var token; - token = lexer.lex() || EOF; - if (typeof token !== 'number') { - token = self.symbols_[token] || token; - } - return token; - }; - var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; - while (true) { - state = stack[stack.length - 1]; - if (this.defaultActions[state]) { - action = this.defaultActions[state]; - } else { - if (symbol === null || typeof symbol == 'undefined') { - symbol = lex(); - } - action = table[state] && table[state][symbol]; - } - if (typeof action === 'undefined' || !action.length || !action[0]) { - var errStr = ''; - expected = []; - for (p in table[state]) { - if (this.terminals_[p] && p > TERROR) { - expected.push('\'' + this.terminals_[p] + '\''); - } - } - if (lexer.showPosition) { - errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; - } else { - errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); - } - this.parseError(errStr, { - text: lexer.match, - token: this.terminals_[symbol] || symbol, - line: lexer.yylineno, - loc: yyloc, - expected: expected - }); - } - if (action[0] instanceof Array && action.length > 1) { - throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); - } - switch (action[0]) { - case 1: - stack.push(symbol); - vstack.push(lexer.yytext); - lstack.push(lexer.yylloc); - stack.push(action[1]); - symbol = null; - if (!preErrorSymbol) { - yyleng = lexer.yyleng; - yytext = lexer.yytext; - yylineno = lexer.yylineno; - yyloc = lexer.yylloc; - if (recovering > 0) { - recovering--; - } - } else { - symbol = preErrorSymbol; - preErrorSymbol = null; - } - break; - case 2: - len = this.productions_[action[1]][1]; - yyval.$ = vstack[vstack.length - len]; - yyval._$ = { - first_line: lstack[lstack.length - (len || 1)].first_line, - last_line: lstack[lstack.length - 1].last_line, - first_column: lstack[lstack.length - (len || 1)].first_column, - last_column: lstack[lstack.length - 1].last_column - }; - if (ranges) { - yyval._$.range = [ - lstack[lstack.length - (len || 1)].range[0], - lstack[lstack.length - 1].range[1] - ]; - } - r = this.performAction.apply(yyval, [ - yytext, - yyleng, - yylineno, - sharedState.yy, - action[1], - vstack, - lstack - ].concat(args)); - if (typeof r !== 'undefined') { - return r; - } - if (len) { - stack = stack.slice(0, -1 * len * 2); - vstack = vstack.slice(0, -1 * len); - lstack = lstack.slice(0, -1 * len); - } - stack.push(this.productions_[action[1]][0]); - vstack.push(yyval.$); - lstack.push(yyval._$); - newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; - stack.push(newState); - break; - case 3: - return true; - } - } - return true; -}}; -/* generated by jison-lex 0.3.4 */ -var lexer = (function(){ -var lexer = ({ +var PRERELEASEIDENTIFIER = R++ +src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + + '|' + src[NONNUMERICIDENTIFIER] + ')' -EOF:1, +var PRERELEASEIDENTIFIERLOOSE = R++ +src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + + '|' + src[NONNUMERICIDENTIFIER] + ')' -parseError:function parseError(str, hash) { - if (this.yy.parser) { - this.yy.parser.parseError(str, hash); - } else { - throw new Error(str); - } - }, +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. -// resets the lexer, sets new input -setInput:function (input, yy) { - this.yy = yy || this.yy || {}; - this._input = input; - this._more = this._backtrack = this.done = false; - this.yylineno = this.yyleng = 0; - this.yytext = this.matched = this.match = ''; - this.conditionStack = ['INITIAL']; - this.yylloc = { - first_line: 1, - first_column: 0, - last_line: 1, - last_column: 0 - }; - if (this.options.ranges) { - this.yylloc.range = [0,0]; - } - this.offset = 0; - return this; - }, +var PRERELEASE = R++ +src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))' -// consumes and returns one char from the input -input:function () { - var ch = this._input[0]; - this.yytext += ch; - this.yyleng++; - this.offset++; - this.match += ch; - this.matched += ch; - var lines = ch.match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno++; - this.yylloc.last_line++; - } else { - this.yylloc.last_column++; - } - if (this.options.ranges) { - this.yylloc.range[1]++; - } +var PRERELEASELOOSE = R++ +src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))' - this._input = this._input.slice(1); - return ch; - }, +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. -// unshifts one char (or a string) into the input -unput:function (ch) { - var len = ch.length; - var lines = ch.split(/(?:\r\n?|\n)/g); +var BUILDIDENTIFIER = R++ +src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+' - this._input = ch + this._input; - this.yytext = this.yytext.substr(0, this.yytext.length - len); - //this.yyleng -= len; - this.offset -= len; - var oldLines = this.match.split(/(?:\r\n?|\n)/g); - this.match = this.match.substr(0, this.match.length - 1); - this.matched = this.matched.substr(0, this.matched.length - 1); +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. - if (lines.length - 1) { - this.yylineno -= lines.length - 1; - } - var r = this.yylloc.range; +var BUILD = R++ +src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))' - this.yylloc = { - first_line: this.yylloc.first_line, - last_line: this.yylineno + 1, - first_column: this.yylloc.first_column, - last_column: lines ? - (lines.length === oldLines.length ? this.yylloc.first_column : 0) - + oldLines[oldLines.length - lines.length].length - lines[0].length : - this.yylloc.first_column - len - }; +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. - if (this.options.ranges) { - this.yylloc.range = [r[0], r[0] + this.yyleng - len]; - } - this.yyleng = this.yytext.length; - return this; - }, +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. -// When called from action, caches matched text and appends it on next action -more:function () { - this._more = true; - return this; - }, +var FULL = R++ +var FULLPLAIN = 'v?' + src[MAINVERSION] + + src[PRERELEASE] + '?' + + src[BUILD] + '?' -// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. -reject:function () { - if (this.options.backtrack_lexer) { - this._backtrack = true; - } else { - return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { - text: "", - token: null, - line: this.yylineno - }); +src[FULL] = '^' + FULLPLAIN + '$' - } - return this; - }, +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + + src[PRERELEASELOOSE] + '?' + + src[BUILD] + '?' -// retain first n characters of the match -less:function (n) { - this.unput(this.match.slice(n)); - }, +var LOOSE = R++ +src[LOOSE] = '^' + LOOSEPLAIN + '$' -// displays already matched input, i.e. for error messages -pastInput:function () { - var past = this.matched.substr(0, this.matched.length - this.match.length); - return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); - }, +var GTLT = R++ +src[GTLT] = '((?:<|>)?=?)' -// displays upcoming input, i.e. for error messages -upcomingInput:function () { - var next = this.match; - if (next.length < 20) { - next += this._input.substr(0, 20-next.length); - } - return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); - }, +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +var XRANGEIDENTIFIERLOOSE = R++ +src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' +var XRANGEIDENTIFIER = R++ +src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*' -// displays the character position where the lexing error occurred, i.e. for error messages -showPosition:function () { - var pre = this.pastInput(); - var c = new Array(pre.length + 1).join("-"); - return pre + this.upcomingInput() + "\n" + c + "^"; - }, +var XRANGEPLAIN = R++ +src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:' + src[PRERELEASE] + ')?' + + src[BUILD] + '?' + + ')?)?' -// test the lexed token: return FALSE when not a match, otherwise return token -test_match:function (match, indexed_rule) { - var token, - lines, - backup; +var XRANGEPLAINLOOSE = R++ +src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[PRERELEASELOOSE] + ')?' + + src[BUILD] + '?' + + ')?)?' - if (this.options.backtrack_lexer) { - // save context - backup = { - yylineno: this.yylineno, - yylloc: { - first_line: this.yylloc.first_line, - last_line: this.last_line, - first_column: this.yylloc.first_column, - last_column: this.yylloc.last_column - }, - yytext: this.yytext, - match: this.match, - matches: this.matches, - matched: this.matched, - yyleng: this.yyleng, - offset: this.offset, - _more: this._more, - _input: this._input, - yy: this.yy, - conditionStack: this.conditionStack.slice(0), - done: this.done - }; - if (this.options.ranges) { - backup.yylloc.range = this.yylloc.range.slice(0); - } - } +var XRANGE = R++ +src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$' +var XRANGELOOSE = R++ +src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$' - lines = match[0].match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno += lines.length; - } - this.yylloc = { - first_line: this.yylloc.last_line, - last_line: this.yylineno + 1, - first_column: this.yylloc.last_column, - last_column: lines ? - lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : - this.yylloc.last_column + match[0].length - }; - this.yytext += match[0]; - this.match += match[0]; - this.matches = match; - this.yyleng = this.yytext.length; - if (this.options.ranges) { - this.yylloc.range = [this.offset, this.offset += this.yyleng]; - } - this._more = false; - this._backtrack = false; - this._input = this._input.slice(match[0].length); - this.matched += match[0]; - token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); - if (this.done && this._input) { - this.done = false; - } - if (token) { - return token; - } else if (this._backtrack) { - // recover context - for (var k in backup) { - this[k] = backup[k]; - } - return false; // rule action called reject() implying the next rule should be tested instead. - } - return false; - }, +// Coercion. +// Extract anything that could conceivably be a part of a valid semver +var COERCE = R++ +src[COERCE] = '(?:^|[^\\d])' + + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:$|[^\\d])' -// return next match in input -next:function () { - if (this.done) { - return this.EOF; - } - if (!this._input) { - this.done = true; - } +// Tilde ranges. +// Meaning is "reasonably at or greater than" +var LONETILDE = R++ +src[LONETILDE] = '(?:~>?)' - var token, - match, - tempMatch, - index; - if (!this._more) { - this.yytext = ''; - this.match = ''; - } - var rules = this._currentRules(); - for (var i = 0; i < rules.length; i++) { - tempMatch = this._input.match(this.rules[rules[i]]); - if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { - match = tempMatch; - index = i; - if (this.options.backtrack_lexer) { - token = this.test_match(tempMatch, rules[i]); - if (token !== false) { - return token; - } else if (this._backtrack) { - match = false; - continue; // rule action called reject() implying a rule MISmatch. - } else { - // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) - return false; - } - } else if (!this.options.flex) { - break; - } - } - } - if (match) { - token = this.test_match(match, rules[index]); - if (token !== false) { - return token; - } - // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) - return false; - } - if (this._input === "") { - return this.EOF; - } else { - return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { - text: "", - token: null, - line: this.yylineno - }); - } - }, +var TILDETRIM = R++ +src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+' +re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g') +var tildeTrimReplace = '$1~' -// return next match that has a token -lex:function lex() { - var r = this.next(); - if (r) { - return r; - } else { - return this.lex(); - } - }, +var TILDE = R++ +src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$' +var TILDELOOSE = R++ +src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$' -// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) -begin:function begin(condition) { - this.conditionStack.push(condition); - }, +// Caret ranges. +// Meaning is "at least and backwards compatible with" +var LONECARET = R++ +src[LONECARET] = '(?:\\^)' -// pop the previously active lexer condition state off the condition stack -popState:function popState() { - var n = this.conditionStack.length - 1; - if (n > 0) { - return this.conditionStack.pop(); - } else { - return this.conditionStack[0]; - } - }, +var CARETTRIM = R++ +src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+' +re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g') +var caretTrimReplace = '$1^' -// produce the lexer rule set which is active for the currently active lexer condition state -_currentRules:function _currentRules() { - if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { - return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; - } else { - return this.conditions["INITIAL"].rules; - } - }, +var CARET = R++ +src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$' +var CARETLOOSE = R++ +src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$' -// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available -topState:function topState(n) { - n = this.conditionStack.length - 1 - Math.abs(n || 0); - if (n >= 0) { - return this.conditionStack[n]; - } else { - return "INITIAL"; +// A simple gt/lt/eq thing, or just "" to indicate "any version" +var COMPARATORLOOSE = R++ +src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$' +var COMPARATOR = R++ +src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$' + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +var COMPARATORTRIM = R++ +src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')' + +// this one has to use the /g flag +re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g') +var comparatorTrimReplace = '$1$2$3' + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +var HYPHENRANGE = R++ +src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAIN] + ')' + + '\\s*$' + +var HYPHENRANGELOOSE = R++ +src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s*$' + +// Star ranges basically just allow anything at all. +var STAR = R++ +src[STAR] = '(<|>)?=?\\s*\\*' + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]) + if (!re[i]) { + re[i] = new RegExp(src[i]) + } +} + +exports.parse = parse +function parse (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (version instanceof SemVer) { + return version + } + + if (typeof version !== 'string') { + return null + } + + if (version.length > MAX_LENGTH) { + return null + } + + var r = options.loose ? re[LOOSE] : re[FULL] + if (!r.test(version)) { + return null + } + + try { + return new SemVer(version, options) + } catch (er) { + return null + } +} + +exports.valid = valid +function valid (version, options) { + var v = parse(version, options) + return v ? v.version : null +} + +exports.clean = clean +function clean (version, options) { + var s = parse(version.trim().replace(/^[=v]+/, ''), options) + return s ? s.version : null +} + +exports.SemVer = SemVer + +function SemVer (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + if (version instanceof SemVer) { + if (version.loose === options.loose) { + return version + } else { + version = version.version + } + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version) + } + + if (version.length > MAX_LENGTH) { + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') + } + + if (!(this instanceof SemVer)) { + return new SemVer(version, options) + } + + debug('SemVer', version, options) + this.options = options + this.loose = !!options.loose + + var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL]) + + if (!m) { + throw new TypeError('Invalid Version: ' + version) + } + + this.raw = version + + // these are actually numbers + this.major = +m[1] + this.minor = +m[2] + this.patch = +m[3] + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version') + } + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version') + } + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version') + } + + // numberify any prerelease numeric ids + if (!m[4]) { + this.prerelease = [] + } else { + this.prerelease = m[4].split('.').map(function (id) { + if (/^[0-9]+$/.test(id)) { + var num = +id + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num } - }, + } + return id + }) + } -// alias for begin(condition) -pushState:function pushState(condition) { - this.begin(condition); - }, + this.build = m[5] ? m[5].split('.') : [] + this.format() +} -// return the number of states currently on the stack -stateStackSize:function stateStackSize() { - return this.conditionStack.length; - }, -options: {}, -performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { -var YYSTATE=YY_START; -switch($avoiding_name_collisions) { -case 0:return 5 -break; -case 1:/* skip whitespace */ -break; -case 2:return 8 -break; -case 3:return 16 -break; -case 4:return 17 -break; -case 5:return 11 -break; -case 6:return 10 -break; -case 7:return 9 -break; -case 8:return 14 -break; -case 9:return 15 -break; -case 10:return 12 -break; -case 11:return 7 -break; -case 12:return 7 -break; -case 13:return 7 -break; -case 14:return 7 -break; -case 15:return 7 -break; -case 16:return 7 -break; -case 17:return 7 -break; -case 18:return 7 -break; -case 19:return 7 -break; -case 20:return 7 -break; -case 21:return 7 -break; -case 22:return 7 -break; -case 23:return 7 -break; -case 24:return 13 -break; -case 25:return 13 -break; -case 26:return 13 -break; -case 27:return 13 -break; -case 28:return 13 -break; -case 29:return 13 -break; -case 30:return 13 -break; -case 31:return 13 -break; -case 32:return 7 -break; -case 33:return 13 -break; -case 34:return 7 -break; -case 35:return 13 -break; -case 36:return 7 -break; -case 37:return 13 -break; -case 38:return 13 -break; +SemVer.prototype.format = function () { + this.version = this.major + '.' + this.minor + '.' + this.patch + if (this.prerelease.length) { + this.version += '-' + this.prerelease.join('.') + } + return this.version +} + +SemVer.prototype.toString = function () { + return this.version +} + +SemVer.prototype.compare = function (other) { + debug('SemVer.compare', this.version, this.options, other) + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return this.compareMain(other) || this.comparePre(other) +} + +SemVer.prototype.compareMain = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch) +} + +SemVer.prototype.comparePre = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) { + return -1 + } else if (!this.prerelease.length && other.prerelease.length) { + return 1 + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0 + } + + var i = 0 + do { + var a = this.prerelease[i] + var b = other.prerelease[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) +} + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function (release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0 + this.patch = 0 + this.minor = 0 + this.major++ + this.inc('pre', identifier) + break + case 'preminor': + this.prerelease.length = 0 + this.patch = 0 + this.minor++ + this.inc('pre', identifier) + break + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0 + this.inc('patch', identifier) + this.inc('pre', identifier) + break + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) { + this.inc('patch', identifier) + } + this.inc('pre', identifier) + break + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || + this.patch !== 0 || + this.prerelease.length === 0) { + this.major++ + } + this.minor = 0 + this.patch = 0 + this.prerelease = [] + break + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++ + } + this.patch = 0 + this.prerelease = [] + break + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) { + this.patch++ + } + this.prerelease = [] + break + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) { + this.prerelease = [0] + } else { + var i = this.prerelease.length + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++ + i = -2 + } + } + if (i === -1) { + // didn't increment anything + this.prerelease.push(0) + } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) { + this.prerelease = [identifier, 0] + } + } else { + this.prerelease = [identifier, 0] + } + } + break + + default: + throw new Error('invalid increment argument: ' + release) + } + this.format() + this.raw = this.version + return this +} + +exports.inc = inc +function inc (version, release, loose, identifier) { + if (typeof (loose) === 'string') { + identifier = loose + loose = undefined + } + + try { + return new SemVer(version, loose).inc(release, identifier).version + } catch (er) { + return null + } +} + +exports.diff = diff +function diff (version1, version2) { + if (eq(version1, version2)) { + return null + } else { + var v1 = parse(version1) + var v2 = parse(version2) + var prefix = '' + if (v1.prerelease.length || v2.prerelease.length) { + prefix = 'pre' + var defaultResult = 'prerelease' + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return prefix + key + } + } + } + return defaultResult // may be undefined + } +} + +exports.compareIdentifiers = compareIdentifiers + +var numeric = /^[0-9]+$/ +function compareIdentifiers (a, b) { + var anum = numeric.test(a) + var bnum = numeric.test(b) + + if (anum && bnum) { + a = +a + b = +b + } + + return a === b ? 0 + : (anum && !bnum) ? -1 + : (bnum && !anum) ? 1 + : a < b ? -1 + : 1 +} + +exports.rcompareIdentifiers = rcompareIdentifiers +function rcompareIdentifiers (a, b) { + return compareIdentifiers(b, a) +} + +exports.major = major +function major (a, loose) { + return new SemVer(a, loose).major +} + +exports.minor = minor +function minor (a, loose) { + return new SemVer(a, loose).minor +} + +exports.patch = patch +function patch (a, loose) { + return new SemVer(a, loose).patch +} + +exports.compare = compare +function compare (a, b, loose) { + return new SemVer(a, loose).compare(new SemVer(b, loose)) +} + +exports.compareLoose = compareLoose +function compareLoose (a, b) { + return compare(a, b, true) +} + +exports.rcompare = rcompare +function rcompare (a, b, loose) { + return compare(b, a, loose) +} + +exports.sort = sort +function sort (list, loose) { + return list.sort(function (a, b) { + return exports.compare(a, b, loose) + }) +} + +exports.rsort = rsort +function rsort (list, loose) { + return list.sort(function (a, b) { + return exports.rcompare(a, b, loose) + }) +} + +exports.gt = gt +function gt (a, b, loose) { + return compare(a, b, loose) > 0 +} + +exports.lt = lt +function lt (a, b, loose) { + return compare(a, b, loose) < 0 +} + +exports.eq = eq +function eq (a, b, loose) { + return compare(a, b, loose) === 0 +} + +exports.neq = neq +function neq (a, b, loose) { + return compare(a, b, loose) !== 0 +} + +exports.gte = gte +function gte (a, b, loose) { + return compare(a, b, loose) >= 0 +} + +exports.lte = lte +function lte (a, b, loose) { + return compare(a, b, loose) <= 0 +} + +exports.cmp = cmp +function cmp (a, op, b, loose) { + switch (op) { + case '===': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a === b + + case '!==': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a !== b + + case '': + case '=': + case '==': + return eq(a, b, loose) + + case '!=': + return neq(a, b, loose) + + case '>': + return gt(a, b, loose) + + case '>=': + return gte(a, b, loose) + + case '<': + return lt(a, b, loose) + + case '<=': + return lte(a, b, loose) + + default: + throw new TypeError('Invalid operator: ' + op) + } +} + +exports.Comparator = Comparator +function Comparator (comp, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp + } else { + comp = comp.value + } + } + + if (!(this instanceof Comparator)) { + return new Comparator(comp, options) + } + + debug('comparator', comp, options) + this.options = options + this.loose = !!options.loose + this.parse(comp) + + if (this.semver === ANY) { + this.value = '' + } else { + this.value = this.operator + this.semver.version + } + + debug('comp', this) +} + +var ANY = {} +Comparator.prototype.parse = function (comp) { + var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR] + var m = comp.match(r) + + if (!m) { + throw new TypeError('Invalid comparator: ' + comp) + } + + this.operator = m[1] + if (this.operator === '=') { + this.operator = '' + } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) { + this.semver = ANY + } else { + this.semver = new SemVer(m[2], this.options.loose) + } +} + +Comparator.prototype.toString = function () { + return this.value +} + +Comparator.prototype.test = function (version) { + debug('Comparator.test', version, this.options.loose) + + if (this.semver === ANY) { + return true + } + + if (typeof version === 'string') { + version = new SemVer(version, this.options) + } + + return cmp(version, this.operator, this.semver, this.options) +} + +Comparator.prototype.intersects = function (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required') + } + + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + var rangeTmp + + if (this.operator === '') { + rangeTmp = new Range(comp.value, options) + return satisfies(this.value, rangeTmp, options) + } else if (comp.operator === '') { + rangeTmp = new Range(this.value, options) + return satisfies(comp.semver, rangeTmp, options) + } + + var sameDirectionIncreasing = + (this.operator === '>=' || this.operator === '>') && + (comp.operator === '>=' || comp.operator === '>') + var sameDirectionDecreasing = + (this.operator === '<=' || this.operator === '<') && + (comp.operator === '<=' || comp.operator === '<') + var sameSemVer = this.semver.version === comp.semver.version + var differentDirectionsInclusive = + (this.operator === '>=' || this.operator === '<=') && + (comp.operator === '>=' || comp.operator === '<=') + var oppositeDirectionsLessThan = + cmp(this.semver, '<', comp.semver, options) && + ((this.operator === '>=' || this.operator === '>') && + (comp.operator === '<=' || comp.operator === '<')) + var oppositeDirectionsGreaterThan = + cmp(this.semver, '>', comp.semver, options) && + ((this.operator === '<=' || this.operator === '<') && + (comp.operator === '>=' || comp.operator === '>')) + + return sameDirectionIncreasing || sameDirectionDecreasing || + (sameSemVer && differentDirectionsInclusive) || + oppositeDirectionsLessThan || oppositeDirectionsGreaterThan +} + +exports.Range = Range +function Range (range, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (range instanceof Range) { + if (range.loose === !!options.loose && + range.includePrerelease === !!options.includePrerelease) { + return range + } else { + return new Range(range.raw, options) + } + } + + if (range instanceof Comparator) { + return new Range(range.value, options) + } + + if (!(this instanceof Range)) { + return new Range(range, options) + } + + this.options = options + this.loose = !!options.loose + this.includePrerelease = !!options.includePrerelease + + // First, split based on boolean or || + this.raw = range + this.set = range.split(/\s*\|\|\s*/).map(function (range) { + return this.parseRange(range.trim()) + }, this).filter(function (c) { + // throw out any that are not relevant for whatever reason + return c.length + }) + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range) + } + + this.format() +} + +Range.prototype.format = function () { + this.range = this.set.map(function (comps) { + return comps.join(' ').trim() + }).join('||').trim() + return this.range +} + +Range.prototype.toString = function () { + return this.range +} + +Range.prototype.parseRange = function (range) { + var loose = this.options.loose + range = range.trim() + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE] + range = range.replace(hr, hyphenReplace) + debug('hyphen replace', range) + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace) + debug('comparator trim', range, re[COMPARATORTRIM]) + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[TILDETRIM], tildeTrimReplace) + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace) + + // normalize spaces + range = range.split(/\s+/).join(' ') + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR] + var set = range.split(' ').map(function (comp) { + return parseComparator(comp, this.options) + }, this).join(' ').split(/\s+/) + if (this.options.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function (comp) { + return !!comp.match(compRe) + }) + } + set = set.map(function (comp) { + return new Comparator(comp, this.options) + }, this) + + return set +} + +Range.prototype.intersects = function (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required') + } + + return this.set.some(function (thisComparators) { + return thisComparators.every(function (thisComparator) { + return range.set.some(function (rangeComparators) { + return rangeComparators.every(function (rangeComparator) { + return thisComparator.intersects(rangeComparator, options) + }) + }) + }) + }) +} + +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators +function toComparators (range, options) { + return new Range(range, options).set.map(function (comp) { + return comp.map(function (c) { + return c.value + }).join(' ').trim().split(' ') + }) +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator (comp, options) { + debug('comp', comp, options) + comp = replaceCarets(comp, options) + debug('caret', comp) + comp = replaceTildes(comp, options) + debug('tildes', comp) + comp = replaceXRanges(comp, options) + debug('xrange', comp) + comp = replaceStars(comp, options) + debug('stars', comp) + return comp +} + +function isX (id) { + return !id || id.toLowerCase() === 'x' || id === '*' +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceTilde(comp, options) + }).join(' ') +} + +function replaceTilde (comp, options) { + var r = options.loose ? re[TILDELOOSE] : re[TILDE] + return comp.replace(r, function (_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else if (pr) { + debug('replaceTilde pr', pr) + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } else { + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + + debug('tilde return', ret) + return ret + }) +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceCaret(comp, options) + }).join(' ') +} + +function replaceCaret (comp, options) { + debug('caret', comp, options) + var r = options.loose ? re[CARETLOOSE] : re[CARET] + return comp.replace(r, function (_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + if (M === '0') { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else { + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' + } + } else if (pr) { + debug('replaceCaret pr', pr) + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + (+M + 1) + '.0.0' + } + } else { + debug('no pr') + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0' + } + } + + debug('caret return', ret) + return ret + }) +} + +function replaceXRanges (comp, options) { + debug('replaceXRanges', comp, options) + return comp.split(/\s+/).map(function (comp) { + return replaceXRange(comp, options) + }).join(' ') +} + +function replaceXRange (comp, options) { + comp = comp.trim() + var r = options.loose ? re[XRANGELOOSE] : re[XRANGE] + return comp.replace(r, function (ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr) + var xM = isX(M) + var xm = xM || isX(m) + var xp = xm || isX(p) + var anyX = xp + + if (gtlt === '=' && anyX) { + gtlt = '' + } + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0' + } else { + // nothing is forbidden + ret = '*' + } + } else if (gtlt && anyX) { + // we know patch is an x, because we have any x at all. + // replace X with 0 + if (xm) { + m = 0 + } + p = 0 + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>=' + if (xm) { + M = +M + 1 + m = 0 + p = 0 + } else { + m = +m + 1 + p = 0 + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) { + M = +M + 1 + } else { + m = +m + 1 + } + } + + ret = gtlt + M + '.' + m + '.' + p + } else if (xm) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (xp) { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } + + debug('xRange return', ret) + + return ret + }) +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars (comp, options) { + debug('replaceStars', comp, options) + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[STAR], '') +} + +// This function is passed to string.replace(re[HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + if (isX(fM)) { + from = '' + } else if (isX(fm)) { + from = '>=' + fM + '.0.0' + } else if (isX(fp)) { + from = '>=' + fM + '.' + fm + '.0' + } else { + from = '>=' + from + } + + if (isX(tM)) { + to = '' + } else if (isX(tm)) { + to = '<' + (+tM + 1) + '.0.0' + } else if (isX(tp)) { + to = '<' + tM + '.' + (+tm + 1) + '.0' + } else if (tpr) { + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr + } else { + to = '<=' + to + } + + return (from + ' ' + to).trim() +} + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function (version) { + if (!version) { + return false + } + + if (typeof version === 'string') { + version = new SemVer(version, this.options) + } + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } + } + return false +} + +function testSet (set, version, options) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false + } + } + + if (version.prerelease.length && !options.includePrerelease) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (i = 0; i < set.length; i++) { + debug(set[i].semver) + if (set[i].semver === ANY) { + continue + } + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false + } + + return true +} + +exports.satisfies = satisfies +function satisfies (version, range, options) { + try { + range = new Range(range, options) + } catch (er) { + return false + } + return range.test(version) +} + +exports.maxSatisfying = maxSatisfying +function maxSatisfying (versions, range, options) { + var max = null + var maxSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v + maxSV = new SemVer(max, options) + } + } + }) + return max +} + +exports.minSatisfying = minSatisfying +function minSatisfying (versions, range, options) { + var min = null + var minSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v + minSV = new SemVer(min, options) + } + } + }) + return min +} + +exports.minVersion = minVersion +function minVersion (range, loose) { + range = new Range(range, loose) + + var minver = new SemVer('0.0.0') + if (range.test(minver)) { + return minver + } + + minver = new SemVer('0.0.0-0') + if (range.test(minver)) { + return minver + } + + minver = null + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + comparators.forEach(function (comparator) { + // Clone to avoid manipulating the comparator's semver object. + var compver = new SemVer(comparator.semver.version) + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++ + } else { + compver.prerelease.push(0) + } + compver.raw = compver.format() + /* fallthrough */ + case '': + case '>=': + if (!minver || gt(minver, compver)) { + minver = compver + } + break + case '<': + case '<=': + /* Ignore maximum versions */ + break + /* istanbul ignore next */ + default: + throw new Error('Unexpected operation: ' + comparator.operator) + } + }) + } + + if (minver && range.test(minver)) { + return minver + } + + return null +} + +exports.validRange = validRange +function validRange (range, options) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*' + } catch (er) { + return null + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr +function ltr (version, range, options) { + return outside(version, range, '<', options) +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr +function gtr (version, range, options) { + return outside(version, range, '>', options) +} + +exports.outside = outside +function outside (version, range, hilo, options) { + version = new SemVer(version, options) + range = new Range(range, options) + + var gtfn, ltefn, ltfn, comp, ecomp + switch (hilo) { + case '>': + gtfn = gt + ltefn = lte + ltfn = lt + comp = '>' + ecomp = '>=' + break + case '<': + gtfn = lt + ltefn = gte + ltfn = gt + comp = '<' + ecomp = '<=' + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, options)) { + return false + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + var high = null + var low = null + + comparators.forEach(function (comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator + low = low || comparator + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator + } + }) + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true +} + +exports.prerelease = prerelease +function prerelease (version, options) { + var parsed = parse(version, options) + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null +} + +exports.intersects = intersects +function intersects (r1, r2, options) { + r1 = new Range(r1, options) + r2 = new Range(r2, options) + return r1.intersects(r2) +} + +exports.coerce = coerce +function coerce (version) { + if (version instanceof SemVer) { + return version + } + + if (typeof version !== 'string') { + return null + } + + var match = version.match(re[COERCE]) + + if (match == null) { + return null + } + + return parse(match[1] + + '.' + (match[2] || '0') + + '.' + (match[3] || '0')) +} + + +/***/ }), +/* 190 */ +/***/ (function(module, exports, __webpack_require__) { + +var parse = __webpack_require__(191); +var correct = __webpack_require__(193); + +var genericWarning = ( + 'license should be ' + + 'a valid SPDX license expression (without "LicenseRef"), ' + + '"UNLICENSED", or ' + + '"SEE LICENSE IN "' +); + +var fileReferenceRE = /^SEE LICEN[CS]E IN (.+)$/; + +function startsWith(prefix, string) { + return string.slice(0, prefix.length) === prefix; +} + +function usesLicenseRef(ast) { + if (ast.hasOwnProperty('license')) { + var license = ast.license; + return ( + startsWith('LicenseRef', license) || + startsWith('DocumentRef', license) + ); + } else { + return ( + usesLicenseRef(ast.left) || + usesLicenseRef(ast.right) + ); + } +} + +module.exports = function(argument) { + var ast; + + try { + ast = parse(argument); + } catch (e) { + var match + if ( + argument === 'UNLICENSED' || + argument === 'UNLICENCED' + ) { + return { + validForOldPackages: true, + validForNewPackages: true, + unlicensed: true + }; + } else if (match = fileReferenceRE.exec(argument)) { + return { + validForOldPackages: true, + validForNewPackages: true, + inFile: match[1] + }; + } else { + var result = { + validForOldPackages: false, + validForNewPackages: false, + warnings: [genericWarning] + }; + var corrected = correct(argument); + if (corrected) { + result.warnings.push( + 'license is similar to the valid expression "' + corrected + '"' + ); + } + return result; + } + } + + if (usesLicenseRef(ast)) { + return { + validForNewPackages: false, + validForOldPackages: false, + spdx: true, + warnings: [genericWarning] + }; + } else { + return { + validForNewPackages: true, + validForOldPackages: true, + spdx: true + }; + } +}; + + +/***/ }), +/* 191 */ +/***/ (function(module, exports, __webpack_require__) { + +var parser = __webpack_require__(192).parser + +module.exports = function (argument) { + return parser.parse(argument) +} + + +/***/ }), +/* 192 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(module) {/* parser generated by jison 0.4.17 */ +/* + Returns a Parser object of the following structure: + + Parser: { + yy: {} + } + + Parser.prototype: { + yy: {}, + trace: function(), + symbols_: {associative list: name ==> number}, + terminals_: {associative list: number ==> name}, + productions_: [...], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), + table: [...], + defaultActions: {...}, + parseError: function(str, hash), + parse: function(input), + + lexer: { + EOF: 1, + parseError: function(str, hash), + setInput: function(input), + input: function(), + unput: function(str), + more: function(), + less: function(n), + pastInput: function(), + upcomingInput: function(), + showPosition: function(), + test_match: function(regex_match_array, rule_index), + next: function(), + lex: function(), + begin: function(condition), + popState: function(), + _currentRules: function(), + topState: function(), + pushState: function(condition), + + options: { + ranges: boolean (optional: true ==> token location info will include a .range[] member) + flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) + backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) + }, + + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), + rules: [...], + conditions: {associative list: name ==> set}, + } + } + + + token location info (@$, _$, etc.): { + first_line: n, + last_line: n, + first_column: n, + last_column: n, + range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) + } + + + the parseError function receives a 'hash' object with these members for lexer and parser errors: { + text: (matched text) + token: (the produced terminal token, if any) + line: (yylineno) + } + while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { + loc: (yylloc) + expected: (string describing the set of expected tokens) + recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) + } +*/ +var spdxparse = (function(){ +var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,6],$V2=[1,7],$V3=[1,4],$V4=[1,9],$V5=[1,10],$V6=[5,14,15,17],$V7=[5,12,14,15,17]; +var parser = {trace: function trace() { }, +yy: {}, +symbols_: {"error":2,"start":3,"expression":4,"EOS":5,"simpleExpression":6,"LICENSE":7,"PLUS":8,"LICENSEREF":9,"DOCUMENTREF":10,"COLON":11,"WITH":12,"EXCEPTION":13,"AND":14,"OR":15,"OPEN":16,"CLOSE":17,"$accept":0,"$end":1}, +terminals_: {2:"error",5:"EOS",7:"LICENSE",8:"PLUS",9:"LICENSEREF",10:"DOCUMENTREF",11:"COLON",12:"WITH",13:"EXCEPTION",14:"AND",15:"OR",16:"OPEN",17:"CLOSE"}, +productions_: [0,[3,2],[6,1],[6,2],[6,1],[6,3],[4,1],[4,3],[4,3],[4,3],[4,3]], +performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { +/* this == yyval */ + +var $0 = $$.length - 1; +switch (yystate) { +case 1: +return this.$ = $$[$0-1] +break; +case 2: case 4: case 5: +this.$ = {license: yytext} +break; +case 3: +this.$ = {license: $$[$0-1], plus: true} +break; +case 6: +this.$ = $$[$0] +break; +case 7: +this.$ = {exception: $$[$0]} +this.$.license = $$[$0-2].license +if ($$[$0-2].hasOwnProperty('plus')) { + this.$.plus = $$[$0-2].plus +} +break; +case 8: +this.$ = {conjunction: 'and', left: $$[$0-2], right: $$[$0]} +break; +case 9: +this.$ = {conjunction: 'or', left: $$[$0-2], right: $$[$0]} +break; +case 10: +this.$ = $$[$0-1] +break; +} +}, +table: [{3:1,4:2,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{1:[3]},{5:[1,8],14:$V4,15:$V5},o($V6,[2,6],{12:[1,11]}),{4:12,6:3,7:$V0,9:$V1,10:$V2,16:$V3},o($V7,[2,2],{8:[1,13]}),o($V7,[2,4]),{11:[1,14]},{1:[2,1]},{4:15,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{4:16,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{13:[1,17]},{14:$V4,15:$V5,17:[1,18]},o($V7,[2,3]),{9:[1,19]},o($V6,[2,8]),o([5,15,17],[2,9],{14:$V4}),o($V6,[2,7]),o($V6,[2,10]),o($V7,[2,5])], +defaultActions: {8:[2,1]}, +parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + function _parseError (msg, hash) { + this.message = msg; + this.hash = hash; + } + _parseError.prototype = Error; + + throw new _parseError(str, hash); + } +}, +parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer; + sharedState.yy.parser = this; + if (typeof lexer.yylloc == 'undefined') { + lexer.yylloc = {}; + } + var yyloc = lexer.yylloc; + lstack.push(yyloc); + var ranges = lexer.options && lexer.options.ranges; + if (typeof sharedState.yy.parseError === 'function') { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + _token_stack: + var lex = function () { + var token; + token = lexer.lex() || EOF; + if (typeof token !== 'number') { + token = self.symbols_[token] || token; + } + return token; + }; + var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == 'undefined') { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push('\'' + this.terminals_[p] + '\''); + } + } + if (lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; + } else { + errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); + } + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer.yytext); + lstack.push(lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = lexer.yyleng; + yytext = lexer.yytext; + yylineno = lexer.yylineno; + yyloc = lexer.yylloc; + if (recovering > 0) { + recovering--; + } + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== 'undefined') { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; +}}; +/* generated by jison-lex 0.3.4 */ +var lexer = (function(){ +var lexer = ({ + +EOF:1, + +parseError:function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + +// resets the lexer, sets new input +setInput:function (input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0,0]; + } + this.offset = 0; + return this; + }, + +// consumes and returns one char from the input +input:function () { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + + this._input = this._input.slice(1); + return ch; + }, + +// unshifts one char (or a string) into the input +unput:function (ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? + (lines.length === oldLines.length ? this.yylloc.first_column : 0) + + oldLines[oldLines.length - lines.length].length - lines[0].length : + this.yylloc.first_column - len + }; + + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + +// When called from action, caches matched text and appends it on next action +more:function () { + this._more = true; + return this; + }, + +// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. +reject:function () { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + + } + return this; + }, + +// retain first n characters of the match +less:function (n) { + this.unput(this.match.slice(n)); + }, + +// displays already matched input, i.e. for error messages +pastInput:function () { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); + }, + +// displays upcoming input, i.e. for error messages +upcomingInput:function () { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20-next.length); + } + return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); + }, + +// displays the character position where the lexing error occurred, i.e. for error messages +showPosition:function () { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + +// test the lexed token: return FALSE when not a match, otherwise return token +test_match:function (match, indexed_rule) { + var token, + lines, + backup; + + if (this.options.backtrack_lexer) { + // save context + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? + lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : + this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + // recover context + for (var k in backup) { + this[k] = backup[k]; + } + return false; // rule action called reject() implying the next rule should be tested instead. + } + return false; + }, + +// return next match in input +next:function () { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + + var token, + match, + tempMatch, + index; + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; // rule action called reject() implying a rule MISmatch. + } else { + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + +// return next match that has a token +lex:function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + +// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) +begin:function begin(condition) { + this.conditionStack.push(condition); + }, + +// pop the previously active lexer condition state off the condition stack +popState:function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + +// produce the lexer rule set which is active for the currently active lexer condition state +_currentRules:function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + +// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available +topState:function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + +// alias for begin(condition) +pushState:function pushState(condition) { + this.begin(condition); + }, + +// return the number of states currently on the stack +stateStackSize:function stateStackSize() { + return this.conditionStack.length; + }, +options: {}, +performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { +var YYSTATE=YY_START; +switch($avoiding_name_collisions) { +case 0:return 5 +break; +case 1:/* skip whitespace */ +break; +case 2:return 8 +break; +case 3:return 16 +break; +case 4:return 17 +break; +case 5:return 11 +break; +case 6:return 10 +break; +case 7:return 9 +break; +case 8:return 14 +break; +case 9:return 15 +break; +case 10:return 12 +break; +case 11:return 7 +break; +case 12:return 7 +break; +case 13:return 7 +break; +case 14:return 7 +break; +case 15:return 7 +break; +case 16:return 7 +break; +case 17:return 7 +break; +case 18:return 7 +break; +case 19:return 7 +break; +case 20:return 7 +break; +case 21:return 7 +break; +case 22:return 7 +break; +case 23:return 7 +break; +case 24:return 13 +break; +case 25:return 13 +break; +case 26:return 13 +break; +case 27:return 13 +break; +case 28:return 13 +break; +case 29:return 13 +break; +case 30:return 13 +break; +case 31:return 13 +break; +case 32:return 7 +break; +case 33:return 13 +break; +case 34:return 7 +break; +case 35:return 13 +break; +case 36:return 7 +break; +case 37:return 13 +break; +case 38:return 13 +break; case 39:return 7 break; case 40:return 13 @@ -19627,4372 +20900,6162 @@ break; case 364:return 7 break; } -}, -rules: [/^(?:$)/,/^(?:\s+)/,/^(?:\+)/,/^(?:\()/,/^(?:\))/,/^(?::)/,/^(?:DocumentRef-([0-9A-Za-z-+.]+))/,/^(?:LicenseRef-([0-9A-Za-z-+.]+))/,/^(?:AND)/,/^(?:OR)/,/^(?:WITH)/,/^(?:BSD-3-Clause-No-Nuclear-License-2014)/,/^(?:BSD-3-Clause-No-Nuclear-Warranty)/,/^(?:GPL-2\.0-with-classpath-exception)/,/^(?:GPL-3\.0-with-autoconf-exception)/,/^(?:GPL-2\.0-with-autoconf-exception)/,/^(?:BSD-3-Clause-No-Nuclear-License)/,/^(?:MPL-2\.0-no-copyleft-exception)/,/^(?:GPL-2\.0-with-bison-exception)/,/^(?:GPL-2\.0-with-font-exception)/,/^(?:GPL-2\.0-with-GCC-exception)/,/^(?:CNRI-Python-GPL-Compatible)/,/^(?:GPL-3\.0-with-GCC-exception)/,/^(?:BSD-3-Clause-Attribution)/,/^(?:Classpath-exception-2\.0)/,/^(?:WxWindows-exception-3\.1)/,/^(?:freertos-exception-2\.0)/,/^(?:Autoconf-exception-3\.0)/,/^(?:i2p-gpl-java-exception)/,/^(?:gnu-javamail-exception)/,/^(?:Nokia-Qt-exception-1\.1)/,/^(?:Autoconf-exception-2\.0)/,/^(?:BSD-2-Clause-FreeBSD)/,/^(?:u-boot-exception-2\.0)/,/^(?:zlib-acknowledgement)/,/^(?:Bison-exception-2\.2)/,/^(?:BSD-2-Clause-NetBSD)/,/^(?:CLISP-exception-2\.0)/,/^(?:eCos-exception-2\.0)/,/^(?:BSD-3-Clause-Clear)/,/^(?:Font-exception-2\.0)/,/^(?:FLTK-exception-2\.0)/,/^(?:GCC-exception-2\.0)/,/^(?:Qwt-exception-1\.0)/,/^(?:Libtool-exception)/,/^(?:BSD-3-Clause-LBNL)/,/^(?:GCC-exception-3\.1)/,/^(?:Artistic-1\.0-Perl)/,/^(?:Artistic-1\.0-cl8)/,/^(?:CC-BY-NC-SA-2\.5)/,/^(?:MIT-advertising)/,/^(?:BSD-Source-Code)/,/^(?:CC-BY-NC-SA-4\.0)/,/^(?:LiLiQ-Rplus-1\.1)/,/^(?:CC-BY-NC-SA-3\.0)/,/^(?:BSD-4-Clause-UC)/,/^(?:CC-BY-NC-SA-2\.0)/,/^(?:CC-BY-NC-SA-1\.0)/,/^(?:CC-BY-NC-ND-4\.0)/,/^(?:CC-BY-NC-ND-3\.0)/,/^(?:CC-BY-NC-ND-2\.5)/,/^(?:CC-BY-NC-ND-2\.0)/,/^(?:CC-BY-NC-ND-1\.0)/,/^(?:LZMA-exception)/,/^(?:BitTorrent-1\.1)/,/^(?:CrystalStacker)/,/^(?:FLTK-exception)/,/^(?:SugarCRM-1\.1\.3)/,/^(?:BSD-Protection)/,/^(?:BitTorrent-1\.0)/,/^(?:HaskellReport)/,/^(?:Interbase-1\.0)/,/^(?:StandardML-NJ)/,/^(?:mif-exception)/,/^(?:Frameworx-1\.0)/,/^(?:389-exception)/,/^(?:CC-BY-NC-2\.0)/,/^(?:CC-BY-NC-2\.5)/,/^(?:CC-BY-NC-3\.0)/,/^(?:CC-BY-NC-4\.0)/,/^(?:W3C-19980720)/,/^(?:CC-BY-SA-1\.0)/,/^(?:CC-BY-SA-2\.0)/,/^(?:CC-BY-SA-2\.5)/,/^(?:CC-BY-ND-2\.0)/,/^(?:CC-BY-SA-4\.0)/,/^(?:CC-BY-SA-3\.0)/,/^(?:Artistic-1\.0)/,/^(?:Artistic-2\.0)/,/^(?:CC-BY-ND-2\.5)/,/^(?:CC-BY-ND-3\.0)/,/^(?:CC-BY-ND-4\.0)/,/^(?:CC-BY-ND-1\.0)/,/^(?:BSD-4-Clause)/,/^(?:BSD-3-Clause)/,/^(?:BSD-2-Clause)/,/^(?:CC-BY-NC-1\.0)/,/^(?:bzip2-1\.0\.6)/,/^(?:Unicode-TOU)/,/^(?:CNRI-Jython)/,/^(?:ImageMagick)/,/^(?:Adobe-Glyph)/,/^(?:CUA-OPL-1\.0)/,/^(?:OLDAP-2\.2\.2)/,/^(?:LiLiQ-R-1\.1)/,/^(?:bzip2-1\.0\.5)/,/^(?:LiLiQ-P-1\.1)/,/^(?:OLDAP-2\.0\.1)/,/^(?:OLDAP-2\.2\.1)/,/^(?:CNRI-Python)/,/^(?:XFree86-1\.1)/,/^(?:OSET-PL-2\.1)/,/^(?:Apache-2\.0)/,/^(?:Watcom-1\.0)/,/^(?:PostgreSQL)/,/^(?:Python-2\.0)/,/^(?:RHeCos-1\.1)/,/^(?:EUDatagrid)/,/^(?:Spencer-99)/,/^(?:Intel-ACPI)/,/^(?:CECILL-1\.0)/,/^(?:CECILL-1\.1)/,/^(?:JasPer-2\.0)/,/^(?:CECILL-2\.0)/,/^(?:CECILL-2\.1)/,/^(?:gSOAP-1\.3b)/,/^(?:Spencer-94)/,/^(?:Apache-1\.1)/,/^(?:Spencer-86)/,/^(?:Apache-1\.0)/,/^(?:ClArtistic)/,/^(?:TORQUE-1\.1)/,/^(?:CATOSL-1\.1)/,/^(?:Adobe-2006)/,/^(?:Zimbra-1\.4)/,/^(?:Zimbra-1\.3)/,/^(?:Condor-1\.1)/,/^(?:CC-BY-3\.0)/,/^(?:CC-BY-2\.5)/,/^(?:OLDAP-2\.4)/,/^(?:SGI-B-1\.1)/,/^(?:SISSL-1\.2)/,/^(?:SGI-B-1\.0)/,/^(?:OLDAP-2\.3)/,/^(?:CC-BY-4\.0)/,/^(?:Crossword)/,/^(?:SimPL-2\.0)/,/^(?:OLDAP-2\.2)/,/^(?:OLDAP-2\.1)/,/^(?:ErlPL-1\.1)/,/^(?:LPPL-1\.3a)/,/^(?:LPPL-1\.3c)/,/^(?:OLDAP-2\.0)/,/^(?:Leptonica)/,/^(?:CPOL-1\.02)/,/^(?:OLDAP-1\.4)/,/^(?:OLDAP-1\.3)/,/^(?:CC-BY-2\.0)/,/^(?:Unlicense)/,/^(?:OLDAP-2\.8)/,/^(?:OLDAP-1\.2)/,/^(?:MakeIndex)/,/^(?:OLDAP-2\.7)/,/^(?:OLDAP-1\.1)/,/^(?:Sleepycat)/,/^(?:D-FSL-1\.0)/,/^(?:CC-BY-1\.0)/,/^(?:OLDAP-2\.6)/,/^(?:WXwindows)/,/^(?:NPOSL-3\.0)/,/^(?:FreeImage)/,/^(?:SGI-B-2\.0)/,/^(?:OLDAP-2\.5)/,/^(?:Beerware)/,/^(?:Newsletr)/,/^(?:NBPL-1\.0)/,/^(?:NASA-1\.3)/,/^(?:NLOD-1\.0)/,/^(?:AGPL-1\.0)/,/^(?:OCLC-2\.0)/,/^(?:ODbL-1\.0)/,/^(?:PDDL-1\.0)/,/^(?:Motosoto)/,/^(?:Afmparse)/,/^(?:ANTLR-PD)/,/^(?:LPL-1\.02)/,/^(?:Abstyles)/,/^(?:eCos-2\.0)/,/^(?:APSL-1\.0)/,/^(?:LPPL-1\.2)/,/^(?:LPPL-1\.1)/,/^(?:LPPL-1\.0)/,/^(?:APSL-1\.1)/,/^(?:APSL-2\.0)/,/^(?:Info-ZIP)/,/^(?:Zend-2\.0)/,/^(?:IBM-pibs)/,/^(?:LGPL-2\.0)/,/^(?:LGPL-3\.0)/,/^(?:LGPL-2\.1)/,/^(?:GFDL-1\.3)/,/^(?:PHP-3\.01)/,/^(?:GFDL-1\.2)/,/^(?:GFDL-1\.1)/,/^(?:AGPL-3\.0)/,/^(?:Giftware)/,/^(?:EUPL-1\.1)/,/^(?:RPSL-1\.0)/,/^(?:EUPL-1\.0)/,/^(?:MIT-enna)/,/^(?:CECILL-B)/,/^(?:diffmark)/,/^(?:CECILL-C)/,/^(?:CDDL-1\.0)/,/^(?:Sendmail)/,/^(?:CDDL-1\.1)/,/^(?:CPAL-1\.0)/,/^(?:APSL-1\.2)/,/^(?:NPL-1\.1)/,/^(?:AFL-1\.2)/,/^(?:Caldera)/,/^(?:AFL-2\.0)/,/^(?:FSFULLR)/,/^(?:AFL-2\.1)/,/^(?:VSL-1\.0)/,/^(?:VOSTROM)/,/^(?:UPL-1\.0)/,/^(?:Dotseqn)/,/^(?:CPL-1\.0)/,/^(?:dvipdfm)/,/^(?:EPL-1\.0)/,/^(?:OCCT-PL)/,/^(?:ECL-1\.0)/,/^(?:Latex2e)/,/^(?:ECL-2\.0)/,/^(?:GPL-1\.0)/,/^(?:GPL-2\.0)/,/^(?:GPL-3\.0)/,/^(?:AFL-3\.0)/,/^(?:LAL-1\.2)/,/^(?:LAL-1\.3)/,/^(?:EFL-1\.0)/,/^(?:EFL-2\.0)/,/^(?:gnuplot)/,/^(?:Aladdin)/,/^(?:LPL-1\.0)/,/^(?:libtiff)/,/^(?:Entessa)/,/^(?:AMDPLPA)/,/^(?:IPL-1\.0)/,/^(?:OPL-1\.0)/,/^(?:OSL-1\.0)/,/^(?:OSL-1\.1)/,/^(?:OSL-2\.0)/,/^(?:OSL-2\.1)/,/^(?:OSL-3\.0)/,/^(?:OpenSSL)/,/^(?:ZPL-2\.1)/,/^(?:PHP-3\.0)/,/^(?:ZPL-2\.0)/,/^(?:ZPL-1\.1)/,/^(?:CC0-1\.0)/,/^(?:SPL-1\.0)/,/^(?:psutils)/,/^(?:MPL-1\.0)/,/^(?:QPL-1\.0)/,/^(?:MPL-1\.1)/,/^(?:MPL-2\.0)/,/^(?:APL-1\.0)/,/^(?:RPL-1\.1)/,/^(?:RPL-1\.5)/,/^(?:MIT-CMU)/,/^(?:Multics)/,/^(?:Eurosym)/,/^(?:BSL-1\.0)/,/^(?:MIT-feh)/,/^(?:Saxpath)/,/^(?:Borceux)/,/^(?:OFL-1\.1)/,/^(?:OFL-1\.0)/,/^(?:AFL-1\.1)/,/^(?:YPL-1\.1)/,/^(?:YPL-1\.0)/,/^(?:NPL-1\.0)/,/^(?:iMatix)/,/^(?:mpich2)/,/^(?:APAFML)/,/^(?:Bahyph)/,/^(?:RSA-MD)/,/^(?:psfrag)/,/^(?:Plexus)/,/^(?:eGenix)/,/^(?:Glulxe)/,/^(?:SAX-PD)/,/^(?:Imlib2)/,/^(?:Wsuipa)/,/^(?:LGPLLR)/,/^(?:Libpng)/,/^(?:xinetd)/,/^(?:MITNFA)/,/^(?:NetCDF)/,/^(?:Naumen)/,/^(?:SMPPL)/,/^(?:Nunit)/,/^(?:FSFUL)/,/^(?:GL2PS)/,/^(?:SMLNJ)/,/^(?:Rdisc)/,/^(?:Noweb)/,/^(?:Nokia)/,/^(?:SISSL)/,/^(?:Qhull)/,/^(?:Intel)/,/^(?:Glide)/,/^(?:Xerox)/,/^(?:AMPAS)/,/^(?:WTFPL)/,/^(?:MS-PL)/,/^(?:XSkat)/,/^(?:MS-RL)/,/^(?:MirOS)/,/^(?:RSCPL)/,/^(?:TMate)/,/^(?:OGTSL)/,/^(?:FSFAP)/,/^(?:NCSA)/,/^(?:Zlib)/,/^(?:SCEA)/,/^(?:SNIA)/,/^(?:NGPL)/,/^(?:NOSL)/,/^(?:ADSL)/,/^(?:MTLL)/,/^(?:NLPL)/,/^(?:Ruby)/,/^(?:JSON)/,/^(?:Barr)/,/^(?:0BSD)/,/^(?:Xnet)/,/^(?:Cube)/,/^(?:curl)/,/^(?:DSDP)/,/^(?:Fair)/,/^(?:HPND)/,/^(?:TOSL)/,/^(?:IJG)/,/^(?:SWL)/,/^(?:Vim)/,/^(?:FTL)/,/^(?:ICU)/,/^(?:OML)/,/^(?:NRL)/,/^(?:DOC)/,/^(?:TCL)/,/^(?:W3C)/,/^(?:NTP)/,/^(?:IPA)/,/^(?:ISC)/,/^(?:X11)/,/^(?:AAL)/,/^(?:AML)/,/^(?:xpp)/,/^(?:Zed)/,/^(?:MIT)/,/^(?:Mup)/], -conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364],"inclusive":true}} -}); -return lexer; -})(); -parser.lexer = lexer; -function Parser () { - this.yy = {}; +}, +rules: [/^(?:$)/,/^(?:\s+)/,/^(?:\+)/,/^(?:\()/,/^(?:\))/,/^(?::)/,/^(?:DocumentRef-([0-9A-Za-z-+.]+))/,/^(?:LicenseRef-([0-9A-Za-z-+.]+))/,/^(?:AND)/,/^(?:OR)/,/^(?:WITH)/,/^(?:BSD-3-Clause-No-Nuclear-License-2014)/,/^(?:BSD-3-Clause-No-Nuclear-Warranty)/,/^(?:GPL-2\.0-with-classpath-exception)/,/^(?:GPL-3\.0-with-autoconf-exception)/,/^(?:GPL-2\.0-with-autoconf-exception)/,/^(?:BSD-3-Clause-No-Nuclear-License)/,/^(?:MPL-2\.0-no-copyleft-exception)/,/^(?:GPL-2\.0-with-bison-exception)/,/^(?:GPL-2\.0-with-font-exception)/,/^(?:GPL-2\.0-with-GCC-exception)/,/^(?:CNRI-Python-GPL-Compatible)/,/^(?:GPL-3\.0-with-GCC-exception)/,/^(?:BSD-3-Clause-Attribution)/,/^(?:Classpath-exception-2\.0)/,/^(?:WxWindows-exception-3\.1)/,/^(?:freertos-exception-2\.0)/,/^(?:Autoconf-exception-3\.0)/,/^(?:i2p-gpl-java-exception)/,/^(?:gnu-javamail-exception)/,/^(?:Nokia-Qt-exception-1\.1)/,/^(?:Autoconf-exception-2\.0)/,/^(?:BSD-2-Clause-FreeBSD)/,/^(?:u-boot-exception-2\.0)/,/^(?:zlib-acknowledgement)/,/^(?:Bison-exception-2\.2)/,/^(?:BSD-2-Clause-NetBSD)/,/^(?:CLISP-exception-2\.0)/,/^(?:eCos-exception-2\.0)/,/^(?:BSD-3-Clause-Clear)/,/^(?:Font-exception-2\.0)/,/^(?:FLTK-exception-2\.0)/,/^(?:GCC-exception-2\.0)/,/^(?:Qwt-exception-1\.0)/,/^(?:Libtool-exception)/,/^(?:BSD-3-Clause-LBNL)/,/^(?:GCC-exception-3\.1)/,/^(?:Artistic-1\.0-Perl)/,/^(?:Artistic-1\.0-cl8)/,/^(?:CC-BY-NC-SA-2\.5)/,/^(?:MIT-advertising)/,/^(?:BSD-Source-Code)/,/^(?:CC-BY-NC-SA-4\.0)/,/^(?:LiLiQ-Rplus-1\.1)/,/^(?:CC-BY-NC-SA-3\.0)/,/^(?:BSD-4-Clause-UC)/,/^(?:CC-BY-NC-SA-2\.0)/,/^(?:CC-BY-NC-SA-1\.0)/,/^(?:CC-BY-NC-ND-4\.0)/,/^(?:CC-BY-NC-ND-3\.0)/,/^(?:CC-BY-NC-ND-2\.5)/,/^(?:CC-BY-NC-ND-2\.0)/,/^(?:CC-BY-NC-ND-1\.0)/,/^(?:LZMA-exception)/,/^(?:BitTorrent-1\.1)/,/^(?:CrystalStacker)/,/^(?:FLTK-exception)/,/^(?:SugarCRM-1\.1\.3)/,/^(?:BSD-Protection)/,/^(?:BitTorrent-1\.0)/,/^(?:HaskellReport)/,/^(?:Interbase-1\.0)/,/^(?:StandardML-NJ)/,/^(?:mif-exception)/,/^(?:Frameworx-1\.0)/,/^(?:389-exception)/,/^(?:CC-BY-NC-2\.0)/,/^(?:CC-BY-NC-2\.5)/,/^(?:CC-BY-NC-3\.0)/,/^(?:CC-BY-NC-4\.0)/,/^(?:W3C-19980720)/,/^(?:CC-BY-SA-1\.0)/,/^(?:CC-BY-SA-2\.0)/,/^(?:CC-BY-SA-2\.5)/,/^(?:CC-BY-ND-2\.0)/,/^(?:CC-BY-SA-4\.0)/,/^(?:CC-BY-SA-3\.0)/,/^(?:Artistic-1\.0)/,/^(?:Artistic-2\.0)/,/^(?:CC-BY-ND-2\.5)/,/^(?:CC-BY-ND-3\.0)/,/^(?:CC-BY-ND-4\.0)/,/^(?:CC-BY-ND-1\.0)/,/^(?:BSD-4-Clause)/,/^(?:BSD-3-Clause)/,/^(?:BSD-2-Clause)/,/^(?:CC-BY-NC-1\.0)/,/^(?:bzip2-1\.0\.6)/,/^(?:Unicode-TOU)/,/^(?:CNRI-Jython)/,/^(?:ImageMagick)/,/^(?:Adobe-Glyph)/,/^(?:CUA-OPL-1\.0)/,/^(?:OLDAP-2\.2\.2)/,/^(?:LiLiQ-R-1\.1)/,/^(?:bzip2-1\.0\.5)/,/^(?:LiLiQ-P-1\.1)/,/^(?:OLDAP-2\.0\.1)/,/^(?:OLDAP-2\.2\.1)/,/^(?:CNRI-Python)/,/^(?:XFree86-1\.1)/,/^(?:OSET-PL-2\.1)/,/^(?:Apache-2\.0)/,/^(?:Watcom-1\.0)/,/^(?:PostgreSQL)/,/^(?:Python-2\.0)/,/^(?:RHeCos-1\.1)/,/^(?:EUDatagrid)/,/^(?:Spencer-99)/,/^(?:Intel-ACPI)/,/^(?:CECILL-1\.0)/,/^(?:CECILL-1\.1)/,/^(?:JasPer-2\.0)/,/^(?:CECILL-2\.0)/,/^(?:CECILL-2\.1)/,/^(?:gSOAP-1\.3b)/,/^(?:Spencer-94)/,/^(?:Apache-1\.1)/,/^(?:Spencer-86)/,/^(?:Apache-1\.0)/,/^(?:ClArtistic)/,/^(?:TORQUE-1\.1)/,/^(?:CATOSL-1\.1)/,/^(?:Adobe-2006)/,/^(?:Zimbra-1\.4)/,/^(?:Zimbra-1\.3)/,/^(?:Condor-1\.1)/,/^(?:CC-BY-3\.0)/,/^(?:CC-BY-2\.5)/,/^(?:OLDAP-2\.4)/,/^(?:SGI-B-1\.1)/,/^(?:SISSL-1\.2)/,/^(?:SGI-B-1\.0)/,/^(?:OLDAP-2\.3)/,/^(?:CC-BY-4\.0)/,/^(?:Crossword)/,/^(?:SimPL-2\.0)/,/^(?:OLDAP-2\.2)/,/^(?:OLDAP-2\.1)/,/^(?:ErlPL-1\.1)/,/^(?:LPPL-1\.3a)/,/^(?:LPPL-1\.3c)/,/^(?:OLDAP-2\.0)/,/^(?:Leptonica)/,/^(?:CPOL-1\.02)/,/^(?:OLDAP-1\.4)/,/^(?:OLDAP-1\.3)/,/^(?:CC-BY-2\.0)/,/^(?:Unlicense)/,/^(?:OLDAP-2\.8)/,/^(?:OLDAP-1\.2)/,/^(?:MakeIndex)/,/^(?:OLDAP-2\.7)/,/^(?:OLDAP-1\.1)/,/^(?:Sleepycat)/,/^(?:D-FSL-1\.0)/,/^(?:CC-BY-1\.0)/,/^(?:OLDAP-2\.6)/,/^(?:WXwindows)/,/^(?:NPOSL-3\.0)/,/^(?:FreeImage)/,/^(?:SGI-B-2\.0)/,/^(?:OLDAP-2\.5)/,/^(?:Beerware)/,/^(?:Newsletr)/,/^(?:NBPL-1\.0)/,/^(?:NASA-1\.3)/,/^(?:NLOD-1\.0)/,/^(?:AGPL-1\.0)/,/^(?:OCLC-2\.0)/,/^(?:ODbL-1\.0)/,/^(?:PDDL-1\.0)/,/^(?:Motosoto)/,/^(?:Afmparse)/,/^(?:ANTLR-PD)/,/^(?:LPL-1\.02)/,/^(?:Abstyles)/,/^(?:eCos-2\.0)/,/^(?:APSL-1\.0)/,/^(?:LPPL-1\.2)/,/^(?:LPPL-1\.1)/,/^(?:LPPL-1\.0)/,/^(?:APSL-1\.1)/,/^(?:APSL-2\.0)/,/^(?:Info-ZIP)/,/^(?:Zend-2\.0)/,/^(?:IBM-pibs)/,/^(?:LGPL-2\.0)/,/^(?:LGPL-3\.0)/,/^(?:LGPL-2\.1)/,/^(?:GFDL-1\.3)/,/^(?:PHP-3\.01)/,/^(?:GFDL-1\.2)/,/^(?:GFDL-1\.1)/,/^(?:AGPL-3\.0)/,/^(?:Giftware)/,/^(?:EUPL-1\.1)/,/^(?:RPSL-1\.0)/,/^(?:EUPL-1\.0)/,/^(?:MIT-enna)/,/^(?:CECILL-B)/,/^(?:diffmark)/,/^(?:CECILL-C)/,/^(?:CDDL-1\.0)/,/^(?:Sendmail)/,/^(?:CDDL-1\.1)/,/^(?:CPAL-1\.0)/,/^(?:APSL-1\.2)/,/^(?:NPL-1\.1)/,/^(?:AFL-1\.2)/,/^(?:Caldera)/,/^(?:AFL-2\.0)/,/^(?:FSFULLR)/,/^(?:AFL-2\.1)/,/^(?:VSL-1\.0)/,/^(?:VOSTROM)/,/^(?:UPL-1\.0)/,/^(?:Dotseqn)/,/^(?:CPL-1\.0)/,/^(?:dvipdfm)/,/^(?:EPL-1\.0)/,/^(?:OCCT-PL)/,/^(?:ECL-1\.0)/,/^(?:Latex2e)/,/^(?:ECL-2\.0)/,/^(?:GPL-1\.0)/,/^(?:GPL-2\.0)/,/^(?:GPL-3\.0)/,/^(?:AFL-3\.0)/,/^(?:LAL-1\.2)/,/^(?:LAL-1\.3)/,/^(?:EFL-1\.0)/,/^(?:EFL-2\.0)/,/^(?:gnuplot)/,/^(?:Aladdin)/,/^(?:LPL-1\.0)/,/^(?:libtiff)/,/^(?:Entessa)/,/^(?:AMDPLPA)/,/^(?:IPL-1\.0)/,/^(?:OPL-1\.0)/,/^(?:OSL-1\.0)/,/^(?:OSL-1\.1)/,/^(?:OSL-2\.0)/,/^(?:OSL-2\.1)/,/^(?:OSL-3\.0)/,/^(?:OpenSSL)/,/^(?:ZPL-2\.1)/,/^(?:PHP-3\.0)/,/^(?:ZPL-2\.0)/,/^(?:ZPL-1\.1)/,/^(?:CC0-1\.0)/,/^(?:SPL-1\.0)/,/^(?:psutils)/,/^(?:MPL-1\.0)/,/^(?:QPL-1\.0)/,/^(?:MPL-1\.1)/,/^(?:MPL-2\.0)/,/^(?:APL-1\.0)/,/^(?:RPL-1\.1)/,/^(?:RPL-1\.5)/,/^(?:MIT-CMU)/,/^(?:Multics)/,/^(?:Eurosym)/,/^(?:BSL-1\.0)/,/^(?:MIT-feh)/,/^(?:Saxpath)/,/^(?:Borceux)/,/^(?:OFL-1\.1)/,/^(?:OFL-1\.0)/,/^(?:AFL-1\.1)/,/^(?:YPL-1\.1)/,/^(?:YPL-1\.0)/,/^(?:NPL-1\.0)/,/^(?:iMatix)/,/^(?:mpich2)/,/^(?:APAFML)/,/^(?:Bahyph)/,/^(?:RSA-MD)/,/^(?:psfrag)/,/^(?:Plexus)/,/^(?:eGenix)/,/^(?:Glulxe)/,/^(?:SAX-PD)/,/^(?:Imlib2)/,/^(?:Wsuipa)/,/^(?:LGPLLR)/,/^(?:Libpng)/,/^(?:xinetd)/,/^(?:MITNFA)/,/^(?:NetCDF)/,/^(?:Naumen)/,/^(?:SMPPL)/,/^(?:Nunit)/,/^(?:FSFUL)/,/^(?:GL2PS)/,/^(?:SMLNJ)/,/^(?:Rdisc)/,/^(?:Noweb)/,/^(?:Nokia)/,/^(?:SISSL)/,/^(?:Qhull)/,/^(?:Intel)/,/^(?:Glide)/,/^(?:Xerox)/,/^(?:AMPAS)/,/^(?:WTFPL)/,/^(?:MS-PL)/,/^(?:XSkat)/,/^(?:MS-RL)/,/^(?:MirOS)/,/^(?:RSCPL)/,/^(?:TMate)/,/^(?:OGTSL)/,/^(?:FSFAP)/,/^(?:NCSA)/,/^(?:Zlib)/,/^(?:SCEA)/,/^(?:SNIA)/,/^(?:NGPL)/,/^(?:NOSL)/,/^(?:ADSL)/,/^(?:MTLL)/,/^(?:NLPL)/,/^(?:Ruby)/,/^(?:JSON)/,/^(?:Barr)/,/^(?:0BSD)/,/^(?:Xnet)/,/^(?:Cube)/,/^(?:curl)/,/^(?:DSDP)/,/^(?:Fair)/,/^(?:HPND)/,/^(?:TOSL)/,/^(?:IJG)/,/^(?:SWL)/,/^(?:Vim)/,/^(?:FTL)/,/^(?:ICU)/,/^(?:OML)/,/^(?:NRL)/,/^(?:DOC)/,/^(?:TCL)/,/^(?:W3C)/,/^(?:NTP)/,/^(?:IPA)/,/^(?:ISC)/,/^(?:X11)/,/^(?:AAL)/,/^(?:AML)/,/^(?:xpp)/,/^(?:Zed)/,/^(?:MIT)/,/^(?:Mup)/], +conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364],"inclusive":true}} +}); +return lexer; +})(); +parser.lexer = lexer; +function Parser () { + this.yy = {}; +} +Parser.prototype = parser;parser.Parser = Parser; +return new Parser; +})(); + + +if (true) { +exports.parser = spdxparse; +exports.Parser = spdxparse.Parser; +exports.parse = function () { return spdxparse.parse.apply(spdxparse, arguments); }; +exports.main = function commonjsMain(args) { + if (!args[1]) { + console.log('Usage: '+args[0]+' FILE'); + process.exit(1); + } + var source = __webpack_require__(133).readFileSync(__webpack_require__(4).normalize(args[1]), "utf8"); + return exports.parser.parse(source); +}; +if ( true && __webpack_require__.c[__webpack_require__.s] === module) { + exports.main(process.argv.slice(1)); +} +} + +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) + +/***/ }), +/* 193 */ +/***/ (function(module, exports, __webpack_require__) { + +var licenseIDs = __webpack_require__(194); + +function valid(string) { + return licenseIDs.indexOf(string) > -1; +} + +// Common transpositions of license identifier acronyms +var transpositions = [ + ['APGL', 'AGPL'], + ['Gpl', 'GPL'], + ['GLP', 'GPL'], + ['APL', 'Apache'], + ['ISD', 'ISC'], + ['GLP', 'GPL'], + ['IST', 'ISC'], + ['Claude', 'Clause'], + [' or later', '+'], + [' International', ''], + ['GNU', 'GPL'], + ['GUN', 'GPL'], + ['+', ''], + ['GNU GPL', 'GPL'], + ['GNU/GPL', 'GPL'], + ['GNU GLP', 'GPL'], + ['GNU General Public License', 'GPL'], + ['Gnu public license', 'GPL'], + ['GNU Public License', 'GPL'], + ['GNU GENERAL PUBLIC LICENSE', 'GPL'], + ['MTI', 'MIT'], + ['Mozilla Public License', 'MPL'], + ['WTH', 'WTF'], + ['-License', ''] +]; + +var TRANSPOSED = 0; +var CORRECT = 1; + +// Simple corrections to nearly valid identifiers. +var transforms = [ + // e.g. 'mit' + function(argument) { + return argument.toUpperCase(); + }, + // e.g. 'MIT ' + function(argument) { + return argument.trim(); + }, + // e.g. 'M.I.T.' + function(argument) { + return argument.replace(/\./g, ''); + }, + // e.g. 'Apache- 2.0' + function(argument) { + return argument.replace(/\s+/g, ''); + }, + // e.g. 'CC BY 4.0'' + function(argument) { + return argument.replace(/\s+/g, '-'); + }, + // e.g. 'LGPLv2.1' + function(argument) { + return argument.replace('v', '-'); + }, + // e.g. 'Apache 2.0' + function(argument) { + return argument.replace(/,?\s*(\d)/, '-$1'); + }, + // e.g. 'GPL 2' + function(argument) { + return argument.replace(/,?\s*(\d)/, '-$1.0'); + }, + // e.g. 'Apache Version 2.0' + function(argument) { + return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2'); + }, + // e.g. 'Apache Version 2' + function(argument) { + return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2.0'); + }, + // e.g. 'ZLIB' + function(argument) { + return argument[0].toUpperCase() + argument.slice(1); + }, + // e.g. 'MPL/2.0' + function(argument) { + return argument.replace('/', '-'); + }, + // e.g. 'Apache 2' + function(argument) { + return argument + .replace(/\s*V\s*(\d)/, '-$1') + .replace(/(\d)$/, '$1.0'); + }, + // e.g. 'GPL-2.0-' + function(argument) { + return argument.slice(0, argument.length - 1); + }, + // e.g. 'GPL2' + function(argument) { + return argument.replace(/(\d)$/, '-$1.0'); + }, + // e.g. 'BSD 3' + function(argument) { + return argument.replace(/(-| )?(\d)$/, '-$2-Clause'); + }, + // e.g. 'BSD clause 3' + function(argument) { + return argument.replace(/(-| )clause(-| )(\d)/, '-$3-Clause'); + }, + // e.g. 'BY-NC-4.0' + function(argument) { + return 'CC-' + argument; + }, + // e.g. 'BY-NC' + function(argument) { + return 'CC-' + argument + '-4.0'; + }, + // e.g. 'Attribution-NonCommercial' + function(argument) { + return argument + .replace('Attribution', 'BY') + .replace('NonCommercial', 'NC') + .replace('NoDerivatives', 'ND') + .replace(/ (\d)/, '-$1') + .replace(/ ?International/, ''); + }, + // e.g. 'Attribution-NonCommercial' + function(argument) { + return 'CC-' + + argument + .replace('Attribution', 'BY') + .replace('NonCommercial', 'NC') + .replace('NoDerivatives', 'ND') + .replace(/ (\d)/, '-$1') + .replace(/ ?International/, '') + + '-4.0'; + } +]; + +// If all else fails, guess that strings containing certain substrings +// meant to identify certain licenses. +var lastResorts = [ + ['UNLI', 'Unlicense'], + ['WTF', 'WTFPL'], + ['2 CLAUSE', 'BSD-2-Clause'], + ['2-CLAUSE', 'BSD-2-Clause'], + ['3 CLAUSE', 'BSD-3-Clause'], + ['3-CLAUSE', 'BSD-3-Clause'], + ['AFFERO', 'AGPL-3.0'], + ['AGPL', 'AGPL-3.0'], + ['APACHE', 'Apache-2.0'], + ['ARTISTIC', 'Artistic-2.0'], + ['Affero', 'AGPL-3.0'], + ['BEER', 'Beerware'], + ['BOOST', 'BSL-1.0'], + ['BSD', 'BSD-2-Clause'], + ['ECLIPSE', 'EPL-1.0'], + ['FUCK', 'WTFPL'], + ['GNU', 'GPL-3.0'], + ['LGPL', 'LGPL-3.0'], + ['GPL', 'GPL-3.0'], + ['MIT', 'MIT'], + ['MPL', 'MPL-2.0'], + ['X11', 'X11'], + ['ZLIB', 'Zlib'] +]; + +var SUBSTRING = 0; +var IDENTIFIER = 1; + +var validTransformation = function(identifier) { + for (var i = 0; i < transforms.length; i++) { + var transformed = transforms[i](identifier); + if (transformed !== identifier && valid(transformed)) { + return transformed; + } + } + return null; +}; + +var validLastResort = function(identifier) { + var upperCased = identifier.toUpperCase(); + for (var i = 0; i < lastResorts.length; i++) { + var lastResort = lastResorts[i]; + if (upperCased.indexOf(lastResort[SUBSTRING]) > -1) { + return lastResort[IDENTIFIER]; + } + } + return null; +}; + +var anyCorrection = function(identifier, check) { + for (var i = 0; i < transpositions.length; i++) { + var transposition = transpositions[i]; + var transposed = transposition[TRANSPOSED]; + if (identifier.indexOf(transposed) > -1) { + var corrected = identifier.replace( + transposed, + transposition[CORRECT] + ); + var checked = check(corrected); + if (checked !== null) { + return checked; + } + } + } + return null; +}; + +module.exports = function(identifier) { + identifier = identifier.replace(/\+$/, ''); + if (valid(identifier)) { + return identifier; + } + var transformed = validTransformation(identifier); + if (transformed !== null) { + return transformed; + } + transformed = anyCorrection(identifier, function(argument) { + if (valid(argument)) { + return argument; + } + return validTransformation(argument); + }); + if (transformed !== null) { + return transformed; + } + transformed = validLastResort(identifier); + if (transformed !== null) { + return transformed; + } + transformed = anyCorrection(identifier, validLastResort); + if (transformed !== null) { + return transformed; + } + return null; +}; + + +/***/ }), +/* 194 */ +/***/ (function(module) { + +module.exports = JSON.parse("[\"Glide\",\"Abstyles\",\"AFL-1.1\",\"AFL-1.2\",\"AFL-2.0\",\"AFL-2.1\",\"AFL-3.0\",\"AMPAS\",\"APL-1.0\",\"Adobe-Glyph\",\"APAFML\",\"Adobe-2006\",\"AGPL-1.0\",\"Afmparse\",\"Aladdin\",\"ADSL\",\"AMDPLPA\",\"ANTLR-PD\",\"Apache-1.0\",\"Apache-1.1\",\"Apache-2.0\",\"AML\",\"APSL-1.0\",\"APSL-1.1\",\"APSL-1.2\",\"APSL-2.0\",\"Artistic-1.0\",\"Artistic-1.0-Perl\",\"Artistic-1.0-cl8\",\"Artistic-2.0\",\"AAL\",\"Bahyph\",\"Barr\",\"Beerware\",\"BitTorrent-1.0\",\"BitTorrent-1.1\",\"BSL-1.0\",\"Borceux\",\"BSD-2-Clause\",\"BSD-2-Clause-FreeBSD\",\"BSD-2-Clause-NetBSD\",\"BSD-3-Clause\",\"BSD-3-Clause-Clear\",\"BSD-4-Clause\",\"BSD-Protection\",\"BSD-Source-Code\",\"BSD-3-Clause-Attribution\",\"0BSD\",\"BSD-4-Clause-UC\",\"bzip2-1.0.5\",\"bzip2-1.0.6\",\"Caldera\",\"CECILL-1.0\",\"CECILL-1.1\",\"CECILL-2.0\",\"CECILL-2.1\",\"CECILL-B\",\"CECILL-C\",\"ClArtistic\",\"MIT-CMU\",\"CNRI-Jython\",\"CNRI-Python\",\"CNRI-Python-GPL-Compatible\",\"CPOL-1.02\",\"CDDL-1.0\",\"CDDL-1.1\",\"CPAL-1.0\",\"CPL-1.0\",\"CATOSL-1.1\",\"Condor-1.1\",\"CC-BY-1.0\",\"CC-BY-2.0\",\"CC-BY-2.5\",\"CC-BY-3.0\",\"CC-BY-4.0\",\"CC-BY-ND-1.0\",\"CC-BY-ND-2.0\",\"CC-BY-ND-2.5\",\"CC-BY-ND-3.0\",\"CC-BY-ND-4.0\",\"CC-BY-NC-1.0\",\"CC-BY-NC-2.0\",\"CC-BY-NC-2.5\",\"CC-BY-NC-3.0\",\"CC-BY-NC-4.0\",\"CC-BY-NC-ND-1.0\",\"CC-BY-NC-ND-2.0\",\"CC-BY-NC-ND-2.5\",\"CC-BY-NC-ND-3.0\",\"CC-BY-NC-ND-4.0\",\"CC-BY-NC-SA-1.0\",\"CC-BY-NC-SA-2.0\",\"CC-BY-NC-SA-2.5\",\"CC-BY-NC-SA-3.0\",\"CC-BY-NC-SA-4.0\",\"CC-BY-SA-1.0\",\"CC-BY-SA-2.0\",\"CC-BY-SA-2.5\",\"CC-BY-SA-3.0\",\"CC-BY-SA-4.0\",\"CC0-1.0\",\"Crossword\",\"CrystalStacker\",\"CUA-OPL-1.0\",\"Cube\",\"curl\",\"D-FSL-1.0\",\"diffmark\",\"WTFPL\",\"DOC\",\"Dotseqn\",\"DSDP\",\"dvipdfm\",\"EPL-1.0\",\"ECL-1.0\",\"ECL-2.0\",\"eGenix\",\"EFL-1.0\",\"EFL-2.0\",\"MIT-advertising\",\"MIT-enna\",\"Entessa\",\"ErlPL-1.1\",\"EUDatagrid\",\"EUPL-1.0\",\"EUPL-1.1\",\"Eurosym\",\"Fair\",\"MIT-feh\",\"Frameworx-1.0\",\"FreeImage\",\"FTL\",\"FSFAP\",\"FSFUL\",\"FSFULLR\",\"Giftware\",\"GL2PS\",\"Glulxe\",\"AGPL-3.0\",\"GFDL-1.1\",\"GFDL-1.2\",\"GFDL-1.3\",\"GPL-1.0\",\"GPL-2.0\",\"GPL-3.0\",\"LGPL-2.1\",\"LGPL-3.0\",\"LGPL-2.0\",\"gnuplot\",\"gSOAP-1.3b\",\"HaskellReport\",\"HPND\",\"IBM-pibs\",\"IPL-1.0\",\"ICU\",\"ImageMagick\",\"iMatix\",\"Imlib2\",\"IJG\",\"Info-ZIP\",\"Intel-ACPI\",\"Intel\",\"Interbase-1.0\",\"IPA\",\"ISC\",\"JasPer-2.0\",\"JSON\",\"LPPL-1.0\",\"LPPL-1.1\",\"LPPL-1.2\",\"LPPL-1.3a\",\"LPPL-1.3c\",\"Latex2e\",\"BSD-3-Clause-LBNL\",\"Leptonica\",\"LGPLLR\",\"Libpng\",\"libtiff\",\"LAL-1.2\",\"LAL-1.3\",\"LiLiQ-P-1.1\",\"LiLiQ-Rplus-1.1\",\"LiLiQ-R-1.1\",\"LPL-1.02\",\"LPL-1.0\",\"MakeIndex\",\"MTLL\",\"MS-PL\",\"MS-RL\",\"MirOS\",\"MITNFA\",\"MIT\",\"Motosoto\",\"MPL-1.0\",\"MPL-1.1\",\"MPL-2.0\",\"MPL-2.0-no-copyleft-exception\",\"mpich2\",\"Multics\",\"Mup\",\"NASA-1.3\",\"Naumen\",\"NBPL-1.0\",\"NetCDF\",\"NGPL\",\"NOSL\",\"NPL-1.0\",\"NPL-1.1\",\"Newsletr\",\"NLPL\",\"Nokia\",\"NPOSL-3.0\",\"NLOD-1.0\",\"Noweb\",\"NRL\",\"NTP\",\"Nunit\",\"OCLC-2.0\",\"ODbL-1.0\",\"PDDL-1.0\",\"OCCT-PL\",\"OGTSL\",\"OLDAP-2.2.2\",\"OLDAP-1.1\",\"OLDAP-1.2\",\"OLDAP-1.3\",\"OLDAP-1.4\",\"OLDAP-2.0\",\"OLDAP-2.0.1\",\"OLDAP-2.1\",\"OLDAP-2.2\",\"OLDAP-2.2.1\",\"OLDAP-2.3\",\"OLDAP-2.4\",\"OLDAP-2.5\",\"OLDAP-2.6\",\"OLDAP-2.7\",\"OLDAP-2.8\",\"OML\",\"OPL-1.0\",\"OSL-1.0\",\"OSL-1.1\",\"OSL-2.0\",\"OSL-2.1\",\"OSL-3.0\",\"OpenSSL\",\"OSET-PL-2.1\",\"PHP-3.0\",\"PHP-3.01\",\"Plexus\",\"PostgreSQL\",\"psfrag\",\"psutils\",\"Python-2.0\",\"QPL-1.0\",\"Qhull\",\"Rdisc\",\"RPSL-1.0\",\"RPL-1.1\",\"RPL-1.5\",\"RHeCos-1.1\",\"RSCPL\",\"RSA-MD\",\"Ruby\",\"SAX-PD\",\"Saxpath\",\"SCEA\",\"SWL\",\"SMPPL\",\"Sendmail\",\"SGI-B-1.0\",\"SGI-B-1.1\",\"SGI-B-2.0\",\"OFL-1.0\",\"OFL-1.1\",\"SimPL-2.0\",\"Sleepycat\",\"SNIA\",\"Spencer-86\",\"Spencer-94\",\"Spencer-99\",\"SMLNJ\",\"SugarCRM-1.1.3\",\"SISSL\",\"SISSL-1.2\",\"SPL-1.0\",\"Watcom-1.0\",\"TCL\",\"Unlicense\",\"TMate\",\"TORQUE-1.1\",\"TOSL\",\"Unicode-TOU\",\"UPL-1.0\",\"NCSA\",\"Vim\",\"VOSTROM\",\"VSL-1.0\",\"W3C-19980720\",\"W3C\",\"Wsuipa\",\"Xnet\",\"X11\",\"Xerox\",\"XFree86-1.1\",\"xinetd\",\"xpp\",\"XSkat\",\"YPL-1.0\",\"YPL-1.1\",\"Zed\",\"Zend-2.0\",\"Zimbra-1.3\",\"Zimbra-1.4\",\"Zlib\",\"zlib-acknowledgement\",\"ZPL-1.1\",\"ZPL-2.0\",\"ZPL-2.1\",\"BSD-3-Clause-No-Nuclear-License\",\"BSD-3-Clause-No-Nuclear-Warranty\",\"BSD-3-Clause-No-Nuclear-License-2014\",\"eCos-2.0\",\"GPL-2.0-with-autoconf-exception\",\"GPL-2.0-with-bison-exception\",\"GPL-2.0-with-classpath-exception\",\"GPL-2.0-with-font-exception\",\"GPL-2.0-with-GCC-exception\",\"GPL-3.0-with-autoconf-exception\",\"GPL-3.0-with-GCC-exception\",\"StandardML-NJ\",\"WXwindows\"]"); + +/***/ }), +/* 195 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var url = __webpack_require__(196) +var gitHosts = __webpack_require__(197) +var GitHost = module.exports = __webpack_require__(198) + +var protocolToRepresentationMap = { + 'git+ssh': 'sshurl', + 'git+https': 'https', + 'ssh': 'sshurl', + 'git': 'git' +} + +function protocolToRepresentation (protocol) { + if (protocol.substr(-1) === ':') protocol = protocol.slice(0, -1) + return protocolToRepresentationMap[protocol] || protocol +} + +var authProtocols = { + 'git:': true, + 'https:': true, + 'git+https:': true, + 'http:': true, + 'git+http:': true +} + +var cache = {} + +module.exports.fromUrl = function (giturl, opts) { + var key = giturl + JSON.stringify(opts || {}) + + if (!(key in cache)) { + cache[key] = fromUrl(giturl, opts) + } + + return cache[key] +} + +function fromUrl (giturl, opts) { + if (giturl == null || giturl === '') return + var url = fixupUnqualifiedGist( + isGitHubShorthand(giturl) ? 'github:' + giturl : giturl + ) + var parsed = parseGitUrl(url) + var shortcutMatch = url.match(new RegExp('^([^:]+):(?:(?:[^@:]+(?:[^@]+)?@)?([^/]*))[/](.+?)(?:[.]git)?($|#)')) + var matches = Object.keys(gitHosts).map(function (gitHostName) { + try { + var gitHostInfo = gitHosts[gitHostName] + var auth = null + if (parsed.auth && authProtocols[parsed.protocol]) { + auth = decodeURIComponent(parsed.auth) + } + var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null + var user = null + var project = null + var defaultRepresentation = null + if (shortcutMatch && shortcutMatch[1] === gitHostName) { + user = shortcutMatch[2] && decodeURIComponent(shortcutMatch[2]) + project = decodeURIComponent(shortcutMatch[3]) + defaultRepresentation = 'shortcut' + } else { + if (parsed.host !== gitHostInfo.domain) return + if (!gitHostInfo.protocols_re.test(parsed.protocol)) return + if (!parsed.path) return + var pathmatch = gitHostInfo.pathmatch + var matched = parsed.path.match(pathmatch) + if (!matched) return + if (matched[1] != null) user = decodeURIComponent(matched[1].replace(/^:/, '')) + if (matched[2] != null) project = decodeURIComponent(matched[2]) + defaultRepresentation = protocolToRepresentation(parsed.protocol) + } + return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation, opts) + } catch (ex) { + if (!(ex instanceof URIError)) throw ex + } + }).filter(function (gitHostInfo) { return gitHostInfo }) + if (matches.length !== 1) return + return matches[0] +} + +function isGitHubShorthand (arg) { + // Note: This does not fully test the git ref format. + // See https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html + // + // The only way to do this properly would be to shell out to + // git-check-ref-format, and as this is a fast sync function, + // we don't want to do that. Just let git fail if it turns + // out that the commit-ish is invalid. + // GH usernames cannot start with . or - + return /^[^:@%/\s.-][^:@%/\s]*[/][^:@\s/%]+(?:#.*)?$/.test(arg) +} + +function fixupUnqualifiedGist (giturl) { + // necessary for round-tripping gists + var parsed = url.parse(giturl) + if (parsed.protocol === 'gist:' && parsed.host && !parsed.path) { + return parsed.protocol + '/' + parsed.host + } else { + return giturl + } +} + +function parseGitUrl (giturl) { + if (typeof giturl !== 'string') giturl = '' + giturl + var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/) + if (!matched) return url.parse(giturl) + return { + protocol: 'git+ssh:', + slashes: true, + auth: matched[1], + host: matched[2], + port: null, + hostname: matched[2], + hash: matched[4], + search: null, + query: null, + pathname: '/' + matched[3], + path: '/' + matched[3], + href: 'git+ssh://' + matched[1] + '@' + matched[2] + + '/' + matched[3] + (matched[4] || '') + } +} + + +/***/ }), +/* 196 */ +/***/ (function(module, exports) { + +module.exports = require("url"); + +/***/ }), +/* 197 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var gitHosts = module.exports = { + github: { + // First two are insecure and generally shouldn't be used any more, but + // they are still supported. + 'protocols': [ 'git', 'http', 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'github.com', + 'treepath': 'tree', + 'filetemplate': 'https://{auth@}raw.githubusercontent.com/{user}/{project}/{committish}/{path}', + 'bugstemplate': 'https://{domain}/{user}/{project}/issues', + 'gittemplate': 'git://{auth@}{domain}/{user}/{project}.git{#committish}', + 'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz' + }, + bitbucket: { + 'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'bitbucket.org', + 'treepath': 'src', + 'tarballtemplate': 'https://{domain}/{user}/{project}/get/{committish}.tar.gz' + }, + gitlab: { + 'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'gitlab.com', + 'treepath': 'tree', + 'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#README', + 'bugstemplate': 'https://{domain}/{user}/{project}/issues', + 'tarballtemplate': 'https://{domain}/{user}/{project}/repository/archive.tar.gz?ref={committish}' + }, + gist: { + 'protocols': [ 'git', 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'gist.github.com', + 'pathmatch': /^[/](?:([^/]+)[/])?([a-z0-9]+)(?:[.]git)?$/, + 'filetemplate': 'https://gist.githubusercontent.com/{user}/{project}/raw{/committish}/{path}', + 'bugstemplate': 'https://{domain}/{project}', + 'gittemplate': 'git://{domain}/{project}.git{#committish}', + 'sshtemplate': 'git@{domain}:/{project}.git{#committish}', + 'sshurltemplate': 'git+ssh://git@{domain}/{project}.git{#committish}', + 'browsetemplate': 'https://{domain}/{project}{/committish}', + 'docstemplate': 'https://{domain}/{project}{/committish}', + 'httpstemplate': 'git+https://{domain}/{project}.git{#committish}', + 'shortcuttemplate': '{type}:{project}{#committish}', + 'pathtemplate': '{project}{#committish}', + 'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz' + } +} + +var gitHostDefaults = { + 'sshtemplate': 'git@{domain}:{user}/{project}.git{#committish}', + 'sshurltemplate': 'git+ssh://git@{domain}/{user}/{project}.git{#committish}', + 'browsetemplate': 'https://{domain}/{user}/{project}{/tree/committish}', + 'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#readme', + 'httpstemplate': 'git+https://{auth@}{domain}/{user}/{project}.git{#committish}', + 'filetemplate': 'https://{domain}/{user}/{project}/raw/{committish}/{path}', + 'shortcuttemplate': '{type}:{user}/{project}{#committish}', + 'pathtemplate': '{user}/{project}{#committish}', + 'pathmatch': /^[/]([^/]+)[/]([^/]+?)(?:[.]git|[/])?$/ +} + +Object.keys(gitHosts).forEach(function (name) { + Object.keys(gitHostDefaults).forEach(function (key) { + if (gitHosts[name][key]) return + gitHosts[name][key] = gitHostDefaults[key] + }) + gitHosts[name].protocols_re = RegExp('^(' + + gitHosts[name].protocols.map(function (protocol) { + return protocol.replace(/([\\+*{}()[\]$^|])/g, '\\$1') + }).join('|') + '):$') +}) + + +/***/ }), +/* 198 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var gitHosts = __webpack_require__(197) +var extend = Object.assign || __webpack_require__(111)._extend + +var GitHost = module.exports = function (type, user, auth, project, committish, defaultRepresentation, opts) { + var gitHostInfo = this + gitHostInfo.type = type + Object.keys(gitHosts[type]).forEach(function (key) { + gitHostInfo[key] = gitHosts[type][key] + }) + gitHostInfo.user = user + gitHostInfo.auth = auth + gitHostInfo.project = project + gitHostInfo.committish = committish + gitHostInfo.default = defaultRepresentation + gitHostInfo.opts = opts || {} +} +GitHost.prototype = {} + +GitHost.prototype.hash = function () { + return this.committish ? '#' + this.committish : '' +} + +GitHost.prototype._fill = function (template, opts) { + if (!template) return + var vars = extend({}, opts) + opts = extend(extend({}, this.opts), opts) + var self = this + Object.keys(this).forEach(function (key) { + if (self[key] != null && vars[key] == null) vars[key] = self[key] + }) + var rawAuth = vars.auth + var rawComittish = vars.committish + Object.keys(vars).forEach(function (key) { + vars[key] = encodeURIComponent(vars[key]) + }) + vars['auth@'] = rawAuth ? rawAuth + '@' : '' + if (opts.noCommittish) { + vars['#committish'] = '' + vars['/tree/committish'] = '' + vars['/comittish'] = '' + vars.comittish = '' + } else { + vars['#committish'] = rawComittish ? '#' + rawComittish : '' + vars['/tree/committish'] = vars.committish + ? '/' + vars.treepath + '/' + vars.committish + : '' + vars['/committish'] = vars.committish ? '/' + vars.committish : '' + vars.committish = vars.committish || 'master' + } + var res = template + Object.keys(vars).forEach(function (key) { + res = res.replace(new RegExp('[{]' + key + '[}]', 'g'), vars[key]) + }) + if (opts.noGitPlus) { + return res.replace(/^git[+]/, '') + } else { + return res + } +} + +GitHost.prototype.ssh = function (opts) { + return this._fill(this.sshtemplate, opts) +} + +GitHost.prototype.sshurl = function (opts) { + return this._fill(this.sshurltemplate, opts) +} + +GitHost.prototype.browse = function (opts) { + return this._fill(this.browsetemplate, opts) +} + +GitHost.prototype.docs = function (opts) { + return this._fill(this.docstemplate, opts) +} + +GitHost.prototype.bugs = function (opts) { + return this._fill(this.bugstemplate, opts) +} + +GitHost.prototype.https = function (opts) { + return this._fill(this.httpstemplate, opts) +} + +GitHost.prototype.git = function (opts) { + return this._fill(this.gittemplate, opts) +} + +GitHost.prototype.shortcut = function (opts) { + return this._fill(this.shortcuttemplate, opts) +} + +GitHost.prototype.path = function (opts) { + return this._fill(this.pathtemplate, opts) +} + +GitHost.prototype.tarball = function (opts) { + return this._fill(this.tarballtemplate, opts) +} + +GitHost.prototype.file = function (P, opts) { + return this._fill(this.filetemplate, extend({ + path: P.replace(/^[/]+/g, '') + }, opts)) +} + +GitHost.prototype.getDefaultRepresentation = function () { + return this.default +} + +GitHost.prototype.toString = function (opts) { + return (this[this.default] || this.sshurl).call(this, opts) +} + + +/***/ }), +/* 199 */ +/***/ (function(module, exports, __webpack_require__) { + +var async = __webpack_require__(200); +async.core = __webpack_require__(206); +async.isCore = __webpack_require__(205); +async.sync = __webpack_require__(208); + +module.exports = async; + + +/***/ }), +/* 200 */ +/***/ (function(module, exports, __webpack_require__) { + +var fs = __webpack_require__(133); +var path = __webpack_require__(4); +var caller = __webpack_require__(201); +var nodeModulesPaths = __webpack_require__(202); +var normalizeOptions = __webpack_require__(204); +var isCore = __webpack_require__(205); + +var realpathFS = fs.realpath && typeof fs.realpath.native === 'function' ? fs.realpath.native : fs.realpath; + +var defaultIsFile = function isFile(file, cb) { + fs.stat(file, function (err, stat) { + if (!err) { + return cb(null, stat.isFile() || stat.isFIFO()); + } + if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false); + return cb(err); + }); +}; + +var defaultIsDir = function isDirectory(dir, cb) { + fs.stat(dir, function (err, stat) { + if (!err) { + return cb(null, stat.isDirectory()); + } + if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false); + return cb(err); + }); +}; + +var defaultRealpath = function realpath(x, cb) { + realpathFS(x, function (realpathErr, realPath) { + if (realpathErr && realpathErr.code !== 'ENOENT') cb(realpathErr); + else cb(null, realpathErr ? x : realPath); + }); +}; + +var maybeRealpath = function maybeRealpath(realpath, x, opts, cb) { + if (opts && opts.preserveSymlinks === false) { + realpath(x, cb); + } else { + cb(null, x); + } +}; + +var getPackageCandidates = function getPackageCandidates(x, start, opts) { + var dirs = nodeModulesPaths(start, opts, x); + for (var i = 0; i < dirs.length; i++) { + dirs[i] = path.join(dirs[i], x); + } + return dirs; +}; + +module.exports = function resolve(x, options, callback) { + var cb = callback; + var opts = options; + if (typeof options === 'function') { + cb = opts; + opts = {}; + } + if (typeof x !== 'string') { + var err = new TypeError('Path must be a string.'); + return process.nextTick(function () { + cb(err); + }); + } + + opts = normalizeOptions(x, opts); + + var isFile = opts.isFile || defaultIsFile; + var isDirectory = opts.isDirectory || defaultIsDir; + var readFile = opts.readFile || fs.readFile; + var realpath = opts.realpath || defaultRealpath; + var packageIterator = opts.packageIterator; + + var extensions = opts.extensions || ['.js']; + var basedir = opts.basedir || path.dirname(caller()); + var parent = opts.filename || basedir; + + opts.paths = opts.paths || []; + + // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory + var absoluteStart = path.resolve(basedir); + + maybeRealpath( + realpath, + absoluteStart, + opts, + function (err, realStart) { + if (err) cb(err); + else init(realStart); + } + ); + + var res; + function init(basedir) { + if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) { + res = path.resolve(basedir, x); + if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/'; + if ((/\/$/).test(x) && res === basedir) { + loadAsDirectory(res, opts.package, onfile); + } else loadAsFile(res, opts.package, onfile); + } else if (isCore(x)) { + return cb(null, x); + } else loadNodeModules(x, basedir, function (err, n, pkg) { + if (err) cb(err); + else if (n) { + return maybeRealpath(realpath, n, opts, function (err, realN) { + if (err) { + cb(err); + } else { + cb(null, realN, pkg); + } + }); + } else { + var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); + moduleError.code = 'MODULE_NOT_FOUND'; + cb(moduleError); + } + }); + } + + function onfile(err, m, pkg) { + if (err) cb(err); + else if (m) cb(null, m, pkg); + else loadAsDirectory(res, function (err, d, pkg) { + if (err) cb(err); + else if (d) { + maybeRealpath(realpath, d, opts, function (err, realD) { + if (err) { + cb(err); + } else { + cb(null, realD, pkg); + } + }); + } else { + var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); + moduleError.code = 'MODULE_NOT_FOUND'; + cb(moduleError); + } + }); + } + + function loadAsFile(x, thePackage, callback) { + var loadAsFilePackage = thePackage; + var cb = callback; + if (typeof loadAsFilePackage === 'function') { + cb = loadAsFilePackage; + loadAsFilePackage = undefined; + } + + var exts = [''].concat(extensions); + load(exts, x, loadAsFilePackage); + + function load(exts, x, loadPackage) { + if (exts.length === 0) return cb(null, undefined, loadPackage); + var file = x + exts[0]; + + var pkg = loadPackage; + if (pkg) onpkg(null, pkg); + else loadpkg(path.dirname(file), onpkg); + + function onpkg(err, pkg_, dir) { + pkg = pkg_; + if (err) return cb(err); + if (dir && pkg && opts.pathFilter) { + var rfile = path.relative(dir, file); + var rel = rfile.slice(0, rfile.length - exts[0].length); + var r = opts.pathFilter(pkg, x, rel); + if (r) return load( + [''].concat(extensions.slice()), + path.resolve(dir, r), + pkg + ); + } + isFile(file, onex); + } + function onex(err, ex) { + if (err) return cb(err); + if (ex) return cb(null, file, pkg); + load(exts.slice(1), x, pkg); + } + } + } + + function loadpkg(dir, cb) { + if (dir === '' || dir === '/') return cb(null); + if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) { + return cb(null); + } + if ((/[/\\]node_modules[/\\]*$/).test(dir)) return cb(null); + + maybeRealpath(realpath, dir, opts, function (unwrapErr, pkgdir) { + if (unwrapErr) return loadpkg(path.dirname(dir), cb); + var pkgfile = path.join(pkgdir, 'package.json'); + isFile(pkgfile, function (err, ex) { + // on err, ex is false + if (!ex) return loadpkg(path.dirname(dir), cb); + + readFile(pkgfile, function (err, body) { + if (err) cb(err); + try { var pkg = JSON.parse(body); } catch (jsonErr) {} + + if (pkg && opts.packageFilter) { + pkg = opts.packageFilter(pkg, pkgfile); + } + cb(null, pkg, dir); + }); + }); + }); + } + + function loadAsDirectory(x, loadAsDirectoryPackage, callback) { + var cb = callback; + var fpkg = loadAsDirectoryPackage; + if (typeof fpkg === 'function') { + cb = fpkg; + fpkg = opts.package; + } + + maybeRealpath(realpath, x, opts, function (unwrapErr, pkgdir) { + if (unwrapErr) return cb(unwrapErr); + var pkgfile = path.join(pkgdir, 'package.json'); + isFile(pkgfile, function (err, ex) { + if (err) return cb(err); + if (!ex) return loadAsFile(path.join(x, 'index'), fpkg, cb); + + readFile(pkgfile, function (err, body) { + if (err) return cb(err); + try { + var pkg = JSON.parse(body); + } catch (jsonErr) {} + + if (pkg && opts.packageFilter) { + pkg = opts.packageFilter(pkg, pkgfile); + } + + if (pkg && pkg.main) { + if (typeof pkg.main !== 'string') { + var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); + mainError.code = 'INVALID_PACKAGE_MAIN'; + return cb(mainError); + } + if (pkg.main === '.' || pkg.main === './') { + pkg.main = 'index'; + } + loadAsFile(path.resolve(x, pkg.main), pkg, function (err, m, pkg) { + if (err) return cb(err); + if (m) return cb(null, m, pkg); + if (!pkg) return loadAsFile(path.join(x, 'index'), pkg, cb); + + var dir = path.resolve(x, pkg.main); + loadAsDirectory(dir, pkg, function (err, n, pkg) { + if (err) return cb(err); + if (n) return cb(null, n, pkg); + loadAsFile(path.join(x, 'index'), pkg, cb); + }); + }); + return; + } + + loadAsFile(path.join(x, '/index'), pkg, cb); + }); + }); + }); + } + + function processDirs(cb, dirs) { + if (dirs.length === 0) return cb(null, undefined); + var dir = dirs[0]; + + isDirectory(path.dirname(dir), isdir); + + function isdir(err, isdir) { + if (err) return cb(err); + if (!isdir) return processDirs(cb, dirs.slice(1)); + loadAsFile(dir, opts.package, onfile); + } + + function onfile(err, m, pkg) { + if (err) return cb(err); + if (m) return cb(null, m, pkg); + loadAsDirectory(dir, opts.package, ondir); + } + + function ondir(err, n, pkg) { + if (err) return cb(err); + if (n) return cb(null, n, pkg); + processDirs(cb, dirs.slice(1)); + } + } + function loadNodeModules(x, start, cb) { + var thunk = function () { return getPackageCandidates(x, start, opts); }; + processDirs( + cb, + packageIterator ? packageIterator(x, start, thunk, opts) : thunk() + ); + } +}; + + +/***/ }), +/* 201 */ +/***/ (function(module, exports) { + +module.exports = function () { + // see https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi + var origPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = function (_, stack) { return stack; }; + var stack = (new Error()).stack; + Error.prepareStackTrace = origPrepareStackTrace; + return stack[2].getFileName(); +}; + + +/***/ }), +/* 202 */ +/***/ (function(module, exports, __webpack_require__) { + +var path = __webpack_require__(4); +var parse = path.parse || __webpack_require__(203); + +var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) { + var prefix = '/'; + if ((/^([A-Za-z]:)/).test(absoluteStart)) { + prefix = ''; + } else if ((/^\\\\/).test(absoluteStart)) { + prefix = '\\\\'; + } + + var paths = [absoluteStart]; + var parsed = parse(absoluteStart); + while (parsed.dir !== paths[paths.length - 1]) { + paths.push(parsed.dir); + parsed = parse(parsed.dir); + } + + return paths.reduce(function (dirs, aPath) { + return dirs.concat(modules.map(function (moduleDir) { + return path.resolve(prefix, aPath, moduleDir); + })); + }, []); +}; + +module.exports = function nodeModulesPaths(start, opts, request) { + var modules = opts && opts.moduleDirectory + ? [].concat(opts.moduleDirectory) + : ['node_modules']; + + if (opts && typeof opts.paths === 'function') { + return opts.paths( + request, + start, + function () { return getNodeModulesDirs(start, modules); }, + opts + ); + } + + var dirs = getNodeModulesDirs(start, modules); + return opts && opts.paths ? dirs.concat(opts.paths) : dirs; +}; + + +/***/ }), +/* 203 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var isWindows = process.platform === 'win32'; + +// Regex to split a windows path into three parts: [*, device, slash, +// tail] windows-only +var splitDeviceRe = + /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + +// Regex to split the tail part of the above into [*, dir, basename, ext] +var splitTailRe = + /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; + +var win32 = {}; + +// Function to split a filename into [root, dir, basename, ext] +function win32SplitPath(filename) { + // Separate device+slash from tail + var result = splitDeviceRe.exec(filename), + device = (result[1] || '') + (result[2] || ''), + tail = result[3] || ''; + // Split the tail into dir, basename and extension + var result2 = splitTailRe.exec(tail), + dir = result2[1], + basename = result2[2], + ext = result2[3]; + return [device, dir, basename, ext]; +} + +win32.parse = function(pathString) { + if (typeof pathString !== 'string') { + throw new TypeError( + "Parameter 'pathString' must be a string, not " + typeof pathString + ); + } + var allParts = win32SplitPath(pathString); + if (!allParts || allParts.length !== 4) { + throw new TypeError("Invalid path '" + pathString + "'"); + } + return { + root: allParts[0], + dir: allParts[0] + allParts[1].slice(0, -1), + base: allParts[2], + ext: allParts[3], + name: allParts[2].slice(0, allParts[2].length - allParts[3].length) + }; +}; + + + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var posix = {}; + + +function posixSplitPath(filename) { + return splitPathRe.exec(filename).slice(1); +} + + +posix.parse = function(pathString) { + if (typeof pathString !== 'string') { + throw new TypeError( + "Parameter 'pathString' must be a string, not " + typeof pathString + ); + } + var allParts = posixSplitPath(pathString); + if (!allParts || allParts.length !== 4) { + throw new TypeError("Invalid path '" + pathString + "'"); + } + allParts[1] = allParts[1] || ''; + allParts[2] = allParts[2] || ''; + allParts[3] = allParts[3] || ''; + + return { + root: allParts[0], + dir: allParts[0] + allParts[1].slice(0, -1), + base: allParts[2], + ext: allParts[3], + name: allParts[2].slice(0, allParts[2].length - allParts[3].length) + }; +}; + + +if (isWindows) + module.exports = win32.parse; +else /* posix */ + module.exports = posix.parse; + +module.exports.posix = posix.parse; +module.exports.win32 = win32.parse; + + +/***/ }), +/* 204 */ +/***/ (function(module, exports) { + +module.exports = function (x, opts) { + /** + * This file is purposefully a passthrough. It's expected that third-party + * environments will override it at runtime in order to inject special logic + * into `resolve` (by manipulating the options). One such example is the PnP + * code path in Yarn. + */ + + return opts || {}; +}; + + +/***/ }), +/* 205 */ +/***/ (function(module, exports, __webpack_require__) { + +var core = __webpack_require__(206); + +module.exports = function isCore(x) { + return Object.prototype.hasOwnProperty.call(core, x); +}; + + +/***/ }), +/* 206 */ +/***/ (function(module, exports, __webpack_require__) { + +var current = (process.versions && process.versions.node && process.versions.node.split('.')) || []; + +function specifierIncluded(specifier) { + var parts = specifier.split(' '); + var op = parts.length > 1 ? parts[0] : '='; + var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.'); + + for (var i = 0; i < 3; ++i) { + var cur = Number(current[i] || 0); + var ver = Number(versionParts[i] || 0); + if (cur === ver) { + continue; // eslint-disable-line no-restricted-syntax, no-continue + } + if (op === '<') { + return cur < ver; + } else if (op === '>=') { + return cur >= ver; + } else { + return false; + } + } + return op === '>='; +} + +function matchesRange(range) { + var specifiers = range.split(/ ?&& ?/); + if (specifiers.length === 0) { return false; } + for (var i = 0; i < specifiers.length; ++i) { + if (!specifierIncluded(specifiers[i])) { return false; } + } + return true; +} + +function versionIncluded(specifierValue) { + if (typeof specifierValue === 'boolean') { return specifierValue; } + if (specifierValue && typeof specifierValue === 'object') { + for (var i = 0; i < specifierValue.length; ++i) { + if (matchesRange(specifierValue[i])) { return true; } + } + return false; + } + return matchesRange(specifierValue); +} + +var data = __webpack_require__(207); + +var core = {}; +for (var mod in data) { // eslint-disable-line no-restricted-syntax + if (Object.prototype.hasOwnProperty.call(data, mod)) { + core[mod] = versionIncluded(data[mod]); + } +} +module.exports = core; + + +/***/ }), +/* 207 */ +/***/ (function(module) { + +module.exports = JSON.parse("{\"assert\":true,\"async_hooks\":\">= 8\",\"buffer_ieee754\":\"< 0.9.7\",\"buffer\":true,\"child_process\":true,\"cluster\":true,\"console\":true,\"constants\":true,\"crypto\":true,\"_debug_agent\":\">= 1 && < 8\",\"_debugger\":\"< 8\",\"dgram\":true,\"dns\":true,\"domain\":true,\"events\":true,\"freelist\":\"< 6\",\"fs\":true,\"fs/promises\":[\">= 10 && < 10.1\",\">= 14\"],\"_http_agent\":\">= 0.11.1\",\"_http_client\":\">= 0.11.1\",\"_http_common\":\">= 0.11.1\",\"_http_incoming\":\">= 0.11.1\",\"_http_outgoing\":\">= 0.11.1\",\"_http_server\":\">= 0.11.1\",\"http\":true,\"http2\":\">= 8.8\",\"https\":true,\"inspector\":\">= 8.0.0\",\"_linklist\":\"< 8\",\"module\":true,\"net\":true,\"node-inspect/lib/_inspect\":\">= 7.6.0 && < 12\",\"node-inspect/lib/internal/inspect_client\":\">= 7.6.0 && < 12\",\"node-inspect/lib/internal/inspect_repl\":\">= 7.6.0 && < 12\",\"os\":true,\"path\":true,\"perf_hooks\":\">= 8.5\",\"process\":\">= 1\",\"punycode\":true,\"querystring\":true,\"readline\":true,\"repl\":true,\"smalloc\":\">= 0.11.5 && < 3\",\"_stream_duplex\":\">= 0.9.4\",\"_stream_transform\":\">= 0.9.4\",\"_stream_wrap\":\">= 1.4.1\",\"_stream_passthrough\":\">= 0.9.4\",\"_stream_readable\":\">= 0.9.4\",\"_stream_writable\":\">= 0.9.4\",\"stream\":true,\"string_decoder\":true,\"sys\":true,\"timers\":true,\"_tls_common\":\">= 0.11.13\",\"_tls_legacy\":\">= 0.11.3 && < 10\",\"_tls_wrap\":\">= 0.11.3\",\"tls\":true,\"trace_events\":\">= 10\",\"tty\":true,\"url\":true,\"util\":true,\"v8/tools/arguments\":\">= 10 && < 12\",\"v8/tools/codemap\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/consarray\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/csvparser\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/logreader\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/profile_view\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/splaytree\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8\":\">= 1\",\"vm\":true,\"wasi\":\">= 13.4 && < 13.5\",\"worker_threads\":\">= 11.7\",\"zlib\":true}"); + +/***/ }), +/* 208 */ +/***/ (function(module, exports, __webpack_require__) { + +var isCore = __webpack_require__(205); +var fs = __webpack_require__(133); +var path = __webpack_require__(4); +var caller = __webpack_require__(201); +var nodeModulesPaths = __webpack_require__(202); +var normalizeOptions = __webpack_require__(204); + +var realpathFS = fs.realpathSync && typeof fs.realpathSync.native === 'function' ? fs.realpathSync.native : fs.realpathSync; + +var defaultIsFile = function isFile(file) { + try { + var stat = fs.statSync(file); + } catch (e) { + if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false; + throw e; + } + return stat.isFile() || stat.isFIFO(); +}; + +var defaultIsDir = function isDirectory(dir) { + try { + var stat = fs.statSync(dir); + } catch (e) { + if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false; + throw e; + } + return stat.isDirectory(); +}; + +var defaultRealpathSync = function realpathSync(x) { + try { + return realpathFS(x); + } catch (realpathErr) { + if (realpathErr.code !== 'ENOENT') { + throw realpathErr; + } + } + return x; +}; + +var maybeRealpathSync = function maybeRealpathSync(realpathSync, x, opts) { + if (opts && opts.preserveSymlinks === false) { + return realpathSync(x); + } + return x; +}; + +var getPackageCandidates = function getPackageCandidates(x, start, opts) { + var dirs = nodeModulesPaths(start, opts, x); + for (var i = 0; i < dirs.length; i++) { + dirs[i] = path.join(dirs[i], x); + } + return dirs; +}; + +module.exports = function resolveSync(x, options) { + if (typeof x !== 'string') { + throw new TypeError('Path must be a string.'); + } + var opts = normalizeOptions(x, options); + + var isFile = opts.isFile || defaultIsFile; + var readFileSync = opts.readFileSync || fs.readFileSync; + var isDirectory = opts.isDirectory || defaultIsDir; + var realpathSync = opts.realpathSync || defaultRealpathSync; + var packageIterator = opts.packageIterator; + + var extensions = opts.extensions || ['.js']; + var basedir = opts.basedir || path.dirname(caller()); + var parent = opts.filename || basedir; + + opts.paths = opts.paths || []; + + // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory + var absoluteStart = maybeRealpathSync(realpathSync, path.resolve(basedir), opts); + + if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) { + var res = path.resolve(absoluteStart, x); + if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/'; + var m = loadAsFileSync(res) || loadAsDirectorySync(res); + if (m) return maybeRealpathSync(realpathSync, m, opts); + } else if (isCore(x)) { + return x; + } else { + var n = loadNodeModulesSync(x, absoluteStart); + if (n) return maybeRealpathSync(realpathSync, n, opts); + } + + var err = new Error("Cannot find module '" + x + "' from '" + parent + "'"); + err.code = 'MODULE_NOT_FOUND'; + throw err; + + function loadAsFileSync(x) { + var pkg = loadpkg(path.dirname(x)); + + if (pkg && pkg.dir && pkg.pkg && opts.pathFilter) { + var rfile = path.relative(pkg.dir, x); + var r = opts.pathFilter(pkg.pkg, x, rfile); + if (r) { + x = path.resolve(pkg.dir, r); // eslint-disable-line no-param-reassign + } + } + + if (isFile(x)) { + return x; + } + + for (var i = 0; i < extensions.length; i++) { + var file = x + extensions[i]; + if (isFile(file)) { + return file; + } + } + } + + function loadpkg(dir) { + if (dir === '' || dir === '/') return; + if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) { + return; + } + if ((/[/\\]node_modules[/\\]*$/).test(dir)) return; + + var pkgfile = path.join(maybeRealpathSync(realpathSync, dir, opts), 'package.json'); + + if (!isFile(pkgfile)) { + return loadpkg(path.dirname(dir)); + } + + var body = readFileSync(pkgfile); + + try { + var pkg = JSON.parse(body); + } catch (jsonErr) {} + + if (pkg && opts.packageFilter) { + // v2 will pass pkgfile + pkg = opts.packageFilter(pkg, /*pkgfile,*/ dir); // eslint-disable-line spaced-comment + } + + return { pkg: pkg, dir: dir }; + } + + function loadAsDirectorySync(x) { + var pkgfile = path.join(maybeRealpathSync(realpathSync, x, opts), '/package.json'); + if (isFile(pkgfile)) { + try { + var body = readFileSync(pkgfile, 'UTF8'); + var pkg = JSON.parse(body); + } catch (e) {} + + if (pkg && opts.packageFilter) { + // v2 will pass pkgfile + pkg = opts.packageFilter(pkg, /*pkgfile,*/ x); // eslint-disable-line spaced-comment + } + + if (pkg && pkg.main) { + if (typeof pkg.main !== 'string') { + var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); + mainError.code = 'INVALID_PACKAGE_MAIN'; + throw mainError; + } + if (pkg.main === '.' || pkg.main === './') { + pkg.main = 'index'; + } + try { + var m = loadAsFileSync(path.resolve(x, pkg.main)); + if (m) return m; + var n = loadAsDirectorySync(path.resolve(x, pkg.main)); + if (n) return n; + } catch (e) {} + } + } + + return loadAsFileSync(path.join(x, '/index')); + } + + function loadNodeModulesSync(x, start) { + var thunk = function () { return getPackageCandidates(x, start, opts); }; + var dirs = packageIterator ? packageIterator(x, start, thunk, opts) : thunk(); + + for (var i = 0; i < dirs.length; i++) { + var dir = dirs[i]; + if (isDirectory(path.dirname(dir))) { + var m = loadAsFileSync(dir); + if (m) return m; + var n = loadAsDirectorySync(dir); + if (n) return n; + } + } + } +}; + + +/***/ }), +/* 209 */ +/***/ (function(module, exports) { + +module.exports = extractDescription + +// Extracts description from contents of a readme file in markdown format +function extractDescription (d) { + if (!d) return; + if (d === "ERROR: No README data found!") return; + // the first block of text before the first heading + // that isn't the first line heading + d = d.trim().split('\n') + for (var s = 0; d[s] && d[s].trim().match(/^(#|$)/); s ++); + var l = d.length + for (var e = s + 1; e < l && d[e].trim(); e ++); + return d.slice(s, e).join(' ').trim() +} + + +/***/ }), +/* 210 */ +/***/ (function(module) { + +module.exports = JSON.parse("{\"topLevel\":{\"dependancies\":\"dependencies\",\"dependecies\":\"dependencies\",\"depdenencies\":\"dependencies\",\"devEependencies\":\"devDependencies\",\"depends\":\"dependencies\",\"dev-dependencies\":\"devDependencies\",\"devDependences\":\"devDependencies\",\"devDepenencies\":\"devDependencies\",\"devdependencies\":\"devDependencies\",\"repostitory\":\"repository\",\"repo\":\"repository\",\"prefereGlobal\":\"preferGlobal\",\"hompage\":\"homepage\",\"hampage\":\"homepage\",\"autohr\":\"author\",\"autor\":\"author\",\"contributers\":\"contributors\",\"publicationConfig\":\"publishConfig\",\"script\":\"scripts\"},\"bugs\":{\"web\":\"url\",\"name\":\"url\"},\"script\":{\"server\":\"start\",\"tests\":\"test\"}}"); + +/***/ }), +/* 211 */ +/***/ (function(module, exports, __webpack_require__) { + +var util = __webpack_require__(111) +var messages = __webpack_require__(212) + +module.exports = function() { + var args = Array.prototype.slice.call(arguments, 0) + var warningName = args.shift() + if (warningName == "typo") { + return makeTypoWarning.apply(null,args) + } + else { + var msgTemplate = messages[warningName] ? messages[warningName] : warningName + ": '%s'" + args.unshift(msgTemplate) + return util.format.apply(null, args) + } } -Parser.prototype = parser;parser.Parser = Parser; -return new Parser; -})(); +function makeTypoWarning (providedName, probableName, field) { + if (field) { + providedName = field + "['" + providedName + "']" + probableName = field + "['" + probableName + "']" + } + return util.format(messages.typo, providedName, probableName) +} + + +/***/ }), +/* 212 */ +/***/ (function(module) { + +module.exports = JSON.parse("{\"repositories\":\"'repositories' (plural) Not supported. Please pick one as the 'repository' field\",\"missingRepository\":\"No repository field.\",\"brokenGitUrl\":\"Probably broken git url: %s\",\"nonObjectScripts\":\"scripts must be an object\",\"nonStringScript\":\"script values must be string commands\",\"nonArrayFiles\":\"Invalid 'files' member\",\"invalidFilename\":\"Invalid filename in 'files' list: %s\",\"nonArrayBundleDependencies\":\"Invalid 'bundleDependencies' list. Must be array of package names\",\"nonStringBundleDependency\":\"Invalid bundleDependencies member: %s\",\"nonDependencyBundleDependency\":\"Non-dependency in bundleDependencies: %s\",\"nonObjectDependencies\":\"%s field must be an object\",\"nonStringDependency\":\"Invalid dependency: %s %s\",\"deprecatedArrayDependencies\":\"specifying %s as array is deprecated\",\"deprecatedModules\":\"modules field is deprecated\",\"nonArrayKeywords\":\"keywords should be an array of strings\",\"nonStringKeyword\":\"keywords should be an array of strings\",\"conflictingName\":\"%s is also the name of a node core module.\",\"nonStringDescription\":\"'description' field should be a string\",\"missingDescription\":\"No description\",\"missingReadme\":\"No README data\",\"missingLicense\":\"No license field.\",\"nonEmailUrlBugsString\":\"Bug string field must be url, email, or {email,url}\",\"nonUrlBugsUrlField\":\"bugs.url field must be a string url. Deleted.\",\"nonEmailBugsEmailField\":\"bugs.email field must be a string email. Deleted.\",\"emptyNormalizedBugs\":\"Normalized value of bugs field is an empty object. Deleted.\",\"nonUrlHomepage\":\"homepage field must be a string url. Deleted.\",\"invalidLicense\":\"license should be a valid SPDX license expression\",\"typo\":\"%s should probably be %s.\"}"); + +/***/ }), +/* 213 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const path = __webpack_require__(4); +const writeJsonFile = __webpack_require__(214); +const sortKeys = __webpack_require__(228); + +const dependencyKeys = new Set([ + 'dependencies', + 'devDependencies', + 'optionalDependencies', + 'peerDependencies' +]); + +function normalize(packageJson) { + const result = {}; + + for (const key of Object.keys(packageJson)) { + if (!dependencyKeys.has(key)) { + result[key] = packageJson[key]; + } else if (Object.keys(packageJson[key]).length !== 0) { + result[key] = sortKeys(packageJson[key]); + } + } + + return result; +} + +module.exports = async (filePath, data, options) => { + if (typeof filePath !== 'string') { + options = data; + data = filePath; + filePath = '.'; + } + + options = { + normalize: true, + ...options, + detectIndent: true + }; + + filePath = path.basename(filePath) === 'package.json' ? filePath : path.join(filePath, 'package.json'); + + data = options.normalize ? normalize(data) : data; + + return writeJsonFile(filePath, data, options); +}; + +module.exports.sync = (filePath, data, options) => { + if (typeof filePath !== 'string') { + options = data; + data = filePath; + filePath = '.'; + } + + options = { + normalize: true, + ...options, + detectIndent: true + }; + + filePath = path.basename(filePath) === 'package.json' ? filePath : path.join(filePath, 'package.json'); + + data = options.normalize ? normalize(data) : data; + + writeJsonFile.sync(filePath, data, options); +}; + + +/***/ }), +/* 214 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const path = __webpack_require__(4); +const fs = __webpack_require__(215); +const writeFileAtomic = __webpack_require__(219); +const sortKeys = __webpack_require__(228); +const makeDir = __webpack_require__(230); +const pify = __webpack_require__(231); +const detectIndent = __webpack_require__(232); + +const init = (fn, filePath, data, options) => { + if (!filePath) { + throw new TypeError('Expected a filepath'); + } + + if (data === undefined) { + throw new TypeError('Expected data to stringify'); + } + + options = Object.assign({ + indent: '\t', + sortKeys: false + }, options); + + if (options.sortKeys) { + data = sortKeys(data, { + deep: true, + compare: typeof options.sortKeys === 'function' ? options.sortKeys : undefined + }); + } + + return fn(filePath, data, options); +}; + +const readFile = filePath => pify(fs.readFile)(filePath, 'utf8').catch(() => {}); + +const main = (filePath, data, options) => { + return (options.detectIndent ? readFile(filePath) : Promise.resolve()) + .then(string => { + const indent = string ? detectIndent(string).indent : options.indent; + const json = JSON.stringify(data, options.replacer, indent); + + return pify(writeFileAtomic)(filePath, `${json}\n`, {mode: options.mode}); + }); +}; + +const mainSync = (filePath, data, options) => { + let {indent} = options; + + if (options.detectIndent) { + try { + const file = fs.readFileSync(filePath, 'utf8'); + indent = detectIndent(file).indent; + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + } + } + + const json = JSON.stringify(data, options.replacer, indent); + + return writeFileAtomic.sync(filePath, `${json}\n`, {mode: options.mode}); +}; + +const writeJsonFile = (filePath, data, options) => { + return makeDir(path.dirname(filePath), {fs}) + .then(() => init(main, filePath, data, options)); +}; + +module.exports = writeJsonFile; +// TODO: Remove this for the next major release +module.exports.default = writeJsonFile; +module.exports.sync = (filePath, data, options) => { + makeDir.sync(path.dirname(filePath), {fs}); + init(mainSync, filePath, data, options); +}; + + +/***/ }), +/* 215 */ +/***/ (function(module, exports, __webpack_require__) { + +var fs = __webpack_require__(133) +var polyfills = __webpack_require__(216) +var legacy = __webpack_require__(217) +var clone = __webpack_require__(218) + +var queue = [] + +var util = __webpack_require__(111) + +function noop () {} + +var debug = noop +if (util.debuglog) + debug = util.debuglog('gfs4') +else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) + debug = function() { + var m = util.format.apply(util, arguments) + m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') + console.error(m) + } + +if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { + process.on('exit', function() { + debug(queue) + __webpack_require__(139).equal(queue.length, 0) + }) +} + +module.exports = patch(clone(fs)) +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { + module.exports = patch(fs) + fs.__patched = true; +} + +// Always patch fs.close/closeSync, because we want to +// retry() whenever a close happens *anywhere* in the program. +// This is essential when multiple graceful-fs instances are +// in play at the same time. +module.exports.close = (function (fs$close) { return function (fd, cb) { + return fs$close.call(fs, fd, function (err) { + if (!err) + retry() + + if (typeof cb === 'function') + cb.apply(this, arguments) + }) +}})(fs.close) + +module.exports.closeSync = (function (fs$closeSync) { return function (fd) { + // Note that graceful-fs also retries when fs.closeSync() fails. + // Looks like a bug to me, although it's probably a harmless one. + var rval = fs$closeSync.apply(fs, arguments) + retry() + return rval +}})(fs.closeSync) + +// Only patch fs once, otherwise we'll run into a memory leak if +// graceful-fs is loaded multiple times, such as in test environments that +// reset the loaded modules between tests. +// We look for the string `graceful-fs` from the comment above. This +// way we are not adding any extra properties and it will detect if older +// versions of graceful-fs are installed. +if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) { + fs.closeSync = module.exports.closeSync; + fs.close = module.exports.close; +} + +function patch (fs) { + // Everything that references the open() function needs to be in here + polyfills(fs) + fs.gracefulify = patch + fs.FileReadStream = ReadStream; // Legacy name. + fs.FileWriteStream = WriteStream; // Legacy name. + fs.createReadStream = createReadStream + fs.createWriteStream = createWriteStream + var fs$readFile = fs.readFile + fs.readFile = readFile + function readFile (path, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$readFile(path, options, cb) + + function go$readFile (path, options, cb) { + return fs$readFile(path, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readFile, [path, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$writeFile = fs.writeFile + fs.writeFile = writeFile + function writeFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$writeFile(path, data, options, cb) + + function go$writeFile (path, data, options, cb) { + return fs$writeFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$writeFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$appendFile = fs.appendFile + if (fs$appendFile) + fs.appendFile = appendFile + function appendFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$appendFile(path, data, options, cb) + + function go$appendFile (path, data, options, cb) { + return fs$appendFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$appendFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$readdir = fs.readdir + fs.readdir = readdir + function readdir (path, options, cb) { + var args = [path] + if (typeof options !== 'function') { + args.push(options) + } else { + cb = options + } + args.push(go$readdir$cb) + + return go$readdir(args) + + function go$readdir$cb (err, files) { + if (files && files.sort) + files.sort() + + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readdir, [args]]) + + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + } + } + + function go$readdir (args) { + return fs$readdir.apply(fs, args) + } + + if (process.version.substr(0, 4) === 'v0.8') { + var legStreams = legacy(fs) + ReadStream = legStreams.ReadStream + WriteStream = legStreams.WriteStream + } + + var fs$ReadStream = fs.ReadStream + if (fs$ReadStream) { + ReadStream.prototype = Object.create(fs$ReadStream.prototype) + ReadStream.prototype.open = ReadStream$open + } + + var fs$WriteStream = fs.WriteStream + if (fs$WriteStream) { + WriteStream.prototype = Object.create(fs$WriteStream.prototype) + WriteStream.prototype.open = WriteStream$open + } + + fs.ReadStream = ReadStream + fs.WriteStream = WriteStream + + function ReadStream (path, options) { + if (this instanceof ReadStream) + return fs$ReadStream.apply(this, arguments), this + else + return ReadStream.apply(Object.create(ReadStream.prototype), arguments) + } + + function ReadStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + if (that.autoClose) + that.destroy() + + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + that.read() + } + }) + } + + function WriteStream (path, options) { + if (this instanceof WriteStream) + return fs$WriteStream.apply(this, arguments), this + else + return WriteStream.apply(Object.create(WriteStream.prototype), arguments) + } + + function WriteStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + that.destroy() + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + } + }) + } + + function createReadStream (path, options) { + return new ReadStream(path, options) + } -if (true) { -exports.parser = spdxparse; -exports.Parser = spdxparse.Parser; -exports.parse = function () { return spdxparse.parse.apply(spdxparse, arguments); }; -exports.main = function commonjsMain(args) { - if (!args[1]) { - console.log('Usage: '+args[0]+' FILE'); - process.exit(1); + function createWriteStream (path, options) { + return new WriteStream(path, options) + } + + var fs$open = fs.open + fs.open = open + function open (path, flags, mode, cb) { + if (typeof mode === 'function') + cb = mode, mode = null + + return go$open(path, flags, mode, cb) + + function go$open (path, flags, mode, cb) { + return fs$open(path, flags, mode, function (err, fd) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$open, [path, flags, mode, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) } - var source = __webpack_require__(132).readFileSync(__webpack_require__(4).normalize(args[1]), "utf8"); - return exports.parser.parse(source); -}; -if ( true && __webpack_require__.c[__webpack_require__.s] === module) { - exports.main(process.argv.slice(1)); + } + + return fs +} + +function enqueue (elem) { + debug('ENQUEUE', elem[0].name, elem[1]) + queue.push(elem) } + +function retry () { + var elem = queue.shift() + if (elem) { + debug('RETRY', elem[0].name, elem[1]) + elem[0].apply(null, elem[1]) + } } -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) /***/ }), -/* 186 */ +/* 216 */ /***/ (function(module, exports, __webpack_require__) { -var licenseIDs = __webpack_require__(187); +var constants = __webpack_require__(135) -function valid(string) { - return licenseIDs.indexOf(string) > -1; +var origCwd = process.cwd +var cwd = null + +var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform + +process.cwd = function() { + if (!cwd) + cwd = origCwd.call(process) + return cwd } +try { + process.cwd() +} catch (er) {} -// Common transpositions of license identifier acronyms -var transpositions = [ - ['APGL', 'AGPL'], - ['Gpl', 'GPL'], - ['GLP', 'GPL'], - ['APL', 'Apache'], - ['ISD', 'ISC'], - ['GLP', 'GPL'], - ['IST', 'ISC'], - ['Claude', 'Clause'], - [' or later', '+'], - [' International', ''], - ['GNU', 'GPL'], - ['GUN', 'GPL'], - ['+', ''], - ['GNU GPL', 'GPL'], - ['GNU/GPL', 'GPL'], - ['GNU GLP', 'GPL'], - ['GNU General Public License', 'GPL'], - ['Gnu public license', 'GPL'], - ['GNU Public License', 'GPL'], - ['GNU GENERAL PUBLIC LICENSE', 'GPL'], - ['MTI', 'MIT'], - ['Mozilla Public License', 'MPL'], - ['WTH', 'WTF'], - ['-License', ''] -]; +var chdir = process.chdir +process.chdir = function(d) { + cwd = null + chdir.call(process, d) +} -var TRANSPOSED = 0; -var CORRECT = 1; +module.exports = patch -// Simple corrections to nearly valid identifiers. -var transforms = [ - // e.g. 'mit' - function(argument) { - return argument.toUpperCase(); - }, - // e.g. 'MIT ' - function(argument) { - return argument.trim(); - }, - // e.g. 'M.I.T.' - function(argument) { - return argument.replace(/\./g, ''); - }, - // e.g. 'Apache- 2.0' - function(argument) { - return argument.replace(/\s+/g, ''); - }, - // e.g. 'CC BY 4.0'' - function(argument) { - return argument.replace(/\s+/g, '-'); - }, - // e.g. 'LGPLv2.1' - function(argument) { - return argument.replace('v', '-'); - }, - // e.g. 'Apache 2.0' - function(argument) { - return argument.replace(/,?\s*(\d)/, '-$1'); - }, - // e.g. 'GPL 2' - function(argument) { - return argument.replace(/,?\s*(\d)/, '-$1.0'); - }, - // e.g. 'Apache Version 2.0' - function(argument) { - return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2'); - }, - // e.g. 'Apache Version 2' - function(argument) { - return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2.0'); - }, - // e.g. 'ZLIB' - function(argument) { - return argument[0].toUpperCase() + argument.slice(1); - }, - // e.g. 'MPL/2.0' - function(argument) { - return argument.replace('/', '-'); - }, - // e.g. 'Apache 2' - function(argument) { - return argument - .replace(/\s*V\s*(\d)/, '-$1') - .replace(/(\d)$/, '$1.0'); - }, - // e.g. 'GPL-2.0-' - function(argument) { - return argument.slice(0, argument.length - 1); - }, - // e.g. 'GPL2' - function(argument) { - return argument.replace(/(\d)$/, '-$1.0'); - }, - // e.g. 'BSD 3' - function(argument) { - return argument.replace(/(-| )?(\d)$/, '-$2-Clause'); - }, - // e.g. 'BSD clause 3' - function(argument) { - return argument.replace(/(-| )clause(-| )(\d)/, '-$3-Clause'); - }, - // e.g. 'BY-NC-4.0' - function(argument) { - return 'CC-' + argument; - }, - // e.g. 'BY-NC' - function(argument) { - return 'CC-' + argument + '-4.0'; - }, - // e.g. 'Attribution-NonCommercial' - function(argument) { - return argument - .replace('Attribution', 'BY') - .replace('NonCommercial', 'NC') - .replace('NoDerivatives', 'ND') - .replace(/ (\d)/, '-$1') - .replace(/ ?International/, ''); - }, - // e.g. 'Attribution-NonCommercial' - function(argument) { - return 'CC-' + - argument - .replace('Attribution', 'BY') - .replace('NonCommercial', 'NC') - .replace('NoDerivatives', 'ND') - .replace(/ (\d)/, '-$1') - .replace(/ ?International/, '') + - '-4.0'; +function patch (fs) { + // (re-)implement some things that are known busted or missing. + + // lchmod, broken prior to 0.6.2 + // back-port the fix here. + if (constants.hasOwnProperty('O_SYMLINK') && + process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + patchLchmod(fs) } -]; -// If all else fails, guess that strings containing certain substrings -// meant to identify certain licenses. -var lastResorts = [ - ['UNLI', 'Unlicense'], - ['WTF', 'WTFPL'], - ['2 CLAUSE', 'BSD-2-Clause'], - ['2-CLAUSE', 'BSD-2-Clause'], - ['3 CLAUSE', 'BSD-3-Clause'], - ['3-CLAUSE', 'BSD-3-Clause'], - ['AFFERO', 'AGPL-3.0'], - ['AGPL', 'AGPL-3.0'], - ['APACHE', 'Apache-2.0'], - ['ARTISTIC', 'Artistic-2.0'], - ['Affero', 'AGPL-3.0'], - ['BEER', 'Beerware'], - ['BOOST', 'BSL-1.0'], - ['BSD', 'BSD-2-Clause'], - ['ECLIPSE', 'EPL-1.0'], - ['FUCK', 'WTFPL'], - ['GNU', 'GPL-3.0'], - ['LGPL', 'LGPL-3.0'], - ['GPL', 'GPL-3.0'], - ['MIT', 'MIT'], - ['MPL', 'MPL-2.0'], - ['X11', 'X11'], - ['ZLIB', 'Zlib'] -]; + // lutimes implementation, or no-op + if (!fs.lutimes) { + patchLutimes(fs) + } -var SUBSTRING = 0; -var IDENTIFIER = 1; + // https://github.com/isaacs/node-graceful-fs/issues/4 + // Chown should not fail on einval or eperm if non-root. + // It should not fail on enosys ever, as this just indicates + // that a fs doesn't support the intended operation. -var validTransformation = function(identifier) { - for (var i = 0; i < transforms.length; i++) { - var transformed = transforms[i](identifier); - if (transformed !== identifier && valid(transformed)) { - return transformed; + fs.chown = chownFix(fs.chown) + fs.fchown = chownFix(fs.fchown) + fs.lchown = chownFix(fs.lchown) + + fs.chmod = chmodFix(fs.chmod) + fs.fchmod = chmodFix(fs.fchmod) + fs.lchmod = chmodFix(fs.lchmod) + + fs.chownSync = chownFixSync(fs.chownSync) + fs.fchownSync = chownFixSync(fs.fchownSync) + fs.lchownSync = chownFixSync(fs.lchownSync) + + fs.chmodSync = chmodFixSync(fs.chmodSync) + fs.fchmodSync = chmodFixSync(fs.fchmodSync) + fs.lchmodSync = chmodFixSync(fs.lchmodSync) + + fs.stat = statFix(fs.stat) + fs.fstat = statFix(fs.fstat) + fs.lstat = statFix(fs.lstat) + + fs.statSync = statFixSync(fs.statSync) + fs.fstatSync = statFixSync(fs.fstatSync) + fs.lstatSync = statFixSync(fs.lstatSync) + + // if lchmod/lchown do not exist, then make them no-ops + if (!fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + if (cb) process.nextTick(cb) } + fs.lchmodSync = function () {} + } + if (!fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + if (cb) process.nextTick(cb) + } + fs.lchownSync = function () {} } - return null; -}; -var validLastResort = function(identifier) { - var upperCased = identifier.toUpperCase(); - for (var i = 0; i < lastResorts.length; i++) { - var lastResort = lastResorts[i]; - if (upperCased.indexOf(lastResort[SUBSTRING]) > -1) { - return lastResort[IDENTIFIER]; + // on Windows, A/V software can lock the directory, causing this + // to fail with an EACCES or EPERM if the directory contains newly + // created files. Try again on failure, for up to 60 seconds. + + // Set the timeout this long because some Windows Anti-Virus, such as Parity + // bit9, may lock files for up to a minute, causing npm package install + // failures. Also, take care to yield the scheduler. Windows scheduling gives + // CPU to a busy looping process, which can cause the program causing the lock + // contention to be starved of CPU by node, so the contention doesn't resolve. + if (platform === "win32") { + fs.rename = (function (fs$rename) { return function (from, to, cb) { + var start = Date.now() + var backoff = 0; + fs$rename(from, to, function CB (er) { + if (er + && (er.code === "EACCES" || er.code === "EPERM") + && Date.now() - start < 60000) { + setTimeout(function() { + fs.stat(to, function (stater, st) { + if (stater && stater.code === "ENOENT") + fs$rename(from, to, CB); + else + cb(er) + }) + }, backoff) + if (backoff < 100) + backoff += 10; + return; + } + if (cb) cb(er) + }) + }})(fs.rename) + } + + // if read() returns EAGAIN, then just try it again. + fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { + var callback + if (callback_ && typeof callback_ === 'function') { + var eagCounter = 0 + callback = function (er, _, __) { + if (er && er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + callback_.apply(this, arguments) + } + } + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + }})(fs.read) + + fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { + var eagCounter = 0 + while (true) { + try { + return fs$readSync.call(fs, fd, buffer, offset, length, position) + } catch (er) { + if (er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + continue + } + throw er + } + } + }})(fs.readSync) + + function patchLchmod (fs) { + fs.lchmod = function (path, mode, callback) { + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + if (callback) callback(err) + return + } + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + if (callback) callback(err || err2) + }) + }) + }) + } + + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) + + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + var threw = true + var ret + try { + ret = fs.fchmodSync(fd, mode) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret } } - return null; -}; -var anyCorrection = function(identifier, check) { - for (var i = 0; i < transpositions.length; i++) { - var transposition = transpositions[i]; - var transposed = transposition[TRANSPOSED]; - if (identifier.indexOf(transposed) > -1) { - var corrected = identifier.replace( - transposed, - transposition[CORRECT] - ); - var checked = check(corrected); - if (checked !== null) { - return checked; + function patchLutimes (fs) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + if (er) { + if (cb) cb(er) + return + } + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + if (cb) cb(er || er2) + }) + }) + }) + } + + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + var ret + var threw = true + try { + ret = fs.futimesSync(fd, at, mt) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } + + } else { + fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } + fs.lutimesSync = function () {} + } + } + + function chmodFix (orig) { + if (!orig) return orig + return function (target, mode, cb) { + return orig.call(fs, target, mode, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } + } + + function chmodFixSync (orig) { + if (!orig) return orig + return function (target, mode) { + try { + return orig.call(fs, target, mode) + } catch (er) { + if (!chownErOk(er)) throw er + } + } + } + + + function chownFix (orig) { + if (!orig) return orig + return function (target, uid, gid, cb) { + return orig.call(fs, target, uid, gid, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } + } + + function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er } } } - return null; -}; -module.exports = function(identifier) { - identifier = identifier.replace(/\+$/, ''); - if (valid(identifier)) { - return identifier; - } - var transformed = validTransformation(identifier); - if (transformed !== null) { - return transformed; - } - transformed = anyCorrection(identifier, function(argument) { - if (valid(argument)) { - return argument; + + function statFix (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, cb) { + return orig.call(fs, target, function (er, stats) { + if (!stats) return cb.apply(this, arguments) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + if (cb) cb.apply(this, arguments) + }) + } + } + + function statFixSync (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target) { + var stats = orig.call(fs, target) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + return stats; } - return validTransformation(argument); - }); - if (transformed !== null) { - return transformed; - } - transformed = validLastResort(identifier); - if (transformed !== null) { - return transformed; - } - transformed = anyCorrection(identifier, validLastResort); - if (transformed !== null) { - return transformed; } - return null; -}; + // ENOSYS means that the fs doesn't support the op. Just ignore + // that, because it doesn't matter. + // + // if there's no getuid, or if getuid() is something other + // than 0, and the error is EINVAL or EPERM, then just ignore + // it. + // + // This specific case is a silent failure in cp, install, tar, + // and most other unix tools that manage permissions. + // + // When running as root, or if other types of errors are + // encountered, then it's strict. + function chownErOk (er) { + if (!er) + return true -/***/ }), -/* 187 */ -/***/ (function(module) { + if (er.code === "ENOSYS") + return true + + var nonroot = !process.getuid || process.getuid() !== 0 + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true + } + + return false + } +} -module.exports = JSON.parse("[\"Glide\",\"Abstyles\",\"AFL-1.1\",\"AFL-1.2\",\"AFL-2.0\",\"AFL-2.1\",\"AFL-3.0\",\"AMPAS\",\"APL-1.0\",\"Adobe-Glyph\",\"APAFML\",\"Adobe-2006\",\"AGPL-1.0\",\"Afmparse\",\"Aladdin\",\"ADSL\",\"AMDPLPA\",\"ANTLR-PD\",\"Apache-1.0\",\"Apache-1.1\",\"Apache-2.0\",\"AML\",\"APSL-1.0\",\"APSL-1.1\",\"APSL-1.2\",\"APSL-2.0\",\"Artistic-1.0\",\"Artistic-1.0-Perl\",\"Artistic-1.0-cl8\",\"Artistic-2.0\",\"AAL\",\"Bahyph\",\"Barr\",\"Beerware\",\"BitTorrent-1.0\",\"BitTorrent-1.1\",\"BSL-1.0\",\"Borceux\",\"BSD-2-Clause\",\"BSD-2-Clause-FreeBSD\",\"BSD-2-Clause-NetBSD\",\"BSD-3-Clause\",\"BSD-3-Clause-Clear\",\"BSD-4-Clause\",\"BSD-Protection\",\"BSD-Source-Code\",\"BSD-3-Clause-Attribution\",\"0BSD\",\"BSD-4-Clause-UC\",\"bzip2-1.0.5\",\"bzip2-1.0.6\",\"Caldera\",\"CECILL-1.0\",\"CECILL-1.1\",\"CECILL-2.0\",\"CECILL-2.1\",\"CECILL-B\",\"CECILL-C\",\"ClArtistic\",\"MIT-CMU\",\"CNRI-Jython\",\"CNRI-Python\",\"CNRI-Python-GPL-Compatible\",\"CPOL-1.02\",\"CDDL-1.0\",\"CDDL-1.1\",\"CPAL-1.0\",\"CPL-1.0\",\"CATOSL-1.1\",\"Condor-1.1\",\"CC-BY-1.0\",\"CC-BY-2.0\",\"CC-BY-2.5\",\"CC-BY-3.0\",\"CC-BY-4.0\",\"CC-BY-ND-1.0\",\"CC-BY-ND-2.0\",\"CC-BY-ND-2.5\",\"CC-BY-ND-3.0\",\"CC-BY-ND-4.0\",\"CC-BY-NC-1.0\",\"CC-BY-NC-2.0\",\"CC-BY-NC-2.5\",\"CC-BY-NC-3.0\",\"CC-BY-NC-4.0\",\"CC-BY-NC-ND-1.0\",\"CC-BY-NC-ND-2.0\",\"CC-BY-NC-ND-2.5\",\"CC-BY-NC-ND-3.0\",\"CC-BY-NC-ND-4.0\",\"CC-BY-NC-SA-1.0\",\"CC-BY-NC-SA-2.0\",\"CC-BY-NC-SA-2.5\",\"CC-BY-NC-SA-3.0\",\"CC-BY-NC-SA-4.0\",\"CC-BY-SA-1.0\",\"CC-BY-SA-2.0\",\"CC-BY-SA-2.5\",\"CC-BY-SA-3.0\",\"CC-BY-SA-4.0\",\"CC0-1.0\",\"Crossword\",\"CrystalStacker\",\"CUA-OPL-1.0\",\"Cube\",\"curl\",\"D-FSL-1.0\",\"diffmark\",\"WTFPL\",\"DOC\",\"Dotseqn\",\"DSDP\",\"dvipdfm\",\"EPL-1.0\",\"ECL-1.0\",\"ECL-2.0\",\"eGenix\",\"EFL-1.0\",\"EFL-2.0\",\"MIT-advertising\",\"MIT-enna\",\"Entessa\",\"ErlPL-1.1\",\"EUDatagrid\",\"EUPL-1.0\",\"EUPL-1.1\",\"Eurosym\",\"Fair\",\"MIT-feh\",\"Frameworx-1.0\",\"FreeImage\",\"FTL\",\"FSFAP\",\"FSFUL\",\"FSFULLR\",\"Giftware\",\"GL2PS\",\"Glulxe\",\"AGPL-3.0\",\"GFDL-1.1\",\"GFDL-1.2\",\"GFDL-1.3\",\"GPL-1.0\",\"GPL-2.0\",\"GPL-3.0\",\"LGPL-2.1\",\"LGPL-3.0\",\"LGPL-2.0\",\"gnuplot\",\"gSOAP-1.3b\",\"HaskellReport\",\"HPND\",\"IBM-pibs\",\"IPL-1.0\",\"ICU\",\"ImageMagick\",\"iMatix\",\"Imlib2\",\"IJG\",\"Info-ZIP\",\"Intel-ACPI\",\"Intel\",\"Interbase-1.0\",\"IPA\",\"ISC\",\"JasPer-2.0\",\"JSON\",\"LPPL-1.0\",\"LPPL-1.1\",\"LPPL-1.2\",\"LPPL-1.3a\",\"LPPL-1.3c\",\"Latex2e\",\"BSD-3-Clause-LBNL\",\"Leptonica\",\"LGPLLR\",\"Libpng\",\"libtiff\",\"LAL-1.2\",\"LAL-1.3\",\"LiLiQ-P-1.1\",\"LiLiQ-Rplus-1.1\",\"LiLiQ-R-1.1\",\"LPL-1.02\",\"LPL-1.0\",\"MakeIndex\",\"MTLL\",\"MS-PL\",\"MS-RL\",\"MirOS\",\"MITNFA\",\"MIT\",\"Motosoto\",\"MPL-1.0\",\"MPL-1.1\",\"MPL-2.0\",\"MPL-2.0-no-copyleft-exception\",\"mpich2\",\"Multics\",\"Mup\",\"NASA-1.3\",\"Naumen\",\"NBPL-1.0\",\"NetCDF\",\"NGPL\",\"NOSL\",\"NPL-1.0\",\"NPL-1.1\",\"Newsletr\",\"NLPL\",\"Nokia\",\"NPOSL-3.0\",\"NLOD-1.0\",\"Noweb\",\"NRL\",\"NTP\",\"Nunit\",\"OCLC-2.0\",\"ODbL-1.0\",\"PDDL-1.0\",\"OCCT-PL\",\"OGTSL\",\"OLDAP-2.2.2\",\"OLDAP-1.1\",\"OLDAP-1.2\",\"OLDAP-1.3\",\"OLDAP-1.4\",\"OLDAP-2.0\",\"OLDAP-2.0.1\",\"OLDAP-2.1\",\"OLDAP-2.2\",\"OLDAP-2.2.1\",\"OLDAP-2.3\",\"OLDAP-2.4\",\"OLDAP-2.5\",\"OLDAP-2.6\",\"OLDAP-2.7\",\"OLDAP-2.8\",\"OML\",\"OPL-1.0\",\"OSL-1.0\",\"OSL-1.1\",\"OSL-2.0\",\"OSL-2.1\",\"OSL-3.0\",\"OpenSSL\",\"OSET-PL-2.1\",\"PHP-3.0\",\"PHP-3.01\",\"Plexus\",\"PostgreSQL\",\"psfrag\",\"psutils\",\"Python-2.0\",\"QPL-1.0\",\"Qhull\",\"Rdisc\",\"RPSL-1.0\",\"RPL-1.1\",\"RPL-1.5\",\"RHeCos-1.1\",\"RSCPL\",\"RSA-MD\",\"Ruby\",\"SAX-PD\",\"Saxpath\",\"SCEA\",\"SWL\",\"SMPPL\",\"Sendmail\",\"SGI-B-1.0\",\"SGI-B-1.1\",\"SGI-B-2.0\",\"OFL-1.0\",\"OFL-1.1\",\"SimPL-2.0\",\"Sleepycat\",\"SNIA\",\"Spencer-86\",\"Spencer-94\",\"Spencer-99\",\"SMLNJ\",\"SugarCRM-1.1.3\",\"SISSL\",\"SISSL-1.2\",\"SPL-1.0\",\"Watcom-1.0\",\"TCL\",\"Unlicense\",\"TMate\",\"TORQUE-1.1\",\"TOSL\",\"Unicode-TOU\",\"UPL-1.0\",\"NCSA\",\"Vim\",\"VOSTROM\",\"VSL-1.0\",\"W3C-19980720\",\"W3C\",\"Wsuipa\",\"Xnet\",\"X11\",\"Xerox\",\"XFree86-1.1\",\"xinetd\",\"xpp\",\"XSkat\",\"YPL-1.0\",\"YPL-1.1\",\"Zed\",\"Zend-2.0\",\"Zimbra-1.3\",\"Zimbra-1.4\",\"Zlib\",\"zlib-acknowledgement\",\"ZPL-1.1\",\"ZPL-2.0\",\"ZPL-2.1\",\"BSD-3-Clause-No-Nuclear-License\",\"BSD-3-Clause-No-Nuclear-Warranty\",\"BSD-3-Clause-No-Nuclear-License-2014\",\"eCos-2.0\",\"GPL-2.0-with-autoconf-exception\",\"GPL-2.0-with-bison-exception\",\"GPL-2.0-with-classpath-exception\",\"GPL-2.0-with-font-exception\",\"GPL-2.0-with-GCC-exception\",\"GPL-3.0-with-autoconf-exception\",\"GPL-3.0-with-GCC-exception\",\"StandardML-NJ\",\"WXwindows\"]"); /***/ }), -/* 188 */ +/* 217 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var Stream = __webpack_require__(137).Stream -var url = __webpack_require__(189) -var gitHosts = __webpack_require__(190) -var GitHost = module.exports = __webpack_require__(191) +module.exports = legacy -var protocolToRepresentationMap = { - 'git+ssh': 'sshurl', - 'git+https': 'https', - 'ssh': 'sshurl', - 'git': 'git' -} +function legacy (fs) { + return { + ReadStream: ReadStream, + WriteStream: WriteStream + } -function protocolToRepresentation (protocol) { - if (protocol.substr(-1) === ':') protocol = protocol.slice(0, -1) - return protocolToRepresentationMap[protocol] || protocol -} + function ReadStream (path, options) { + if (!(this instanceof ReadStream)) return new ReadStream(path, options); -var authProtocols = { - 'git:': true, - 'https:': true, - 'git+https:': true, - 'http:': true, - 'git+http:': true -} + Stream.call(this); -var cache = {} + var self = this; -module.exports.fromUrl = function (giturl, opts) { - var key = giturl + JSON.stringify(opts || {}) + this.path = path; + this.fd = null; + this.readable = true; + this.paused = false; - if (!(key in cache)) { - cache[key] = fromUrl(giturl, opts) - } + this.flags = 'r'; + this.mode = 438; /*=0666*/ + this.bufferSize = 64 * 1024; - return cache[key] -} + options = options || {}; -function fromUrl (giturl, opts) { - if (giturl == null || giturl === '') return - var url = fixupUnqualifiedGist( - isGitHubShorthand(giturl) ? 'github:' + giturl : giturl - ) - var parsed = parseGitUrl(url) - var shortcutMatch = url.match(new RegExp('^([^:]+):(?:(?:[^@:]+(?:[^@]+)?@)?([^/]*))[/](.+?)(?:[.]git)?($|#)')) - var matches = Object.keys(gitHosts).map(function (gitHostName) { - try { - var gitHostInfo = gitHosts[gitHostName] - var auth = null - if (parsed.auth && authProtocols[parsed.protocol]) { - auth = decodeURIComponent(parsed.auth) + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.encoding) this.setEncoding(this.encoding); + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); } - var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null - var user = null - var project = null - var defaultRepresentation = null - if (shortcutMatch && shortcutMatch[1] === gitHostName) { - user = shortcutMatch[2] && decodeURIComponent(shortcutMatch[2]) - project = decodeURIComponent(shortcutMatch[3]) - defaultRepresentation = 'shortcut' - } else { - if (parsed.host !== gitHostInfo.domain) return - if (!gitHostInfo.protocols_re.test(parsed.protocol)) return - if (!parsed.path) return - var pathmatch = gitHostInfo.pathmatch - var matched = parsed.path.match(pathmatch) - if (!matched) return - if (matched[1] != null) user = decodeURIComponent(matched[1].replace(/^:/, '')) - if (matched[2] != null) project = decodeURIComponent(matched[2]) - defaultRepresentation = protocolToRepresentation(parsed.protocol) + if (this.end === undefined) { + this.end = Infinity; + } else if ('number' !== typeof this.end) { + throw TypeError('end must be a Number'); } - return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation, opts) - } catch (ex) { - if (!(ex instanceof URIError)) throw ex + + if (this.start > this.end) { + throw new Error('start must be <= end'); + } + + this.pos = this.start; } - }).filter(function (gitHostInfo) { return gitHostInfo }) - if (matches.length !== 1) return - return matches[0] -} -function isGitHubShorthand (arg) { - // Note: This does not fully test the git ref format. - // See https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html - // - // The only way to do this properly would be to shell out to - // git-check-ref-format, and as this is a fast sync function, - // we don't want to do that. Just let git fail if it turns - // out that the commit-ish is invalid. - // GH usernames cannot start with . or - - return /^[^:@%/\s.-][^:@%/\s]*[/][^:@\s/%]+(?:#.*)?$/.test(arg) -} + if (this.fd !== null) { + process.nextTick(function() { + self._read(); + }); + return; + } -function fixupUnqualifiedGist (giturl) { - // necessary for round-tripping gists - var parsed = url.parse(giturl) - if (parsed.protocol === 'gist:' && parsed.host && !parsed.path) { - return parsed.protocol + '/' + parsed.host - } else { - return giturl + fs.open(this.path, this.flags, this.mode, function (err, fd) { + if (err) { + self.emit('error', err); + self.readable = false; + return; + } + + self.fd = fd; + self.emit('open', fd); + self._read(); + }) } -} -function parseGitUrl (giturl) { - if (typeof giturl !== 'string') giturl = '' + giturl - var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/) - if (!matched) return url.parse(giturl) - return { - protocol: 'git+ssh:', - slashes: true, - auth: matched[1], - host: matched[2], - port: null, - hostname: matched[2], - hash: matched[4], - search: null, - query: null, - pathname: '/' + matched[3], - path: '/' + matched[3], - href: 'git+ssh://' + matched[1] + '@' + matched[2] + - '/' + matched[3] + (matched[4] || '') + function WriteStream (path, options) { + if (!(this instanceof WriteStream)) return new WriteStream(path, options); + + Stream.call(this); + + this.path = path; + this.fd = null; + this.writable = true; + + this.flags = 'w'; + this.encoding = 'binary'; + this.mode = 438; /*=0666*/ + this.bytesWritten = 0; + + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.start < 0) { + throw new Error('start must be >= zero'); + } + + this.pos = this.start; + } + + this.busy = false; + this._queue = []; + + if (this.fd === null) { + this._open = fs.open; + this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); + this.flush(); + } } } /***/ }), -/* 189 */ -/***/ (function(module, exports) { +/* 218 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = clone + +function clone (obj) { + if (obj === null || typeof obj !== 'object') + return obj + + if (obj instanceof Object) + var copy = { __proto__: obj.__proto__ } + else + var copy = Object.create(null) + + Object.getOwnPropertyNames(obj).forEach(function (key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) + }) + + return copy +} -module.exports = require("url"); /***/ }), -/* 190 */ +/* 219 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +module.exports = writeFile +module.exports.sync = writeFileSync +module.exports._getTmpname = getTmpname // for testing +module.exports._cleanupOnExit = cleanupOnExit -var gitHosts = module.exports = { - github: { - // First two are insecure and generally shouldn't be used any more, but - // they are still supported. - 'protocols': [ 'git', 'http', 'git+ssh', 'git+https', 'ssh', 'https' ], - 'domain': 'github.com', - 'treepath': 'tree', - 'filetemplate': 'https://{auth@}raw.githubusercontent.com/{user}/{project}/{committish}/{path}', - 'bugstemplate': 'https://{domain}/{user}/{project}/issues', - 'gittemplate': 'git://{auth@}{domain}/{user}/{project}.git{#committish}', - 'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz' - }, - bitbucket: { - 'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ], - 'domain': 'bitbucket.org', - 'treepath': 'src', - 'tarballtemplate': 'https://{domain}/{user}/{project}/get/{committish}.tar.gz' - }, - gitlab: { - 'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ], - 'domain': 'gitlab.com', - 'treepath': 'tree', - 'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#README', - 'bugstemplate': 'https://{domain}/{user}/{project}/issues', - 'tarballtemplate': 'https://{domain}/{user}/{project}/repository/archive.tar.gz?ref={committish}' - }, - gist: { - 'protocols': [ 'git', 'git+ssh', 'git+https', 'ssh', 'https' ], - 'domain': 'gist.github.com', - 'pathmatch': /^[/](?:([^/]+)[/])?([a-z0-9]+)(?:[.]git)?$/, - 'filetemplate': 'https://gist.githubusercontent.com/{user}/{project}/raw{/committish}/{path}', - 'bugstemplate': 'https://{domain}/{project}', - 'gittemplate': 'git://{domain}/{project}.git{#committish}', - 'sshtemplate': 'git@{domain}:/{project}.git{#committish}', - 'sshurltemplate': 'git+ssh://git@{domain}/{project}.git{#committish}', - 'browsetemplate': 'https://{domain}/{project}{/committish}', - 'docstemplate': 'https://{domain}/{project}{/committish}', - 'httpstemplate': 'git+https://{domain}/{project}.git{#committish}', - 'shortcuttemplate': '{type}:{project}{#committish}', - 'pathtemplate': '{project}{#committish}', - 'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz' +var fs = __webpack_require__(220) +var MurmurHash3 = __webpack_require__(224) +var onExit = __webpack_require__(225) +var path = __webpack_require__(4) +var activeFiles = {} + +// if we run inside of a worker_thread, `process.pid` is not unique +/* istanbul ignore next */ +var threadId = (function getId () { + try { + var workerThreads = __webpack_require__(227) + + /// if we are in main thread, this is set to `0` + return workerThreads.threadId + } catch (e) { + // worker_threads are not available, fallback to 0 + return 0 } -} +})() -var gitHostDefaults = { - 'sshtemplate': 'git@{domain}:{user}/{project}.git{#committish}', - 'sshurltemplate': 'git+ssh://git@{domain}/{user}/{project}.git{#committish}', - 'browsetemplate': 'https://{domain}/{user}/{project}{/tree/committish}', - 'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#readme', - 'httpstemplate': 'git+https://{auth@}{domain}/{user}/{project}.git{#committish}', - 'filetemplate': 'https://{domain}/{user}/{project}/raw/{committish}/{path}', - 'shortcuttemplate': '{type}:{user}/{project}{#committish}', - 'pathtemplate': '{user}/{project}{#committish}', - 'pathmatch': /^[/]([^/]+)[/]([^/]+?)(?:[.]git|[/])?$/ +var invocations = 0 +function getTmpname (filename) { + return filename + '.' + + MurmurHash3(__filename) + .hash(String(process.pid)) + .hash(String(threadId)) + .hash(String(++invocations)) + .result() } -Object.keys(gitHosts).forEach(function (name) { - Object.keys(gitHostDefaults).forEach(function (key) { - if (gitHosts[name][key]) return - gitHosts[name][key] = gitHostDefaults[key] - }) - gitHosts[name].protocols_re = RegExp('^(' + - gitHosts[name].protocols.map(function (protocol) { - return protocol.replace(/([\\+*{}()[\]$^|])/g, '\\$1') - }).join('|') + '):$') -}) +function cleanupOnExit (tmpfile) { + return function () { + try { + fs.unlinkSync(typeof tmpfile === 'function' ? tmpfile() : tmpfile) + } catch (_) {} + } +} +function writeFile (filename, data, options, callback) { + if (options) { + if (options instanceof Function) { + callback = options + options = {} + } else if (typeof options === 'string') { + options = { encoding: options } + } + } else { + options = {} + } -/***/ }), -/* 191 */ -/***/ (function(module, exports, __webpack_require__) { + var Promise = options.Promise || global.Promise + var truename + var fd + var tmpfile + /* istanbul ignore next -- The closure only gets called when onExit triggers */ + var removeOnExitHandler = onExit(cleanupOnExit(() => tmpfile)) + var absoluteName = path.resolve(filename) -"use strict"; + new Promise(function serializeSameFile (resolve) { + // make a queue if it doesn't already exist + if (!activeFiles[absoluteName]) activeFiles[absoluteName] = [] -var gitHosts = __webpack_require__(190) -var extend = Object.assign || __webpack_require__(111)._extend + activeFiles[absoluteName].push(resolve) // add this job to the queue + if (activeFiles[absoluteName].length === 1) resolve() // kick off the first one + }).then(function getRealPath () { + return new Promise(function (resolve) { + fs.realpath(filename, function (_, realname) { + truename = realname || filename + tmpfile = getTmpname(truename) + resolve() + }) + }) + }).then(function stat () { + return new Promise(function stat (resolve) { + if (options.mode && options.chown) resolve() + else { + // Either mode or chown is not explicitly set + // Default behavior is to copy it from original file + fs.stat(truename, function (err, stats) { + if (err || !stats) resolve() + else { + options = Object.assign({}, options) -var GitHost = module.exports = function (type, user, auth, project, committish, defaultRepresentation, opts) { - var gitHostInfo = this - gitHostInfo.type = type - Object.keys(gitHosts[type]).forEach(function (key) { - gitHostInfo[key] = gitHosts[type][key] + if (options.mode == null) { + options.mode = stats.mode + } + if (options.chown == null && process.getuid) { + options.chown = { uid: stats.uid, gid: stats.gid } + } + resolve() + } + }) + } + }) + }).then(function thenWriteFile () { + return new Promise(function (resolve, reject) { + fs.open(tmpfile, 'w', options.mode, function (err, _fd) { + fd = _fd + if (err) reject(err) + else resolve() + }) + }) + }).then(function write () { + return new Promise(function (resolve, reject) { + if (Buffer.isBuffer(data)) { + fs.write(fd, data, 0, data.length, 0, function (err) { + if (err) reject(err) + else resolve() + }) + } else if (data != null) { + fs.write(fd, String(data), 0, String(options.encoding || 'utf8'), function (err) { + if (err) reject(err) + else resolve() + }) + } else resolve() + }) + }).then(function syncAndClose () { + return new Promise(function (resolve, reject) { + if (options.fsync !== false) { + fs.fsync(fd, function (err) { + if (err) fs.close(fd, () => reject(err)) + else fs.close(fd, resolve) + }) + } else { + fs.close(fd, resolve) + } + }) + }).then(function chown () { + fd = null + if (options.chown) { + return new Promise(function (resolve, reject) { + fs.chown(tmpfile, options.chown.uid, options.chown.gid, function (err) { + if (err) reject(err) + else resolve() + }) + }) + } + }).then(function chmod () { + if (options.mode) { + return new Promise(function (resolve, reject) { + fs.chmod(tmpfile, options.mode, function (err) { + if (err) reject(err) + else resolve() + }) + }) + } + }).then(function rename () { + return new Promise(function (resolve, reject) { + fs.rename(tmpfile, truename, function (err) { + if (err) reject(err) + else resolve() + }) + }) + }).then(function success () { + removeOnExitHandler() + callback() + }, function fail (err) { + return new Promise(resolve => { + return fd ? fs.close(fd, resolve) : resolve() + }).then(() => { + removeOnExitHandler() + fs.unlink(tmpfile, function () { + callback(err) + }) + }) + }).then(function checkQueue () { + activeFiles[absoluteName].shift() // remove the element added by serializeSameFile + if (activeFiles[absoluteName].length > 0) { + activeFiles[absoluteName][0]() // start next job if one is pending + } else delete activeFiles[absoluteName] }) - gitHostInfo.user = user - gitHostInfo.auth = auth - gitHostInfo.project = project - gitHostInfo.committish = committish - gitHostInfo.default = defaultRepresentation - gitHostInfo.opts = opts || {} -} -GitHost.prototype = {} - -GitHost.prototype.hash = function () { - return this.committish ? '#' + this.committish : '' } -GitHost.prototype._fill = function (template, opts) { - if (!template) return - var vars = extend({}, opts) - opts = extend(extend({}, this.opts), opts) - var self = this - Object.keys(this).forEach(function (key) { - if (self[key] != null && vars[key] == null) vars[key] = self[key] - }) - var rawAuth = vars.auth - var rawComittish = vars.committish - Object.keys(vars).forEach(function (key) { - vars[key] = encodeURIComponent(vars[key]) - }) - vars['auth@'] = rawAuth ? rawAuth + '@' : '' - if (opts.noCommittish) { - vars['#committish'] = '' - vars['/tree/committish'] = '' - vars['/comittish'] = '' - vars.comittish = '' - } else { - vars['#committish'] = rawComittish ? '#' + rawComittish : '' - vars['/tree/committish'] = vars.committish - ? '/' + vars.treepath + '/' + vars.committish - : '' - vars['/committish'] = vars.committish ? '/' + vars.committish : '' - vars.committish = vars.committish || 'master' - } - var res = template - Object.keys(vars).forEach(function (key) { - res = res.replace(new RegExp('[{]' + key + '[}]', 'g'), vars[key]) - }) - if (opts.noGitPlus) { - return res.replace(/^git[+]/, '') - } else { - return res +function writeFileSync (filename, data, options) { + if (typeof options === 'string') options = { encoding: options } + else if (!options) options = {} + try { + filename = fs.realpathSync(filename) + } catch (ex) { + // it's ok, it'll happen on a not yet existing file } -} - -GitHost.prototype.ssh = function (opts) { - return this._fill(this.sshtemplate, opts) -} - -GitHost.prototype.sshurl = function (opts) { - return this._fill(this.sshurltemplate, opts) -} + var tmpfile = getTmpname(filename) -GitHost.prototype.browse = function (opts) { - return this._fill(this.browsetemplate, opts) -} + if (!options.mode || !options.chown) { + // Either mode or chown is not explicitly set + // Default behavior is to copy it from original file + try { + var stats = fs.statSync(filename) + options = Object.assign({}, options) + if (!options.mode) { + options.mode = stats.mode + } + if (!options.chown && process.getuid) { + options.chown = { uid: stats.uid, gid: stats.gid } + } + } catch (ex) { + // ignore stat errors + } + } -GitHost.prototype.docs = function (opts) { - return this._fill(this.docstemplate, opts) -} + var fd + var cleanup = cleanupOnExit(tmpfile) + var removeOnExitHandler = onExit(cleanup) -GitHost.prototype.bugs = function (opts) { - return this._fill(this.bugstemplate, opts) + try { + fd = fs.openSync(tmpfile, 'w', options.mode) + if (Buffer.isBuffer(data)) { + fs.writeSync(fd, data, 0, data.length, 0) + } else if (data != null) { + fs.writeSync(fd, String(data), 0, String(options.encoding || 'utf8')) + } + if (options.fsync !== false) { + fs.fsyncSync(fd) + } + fs.closeSync(fd) + if (options.chown) fs.chownSync(tmpfile, options.chown.uid, options.chown.gid) + if (options.mode) fs.chmodSync(tmpfile, options.mode) + fs.renameSync(tmpfile, filename) + removeOnExitHandler() + } catch (err) { + if (fd) { + try { + fs.closeSync(fd) + } catch (ex) { + // ignore close errors at this stage, error may have closed fd already. + } + } + removeOnExitHandler() + cleanup() + throw err + } } -GitHost.prototype.https = function (opts) { - return this._fill(this.httpstemplate, opts) -} -GitHost.prototype.git = function (opts) { - return this._fill(this.gittemplate, opts) -} +/***/ }), +/* 220 */ +/***/ (function(module, exports, __webpack_require__) { -GitHost.prototype.shortcut = function (opts) { - return this._fill(this.shortcuttemplate, opts) -} +var fs = __webpack_require__(133) +var polyfills = __webpack_require__(221) +var legacy = __webpack_require__(223) +var queue = [] -GitHost.prototype.path = function (opts) { - return this._fill(this.pathtemplate, opts) -} +var util = __webpack_require__(111) -GitHost.prototype.tarball = function (opts) { - return this._fill(this.tarballtemplate, opts) -} +function noop () {} -GitHost.prototype.file = function (P, opts) { - return this._fill(this.filetemplate, extend({ - path: P.replace(/^[/]+/g, '') - }, opts)) -} +var debug = noop +if (util.debuglog) + debug = util.debuglog('gfs4') +else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) + debug = function() { + var m = util.format.apply(util, arguments) + m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') + console.error(m) + } -GitHost.prototype.getDefaultRepresentation = function () { - return this.default +if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { + process.on('exit', function() { + debug(queue) + __webpack_require__(139).equal(queue.length, 0) + }) } -GitHost.prototype.toString = function (opts) { - return (this[this.default] || this.sshurl).call(this, opts) +module.exports = patch(__webpack_require__(222)) +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) { + module.exports = patch(fs) } +// Always patch fs.close/closeSync, because we want to +// retry() whenever a close happens *anywhere* in the program. +// This is essential when multiple graceful-fs instances are +// in play at the same time. +module.exports.close = +fs.close = (function (fs$close) { return function (fd, cb) { + return fs$close.call(fs, fd, function (err) { + if (!err) + retry() -/***/ }), -/* 192 */ -/***/ (function(module, exports, __webpack_require__) { - -var async = __webpack_require__(193); -async.core = __webpack_require__(199); -async.isCore = __webpack_require__(198); -async.sync = __webpack_require__(201); + if (typeof cb === 'function') + cb.apply(this, arguments) + }) +}})(fs.close) -module.exports = async; +module.exports.closeSync = +fs.closeSync = (function (fs$closeSync) { return function (fd) { + // Note that graceful-fs also retries when fs.closeSync() fails. + // Looks like a bug to me, although it's probably a harmless one. + var rval = fs$closeSync.apply(fs, arguments) + retry() + return rval +}})(fs.closeSync) +function patch (fs) { + // Everything that references the open() function needs to be in here + polyfills(fs) + fs.gracefulify = patch + fs.FileReadStream = ReadStream; // Legacy name. + fs.FileWriteStream = WriteStream; // Legacy name. + fs.createReadStream = createReadStream + fs.createWriteStream = createWriteStream + var fs$readFile = fs.readFile + fs.readFile = readFile + function readFile (path, options, cb) { + if (typeof options === 'function') + cb = options, options = null -/***/ }), -/* 193 */ -/***/ (function(module, exports, __webpack_require__) { + return go$readFile(path, options, cb) -var fs = __webpack_require__(132); -var path = __webpack_require__(4); -var caller = __webpack_require__(194); -var nodeModulesPaths = __webpack_require__(195); -var normalizeOptions = __webpack_require__(197); -var isCore = __webpack_require__(198); + function go$readFile (path, options, cb) { + return fs$readFile(path, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readFile, [path, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } -var realpathFS = fs.realpath && typeof fs.realpath.native === 'function' ? fs.realpath.native : fs.realpath; + var fs$writeFile = fs.writeFile + fs.writeFile = writeFile + function writeFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null -var defaultIsFile = function isFile(file, cb) { - fs.stat(file, function (err, stat) { - if (!err) { - return cb(null, stat.isFile() || stat.isFIFO()); - } - if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false); - return cb(err); - }); -}; + return go$writeFile(path, data, options, cb) -var defaultIsDir = function isDirectory(dir, cb) { - fs.stat(dir, function (err, stat) { - if (!err) { - return cb(null, stat.isDirectory()); + function go$writeFile (path, data, options, cb) { + return fs$writeFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$writeFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() } - if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false); - return cb(err); - }); -}; + }) + } + } -var defaultRealpath = function realpath(x, cb) { - realpathFS(x, function (realpathErr, realPath) { - if (realpathErr && realpathErr.code !== 'ENOENT') cb(realpathErr); - else cb(null, realpathErr ? x : realPath); - }); -}; + var fs$appendFile = fs.appendFile + if (fs$appendFile) + fs.appendFile = appendFile + function appendFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null -var maybeRealpath = function maybeRealpath(realpath, x, opts, cb) { - if (opts && opts.preserveSymlinks === false) { - realpath(x, cb); - } else { - cb(null, x); - } -}; + return go$appendFile(path, data, options, cb) -var getPackageCandidates = function getPackageCandidates(x, start, opts) { - var dirs = nodeModulesPaths(start, opts, x); - for (var i = 0; i < dirs.length; i++) { - dirs[i] = path.join(dirs[i], x); + function go$appendFile (path, data, options, cb) { + return fs$appendFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$appendFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) } - return dirs; -}; + } -module.exports = function resolve(x, options, callback) { - var cb = callback; - var opts = options; - if (typeof options === 'function') { - cb = opts; - opts = {}; - } - if (typeof x !== 'string') { - var err = new TypeError('Path must be a string.'); - return process.nextTick(function () { - cb(err); - }); + var fs$readdir = fs.readdir + fs.readdir = readdir + function readdir (path, options, cb) { + var args = [path] + if (typeof options !== 'function') { + args.push(options) + } else { + cb = options } + args.push(go$readdir$cb) - opts = normalizeOptions(x, opts); + return go$readdir(args) - var isFile = opts.isFile || defaultIsFile; - var isDirectory = opts.isDirectory || defaultIsDir; - var readFile = opts.readFile || fs.readFile; - var realpath = opts.realpath || defaultRealpath; - var packageIterator = opts.packageIterator; + function go$readdir$cb (err, files) { + if (files && files.sort) + files.sort() - var extensions = opts.extensions || ['.js']; - var basedir = opts.basedir || path.dirname(caller()); - var parent = opts.filename || basedir; + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readdir, [args]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + } + } - opts.paths = opts.paths || []; + function go$readdir (args) { + return fs$readdir.apply(fs, args) + } - // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory - var absoluteStart = path.resolve(basedir); + if (process.version.substr(0, 4) === 'v0.8') { + var legStreams = legacy(fs) + ReadStream = legStreams.ReadStream + WriteStream = legStreams.WriteStream + } - maybeRealpath( - realpath, - absoluteStart, - opts, - function (err, realStart) { - if (err) cb(err); - else init(realStart); - } - ); + var fs$ReadStream = fs.ReadStream + ReadStream.prototype = Object.create(fs$ReadStream.prototype) + ReadStream.prototype.open = ReadStream$open - var res; - function init(basedir) { - if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) { - res = path.resolve(basedir, x); - if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/'; - if ((/\/$/).test(x) && res === basedir) { - loadAsDirectory(res, opts.package, onfile); - } else loadAsFile(res, opts.package, onfile); - } else if (isCore(x)) { - return cb(null, x); - } else loadNodeModules(x, basedir, function (err, n, pkg) { - if (err) cb(err); - else if (n) { - return maybeRealpath(realpath, n, opts, function (err, realN) { - if (err) { - cb(err); - } else { - cb(null, realN, pkg); - } - }); - } else { - var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); - moduleError.code = 'MODULE_NOT_FOUND'; - cb(moduleError); - } - }); - } + var fs$WriteStream = fs.WriteStream + WriteStream.prototype = Object.create(fs$WriteStream.prototype) + WriteStream.prototype.open = WriteStream$open - function onfile(err, m, pkg) { - if (err) cb(err); - else if (m) cb(null, m, pkg); - else loadAsDirectory(res, function (err, d, pkg) { - if (err) cb(err); - else if (d) { - maybeRealpath(realpath, d, opts, function (err, realD) { - if (err) { - cb(err); - } else { - cb(null, realD, pkg); - } - }); - } else { - var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); - moduleError.code = 'MODULE_NOT_FOUND'; - cb(moduleError); - } - }); - } + fs.ReadStream = ReadStream + fs.WriteStream = WriteStream - function loadAsFile(x, thePackage, callback) { - var loadAsFilePackage = thePackage; - var cb = callback; - if (typeof loadAsFilePackage === 'function') { - cb = loadAsFilePackage; - loadAsFilePackage = undefined; - } + function ReadStream (path, options) { + if (this instanceof ReadStream) + return fs$ReadStream.apply(this, arguments), this + else + return ReadStream.apply(Object.create(ReadStream.prototype), arguments) + } - var exts = [''].concat(extensions); - load(exts, x, loadAsFilePackage); + function ReadStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + if (that.autoClose) + that.destroy() - function load(exts, x, loadPackage) { - if (exts.length === 0) return cb(null, undefined, loadPackage); - var file = x + exts[0]; + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + that.read() + } + }) + } - var pkg = loadPackage; - if (pkg) onpkg(null, pkg); - else loadpkg(path.dirname(file), onpkg); + function WriteStream (path, options) { + if (this instanceof WriteStream) + return fs$WriteStream.apply(this, arguments), this + else + return WriteStream.apply(Object.create(WriteStream.prototype), arguments) + } - function onpkg(err, pkg_, dir) { - pkg = pkg_; - if (err) return cb(err); - if (dir && pkg && opts.pathFilter) { - var rfile = path.relative(dir, file); - var rel = rfile.slice(0, rfile.length - exts[0].length); - var r = opts.pathFilter(pkg, x, rel); - if (r) return load( - [''].concat(extensions.slice()), - path.resolve(dir, r), - pkg - ); - } - isFile(file, onex); - } - function onex(err, ex) { - if (err) return cb(err); - if (ex) return cb(null, file, pkg); - load(exts.slice(1), x, pkg); - } - } - } + function WriteStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + that.destroy() + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + } + }) + } - function loadpkg(dir, cb) { - if (dir === '' || dir === '/') return cb(null); - if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) { - return cb(null); - } - if ((/[/\\]node_modules[/\\]*$/).test(dir)) return cb(null); + function createReadStream (path, options) { + return new ReadStream(path, options) + } - maybeRealpath(realpath, dir, opts, function (unwrapErr, pkgdir) { - if (unwrapErr) return loadpkg(path.dirname(dir), cb); - var pkgfile = path.join(pkgdir, 'package.json'); - isFile(pkgfile, function (err, ex) { - // on err, ex is false - if (!ex) return loadpkg(path.dirname(dir), cb); + function createWriteStream (path, options) { + return new WriteStream(path, options) + } - readFile(pkgfile, function (err, body) { - if (err) cb(err); - try { var pkg = JSON.parse(body); } catch (jsonErr) {} + var fs$open = fs.open + fs.open = open + function open (path, flags, mode, cb) { + if (typeof mode === 'function') + cb = mode, mode = null - if (pkg && opts.packageFilter) { - pkg = opts.packageFilter(pkg, pkgfile); - } - cb(null, pkg, dir); - }); - }); - }); - } + return go$open(path, flags, mode, cb) - function loadAsDirectory(x, loadAsDirectoryPackage, callback) { - var cb = callback; - var fpkg = loadAsDirectoryPackage; - if (typeof fpkg === 'function') { - cb = fpkg; - fpkg = opts.package; + function go$open (path, flags, mode, cb) { + return fs$open(path, flags, mode, function (err, fd) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$open, [path, flags, mode, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() } + }) + } + } - maybeRealpath(realpath, x, opts, function (unwrapErr, pkgdir) { - if (unwrapErr) return cb(unwrapErr); - var pkgfile = path.join(pkgdir, 'package.json'); - isFile(pkgfile, function (err, ex) { - if (err) return cb(err); - if (!ex) return loadAsFile(path.join(x, 'index'), fpkg, cb); + return fs +} - readFile(pkgfile, function (err, body) { - if (err) return cb(err); - try { - var pkg = JSON.parse(body); - } catch (jsonErr) {} +function enqueue (elem) { + debug('ENQUEUE', elem[0].name, elem[1]) + queue.push(elem) +} - if (pkg && opts.packageFilter) { - pkg = opts.packageFilter(pkg, pkgfile); - } +function retry () { + var elem = queue.shift() + if (elem) { + debug('RETRY', elem[0].name, elem[1]) + elem[0].apply(null, elem[1]) + } +} - if (pkg && pkg.main) { - if (typeof pkg.main !== 'string') { - var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); - mainError.code = 'INVALID_PACKAGE_MAIN'; - return cb(mainError); - } - if (pkg.main === '.' || pkg.main === './') { - pkg.main = 'index'; - } - loadAsFile(path.resolve(x, pkg.main), pkg, function (err, m, pkg) { - if (err) return cb(err); - if (m) return cb(null, m, pkg); - if (!pkg) return loadAsFile(path.join(x, 'index'), pkg, cb); - var dir = path.resolve(x, pkg.main); - loadAsDirectory(dir, pkg, function (err, n, pkg) { - if (err) return cb(err); - if (n) return cb(null, n, pkg); - loadAsFile(path.join(x, 'index'), pkg, cb); - }); - }); - return; - } +/***/ }), +/* 221 */ +/***/ (function(module, exports, __webpack_require__) { - loadAsFile(path.join(x, '/index'), pkg, cb); - }); - }); - }); - } +var fs = __webpack_require__(222) +var constants = __webpack_require__(135) - function processDirs(cb, dirs) { - if (dirs.length === 0) return cb(null, undefined); - var dir = dirs[0]; +var origCwd = process.cwd +var cwd = null - isDirectory(path.dirname(dir), isdir); +var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform - function isdir(err, isdir) { - if (err) return cb(err); - if (!isdir) return processDirs(cb, dirs.slice(1)); - loadAsFile(dir, opts.package, onfile); - } +process.cwd = function() { + if (!cwd) + cwd = origCwd.call(process) + return cwd +} +try { + process.cwd() +} catch (er) {} - function onfile(err, m, pkg) { - if (err) return cb(err); - if (m) return cb(null, m, pkg); - loadAsDirectory(dir, opts.package, ondir); - } +var chdir = process.chdir +process.chdir = function(d) { + cwd = null + chdir.call(process, d) +} - function ondir(err, n, pkg) { - if (err) return cb(err); - if (n) return cb(null, n, pkg); - processDirs(cb, dirs.slice(1)); - } - } - function loadNodeModules(x, start, cb) { - var thunk = function () { return getPackageCandidates(x, start, opts); }; - processDirs( - cb, - packageIterator ? packageIterator(x, start, thunk, opts) : thunk() - ); - } -}; +module.exports = patch +function patch (fs) { + // (re-)implement some things that are known busted or missing. -/***/ }), -/* 194 */ -/***/ (function(module, exports) { + // lchmod, broken prior to 0.6.2 + // back-port the fix here. + if (constants.hasOwnProperty('O_SYMLINK') && + process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + patchLchmod(fs) + } -module.exports = function () { - // see https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi - var origPrepareStackTrace = Error.prepareStackTrace; - Error.prepareStackTrace = function (_, stack) { return stack; }; - var stack = (new Error()).stack; - Error.prepareStackTrace = origPrepareStackTrace; - return stack[2].getFileName(); -}; + // lutimes implementation, or no-op + if (!fs.lutimes) { + patchLutimes(fs) + } + // https://github.com/isaacs/node-graceful-fs/issues/4 + // Chown should not fail on einval or eperm if non-root. + // It should not fail on enosys ever, as this just indicates + // that a fs doesn't support the intended operation. -/***/ }), -/* 195 */ -/***/ (function(module, exports, __webpack_require__) { + fs.chown = chownFix(fs.chown) + fs.fchown = chownFix(fs.fchown) + fs.lchown = chownFix(fs.lchown) -var path = __webpack_require__(4); -var parse = path.parse || __webpack_require__(196); + fs.chmod = chmodFix(fs.chmod) + fs.fchmod = chmodFix(fs.fchmod) + fs.lchmod = chmodFix(fs.lchmod) -var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) { - var prefix = '/'; - if ((/^([A-Za-z]:)/).test(absoluteStart)) { - prefix = ''; - } else if ((/^\\\\/).test(absoluteStart)) { - prefix = '\\\\'; - } + fs.chownSync = chownFixSync(fs.chownSync) + fs.fchownSync = chownFixSync(fs.fchownSync) + fs.lchownSync = chownFixSync(fs.lchownSync) - var paths = [absoluteStart]; - var parsed = parse(absoluteStart); - while (parsed.dir !== paths[paths.length - 1]) { - paths.push(parsed.dir); - parsed = parse(parsed.dir); - } + fs.chmodSync = chmodFixSync(fs.chmodSync) + fs.fchmodSync = chmodFixSync(fs.fchmodSync) + fs.lchmodSync = chmodFixSync(fs.lchmodSync) - return paths.reduce(function (dirs, aPath) { - return dirs.concat(modules.map(function (moduleDir) { - return path.resolve(prefix, aPath, moduleDir); - })); - }, []); -}; + fs.stat = statFix(fs.stat) + fs.fstat = statFix(fs.fstat) + fs.lstat = statFix(fs.lstat) -module.exports = function nodeModulesPaths(start, opts, request) { - var modules = opts && opts.moduleDirectory - ? [].concat(opts.moduleDirectory) - : ['node_modules']; + fs.statSync = statFixSync(fs.statSync) + fs.fstatSync = statFixSync(fs.fstatSync) + fs.lstatSync = statFixSync(fs.lstatSync) - if (opts && typeof opts.paths === 'function') { - return opts.paths( - request, - start, - function () { return getNodeModulesDirs(start, modules); }, - opts - ); + // if lchmod/lchown do not exist, then make them no-ops + if (!fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + if (cb) process.nextTick(cb) + } + fs.lchmodSync = function () {} + } + if (!fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + if (cb) process.nextTick(cb) } + fs.lchownSync = function () {} + } - var dirs = getNodeModulesDirs(start, modules); - return opts && opts.paths ? dirs.concat(opts.paths) : dirs; -}; + // on Windows, A/V software can lock the directory, causing this + // to fail with an EACCES or EPERM if the directory contains newly + // created files. Try again on failure, for up to 60 seconds. + + // Set the timeout this long because some Windows Anti-Virus, such as Parity + // bit9, may lock files for up to a minute, causing npm package install + // failures. Also, take care to yield the scheduler. Windows scheduling gives + // CPU to a busy looping process, which can cause the program causing the lock + // contention to be starved of CPU by node, so the contention doesn't resolve. + if (platform === "win32") { + fs.rename = (function (fs$rename) { return function (from, to, cb) { + var start = Date.now() + var backoff = 0; + fs$rename(from, to, function CB (er) { + if (er + && (er.code === "EACCES" || er.code === "EPERM") + && Date.now() - start < 60000) { + setTimeout(function() { + fs.stat(to, function (stater, st) { + if (stater && stater.code === "ENOENT") + fs$rename(from, to, CB); + else + cb(er) + }) + }, backoff) + if (backoff < 100) + backoff += 10; + return; + } + if (cb) cb(er) + }) + }})(fs.rename) + } + // if read() returns EAGAIN, then just try it again. + fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { + var callback + if (callback_ && typeof callback_ === 'function') { + var eagCounter = 0 + callback = function (er, _, __) { + if (er && er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + callback_.apply(this, arguments) + } + } + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + }})(fs.read) -/***/ }), -/* 196 */ -/***/ (function(module, exports, __webpack_require__) { + fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { + var eagCounter = 0 + while (true) { + try { + return fs$readSync.call(fs, fd, buffer, offset, length, position) + } catch (er) { + if (er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + continue + } + throw er + } + } + }})(fs.readSync) +} -"use strict"; +function patchLchmod (fs) { + fs.lchmod = function (path, mode, callback) { + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + if (callback) callback(err) + return + } + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + if (callback) callback(err || err2) + }) + }) + }) + } + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) -var isWindows = process.platform === 'win32'; + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + var threw = true + var ret + try { + ret = fs.fchmodSync(fd, mode) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } +} -// Regex to split a windows path into three parts: [*, device, slash, -// tail] windows-only -var splitDeviceRe = - /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; +function patchLutimes (fs) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + if (er) { + if (cb) cb(er) + return + } + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + if (cb) cb(er || er2) + }) + }) + }) + } -// Regex to split the tail part of the above into [*, dir, basename, ext] -var splitTailRe = - /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + var ret + var threw = true + try { + ret = fs.futimesSync(fd, at, mt) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } -var win32 = {}; + } else { + fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } + fs.lutimesSync = function () {} + } +} -// Function to split a filename into [root, dir, basename, ext] -function win32SplitPath(filename) { - // Separate device+slash from tail - var result = splitDeviceRe.exec(filename), - device = (result[1] || '') + (result[2] || ''), - tail = result[3] || ''; - // Split the tail into dir, basename and extension - var result2 = splitTailRe.exec(tail), - dir = result2[1], - basename = result2[2], - ext = result2[3]; - return [device, dir, basename, ext]; +function chmodFix (orig) { + if (!orig) return orig + return function (target, mode, cb) { + return orig.call(fs, target, mode, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } } -win32.parse = function(pathString) { - if (typeof pathString !== 'string') { - throw new TypeError( - "Parameter 'pathString' must be a string, not " + typeof pathString - ); +function chmodFixSync (orig) { + if (!orig) return orig + return function (target, mode) { + try { + return orig.call(fs, target, mode) + } catch (er) { + if (!chownErOk(er)) throw er + } } - var allParts = win32SplitPath(pathString); - if (!allParts || allParts.length !== 4) { - throw new TypeError("Invalid path '" + pathString + "'"); +} + + +function chownFix (orig) { + if (!orig) return orig + return function (target, uid, gid, cb) { + return orig.call(fs, target, uid, gid, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) } - return { - root: allParts[0], - dir: allParts[0] + allParts[1].slice(0, -1), - base: allParts[2], - ext: allParts[3], - name: allParts[2].slice(0, allParts[2].length - allParts[3].length) - }; -}; +} +function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er + } + } +} -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var posix = {}; +function statFix (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, cb) { + return orig.call(fs, target, function (er, stats) { + if (!stats) return cb.apply(this, arguments) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + if (cb) cb.apply(this, arguments) + }) + } +} + +function statFixSync (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target) { + var stats = orig.call(fs, target) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + return stats; + } +} + +// ENOSYS means that the fs doesn't support the op. Just ignore +// that, because it doesn't matter. +// +// if there's no getuid, or if getuid() is something other +// than 0, and the error is EINVAL or EPERM, then just ignore +// it. +// +// This specific case is a silent failure in cp, install, tar, +// and most other unix tools that manage permissions. +// +// When running as root, or if other types of errors are +// encountered, then it's strict. +function chownErOk (er) { + if (!er) + return true + if (er.code === "ENOSYS") + return true -function posixSplitPath(filename) { - return splitPathRe.exec(filename).slice(1); + var nonroot = !process.getuid || process.getuid() !== 0 + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true + } + + return false } -posix.parse = function(pathString) { - if (typeof pathString !== 'string') { - throw new TypeError( - "Parameter 'pathString' must be a string, not " + typeof pathString - ); - } - var allParts = posixSplitPath(pathString); - if (!allParts || allParts.length !== 4) { - throw new TypeError("Invalid path '" + pathString + "'"); - } - allParts[1] = allParts[1] || ''; - allParts[2] = allParts[2] || ''; - allParts[3] = allParts[3] || ''; +/***/ }), +/* 222 */ +/***/ (function(module, exports, __webpack_require__) { - return { - root: allParts[0], - dir: allParts[0] + allParts[1].slice(0, -1), - base: allParts[2], - ext: allParts[3], - name: allParts[2].slice(0, allParts[2].length - allParts[3].length) - }; -}; +"use strict"; -if (isWindows) - module.exports = win32.parse; -else /* posix */ - module.exports = posix.parse; +var fs = __webpack_require__(133) -module.exports.posix = posix.parse; -module.exports.win32 = win32.parse; +module.exports = clone(fs) +function clone (obj) { + if (obj === null || typeof obj !== 'object') + return obj -/***/ }), -/* 197 */ -/***/ (function(module, exports) { + if (obj instanceof Object) + var copy = { __proto__: obj.__proto__ } + else + var copy = Object.create(null) -module.exports = function (x, opts) { - /** - * This file is purposefully a passthrough. It's expected that third-party - * environments will override it at runtime in order to inject special logic - * into `resolve` (by manipulating the options). One such example is the PnP - * code path in Yarn. - */ + Object.getOwnPropertyNames(obj).forEach(function (key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) + }) - return opts || {}; -}; + return copy +} /***/ }), -/* 198 */ +/* 223 */ /***/ (function(module, exports, __webpack_require__) { -var core = __webpack_require__(199); +var Stream = __webpack_require__(137).Stream -module.exports = function isCore(x) { - return Object.prototype.hasOwnProperty.call(core, x); -}; +module.exports = legacy +function legacy (fs) { + return { + ReadStream: ReadStream, + WriteStream: WriteStream + } -/***/ }), -/* 199 */ -/***/ (function(module, exports, __webpack_require__) { + function ReadStream (path, options) { + if (!(this instanceof ReadStream)) return new ReadStream(path, options); -var current = (process.versions && process.versions.node && process.versions.node.split('.')) || []; + Stream.call(this); -function specifierIncluded(specifier) { - var parts = specifier.split(' '); - var op = parts.length > 1 ? parts[0] : '='; - var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.'); + var self = this; - for (var i = 0; i < 3; ++i) { - var cur = Number(current[i] || 0); - var ver = Number(versionParts[i] || 0); - if (cur === ver) { - continue; // eslint-disable-line no-restricted-syntax, no-continue - } - if (op === '<') { - return cur < ver; - } else if (op === '>=') { - return cur >= ver; - } else { - return false; - } - } - return op === '>='; -} + this.path = path; + this.fd = null; + this.readable = true; + this.paused = false; -function matchesRange(range) { - var specifiers = range.split(/ ?&& ?/); - if (specifiers.length === 0) { return false; } - for (var i = 0; i < specifiers.length; ++i) { - if (!specifierIncluded(specifiers[i])) { return false; } - } - return true; -} + this.flags = 'r'; + this.mode = 438; /*=0666*/ + this.bufferSize = 64 * 1024; -function versionIncluded(specifierValue) { - if (typeof specifierValue === 'boolean') { return specifierValue; } - if (specifierValue && typeof specifierValue === 'object') { - for (var i = 0; i < specifierValue.length; ++i) { - if (matchesRange(specifierValue[i])) { return true; } - } - return false; + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; } - return matchesRange(specifierValue); -} -var data = __webpack_require__(200); + if (this.encoding) this.setEncoding(this.encoding); -var core = {}; -for (var mod in data) { // eslint-disable-line no-restricted-syntax - if (Object.prototype.hasOwnProperty.call(data, mod)) { - core[mod] = versionIncluded(data[mod]); + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.end === undefined) { + this.end = Infinity; + } else if ('number' !== typeof this.end) { + throw TypeError('end must be a Number'); + } + + if (this.start > this.end) { + throw new Error('start must be <= end'); + } + + this.pos = this.start; } -} -module.exports = core; + if (this.fd !== null) { + process.nextTick(function() { + self._read(); + }); + return; + } -/***/ }), -/* 200 */ -/***/ (function(module) { + fs.open(this.path, this.flags, this.mode, function (err, fd) { + if (err) { + self.emit('error', err); + self.readable = false; + return; + } -module.exports = JSON.parse("{\"assert\":true,\"async_hooks\":\">= 8\",\"buffer_ieee754\":\"< 0.9.7\",\"buffer\":true,\"child_process\":true,\"cluster\":true,\"console\":true,\"constants\":true,\"crypto\":true,\"_debug_agent\":\">= 1 && < 8\",\"_debugger\":\"< 8\",\"dgram\":true,\"dns\":true,\"domain\":true,\"events\":true,\"freelist\":\"< 6\",\"fs\":true,\"fs/promises\":[\">= 10 && < 10.1\",\">= 14\"],\"_http_agent\":\">= 0.11.1\",\"_http_client\":\">= 0.11.1\",\"_http_common\":\">= 0.11.1\",\"_http_incoming\":\">= 0.11.1\",\"_http_outgoing\":\">= 0.11.1\",\"_http_server\":\">= 0.11.1\",\"http\":true,\"http2\":\">= 8.8\",\"https\":true,\"inspector\":\">= 8.0.0\",\"_linklist\":\"< 8\",\"module\":true,\"net\":true,\"node-inspect/lib/_inspect\":\">= 7.6.0 && < 12\",\"node-inspect/lib/internal/inspect_client\":\">= 7.6.0 && < 12\",\"node-inspect/lib/internal/inspect_repl\":\">= 7.6.0 && < 12\",\"os\":true,\"path\":true,\"perf_hooks\":\">= 8.5\",\"process\":\">= 1\",\"punycode\":true,\"querystring\":true,\"readline\":true,\"repl\":true,\"smalloc\":\">= 0.11.5 && < 3\",\"_stream_duplex\":\">= 0.9.4\",\"_stream_transform\":\">= 0.9.4\",\"_stream_wrap\":\">= 1.4.1\",\"_stream_passthrough\":\">= 0.9.4\",\"_stream_readable\":\">= 0.9.4\",\"_stream_writable\":\">= 0.9.4\",\"stream\":true,\"string_decoder\":true,\"sys\":true,\"timers\":true,\"_tls_common\":\">= 0.11.13\",\"_tls_legacy\":\">= 0.11.3 && < 10\",\"_tls_wrap\":\">= 0.11.3\",\"tls\":true,\"trace_events\":\">= 10\",\"tty\":true,\"url\":true,\"util\":true,\"v8/tools/arguments\":\">= 10 && < 12\",\"v8/tools/codemap\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/consarray\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/csvparser\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/logreader\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/profile_view\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/splaytree\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8\":\">= 1\",\"vm\":true,\"wasi\":\">= 13.4 && < 13.5\",\"worker_threads\":\">= 11.7\",\"zlib\":true}"); + self.fd = fd; + self.emit('open', fd); + self._read(); + }) + } -/***/ }), -/* 201 */ -/***/ (function(module, exports, __webpack_require__) { + function WriteStream (path, options) { + if (!(this instanceof WriteStream)) return new WriteStream(path, options); -var isCore = __webpack_require__(198); -var fs = __webpack_require__(132); -var path = __webpack_require__(4); -var caller = __webpack_require__(194); -var nodeModulesPaths = __webpack_require__(195); -var normalizeOptions = __webpack_require__(197); + Stream.call(this); -var realpathFS = fs.realpathSync && typeof fs.realpathSync.native === 'function' ? fs.realpathSync.native : fs.realpathSync; + this.path = path; + this.fd = null; + this.writable = true; -var defaultIsFile = function isFile(file) { - try { - var stat = fs.statSync(file); - } catch (e) { - if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false; - throw e; - } - return stat.isFile() || stat.isFIFO(); -}; + this.flags = 'w'; + this.encoding = 'binary'; + this.mode = 438; /*=0666*/ + this.bytesWritten = 0; -var defaultIsDir = function isDirectory(dir) { - try { - var stat = fs.statSync(dir); - } catch (e) { - if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false; - throw e; - } - return stat.isDirectory(); -}; + options = options || {}; -var defaultRealpathSync = function realpathSync(x) { - try { - return realpathFS(x); - } catch (realpathErr) { - if (realpathErr.code !== 'ENOENT') { - throw realpathErr; - } + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; } - return x; -}; -var maybeRealpathSync = function maybeRealpathSync(realpathSync, x, opts) { - if (opts && opts.preserveSymlinks === false) { - return realpathSync(x); - } - return x; -}; + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.start < 0) { + throw new Error('start must be >= zero'); + } -var getPackageCandidates = function getPackageCandidates(x, start, opts) { - var dirs = nodeModulesPaths(start, opts, x); - for (var i = 0; i < dirs.length; i++) { - dirs[i] = path.join(dirs[i], x); + this.pos = this.start; } - return dirs; -}; -module.exports = function resolveSync(x, options) { - if (typeof x !== 'string') { - throw new TypeError('Path must be a string.'); + this.busy = false; + this._queue = []; + + if (this.fd === null) { + this._open = fs.open; + this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); + this.flush(); } - var opts = normalizeOptions(x, options); + } +} - var isFile = opts.isFile || defaultIsFile; - var readFileSync = opts.readFileSync || fs.readFileSync; - var isDirectory = opts.isDirectory || defaultIsDir; - var realpathSync = opts.realpathSync || defaultRealpathSync; - var packageIterator = opts.packageIterator; - var extensions = opts.extensions || ['.js']; - var basedir = opts.basedir || path.dirname(caller()); - var parent = opts.filename || basedir; +/***/ }), +/* 224 */ +/***/ (function(module, exports, __webpack_require__) { - opts.paths = opts.paths || []; +/** + * @preserve + * JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013) + * + * @author Jens Taylor + * @see http://github.com/homebrewing/brauhaus-diff + * @author Gary Court + * @see http://github.com/garycourt/murmurhash-js + * @author Austin Appleby + * @see http://sites.google.com/site/murmurhash/ + */ +(function(){ + var cache; - // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory - var absoluteStart = maybeRealpathSync(realpathSync, path.resolve(basedir), opts); + // Call this function without `new` to use the cached object (good for + // single-threaded environments), or with `new` to create a new object. + // + // @param {string} key A UTF-16 or ASCII string + // @param {number} seed An optional positive integer + // @return {object} A MurmurHash3 object for incremental hashing + function MurmurHash3(key, seed) { + var m = this instanceof MurmurHash3 ? this : cache; + m.reset(seed) + if (typeof key === 'string' && key.length > 0) { + m.hash(key); + } - if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) { - var res = path.resolve(absoluteStart, x); - if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/'; - var m = loadAsFileSync(res) || loadAsDirectorySync(res); - if (m) return maybeRealpathSync(realpathSync, m, opts); - } else if (isCore(x)) { - return x; - } else { - var n = loadNodeModulesSync(x, absoluteStart); - if (n) return maybeRealpathSync(realpathSync, n, opts); - } + if (m !== this) { + return m; + } + }; - var err = new Error("Cannot find module '" + x + "' from '" + parent + "'"); - err.code = 'MODULE_NOT_FOUND'; - throw err; + // Incrementally add a string to this hash + // + // @param {string} key A UTF-16 or ASCII string + // @return {object} this + MurmurHash3.prototype.hash = function(key) { + var h1, k1, i, top, len; - function loadAsFileSync(x) { - var pkg = loadpkg(path.dirname(x)); + len = key.length; + this.len += len; - if (pkg && pkg.dir && pkg.pkg && opts.pathFilter) { - var rfile = path.relative(pkg.dir, x); - var r = opts.pathFilter(pkg.pkg, x, rfile); - if (r) { - x = path.resolve(pkg.dir, r); // eslint-disable-line no-param-reassign - } + k1 = this.k1; + i = 0; + switch (this.rem) { + case 0: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) : 0; + case 1: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 8 : 0; + case 2: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 16 : 0; + case 3: + k1 ^= len > i ? (key.charCodeAt(i) & 0xff) << 24 : 0; + k1 ^= len > i ? (key.charCodeAt(i++) & 0xff00) >> 8 : 0; } - if (isFile(x)) { - return x; - } + this.rem = (len + this.rem) & 3; // & 3 is same as % 4 + len -= this.rem; + if (len > 0) { + h1 = this.h1; + while (1) { + k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; - for (var i = 0; i < extensions.length; i++) { - var file = x + extensions[i]; - if (isFile(file)) { - return file; - } - } - } + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); + h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff; - function loadpkg(dir) { - if (dir === '' || dir === '/') return; - if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) { - return; - } - if ((/[/\\]node_modules[/\\]*$/).test(dir)) return; + if (i >= len) { + break; + } - var pkgfile = path.join(maybeRealpathSync(realpathSync, dir, opts), 'package.json'); + k1 = ((key.charCodeAt(i++) & 0xffff)) ^ + ((key.charCodeAt(i++) & 0xffff) << 8) ^ + ((key.charCodeAt(i++) & 0xffff) << 16); + top = key.charCodeAt(i++); + k1 ^= ((top & 0xff) << 24) ^ + ((top & 0xff00) >> 8); + } - if (!isFile(pkgfile)) { - return loadpkg(path.dirname(dir)); + k1 = 0; + switch (this.rem) { + case 3: k1 ^= (key.charCodeAt(i + 2) & 0xffff) << 16; + case 2: k1 ^= (key.charCodeAt(i + 1) & 0xffff) << 8; + case 1: k1 ^= (key.charCodeAt(i) & 0xffff); + } + + this.h1 = h1; } - var body = readFileSync(pkgfile); + this.k1 = k1; + return this; + }; - try { - var pkg = JSON.parse(body); - } catch (jsonErr) {} + // Get the result of this hash + // + // @return {number} The 32-bit hash + MurmurHash3.prototype.result = function() { + var k1, h1; + + k1 = this.k1; + h1 = this.h1; - if (pkg && opts.packageFilter) { - // v2 will pass pkgfile - pkg = opts.packageFilter(pkg, /*pkgfile,*/ dir); // eslint-disable-line spaced-comment + if (k1 > 0) { + k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; + h1 ^= k1; } - return { pkg: pkg, dir: dir }; - } - - function loadAsDirectorySync(x) { - var pkgfile = path.join(maybeRealpathSync(realpathSync, x, opts), '/package.json'); - if (isFile(pkgfile)) { - try { - var body = readFileSync(pkgfile, 'UTF8'); - var pkg = JSON.parse(body); - } catch (e) {} + h1 ^= this.len; - if (pkg && opts.packageFilter) { - // v2 will pass pkgfile - pkg = opts.packageFilter(pkg, /*pkgfile,*/ x); // eslint-disable-line spaced-comment - } + h1 ^= h1 >>> 16; + h1 = (h1 * 0xca6b + (h1 & 0xffff) * 0x85eb0000) & 0xffffffff; + h1 ^= h1 >>> 13; + h1 = (h1 * 0xae35 + (h1 & 0xffff) * 0xc2b20000) & 0xffffffff; + h1 ^= h1 >>> 16; - if (pkg && pkg.main) { - if (typeof pkg.main !== 'string') { - var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); - mainError.code = 'INVALID_PACKAGE_MAIN'; - throw mainError; - } - if (pkg.main === '.' || pkg.main === './') { - pkg.main = 'index'; - } - try { - var m = loadAsFileSync(path.resolve(x, pkg.main)); - if (m) return m; - var n = loadAsDirectorySync(path.resolve(x, pkg.main)); - if (n) return n; - } catch (e) {} - } - } + return h1 >>> 0; + }; - return loadAsFileSync(path.join(x, '/index')); - } + // Reset the hash object for reuse + // + // @param {number} seed An optional positive integer + MurmurHash3.prototype.reset = function(seed) { + this.h1 = typeof seed === 'number' ? seed : 0; + this.rem = this.k1 = this.len = 0; + return this; + }; - function loadNodeModulesSync(x, start) { - var thunk = function () { return getPackageCandidates(x, start, opts); }; - var dirs = packageIterator ? packageIterator(x, start, thunk, opts) : thunk(); + // A cached object to use. This can be safely used if you're in a single- + // threaded environment, otherwise you need to create new hashes to use. + cache = new MurmurHash3(); - for (var i = 0; i < dirs.length; i++) { - var dir = dirs[i]; - if (isDirectory(path.dirname(dir))) { - var m = loadAsFileSync(dir); - if (m) return m; - var n = loadAsDirectorySync(dir); - if (n) return n; - } - } - } -}; + if (true) { + module.exports = MurmurHash3; + } else {} +}()); /***/ }), -/* 202 */ -/***/ (function(module, exports) { +/* 225 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = extractDescription +// Note: since nyc uses this module to output coverage, any lines +// that are in the direct sync flow of nyc's outputCoverage are +// ignored, since we can never get coverage for them. +var assert = __webpack_require__(139) +var signals = __webpack_require__(226) -// Extracts description from contents of a readme file in markdown format -function extractDescription (d) { - if (!d) return; - if (d === "ERROR: No README data found!") return; - // the first block of text before the first heading - // that isn't the first line heading - d = d.trim().split('\n') - for (var s = 0; d[s] && d[s].trim().match(/^(#|$)/); s ++); - var l = d.length - for (var e = s + 1; e < l && d[e].trim(); e ++); - return d.slice(s, e).join(' ').trim() +var EE = __webpack_require__(155) +/* istanbul ignore if */ +if (typeof EE !== 'function') { + EE = EE.EventEmitter +} + +var emitter +if (process.__signal_exit_emitter__) { + emitter = process.__signal_exit_emitter__ +} else { + emitter = process.__signal_exit_emitter__ = new EE() + emitter.count = 0 + emitter.emitted = {} } +// Because this emitter is a global, we have to check to see if a +// previous version of this library failed to enable infinite listeners. +// I know what you're about to say. But literally everything about +// signal-exit is a compromise with evil. Get used to it. +if (!emitter.infinite) { + emitter.setMaxListeners(Infinity) + emitter.infinite = true +} -/***/ }), -/* 203 */ -/***/ (function(module) { - -module.exports = JSON.parse("{\"topLevel\":{\"dependancies\":\"dependencies\",\"dependecies\":\"dependencies\",\"depdenencies\":\"dependencies\",\"devEependencies\":\"devDependencies\",\"depends\":\"dependencies\",\"dev-dependencies\":\"devDependencies\",\"devDependences\":\"devDependencies\",\"devDepenencies\":\"devDependencies\",\"devdependencies\":\"devDependencies\",\"repostitory\":\"repository\",\"repo\":\"repository\",\"prefereGlobal\":\"preferGlobal\",\"hompage\":\"homepage\",\"hampage\":\"homepage\",\"autohr\":\"author\",\"autor\":\"author\",\"contributers\":\"contributors\",\"publicationConfig\":\"publishConfig\",\"script\":\"scripts\"},\"bugs\":{\"web\":\"url\",\"name\":\"url\"},\"script\":{\"server\":\"start\",\"tests\":\"test\"}}"); - -/***/ }), -/* 204 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = function (cb, opts) { + assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler') -var util = __webpack_require__(111) -var messages = __webpack_require__(205) + if (loaded === false) { + load() + } -module.exports = function() { - var args = Array.prototype.slice.call(arguments, 0) - var warningName = args.shift() - if (warningName == "typo") { - return makeTypoWarning.apply(null,args) + var ev = 'exit' + if (opts && opts.alwaysLast) { + ev = 'afterexit' } - else { - var msgTemplate = messages[warningName] ? messages[warningName] : warningName + ": '%s'" - args.unshift(msgTemplate) - return util.format.apply(null, args) + + var remove = function () { + emitter.removeListener(ev, cb) + if (emitter.listeners('exit').length === 0 && + emitter.listeners('afterexit').length === 0) { + unload() + } } + emitter.on(ev, cb) + + return remove } -function makeTypoWarning (providedName, probableName, field) { - if (field) { - providedName = field + "['" + providedName + "']" - probableName = field + "['" + probableName + "']" +module.exports.unload = unload +function unload () { + if (!loaded) { + return } - return util.format(messages.typo, providedName, probableName) -} + loaded = false + signals.forEach(function (sig) { + try { + process.removeListener(sig, sigListeners[sig]) + } catch (er) {} + }) + process.emit = originalProcessEmit + process.reallyExit = originalProcessReallyExit + emitter.count -= 1 +} -/***/ }), -/* 205 */ -/***/ (function(module) { +function emit (event, code, signal) { + if (emitter.emitted[event]) { + return + } + emitter.emitted[event] = true + emitter.emit(event, code, signal) +} -module.exports = JSON.parse("{\"repositories\":\"'repositories' (plural) Not supported. Please pick one as the 'repository' field\",\"missingRepository\":\"No repository field.\",\"brokenGitUrl\":\"Probably broken git url: %s\",\"nonObjectScripts\":\"scripts must be an object\",\"nonStringScript\":\"script values must be string commands\",\"nonArrayFiles\":\"Invalid 'files' member\",\"invalidFilename\":\"Invalid filename in 'files' list: %s\",\"nonArrayBundleDependencies\":\"Invalid 'bundleDependencies' list. Must be array of package names\",\"nonStringBundleDependency\":\"Invalid bundleDependencies member: %s\",\"nonDependencyBundleDependency\":\"Non-dependency in bundleDependencies: %s\",\"nonObjectDependencies\":\"%s field must be an object\",\"nonStringDependency\":\"Invalid dependency: %s %s\",\"deprecatedArrayDependencies\":\"specifying %s as array is deprecated\",\"deprecatedModules\":\"modules field is deprecated\",\"nonArrayKeywords\":\"keywords should be an array of strings\",\"nonStringKeyword\":\"keywords should be an array of strings\",\"conflictingName\":\"%s is also the name of a node core module.\",\"nonStringDescription\":\"'description' field should be a string\",\"missingDescription\":\"No description\",\"missingReadme\":\"No README data\",\"missingLicense\":\"No license field.\",\"nonEmailUrlBugsString\":\"Bug string field must be url, email, or {email,url}\",\"nonUrlBugsUrlField\":\"bugs.url field must be a string url. Deleted.\",\"nonEmailBugsEmailField\":\"bugs.email field must be a string email. Deleted.\",\"emptyNormalizedBugs\":\"Normalized value of bugs field is an empty object. Deleted.\",\"nonUrlHomepage\":\"homepage field must be a string url. Deleted.\",\"invalidLicense\":\"license should be a valid SPDX license expression\",\"typo\":\"%s should probably be %s.\"}"); +// { : , ... } +var sigListeners = {} +signals.forEach(function (sig) { + sigListeners[sig] = function listener () { + // If there are no other listeners, an exit is coming! + // Simplest way: remove us and then re-send the signal. + // We know that this will kill the process, so we can + // safely emit now. + var listeners = process.listeners(sig) + if (listeners.length === emitter.count) { + unload() + emit('exit', null, sig) + /* istanbul ignore next */ + emit('afterexit', null, sig) + /* istanbul ignore next */ + process.kill(process.pid, sig) + } + } +}) -/***/ }), -/* 206 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports.signals = function () { + return signals +} -"use strict"; +module.exports.load = load -const path = __webpack_require__(4); -const writeJsonFile = __webpack_require__(207); -const sortKeys = __webpack_require__(221); +var loaded = false -const dependencyKeys = new Set([ - 'dependencies', - 'devDependencies', - 'optionalDependencies', - 'peerDependencies' -]); +function load () { + if (loaded) { + return + } + loaded = true -function normalize(packageJson) { - const result = {}; + // This is the number of onSignalExit's that are in play. + // It's important so that we can count the correct number of + // listeners on signals, and don't wait for the other one to + // handle it instead of us. + emitter.count += 1 - for (const key of Object.keys(packageJson)) { - if (!dependencyKeys.has(key)) { - result[key] = packageJson[key]; - } else if (Object.keys(packageJson[key]).length !== 0) { - result[key] = sortKeys(packageJson[key]); - } - } + signals = signals.filter(function (sig) { + try { + process.on(sig, sigListeners[sig]) + return true + } catch (er) { + return false + } + }) - return result; + process.emit = processEmit + process.reallyExit = processReallyExit } -module.exports = async (filePath, data, options) => { - if (typeof filePath !== 'string') { - options = data; - data = filePath; - filePath = '.'; - } - - options = { - normalize: true, - ...options, - detectIndent: true - }; +var originalProcessReallyExit = process.reallyExit +function processReallyExit (code) { + process.exitCode = code || 0 + emit('exit', process.exitCode, null) + /* istanbul ignore next */ + emit('afterexit', process.exitCode, null) + /* istanbul ignore next */ + originalProcessReallyExit.call(process, process.exitCode) +} - filePath = path.basename(filePath) === 'package.json' ? filePath : path.join(filePath, 'package.json'); +var originalProcessEmit = process.emit +function processEmit (ev, arg) { + if (ev === 'exit') { + if (arg !== undefined) { + process.exitCode = arg + } + var ret = originalProcessEmit.apply(this, arguments) + emit('exit', process.exitCode, null) + /* istanbul ignore next */ + emit('afterexit', process.exitCode, null) + return ret + } else { + return originalProcessEmit.apply(this, arguments) + } +} - data = options.normalize ? normalize(data) : data; - return writeJsonFile(filePath, data, options); -}; +/***/ }), +/* 226 */ +/***/ (function(module, exports) { -module.exports.sync = (filePath, data, options) => { - if (typeof filePath !== 'string') { - options = data; - data = filePath; - filePath = '.'; - } +// This is not the set of all possible signals. +// +// It IS, however, the set of all signals that trigger +// an exit on either Linux or BSD systems. Linux is a +// superset of the signal names supported on BSD, and +// the unknown signals just fail to register, so we can +// catch that easily enough. +// +// Don't bother with SIGKILL. It's uncatchable, which +// means that we can't fire any callbacks anyway. +// +// If a user does happen to register a handler on a non- +// fatal signal like SIGWINCH or something, and then +// exit, it'll end up firing `process.emit('exit')`, so +// the handler will be fired anyway. +// +// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised +// artificially, inherently leave the process in a +// state from which it is not safe to try and enter JS +// listeners. +module.exports = [ + 'SIGABRT', + 'SIGALRM', + 'SIGHUP', + 'SIGINT', + 'SIGTERM' +] - options = { - normalize: true, - ...options, - detectIndent: true - }; +if (process.platform !== 'win32') { + module.exports.push( + 'SIGVTALRM', + 'SIGXCPU', + 'SIGXFSZ', + 'SIGUSR2', + 'SIGTRAP', + 'SIGSYS', + 'SIGQUIT', + 'SIGIOT' + // should detect profiler and enable/disable accordingly. + // see #21 + // 'SIGPROF' + ) +} - filePath = path.basename(filePath) === 'package.json' ? filePath : path.join(filePath, 'package.json'); +if (process.platform === 'linux') { + module.exports.push( + 'SIGIO', + 'SIGPOLL', + 'SIGPWR', + 'SIGSTKFLT', + 'SIGUNUSED' + ) +} - data = options.normalize ? normalize(data) : data; - writeJsonFile.sync(filePath, data, options); -}; +/***/ }), +/* 227 */ +/***/ (function(module, exports) { +module.exports = require(undefined); /***/ }), -/* 207 */ +/* 228 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(4); -const fs = __webpack_require__(208); -const writeFileAtomic = __webpack_require__(212); -const sortKeys = __webpack_require__(221); -const makeDir = __webpack_require__(223); -const pify = __webpack_require__(224); -const detectIndent = __webpack_require__(225); +const isPlainObj = __webpack_require__(229); -const init = (fn, filePath, data, options) => { - if (!filePath) { - throw new TypeError('Expected a filepath'); +module.exports = (obj, opts) => { + if (!isPlainObj(obj)) { + throw new TypeError('Expected a plain object'); } - if (data === undefined) { - throw new TypeError('Expected data to stringify'); + opts = opts || {}; + + // DEPRECATED + if (typeof opts === 'function') { + throw new TypeError('Specify the compare function as an option instead'); } - options = Object.assign({ - indent: '\t', - sortKeys: false - }, options); + const deep = opts.deep; + const seenInput = []; + const seenOutput = []; - if (options.sortKeys) { - data = sortKeys(data, { - deep: true, - compare: typeof options.sortKeys === 'function' ? options.sortKeys : undefined - }); - } + const sortKeys = x => { + const seenIndex = seenInput.indexOf(x); - return fn(filePath, data, options); -}; + if (seenIndex !== -1) { + return seenOutput[seenIndex]; + } -const readFile = filePath => pify(fs.readFile)(filePath, 'utf8').catch(() => {}); + const ret = {}; + const keys = Object.keys(x).sort(opts.compare); -const main = (filePath, data, options) => { - return (options.detectIndent ? readFile(filePath) : Promise.resolve()) - .then(string => { - const indent = string ? detectIndent(string).indent : options.indent; - const json = JSON.stringify(data, options.replacer, indent); + seenInput.push(x); + seenOutput.push(ret); - return pify(writeFileAtomic)(filePath, `${json}\n`, {mode: options.mode}); - }); -}; + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const val = x[key]; -const mainSync = (filePath, data, options) => { - let {indent} = options; + if (deep && Array.isArray(val)) { + const retArr = []; - if (options.detectIndent) { - try { - const file = fs.readFileSync(filePath, 'utf8'); - indent = detectIndent(file).indent; - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; - } - } - } + for (let j = 0; j < val.length; j++) { + retArr[j] = isPlainObj(val[j]) ? sortKeys(val[j]) : val[j]; + } - const json = JSON.stringify(data, options.replacer, indent); + ret[key] = retArr; + continue; + } - return writeFileAtomic.sync(filePath, `${json}\n`, {mode: options.mode}); -}; + ret[key] = deep && isPlainObj(val) ? sortKeys(val) : val; + } -const writeJsonFile = (filePath, data, options) => { - return makeDir(path.dirname(filePath), {fs}) - .then(() => init(main, filePath, data, options)); -}; + return ret; + }; -module.exports = writeJsonFile; -// TODO: Remove this for the next major release -module.exports.default = writeJsonFile; -module.exports.sync = (filePath, data, options) => { - makeDir.sync(path.dirname(filePath), {fs}); - init(mainSync, filePath, data, options); + return sortKeys(obj); }; /***/ }), -/* 208 */ +/* 229 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(132) -var polyfills = __webpack_require__(209) -var legacy = __webpack_require__(210) -var clone = __webpack_require__(211) - -var queue = [] - -var util = __webpack_require__(111) - -function noop () {} - -var debug = noop -if (util.debuglog) - debug = util.debuglog('gfs4') -else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) - debug = function() { - var m = util.format.apply(util, arguments) - m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') - console.error(m) - } - -if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { - process.on('exit', function() { - debug(queue) - __webpack_require__(138).equal(queue.length, 0) - }) -} - -module.exports = patch(clone(fs)) -if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { - module.exports = patch(fs) - fs.__patched = true; -} - -// Always patch fs.close/closeSync, because we want to -// retry() whenever a close happens *anywhere* in the program. -// This is essential when multiple graceful-fs instances are -// in play at the same time. -module.exports.close = (function (fs$close) { return function (fd, cb) { - return fs$close.call(fs, fd, function (err) { - if (!err) - retry() - - if (typeof cb === 'function') - cb.apply(this, arguments) - }) -}})(fs.close) - -module.exports.closeSync = (function (fs$closeSync) { return function (fd) { - // Note that graceful-fs also retries when fs.closeSync() fails. - // Looks like a bug to me, although it's probably a harmless one. - var rval = fs$closeSync.apply(fs, arguments) - retry() - return rval -}})(fs.closeSync) +"use strict"; -// Only patch fs once, otherwise we'll run into a memory leak if -// graceful-fs is loaded multiple times, such as in test environments that -// reset the loaded modules between tests. -// We look for the string `graceful-fs` from the comment above. This -// way we are not adding any extra properties and it will detect if older -// versions of graceful-fs are installed. -if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) { - fs.closeSync = module.exports.closeSync; - fs.close = module.exports.close; -} +var toString = Object.prototype.toString; -function patch (fs) { - // Everything that references the open() function needs to be in here - polyfills(fs) - fs.gracefulify = patch - fs.FileReadStream = ReadStream; // Legacy name. - fs.FileWriteStream = WriteStream; // Legacy name. - fs.createReadStream = createReadStream - fs.createWriteStream = createWriteStream - var fs$readFile = fs.readFile - fs.readFile = readFile - function readFile (path, options, cb) { - if (typeof options === 'function') - cb = options, options = null +module.exports = function (x) { + var prototype; + return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({})); +}; - return go$readFile(path, options, cb) - function go$readFile (path, options, cb) { - return fs$readFile(path, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readFile, [path, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } +/***/ }), +/* 230 */ +/***/ (function(module, exports, __webpack_require__) { - var fs$writeFile = fs.writeFile - fs.writeFile = writeFile - function writeFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null +"use strict"; - return go$writeFile(path, data, options, cb) +const fs = __webpack_require__(133); +const path = __webpack_require__(4); +const pify = __webpack_require__(231); +const semver = __webpack_require__(189); - function go$writeFile (path, data, options, cb) { - return fs$writeFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$writeFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } +const defaults = { + mode: 0o777 & (~process.umask()), + fs +}; - var fs$appendFile = fs.appendFile - if (fs$appendFile) - fs.appendFile = appendFile - function appendFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null +const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); - return go$appendFile(path, data, options, cb) +// https://github.com/nodejs/node/issues/8987 +// https://github.com/libuv/libuv/pull/1088 +const checkPath = pth => { + if (process.platform === 'win32') { + const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, '')); - function go$appendFile (path, data, options, cb) { - return fs$appendFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$appendFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + if (pathHasInvalidWinCharacters) { + const error = new Error(`Path contains invalid characters: ${pth}`); + error.code = 'EINVAL'; + throw error; + } + } +}; - var fs$readdir = fs.readdir - fs.readdir = readdir - function readdir (path, options, cb) { - var args = [path] - if (typeof options !== 'function') { - args.push(options) - } else { - cb = options - } - args.push(go$readdir$cb) +const permissionError = pth => { + // This replicates the exception of `fs.mkdir` with native the + // `recusive` option when run on an invalid drive under Windows. + const error = new Error(`operation not permitted, mkdir '${pth}'`); + error.code = 'EPERM'; + error.errno = -4048; + error.path = pth; + error.syscall = 'mkdir'; + return error; +}; - return go$readdir(args) +const makeDir = (input, options) => Promise.resolve().then(() => { + checkPath(input); + options = Object.assign({}, defaults, options); - function go$readdir$cb (err, files) { - if (files && files.sort) - files.sort() + // TODO: Use util.promisify when targeting Node.js 8 + const mkdir = pify(options.fs.mkdir); + const stat = pify(options.fs.stat); - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readdir, [args]]) + if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) { + const pth = path.resolve(input); - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - } - } + return mkdir(pth, { + mode: options.mode, + recursive: true + }).then(() => pth); + } - function go$readdir (args) { - return fs$readdir.apply(fs, args) - } + const make = pth => { + return mkdir(pth, options.mode) + .then(() => pth) + .catch(error => { + if (error.code === 'EPERM') { + throw error; + } - if (process.version.substr(0, 4) === 'v0.8') { - var legStreams = legacy(fs) - ReadStream = legStreams.ReadStream - WriteStream = legStreams.WriteStream - } + if (error.code === 'ENOENT') { + if (path.dirname(pth) === pth) { + throw permissionError(pth); + } - var fs$ReadStream = fs.ReadStream - if (fs$ReadStream) { - ReadStream.prototype = Object.create(fs$ReadStream.prototype) - ReadStream.prototype.open = ReadStream$open - } + if (error.message.includes('null bytes')) { + throw error; + } - var fs$WriteStream = fs.WriteStream - if (fs$WriteStream) { - WriteStream.prototype = Object.create(fs$WriteStream.prototype) - WriteStream.prototype.open = WriteStream$open - } + return make(path.dirname(pth)).then(() => make(pth)); + } - fs.ReadStream = ReadStream - fs.WriteStream = WriteStream + return stat(pth) + .then(stats => stats.isDirectory() ? pth : Promise.reject()) + .catch(() => { + throw error; + }); + }); + }; - function ReadStream (path, options) { - if (this instanceof ReadStream) - return fs$ReadStream.apply(this, arguments), this - else - return ReadStream.apply(Object.create(ReadStream.prototype), arguments) - } + return make(path.resolve(input)); +}); - function ReadStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - if (that.autoClose) - that.destroy() +module.exports = makeDir; +module.exports.default = makeDir; - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - that.read() - } - }) - } +module.exports.sync = (input, options) => { + checkPath(input); + options = Object.assign({}, defaults, options); - function WriteStream (path, options) { - if (this instanceof WriteStream) - return fs$WriteStream.apply(this, arguments), this - else - return WriteStream.apply(Object.create(WriteStream.prototype), arguments) - } + if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) { + const pth = path.resolve(input); - function WriteStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - that.destroy() - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - } - }) - } + fs.mkdirSync(pth, { + mode: options.mode, + recursive: true + }); - function createReadStream (path, options) { - return new ReadStream(path, options) - } + return pth; + } - function createWriteStream (path, options) { - return new WriteStream(path, options) - } + const make = pth => { + try { + options.fs.mkdirSync(pth, options.mode); + } catch (error) { + if (error.code === 'EPERM') { + throw error; + } - var fs$open = fs.open - fs.open = open - function open (path, flags, mode, cb) { - if (typeof mode === 'function') - cb = mode, mode = null + if (error.code === 'ENOENT') { + if (path.dirname(pth) === pth) { + throw permissionError(pth); + } - return go$open(path, flags, mode, cb) + if (error.message.includes('null bytes')) { + throw error; + } - function go$open (path, flags, mode, cb) { - return fs$open(path, flags, mode, function (err, fd) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$open, [path, flags, mode, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + make(path.dirname(pth)); + return make(pth); + } - return fs -} + try { + if (!options.fs.statSync(pth).isDirectory()) { + throw new Error('The path is not a directory'); + } + } catch (_) { + throw error; + } + } -function enqueue (elem) { - debug('ENQUEUE', elem[0].name, elem[1]) - queue.push(elem) -} + return pth; + }; -function retry () { - var elem = queue.shift() - if (elem) { - debug('RETRY', elem[0].name, elem[1]) - elem[0].apply(null, elem[1]) - } -} + return make(path.resolve(input)); +}; /***/ }), -/* 209 */ +/* 231 */ /***/ (function(module, exports, __webpack_require__) { -var constants = __webpack_require__(134) - -var origCwd = process.cwd -var cwd = null - -var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform - -process.cwd = function() { - if (!cwd) - cwd = origCwd.call(process) - return cwd -} -try { - process.cwd() -} catch (er) {} +"use strict"; -var chdir = process.chdir -process.chdir = function(d) { - cwd = null - chdir.call(process, d) -} -module.exports = patch +const processFn = (fn, options) => function (...args) { + const P = options.promiseModule; -function patch (fs) { - // (re-)implement some things that are known busted or missing. + return new P((resolve, reject) => { + if (options.multiArgs) { + args.push((...result) => { + if (options.errorFirst) { + if (result[0]) { + reject(result); + } else { + result.shift(); + resolve(result); + } + } else { + resolve(result); + } + }); + } else if (options.errorFirst) { + args.push((error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + } else { + args.push(resolve); + } - // lchmod, broken prior to 0.6.2 - // back-port the fix here. - if (constants.hasOwnProperty('O_SYMLINK') && - process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { - patchLchmod(fs) - } + fn.apply(this, args); + }); +}; - // lutimes implementation, or no-op - if (!fs.lutimes) { - patchLutimes(fs) - } +module.exports = (input, options) => { + options = Object.assign({ + exclude: [/.+(Sync|Stream)$/], + errorFirst: true, + promiseModule: Promise + }, options); - // https://github.com/isaacs/node-graceful-fs/issues/4 - // Chown should not fail on einval or eperm if non-root. - // It should not fail on enosys ever, as this just indicates - // that a fs doesn't support the intended operation. + const objType = typeof input; + if (!(input !== null && (objType === 'object' || objType === 'function'))) { + throw new TypeError(`Expected \`input\` to be a \`Function\` or \`Object\`, got \`${input === null ? 'null' : objType}\``); + } - fs.chown = chownFix(fs.chown) - fs.fchown = chownFix(fs.fchown) - fs.lchown = chownFix(fs.lchown) + const filter = key => { + const match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key); + return options.include ? options.include.some(match) : !options.exclude.some(match); + }; - fs.chmod = chmodFix(fs.chmod) - fs.fchmod = chmodFix(fs.fchmod) - fs.lchmod = chmodFix(fs.lchmod) + let ret; + if (objType === 'function') { + ret = function (...args) { + return options.excludeMain ? input(...args) : processFn(input, options).apply(this, args); + }; + } else { + ret = Object.create(Object.getPrototypeOf(input)); + } - fs.chownSync = chownFixSync(fs.chownSync) - fs.fchownSync = chownFixSync(fs.fchownSync) - fs.lchownSync = chownFixSync(fs.lchownSync) + for (const key in input) { // eslint-disable-line guard-for-in + const property = input[key]; + ret[key] = typeof property === 'function' && filter(key) ? processFn(property, options) : property; + } - fs.chmodSync = chmodFixSync(fs.chmodSync) - fs.fchmodSync = chmodFixSync(fs.fchmodSync) - fs.lchmodSync = chmodFixSync(fs.lchmodSync) + return ret; +}; - fs.stat = statFix(fs.stat) - fs.fstat = statFix(fs.fstat) - fs.lstat = statFix(fs.lstat) - fs.statSync = statFixSync(fs.statSync) - fs.fstatSync = statFixSync(fs.fstatSync) - fs.lstatSync = statFixSync(fs.lstatSync) +/***/ }), +/* 232 */ +/***/ (function(module, exports, __webpack_require__) { - // if lchmod/lchown do not exist, then make them no-ops - if (!fs.lchmod) { - fs.lchmod = function (path, mode, cb) { - if (cb) process.nextTick(cb) - } - fs.lchmodSync = function () {} - } - if (!fs.lchown) { - fs.lchown = function (path, uid, gid, cb) { - if (cb) process.nextTick(cb) - } - fs.lchownSync = function () {} - } +"use strict"; - // on Windows, A/V software can lock the directory, causing this - // to fail with an EACCES or EPERM if the directory contains newly - // created files. Try again on failure, for up to 60 seconds. - // Set the timeout this long because some Windows Anti-Virus, such as Parity - // bit9, may lock files for up to a minute, causing npm package install - // failures. Also, take care to yield the scheduler. Windows scheduling gives - // CPU to a busy looping process, which can cause the program causing the lock - // contention to be starved of CPU by node, so the contention doesn't resolve. - if (platform === "win32") { - fs.rename = (function (fs$rename) { return function (from, to, cb) { - var start = Date.now() - var backoff = 0; - fs$rename(from, to, function CB (er) { - if (er - && (er.code === "EACCES" || er.code === "EPERM") - && Date.now() - start < 60000) { - setTimeout(function() { - fs.stat(to, function (stater, st) { - if (stater && stater.code === "ENOENT") - fs$rename(from, to, CB); - else - cb(er) - }) - }, backoff) - if (backoff < 100) - backoff += 10; - return; - } - if (cb) cb(er) - }) - }})(fs.rename) - } +// detect either spaces or tabs but not both to properly handle tabs +// for indentation and spaces for alignment +const INDENT_RE = /^(?:( )+|\t+)/; - // if read() returns EAGAIN, then just try it again. - fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { - var callback - if (callback_ && typeof callback_ === 'function') { - var eagCounter = 0 - callback = function (er, _, __) { - if (er && er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - } - callback_.apply(this, arguments) - } - } - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - }})(fs.read) +function getMostUsed(indents) { + let result = 0; + let maxUsed = 0; + let maxWeight = 0; - fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { - var eagCounter = 0 - while (true) { - try { - return fs$readSync.call(fs, fd, buffer, offset, length, position) - } catch (er) { - if (er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - continue - } - throw er - } - } - }})(fs.readSync) + for (const entry of indents) { + // TODO: use destructuring when targeting Node.js 6 + const key = entry[0]; + const val = entry[1]; - function patchLchmod (fs) { - fs.lchmod = function (path, mode, callback) { - fs.open( path - , constants.O_WRONLY | constants.O_SYMLINK - , mode - , function (err, fd) { - if (err) { - if (callback) callback(err) - return - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function (err) { - fs.close(fd, function(err2) { - if (callback) callback(err || err2) - }) - }) - }) - } + const u = val[0]; + const w = val[1]; - fs.lchmodSync = function (path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) + if (u > maxUsed || (u === maxUsed && w > maxWeight)) { + maxUsed = u; + maxWeight = w; + result = Number(key); + } + } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var threw = true - var ret - try { - ret = fs.fchmodSync(fd, mode) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret - } - } + return result; +} - function patchLutimes (fs) { - if (constants.hasOwnProperty("O_SYMLINK")) { - fs.lutimes = function (path, at, mt, cb) { - fs.open(path, constants.O_SYMLINK, function (er, fd) { - if (er) { - if (cb) cb(er) - return - } - fs.futimes(fd, at, mt, function (er) { - fs.close(fd, function (er2) { - if (cb) cb(er || er2) - }) - }) - }) - } +module.exports = str => { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } - fs.lutimesSync = function (path, at, mt) { - var fd = fs.openSync(path, constants.O_SYMLINK) - var ret - var threw = true - try { - ret = fs.futimesSync(fd, at, mt) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret - } + // used to see if tabs or spaces are the most used + let tabs = 0; + let spaces = 0; - } else { - fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } - fs.lutimesSync = function () {} - } - } + // remember the size of previous line's indentation + let prev = 0; - function chmodFix (orig) { - if (!orig) return orig - return function (target, mode, cb) { - return orig.call(fs, target, mode, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) - } - } + // remember how many indents/unindents as occurred for a given size + // and how much lines follow a given indentation + // + // indents = { + // 3: [1, 0], + // 4: [1, 5], + // 5: [1, 0], + // 12: [1, 0], + // } + const indents = new Map(); - function chmodFixSync (orig) { - if (!orig) return orig - return function (target, mode) { - try { - return orig.call(fs, target, mode) - } catch (er) { - if (!chownErOk(er)) throw er - } - } - } + // pointer to the array of last used indent + let current; + // whether the last action was an indent (opposed to an unindent) + let isIndent; - function chownFix (orig) { - if (!orig) return orig - return function (target, uid, gid, cb) { - return orig.call(fs, target, uid, gid, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) - } - } + for (const line of str.split(/\n/g)) { + if (!line) { + // ignore empty lines + continue; + } - function chownFixSync (orig) { - if (!orig) return orig - return function (target, uid, gid) { - try { - return orig.call(fs, target, uid, gid) - } catch (er) { - if (!chownErOk(er)) throw er - } - } - } + let indent; + const matches = line.match(INDENT_RE); + if (matches) { + indent = matches[0].length; - function statFix (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, cb) { - return orig.call(fs, target, function (er, stats) { - if (!stats) return cb.apply(this, arguments) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - if (cb) cb.apply(this, arguments) - }) - } - } + if (matches[1]) { + spaces++; + } else { + tabs++; + } + } else { + indent = 0; + } - function statFixSync (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target) { - var stats = orig.call(fs, target) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - return stats; - } - } + const diff = indent - prev; + prev = indent; - // ENOSYS means that the fs doesn't support the op. Just ignore - // that, because it doesn't matter. - // - // if there's no getuid, or if getuid() is something other - // than 0, and the error is EINVAL or EPERM, then just ignore - // it. - // - // This specific case is a silent failure in cp, install, tar, - // and most other unix tools that manage permissions. - // - // When running as root, or if other types of errors are - // encountered, then it's strict. - function chownErOk (er) { - if (!er) - return true + if (diff) { + // an indent or unindent has been detected - if (er.code === "ENOSYS") - return true + isIndent = diff > 0; - var nonroot = !process.getuid || process.getuid() !== 0 - if (nonroot) { - if (er.code === "EINVAL" || er.code === "EPERM") - return true - } + current = indents.get(isIndent ? diff : -diff); - return false - } -} + if (current) { + current[0]++; + } else { + current = [1, 0]; + indents.set(diff, current); + } + } else if (current) { + // if the last action was an indent, increment the weight + current[1] += Number(isIndent); + } + } + const amount = getMostUsed(indents); -/***/ }), -/* 210 */ -/***/ (function(module, exports, __webpack_require__) { + let type; + let indent; + if (!amount) { + type = null; + indent = ''; + } else if (spaces >= tabs) { + type = 'space'; + indent = ' '.repeat(amount); + } else { + type = 'tab'; + indent = '\t'.repeat(amount); + } -var Stream = __webpack_require__(136).Stream + return { + amount, + type, + indent + }; +}; -module.exports = legacy -function legacy (fs) { - return { - ReadStream: ReadStream, - WriteStream: WriteStream - } +/***/ }), +/* 233 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - function ReadStream (path, options) { - if (!(this instanceof ReadStream)) return new ReadStream(path, options); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "installInDir", function() { return installInDir; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackage", function() { return runScriptInPackage; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackageStreaming", function() { return runScriptInPackageStreaming; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yarnWorkspacesInfo", function() { return yarnWorkspacesInfo; }); +/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(234); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ - Stream.call(this); +const YARN_EXEC = process.env.npm_execpath || 'yarn'; - var self = this; +/** + * Install all dependencies in the given directory + */ +async function installInDir(directory, extraArgs = []) { + const options = ['install', '--non-interactive', ...extraArgs]; // We pass the mutex flag to ensure only one instance of yarn runs at any + // given time (e.g. to avoid conflicts). - this.path = path; - this.fd = null; - this.readable = true; - this.paused = false; + await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, options, { + cwd: directory + }); +} +/** + * Run script in the given directory + */ - this.flags = 'r'; - this.mode = 438; /*=0666*/ - this.bufferSize = 64 * 1024; +async function runScriptInPackage(script, args, pkg) { + const execOpts = { + cwd: pkg.path + }; + await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, ['run', script, ...args], execOpts); +} +/** + * Run script in the given directory + */ - options = options || {}; +function runScriptInPackageStreaming({ + script, + args, + pkg, + debug +}) { + const execOpts = { + cwd: pkg.path + }; + return Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawnStreaming"])(YARN_EXEC, ['run', script, ...args], execOpts, { + prefix: pkg.name, + debug + }); +} +async function yarnWorkspacesInfo(directory) { + const { + stdout + } = await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, ['--json', 'workspaces', 'info'], { + cwd: directory, + stdio: 'pipe' + }); - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } + try { + return JSON.parse(JSON.parse(stdout).data); + } catch (error) { + throw new Error(`'yarn workspaces info --json' produced unexpected output: \n${stdout}`); + } +} - if (this.encoding) this.setEncoding(this.encoding); +/***/ }), +/* 234 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawn", function() { return spawn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawnStreaming", function() { return spawnStreaming; }); +/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(137); +/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(stream__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(235); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(244); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(279); +/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - if (this.start > this.end) { - throw new Error('start must be <= end'); - } +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - this.pos = this.start; - } +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - if (this.fd !== null) { - process.nextTick(function() { - self._read(); - }); - return; - } +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ - fs.open(this.path, this.flags, this.mode, function (err, fd) { - if (err) { - self.emit('error', err); - self.readable = false; - return; - } - self.fd = fd; - self.emit('open', fd); - self._read(); - }) - } - function WriteStream (path, options) { - if (!(this instanceof WriteStream)) return new WriteStream(path, options); - Stream.call(this); - this.path = path; - this.fd = null; - this.writable = true; +const colorWheel = [chalk__WEBPACK_IMPORTED_MODULE_1___default.a.cyan, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.magenta, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.blue, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.yellow, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.green]; - this.flags = 'w'; - this.encoding = 'binary'; - this.mode = 438; /*=0666*/ - this.bytesWritten = 0; +const getColor = () => { + const color = colorWheel.shift(); + colorWheel.push(color); + return color; +}; - options = options || {}; +function spawn(command, args, opts) { + return execa__WEBPACK_IMPORTED_MODULE_2___default()(command, args, _objectSpread({ + stdio: 'inherit', + preferLocal: true + }, opts)); +} - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } +function streamToLog(debug = true) { + return new stream__WEBPACK_IMPORTED_MODULE_0__["Writable"]({ + objectMode: true, - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); + write(line, _, cb) { + if (line.endsWith('\n')) { + _log__WEBPACK_IMPORTED_MODULE_4__["log"][debug ? 'debug' : 'write'](line.slice(0, -1)); + } else { + _log__WEBPACK_IMPORTED_MODULE_4__["log"][debug ? 'debug' : 'write'](line); } - this.pos = this.start; + cb(); } - this.busy = false; - this._queue = []; - - if (this.fd === null) { - this._open = fs.open; - this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); - this.flush(); - } - } + }); } +function spawnStreaming(command, args, opts, { + prefix, + debug +}) { + const spawned = execa__WEBPACK_IMPORTED_MODULE_2___default()(command, args, _objectSpread({ + stdio: ['ignore', 'pipe', 'pipe'], + preferLocal: true + }, opts)); + const color = getColor(); + const prefixedStdout = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ + tag: color.bold(prefix) + }); + const prefixedStderr = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ + mergeMultiline: true, + tag: color.bold(prefix) + }); + spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); + spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); + return spawned; +} /***/ }), -/* 211 */ +/* 235 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const ansiStyles = __webpack_require__(236); +const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(240); +const { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex +} = __webpack_require__(242); -module.exports = clone +const {isArray} = Array; -function clone (obj) { - if (obj === null || typeof obj !== 'object') - return obj +// `supportsColor.level` → `ansiStyles.color[name]` mapping +const levelMapping = [ + 'ansi', + 'ansi', + 'ansi256', + 'ansi16m' +]; - if (obj instanceof Object) - var copy = { __proto__: obj.__proto__ } - else - var copy = Object.create(null) +const styles = Object.create(null); - Object.getOwnPropertyNames(obj).forEach(function (key) { - Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) - }) +const applyOptions = (object, options = {}) => { + if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { + throw new Error('The `level` option should be an integer from 0 to 3'); + } - return copy + // Detect level if not set manually + const colorLevel = stdoutColor ? stdoutColor.level : 0; + object.level = options.level === undefined ? colorLevel : options.level; +}; + +class ChalkClass { + constructor(options) { + // eslint-disable-next-line no-constructor-return + return chalkFactory(options); + } } +const chalkFactory = options => { + const chalk = {}; + applyOptions(chalk, options); -/***/ }), -/* 212 */ -/***/ (function(module, exports, __webpack_require__) { + chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); -"use strict"; + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); -module.exports = writeFile -module.exports.sync = writeFileSync -module.exports._getTmpname = getTmpname // for testing -module.exports._cleanupOnExit = cleanupOnExit + chalk.template.constructor = () => { + throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); + }; -var fs = __webpack_require__(213) -var MurmurHash3 = __webpack_require__(217) -var onExit = __webpack_require__(218) -var path = __webpack_require__(4) -var activeFiles = {} + chalk.template.Instance = ChalkClass; -// if we run inside of a worker_thread, `process.pid` is not unique -/* istanbul ignore next */ -var threadId = (function getId () { - try { - var workerThreads = __webpack_require__(220) + return chalk.template; +}; - /// if we are in main thread, this is set to `0` - return workerThreads.threadId - } catch (e) { - // worker_threads are not available, fallback to 0 - return 0 - } -})() +function Chalk(options) { + return chalkFactory(options); +} -var invocations = 0 -function getTmpname (filename) { - return filename + '.' + - MurmurHash3(__filename) - .hash(String(process.pid)) - .hash(String(threadId)) - .hash(String(++invocations)) - .result() +for (const [styleName, style] of Object.entries(ansiStyles)) { + styles[styleName] = { + get() { + const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); + Object.defineProperty(this, styleName, {value: builder}); + return builder; + } + }; } -function cleanupOnExit (tmpfile) { - return function () { - try { - fs.unlinkSync(typeof tmpfile === 'function' ? tmpfile() : tmpfile) - } catch (_) {} - } +styles.visible = { + get() { + const builder = createBuilder(this, this._styler, true); + Object.defineProperty(this, 'visible', {value: builder}); + return builder; + } +}; + +const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; + +for (const model of usedModels) { + styles[model] = { + get() { + const {level} = this; + return function (...arguments_) { + const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler); + return createBuilder(this, styler, this._isEmpty); + }; + } + }; } -function writeFile (filename, data, options, callback) { - if (options) { - if (options instanceof Function) { - callback = options - options = {} - } else if (typeof options === 'string') { - options = { encoding: options } - } - } else { - options = {} - } +for (const model of usedModels) { + const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); + styles[bgModel] = { + get() { + const {level} = this; + return function (...arguments_) { + const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler); + return createBuilder(this, styler, this._isEmpty); + }; + } + }; +} + +const proto = Object.defineProperties(() => {}, { + ...styles, + level: { + enumerable: true, + get() { + return this._generator.level; + }, + set(level) { + this._generator.level = level; + } + } +}); + +const createStyler = (open, close, parent) => { + let openAll; + let closeAll; + if (parent === undefined) { + openAll = open; + closeAll = close; + } else { + openAll = parent.openAll + open; + closeAll = close + parent.closeAll; + } + + return { + open, + close, + openAll, + closeAll, + parent + }; +}; + +const createBuilder = (self, _styler, _isEmpty) => { + const builder = (...arguments_) => { + if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) { + // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}` + return applyStyle(builder, chalkTag(builder, ...arguments_)); + } + + // Single argument is hot path, implicit coercion is faster than anything + // eslint-disable-next-line no-implicit-coercion + return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); + }; + + // We alter the prototype because we must return a function, but there is + // no way to create a function with a different prototype + Object.setPrototypeOf(builder, proto); + + builder._generator = self; + builder._styler = _styler; + builder._isEmpty = _isEmpty; + + return builder; +}; + +const applyStyle = (self, string) => { + if (self.level <= 0 || !string) { + return self._isEmpty ? '' : string; + } + + let styler = self._styler; + + if (styler === undefined) { + return string; + } + + const {openAll, closeAll} = styler; + if (string.indexOf('\u001B') !== -1) { + while (styler !== undefined) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + string = stringReplaceAll(string, styler.close, styler.open); + + styler = styler.parent; + } + } - var Promise = options.Promise || global.Promise - var truename - var fd - var tmpfile - /* istanbul ignore next -- The closure only gets called when onExit triggers */ - var removeOnExitHandler = onExit(cleanupOnExit(() => tmpfile)) - var absoluteName = path.resolve(filename) + // We can move both next actions out of loop, because remaining actions in loop won't have + // any/visible effect on parts we add here. Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 + const lfIndex = string.indexOf('\n'); + if (lfIndex !== -1) { + string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); + } - new Promise(function serializeSameFile (resolve) { - // make a queue if it doesn't already exist - if (!activeFiles[absoluteName]) activeFiles[absoluteName] = [] + return openAll + string + closeAll; +}; - activeFiles[absoluteName].push(resolve) // add this job to the queue - if (activeFiles[absoluteName].length === 1) resolve() // kick off the first one - }).then(function getRealPath () { - return new Promise(function (resolve) { - fs.realpath(filename, function (_, realname) { - truename = realname || filename - tmpfile = getTmpname(truename) - resolve() - }) - }) - }).then(function stat () { - return new Promise(function stat (resolve) { - if (options.mode && options.chown) resolve() - else { - // Either mode or chown is not explicitly set - // Default behavior is to copy it from original file - fs.stat(truename, function (err, stats) { - if (err || !stats) resolve() - else { - options = Object.assign({}, options) +let template; +const chalkTag = (chalk, ...strings) => { + const [firstString] = strings; - if (options.mode == null) { - options.mode = stats.mode - } - if (options.chown == null && process.getuid) { - options.chown = { uid: stats.uid, gid: stats.gid } - } - resolve() - } - }) - } - }) - }).then(function thenWriteFile () { - return new Promise(function (resolve, reject) { - fs.open(tmpfile, 'w', options.mode, function (err, _fd) { - fd = _fd - if (err) reject(err) - else resolve() - }) - }) - }).then(function write () { - return new Promise(function (resolve, reject) { - if (Buffer.isBuffer(data)) { - fs.write(fd, data, 0, data.length, 0, function (err) { - if (err) reject(err) - else resolve() - }) - } else if (data != null) { - fs.write(fd, String(data), 0, String(options.encoding || 'utf8'), function (err) { - if (err) reject(err) - else resolve() - }) - } else resolve() - }) - }).then(function syncAndClose () { - return new Promise(function (resolve, reject) { - if (options.fsync !== false) { - fs.fsync(fd, function (err) { - if (err) fs.close(fd, () => reject(err)) - else fs.close(fd, resolve) - }) - } else { - fs.close(fd, resolve) - } - }) - }).then(function chown () { - fd = null - if (options.chown) { - return new Promise(function (resolve, reject) { - fs.chown(tmpfile, options.chown.uid, options.chown.gid, function (err) { - if (err) reject(err) - else resolve() - }) - }) - } - }).then(function chmod () { - if (options.mode) { - return new Promise(function (resolve, reject) { - fs.chmod(tmpfile, options.mode, function (err) { - if (err) reject(err) - else resolve() - }) - }) - } - }).then(function rename () { - return new Promise(function (resolve, reject) { - fs.rename(tmpfile, truename, function (err) { - if (err) reject(err) - else resolve() - }) - }) - }).then(function success () { - removeOnExitHandler() - callback() - }, function fail (err) { - return new Promise(resolve => { - return fd ? fs.close(fd, resolve) : resolve() - }).then(() => { - removeOnExitHandler() - fs.unlink(tmpfile, function () { - callback(err) - }) - }) - }).then(function checkQueue () { - activeFiles[absoluteName].shift() // remove the element added by serializeSameFile - if (activeFiles[absoluteName].length > 0) { - activeFiles[absoluteName][0]() // start next job if one is pending - } else delete activeFiles[absoluteName] - }) -} + if (!isArray(firstString) || !isArray(firstString.raw)) { + // If chalk() was called by itself or with a string, + // return the string itself as a string. + return strings.join(' '); + } -function writeFileSync (filename, data, options) { - if (typeof options === 'string') options = { encoding: options } - else if (!options) options = {} - try { - filename = fs.realpathSync(filename) - } catch (ex) { - // it's ok, it'll happen on a not yet existing file - } - var tmpfile = getTmpname(filename) + const arguments_ = strings.slice(1); + const parts = [firstString.raw[0]]; - if (!options.mode || !options.chown) { - // Either mode or chown is not explicitly set - // Default behavior is to copy it from original file - try { - var stats = fs.statSync(filename) - options = Object.assign({}, options) - if (!options.mode) { - options.mode = stats.mode - } - if (!options.chown && process.getuid) { - options.chown = { uid: stats.uid, gid: stats.gid } - } - } catch (ex) { - // ignore stat errors - } - } + for (let i = 1; i < firstString.length; i++) { + parts.push( + String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), + String(firstString.raw[i]) + ); + } - var fd - var cleanup = cleanupOnExit(tmpfile) - var removeOnExitHandler = onExit(cleanup) + if (template === undefined) { + template = __webpack_require__(243); + } - try { - fd = fs.openSync(tmpfile, 'w', options.mode) - if (Buffer.isBuffer(data)) { - fs.writeSync(fd, data, 0, data.length, 0) - } else if (data != null) { - fs.writeSync(fd, String(data), 0, String(options.encoding || 'utf8')) - } - if (options.fsync !== false) { - fs.fsyncSync(fd) - } - fs.closeSync(fd) - if (options.chown) fs.chownSync(tmpfile, options.chown.uid, options.chown.gid) - if (options.mode) fs.chmodSync(tmpfile, options.mode) - fs.renameSync(tmpfile, filename) - removeOnExitHandler() - } catch (err) { - if (fd) { - try { - fs.closeSync(fd) - } catch (ex) { - // ignore close errors at this stage, error may have closed fd already. - } - } - removeOnExitHandler() - cleanup() - throw err - } -} + return template(chalk, parts.join('')); +}; + +Object.defineProperties(Chalk.prototype, styles); + +const chalk = Chalk(); // eslint-disable-line new-cap +chalk.supportsColor = stdoutColor; +chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap +chalk.stderr.supportsColor = stderrColor; + +module.exports = chalk; /***/ }), -/* 213 */ +/* 236 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(132) -var polyfills = __webpack_require__(214) -var legacy = __webpack_require__(216) -var queue = [] +"use strict"; +/* WEBPACK VAR INJECTION */(function(module) { -var util = __webpack_require__(111) +const wrapAnsi16 = (fn, offset) => (...args) => { + const code = fn(...args); + return `\u001B[${code + offset}m`; +}; -function noop () {} +const wrapAnsi256 = (fn, offset) => (...args) => { + const code = fn(...args); + return `\u001B[${38 + offset};5;${code}m`; +}; -var debug = noop -if (util.debuglog) - debug = util.debuglog('gfs4') -else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) - debug = function() { - var m = util.format.apply(util, arguments) - m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') - console.error(m) - } +const wrapAnsi16m = (fn, offset) => (...args) => { + const rgb = fn(...args); + return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; +}; -if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { - process.on('exit', function() { - debug(queue) - __webpack_require__(138).equal(queue.length, 0) - }) -} +const ansi2ansi = n => n; +const rgb2rgb = (r, g, b) => [r, g, b]; -module.exports = patch(__webpack_require__(215)) -if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) { - module.exports = patch(fs) -} +const setLazyProperty = (object, property, get) => { + Object.defineProperty(object, property, { + get: () => { + const value = get(); -// Always patch fs.close/closeSync, because we want to -// retry() whenever a close happens *anywhere* in the program. -// This is essential when multiple graceful-fs instances are -// in play at the same time. -module.exports.close = -fs.close = (function (fs$close) { return function (fd, cb) { - return fs$close.call(fs, fd, function (err) { - if (!err) - retry() + Object.defineProperty(object, property, { + value, + enumerable: true, + configurable: true + }); - if (typeof cb === 'function') - cb.apply(this, arguments) - }) -}})(fs.close) + return value; + }, + enumerable: true, + configurable: true + }); +}; -module.exports.closeSync = -fs.closeSync = (function (fs$closeSync) { return function (fd) { - // Note that graceful-fs also retries when fs.closeSync() fails. - // Looks like a bug to me, although it's probably a harmless one. - var rval = fs$closeSync.apply(fs, arguments) - retry() - return rval -}})(fs.closeSync) +/** @type {typeof import('color-convert')} */ +let colorConvert; +const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { + if (colorConvert === undefined) { + colorConvert = __webpack_require__(237); + } -function patch (fs) { - // Everything that references the open() function needs to be in here - polyfills(fs) - fs.gracefulify = patch - fs.FileReadStream = ReadStream; // Legacy name. - fs.FileWriteStream = WriteStream; // Legacy name. - fs.createReadStream = createReadStream - fs.createWriteStream = createWriteStream - var fs$readFile = fs.readFile - fs.readFile = readFile - function readFile (path, options, cb) { - if (typeof options === 'function') - cb = options, options = null + const offset = isBackground ? 10 : 0; + const styles = {}; - return go$readFile(path, options, cb) + for (const [sourceSpace, suite] of Object.entries(colorConvert)) { + const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace; + if (sourceSpace === targetSpace) { + styles[name] = wrap(identity, offset); + } else if (typeof suite === 'object') { + styles[name] = wrap(suite[targetSpace], offset); + } + } - function go$readFile (path, options, cb) { - return fs$readFile(path, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readFile, [path, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + return styles; +}; - var fs$writeFile = fs.writeFile - fs.writeFile = writeFile - function writeFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null +function assembleStyles() { + const codes = new Map(); + const styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29] + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], - return go$writeFile(path, data, options, cb) + // Bright color + blackBright: [90, 39], + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39] + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], - function go$writeFile (path, data, options, cb) { - return fs$writeFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$writeFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + // Bright color + bgBlackBright: [100, 49], + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] + } + }; - var fs$appendFile = fs.appendFile - if (fs$appendFile) - fs.appendFile = appendFile - function appendFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + // Alias bright black as gray (and grey) + styles.color.gray = styles.color.blackBright; + styles.bgColor.bgGray = styles.bgColor.bgBlackBright; + styles.color.grey = styles.color.blackBright; + styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; - return go$appendFile(path, data, options, cb) + for (const [groupName, group] of Object.entries(styles)) { + for (const [styleName, style] of Object.entries(group)) { + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m` + }; - function go$appendFile (path, data, options, cb) { - return fs$appendFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$appendFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + group[styleName] = styles[styleName]; - var fs$readdir = fs.readdir - fs.readdir = readdir - function readdir (path, options, cb) { - var args = [path] - if (typeof options !== 'function') { - args.push(options) - } else { - cb = options - } - args.push(go$readdir$cb) + codes.set(style[0], style[1]); + } - return go$readdir(args) + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false + }); + } - function go$readdir$cb (err, files) { - if (files && files.sort) - files.sort() + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false + }); - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readdir, [args]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - } - } + styles.color.close = '\u001B[39m'; + styles.bgColor.close = '\u001B[49m'; - function go$readdir (args) { - return fs$readdir.apply(fs, args) - } + setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false)); + setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false)); + setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false)); + setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true)); + setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true)); + setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true)); - if (process.version.substr(0, 4) === 'v0.8') { - var legStreams = legacy(fs) - ReadStream = legStreams.ReadStream - WriteStream = legStreams.WriteStream - } + return styles; +} - var fs$ReadStream = fs.ReadStream - ReadStream.prototype = Object.create(fs$ReadStream.prototype) - ReadStream.prototype.open = ReadStream$open +// Make the export immutable +Object.defineProperty(module, 'exports', { + enumerable: true, + get: assembleStyles +}); - var fs$WriteStream = fs.WriteStream - WriteStream.prototype = Object.create(fs$WriteStream.prototype) - WriteStream.prototype.open = WriteStream$open +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) - fs.ReadStream = ReadStream - fs.WriteStream = WriteStream +/***/ }), +/* 237 */ +/***/ (function(module, exports, __webpack_require__) { - function ReadStream (path, options) { - if (this instanceof ReadStream) - return fs$ReadStream.apply(this, arguments), this - else - return ReadStream.apply(Object.create(ReadStream.prototype), arguments) - } +const conversions = __webpack_require__(238); +const route = __webpack_require__(239); - function ReadStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - if (that.autoClose) - that.destroy() +const convert = {}; - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - that.read() - } - }) - } +const models = Object.keys(conversions); - function WriteStream (path, options) { - if (this instanceof WriteStream) - return fs$WriteStream.apply(this, arguments), this - else - return WriteStream.apply(Object.create(WriteStream.prototype), arguments) - } +function wrapRaw(fn) { + const wrappedFn = function (...args) { + const arg0 = args[0]; + if (arg0 === undefined || arg0 === null) { + return arg0; + } - function WriteStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - that.destroy() - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - } - }) - } + if (arg0.length > 1) { + args = arg0; + } - function createReadStream (path, options) { - return new ReadStream(path, options) - } + return fn(args); + }; - function createWriteStream (path, options) { - return new WriteStream(path, options) - } + // Preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } - var fs$open = fs.open - fs.open = open - function open (path, flags, mode, cb) { - if (typeof mode === 'function') - cb = mode, mode = null + return wrappedFn; +} + +function wrapRounded(fn) { + const wrappedFn = function (...args) { + const arg0 = args[0]; + + if (arg0 === undefined || arg0 === null) { + return arg0; + } + + if (arg0.length > 1) { + args = arg0; + } + + const result = fn(args); + + // We're assuming the result is an array here. + // see notice in conversions.js; don't use box types + // in conversion functions. + if (typeof result === 'object') { + for (let len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } + } + + return result; + }; + + // Preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } - return go$open(path, flags, mode, cb) + return wrappedFn; +} - function go$open (path, flags, mode, cb) { - return fs$open(path, flags, mode, function (err, fd) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$open, [path, flags, mode, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } +models.forEach(fromModel => { + convert[fromModel] = {}; - return fs -} + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); -function enqueue (elem) { - debug('ENQUEUE', elem[0].name, elem[1]) - queue.push(elem) -} + const routes = route(fromModel); + const routeModels = Object.keys(routes); -function retry () { - var elem = queue.shift() - if (elem) { - debug('RETRY', elem[0].name, elem[1]) - elem[0].apply(null, elem[1]) - } -} + routeModels.forEach(toModel => { + const fn = routes[toModel]; + + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); + +module.exports = convert; /***/ }), -/* 214 */ +/* 238 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(215) -var constants = __webpack_require__(134) - -var origCwd = process.cwd -var cwd = null - -var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform +/* MIT license */ +/* eslint-disable no-mixed-operators */ +const cssKeywords = __webpack_require__(117); -process.cwd = function() { - if (!cwd) - cwd = origCwd.call(process) - return cwd -} -try { - process.cwd() -} catch (er) {} +// NOTE: conversions should only return primitive values (i.e. arrays, or +// values that give correct `typeof` results). +// do not use box values types (i.e. Number(), String(), etc.) -var chdir = process.chdir -process.chdir = function(d) { - cwd = null - chdir.call(process, d) +const reverseKeywords = {}; +for (const key of Object.keys(cssKeywords)) { + reverseKeywords[cssKeywords[key]] = key; } -module.exports = patch +const convert = { + rgb: {channels: 3, labels: 'rgb'}, + hsl: {channels: 3, labels: 'hsl'}, + hsv: {channels: 3, labels: 'hsv'}, + hwb: {channels: 3, labels: 'hwb'}, + cmyk: {channels: 4, labels: 'cmyk'}, + xyz: {channels: 3, labels: 'xyz'}, + lab: {channels: 3, labels: 'lab'}, + lch: {channels: 3, labels: 'lch'}, + hex: {channels: 1, labels: ['hex']}, + keyword: {channels: 1, labels: ['keyword']}, + ansi16: {channels: 1, labels: ['ansi16']}, + ansi256: {channels: 1, labels: ['ansi256']}, + hcg: {channels: 3, labels: ['h', 'c', 'g']}, + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, + gray: {channels: 1, labels: ['gray']} +}; -function patch (fs) { - // (re-)implement some things that are known busted or missing. +module.exports = convert; - // lchmod, broken prior to 0.6.2 - // back-port the fix here. - if (constants.hasOwnProperty('O_SYMLINK') && - process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { - patchLchmod(fs) - } +// Hide .channels and .labels properties +for (const model of Object.keys(convert)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } - // lutimes implementation, or no-op - if (!fs.lutimes) { - patchLutimes(fs) - } + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } - // https://github.com/isaacs/node-graceful-fs/issues/4 - // Chown should not fail on einval or eperm if non-root. - // It should not fail on enosys ever, as this just indicates - // that a fs doesn't support the intended operation. + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); + } - fs.chown = chownFix(fs.chown) - fs.fchown = chownFix(fs.fchown) - fs.lchown = chownFix(fs.lchown) + const {channels, labels} = convert[model]; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); +} - fs.chmod = chmodFix(fs.chmod) - fs.fchmod = chmodFix(fs.fchmod) - fs.lchmod = chmodFix(fs.lchmod) +convert.rgb.hsl = function (rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const min = Math.min(r, g, b); + const max = Math.max(r, g, b); + const delta = max - min; + let h; + let s; - fs.chownSync = chownFixSync(fs.chownSync) - fs.fchownSync = chownFixSync(fs.fchownSync) - fs.lchownSync = chownFixSync(fs.lchownSync) + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; + } - fs.chmodSync = chmodFixSync(fs.chmodSync) - fs.fchmodSync = chmodFixSync(fs.fchmodSync) - fs.lchmodSync = chmodFixSync(fs.lchmodSync) + h = Math.min(h * 60, 360); - fs.stat = statFix(fs.stat) - fs.fstat = statFix(fs.fstat) - fs.lstat = statFix(fs.lstat) + if (h < 0) { + h += 360; + } - fs.statSync = statFixSync(fs.statSync) - fs.fstatSync = statFixSync(fs.fstatSync) - fs.lstatSync = statFixSync(fs.lstatSync) + const l = (min + max) / 2; - // if lchmod/lchown do not exist, then make them no-ops - if (!fs.lchmod) { - fs.lchmod = function (path, mode, cb) { - if (cb) process.nextTick(cb) - } - fs.lchmodSync = function () {} - } - if (!fs.lchown) { - fs.lchown = function (path, uid, gid, cb) { - if (cb) process.nextTick(cb) - } - fs.lchownSync = function () {} - } + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } - // on Windows, A/V software can lock the directory, causing this - // to fail with an EACCES or EPERM if the directory contains newly - // created files. Try again on failure, for up to 60 seconds. + return [h, s * 100, l * 100]; +}; - // Set the timeout this long because some Windows Anti-Virus, such as Parity - // bit9, may lock files for up to a minute, causing npm package install - // failures. Also, take care to yield the scheduler. Windows scheduling gives - // CPU to a busy looping process, which can cause the program causing the lock - // contention to be starved of CPU by node, so the contention doesn't resolve. - if (platform === "win32") { - fs.rename = (function (fs$rename) { return function (from, to, cb) { - var start = Date.now() - var backoff = 0; - fs$rename(from, to, function CB (er) { - if (er - && (er.code === "EACCES" || er.code === "EPERM") - && Date.now() - start < 60000) { - setTimeout(function() { - fs.stat(to, function (stater, st) { - if (stater && stater.code === "ENOENT") - fs$rename(from, to, CB); - else - cb(er) - }) - }, backoff) - if (backoff < 100) - backoff += 10; - return; - } - if (cb) cb(er) - }) - }})(fs.rename) - } +convert.rgb.hsv = function (rgb) { + let rdif; + let gdif; + let bdif; + let h; + let s; + + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const v = Math.max(r, g, b); + const diff = v - Math.min(r, g, b); + const diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; + }; - // if read() returns EAGAIN, then just try it again. - fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { - var callback - if (callback_ && typeof callback_ === 'function') { - var eagCounter = 0 - callback = function (er, _, __) { - if (er && er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - } - callback_.apply(this, arguments) - } - } - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - }})(fs.read) + if (diff === 0) { + h = 0; + s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); + + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } - fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { - var eagCounter = 0 - while (true) { - try { - return fs$readSync.call(fs, fd, buffer, offset, length, position) - } catch (er) { - if (er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - continue - } - throw er - } - } - }})(fs.readSync) -} + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } -function patchLchmod (fs) { - fs.lchmod = function (path, mode, callback) { - fs.open( path - , constants.O_WRONLY | constants.O_SYMLINK - , mode - , function (err, fd) { - if (err) { - if (callback) callback(err) - return - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function (err) { - fs.close(fd, function(err2) { - if (callback) callback(err || err2) - }) - }) - }) - } + return [ + h * 360, + s * 100, + v * 100 + ]; +}; - fs.lchmodSync = function (path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) +convert.rgb.hwb = function (rgb) { + const r = rgb[0]; + const g = rgb[1]; + let b = rgb[2]; + const h = convert.rgb.hsl(rgb)[0]; + const w = 1 / 255 * Math.min(r, Math.min(g, b)); - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var threw = true - var ret - try { - ret = fs.fchmodSync(fd, mode) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret - } -} + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); -function patchLutimes (fs) { - if (constants.hasOwnProperty("O_SYMLINK")) { - fs.lutimes = function (path, at, mt, cb) { - fs.open(path, constants.O_SYMLINK, function (er, fd) { - if (er) { - if (cb) cb(er) - return - } - fs.futimes(fd, at, mt, function (er) { - fs.close(fd, function (er2) { - if (cb) cb(er || er2) - }) - }) - }) - } + return [h, w * 100, b * 100]; +}; - fs.lutimesSync = function (path, at, mt) { - var fd = fs.openSync(path, constants.O_SYMLINK) - var ret - var threw = true - try { - ret = fs.futimesSync(fd, at, mt) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret - } +convert.rgb.cmyk = function (rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; - } else { - fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } - fs.lutimesSync = function () {} - } -} + const k = Math.min(1 - r, 1 - g, 1 - b); + const c = (1 - r - k) / (1 - k) || 0; + const m = (1 - g - k) / (1 - k) || 0; + const y = (1 - b - k) / (1 - k) || 0; -function chmodFix (orig) { - if (!orig) return orig - return function (target, mode, cb) { - return orig.call(fs, target, mode, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) - } -} + return [c * 100, m * 100, y * 100, k * 100]; +}; -function chmodFixSync (orig) { - if (!orig) return orig - return function (target, mode) { - try { - return orig.call(fs, target, mode) - } catch (er) { - if (!chownErOk(er)) throw er - } - } +function comparativeDistance(x, y) { + /* + See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + */ + return ( + ((x[0] - y[0]) ** 2) + + ((x[1] - y[1]) ** 2) + + ((x[2] - y[2]) ** 2) + ); } +convert.rgb.keyword = function (rgb) { + const reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } -function chownFix (orig) { - if (!orig) return orig - return function (target, uid, gid, cb) { - return orig.call(fs, target, uid, gid, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) - } -} + let currentClosestDistance = Infinity; + let currentClosestKeyword; -function chownFixSync (orig) { - if (!orig) return orig - return function (target, uid, gid) { - try { - return orig.call(fs, target, uid, gid) - } catch (er) { - if (!chownErOk(er)) throw er - } - } -} + for (const keyword of Object.keys(cssKeywords)) { + const value = cssKeywords[keyword]; + // Compute comparative distance + const distance = comparativeDistance(rgb, value); -function statFix (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, cb) { - return orig.call(fs, target, function (er, stats) { - if (!stats) return cb.apply(this, arguments) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - if (cb) cb.apply(this, arguments) - }) - } -} + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } -function statFixSync (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target) { - var stats = orig.call(fs, target) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - return stats; - } -} + return currentClosestKeyword; +}; -// ENOSYS means that the fs doesn't support the op. Just ignore -// that, because it doesn't matter. -// -// if there's no getuid, or if getuid() is something other -// than 0, and the error is EINVAL or EPERM, then just ignore -// it. -// -// This specific case is a silent failure in cp, install, tar, -// and most other unix tools that manage permissions. -// -// When running as root, or if other types of errors are -// encountered, then it's strict. -function chownErOk (er) { - if (!er) - return true +convert.keyword.rgb = function (keyword) { + return cssKeywords[keyword]; +}; - if (er.code === "ENOSYS") - return true +convert.rgb.xyz = function (rgb) { + let r = rgb[0] / 255; + let g = rgb[1] / 255; + let b = rgb[2] / 255; - var nonroot = !process.getuid || process.getuid() !== 0 - if (nonroot) { - if (er.code === "EINVAL" || er.code === "EPERM") - return true - } + // Assume sRGB + r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92); + g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92); + b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92); - return false -} + const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); + return [x * 100, y * 100, z * 100]; +}; -/***/ }), -/* 215 */ -/***/ (function(module, exports, __webpack_require__) { +convert.rgb.lab = function (rgb) { + const xyz = convert.rgb.xyz(rgb); + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; -"use strict"; + x /= 95.047; + y /= 100; + z /= 108.883; + x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); -var fs = __webpack_require__(132) + const l = (116 * y) - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); -module.exports = clone(fs) + return [l, a, b]; +}; -function clone (obj) { - if (obj === null || typeof obj !== 'object') - return obj +convert.hsl.rgb = function (hsl) { + const h = hsl[0] / 360; + const s = hsl[1] / 100; + const l = hsl[2] / 100; + let t2; + let t3; + let val; - if (obj instanceof Object) - var copy = { __proto__: obj.__proto__ } - else - var copy = Object.create(null) + if (s === 0) { + val = l * 255; + return [val, val, val]; + } - Object.getOwnPropertyNames(obj).forEach(function (key) { - Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) - }) + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; + } - return copy -} + const t1 = 2 * l - t2; + const rgb = [0, 0, 0]; + for (let i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } -/***/ }), -/* 216 */ -/***/ (function(module, exports, __webpack_require__) { + if (t3 > 1) { + t3--; + } -var Stream = __webpack_require__(136).Stream + if (6 * t3 < 1) { + val = t1 + (t2 - t1) * 6 * t3; + } else if (2 * t3 < 1) { + val = t2; + } else if (3 * t3 < 2) { + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + } else { + val = t1; + } -module.exports = legacy + rgb[i] = val * 255; + } -function legacy (fs) { - return { - ReadStream: ReadStream, - WriteStream: WriteStream - } + return rgb; +}; - function ReadStream (path, options) { - if (!(this instanceof ReadStream)) return new ReadStream(path, options); +convert.hsl.hsv = function (hsl) { + const h = hsl[0]; + let s = hsl[1] / 100; + let l = hsl[2] / 100; + let smin = s; + const lmin = Math.max(l, 0.01); - Stream.call(this); + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + const v = (l + s) / 2; + const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); - var self = this; + return [h, sv * 100, v * 100]; +}; - this.path = path; - this.fd = null; - this.readable = true; - this.paused = false; +convert.hsv.rgb = function (hsv) { + const h = hsv[0] / 60; + const s = hsv[1] / 100; + let v = hsv[2] / 100; + const hi = Math.floor(h) % 6; + + const f = h - Math.floor(h); + const p = 255 * v * (1 - s); + const q = 255 * v * (1 - (s * f)); + const t = 255 * v * (1 - (s * (1 - f))); + v *= 255; - this.flags = 'r'; - this.mode = 438; /*=0666*/ - this.bufferSize = 64 * 1024; + switch (hi) { + case 0: + return [v, t, p]; + case 1: + return [q, v, p]; + case 2: + return [p, v, t]; + case 3: + return [p, q, v]; + case 4: + return [t, p, v]; + case 5: + return [v, p, q]; + } +}; - options = options || {}; +convert.hsv.hsl = function (hsv) { + const h = hsv[0]; + const s = hsv[1] / 100; + const v = hsv[2] / 100; + const vmin = Math.max(v, 0.01); + let sl; + let l; - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } + l = (2 - s) * v; + const lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; - if (this.encoding) this.setEncoding(this.encoding); + return [h, sl * 100, l * 100]; +}; - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +convert.hwb.rgb = function (hwb) { + const h = hwb[0] / 360; + let wh = hwb[1] / 100; + let bl = hwb[2] / 100; + const ratio = wh + bl; + let f; - if (this.start > this.end) { - throw new Error('start must be <= end'); - } + // Wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; + } - this.pos = this.start; - } + const i = Math.floor(6 * h); + const v = 1 - bl; + f = 6 * h - i; - if (this.fd !== null) { - process.nextTick(function() { - self._read(); - }); - return; - } + if ((i & 0x01) !== 0) { + f = 1 - f; + } - fs.open(this.path, this.flags, this.mode, function (err, fd) { - if (err) { - self.emit('error', err); - self.readable = false; - return; - } + const n = wh + f * (v - wh); // Linear interpolation - self.fd = fd; - self.emit('open', fd); - self._read(); - }) - } + let r; + let g; + let b; + /* eslint-disable max-statements-per-line,no-multi-spaces */ + switch (i) { + default: + case 6: + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; + } + /* eslint-enable max-statements-per-line,no-multi-spaces */ - function WriteStream (path, options) { - if (!(this instanceof WriteStream)) return new WriteStream(path, options); + return [r * 255, g * 255, b * 255]; +}; - Stream.call(this); +convert.cmyk.rgb = function (cmyk) { + const c = cmyk[0] / 100; + const m = cmyk[1] / 100; + const y = cmyk[2] / 100; + const k = cmyk[3] / 100; - this.path = path; - this.fd = null; - this.writable = true; + const r = 1 - Math.min(1, c * (1 - k) + k); + const g = 1 - Math.min(1, m * (1 - k) + k); + const b = 1 - Math.min(1, y * (1 - k) + k); - this.flags = 'w'; - this.encoding = 'binary'; - this.mode = 438; /*=0666*/ - this.bytesWritten = 0; + return [r * 255, g * 255, b * 255]; +}; - options = options || {}; +convert.xyz.rgb = function (xyz) { + const x = xyz[0] / 100; + const y = xyz[1] / 100; + const z = xyz[2] / 100; + let r; + let g; + let b; - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } + // Assume sRGB + r = r > 0.0031308 + ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055) + : r * 12.92; - this.pos = this.start; - } + g = g > 0.0031308 + ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055) + : g * 12.92; - this.busy = false; - this._queue = []; + b = b > 0.0031308 + ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055) + : b * 12.92; - if (this.fd === null) { - this._open = fs.open; - this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); - this.flush(); - } - } -} + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); + return [r * 255, g * 255, b * 255]; +}; -/***/ }), -/* 217 */ -/***/ (function(module, exports, __webpack_require__) { +convert.xyz.lab = function (xyz) { + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; -/** - * @preserve - * JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013) - * - * @author Jens Taylor - * @see http://github.com/homebrewing/brauhaus-diff - * @author Gary Court - * @see http://github.com/garycourt/murmurhash-js - * @author Austin Appleby - * @see http://sites.google.com/site/murmurhash/ - */ -(function(){ - var cache; + x /= 95.047; + y /= 100; + z /= 108.883; - // Call this function without `new` to use the cached object (good for - // single-threaded environments), or with `new` to create a new object. - // - // @param {string} key A UTF-16 or ASCII string - // @param {number} seed An optional positive integer - // @return {object} A MurmurHash3 object for incremental hashing - function MurmurHash3(key, seed) { - var m = this instanceof MurmurHash3 ? this : cache; - m.reset(seed) - if (typeof key === 'string' && key.length > 0) { - m.hash(key); - } + x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - if (m !== this) { - return m; - } - }; + const l = (116 * y) - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); - // Incrementally add a string to this hash - // - // @param {string} key A UTF-16 or ASCII string - // @return {object} this - MurmurHash3.prototype.hash = function(key) { - var h1, k1, i, top, len; + return [l, a, b]; +}; - len = key.length; - this.len += len; +convert.lab.xyz = function (lab) { + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let x; + let y; + let z; - k1 = this.k1; - i = 0; - switch (this.rem) { - case 0: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) : 0; - case 1: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 8 : 0; - case 2: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 16 : 0; - case 3: - k1 ^= len > i ? (key.charCodeAt(i) & 0xff) << 24 : 0; - k1 ^= len > i ? (key.charCodeAt(i++) & 0xff00) >> 8 : 0; - } + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; - this.rem = (len + this.rem) & 3; // & 3 is same as % 4 - len -= this.rem; - if (len > 0) { - h1 = this.h1; - while (1) { - k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; - k1 = (k1 << 15) | (k1 >>> 17); - k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; + const y2 = y ** 3; + const x2 = x ** 3; + const z2 = z ** 3; + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; - h1 ^= k1; - h1 = (h1 << 13) | (h1 >>> 19); - h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff; + x *= 95.047; + y *= 100; + z *= 108.883; - if (i >= len) { - break; - } + return [x, y, z]; +}; - k1 = ((key.charCodeAt(i++) & 0xffff)) ^ - ((key.charCodeAt(i++) & 0xffff) << 8) ^ - ((key.charCodeAt(i++) & 0xffff) << 16); - top = key.charCodeAt(i++); - k1 ^= ((top & 0xff) << 24) ^ - ((top & 0xff00) >> 8); - } +convert.lab.lch = function (lab) { + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let h; - k1 = 0; - switch (this.rem) { - case 3: k1 ^= (key.charCodeAt(i + 2) & 0xffff) << 16; - case 2: k1 ^= (key.charCodeAt(i + 1) & 0xffff) << 8; - case 1: k1 ^= (key.charCodeAt(i) & 0xffff); - } + const hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; - this.h1 = h1; - } + if (h < 0) { + h += 360; + } - this.k1 = k1; - return this; - }; + const c = Math.sqrt(a * a + b * b); - // Get the result of this hash - // - // @return {number} The 32-bit hash - MurmurHash3.prototype.result = function() { - var k1, h1; - - k1 = this.k1; - h1 = this.h1; + return [l, c, h]; +}; - if (k1 > 0) { - k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; - k1 = (k1 << 15) | (k1 >>> 17); - k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; - h1 ^= k1; - } +convert.lch.lab = function (lch) { + const l = lch[0]; + const c = lch[1]; + const h = lch[2]; - h1 ^= this.len; + const hr = h / 360 * 2 * Math.PI; + const a = c * Math.cos(hr); + const b = c * Math.sin(hr); - h1 ^= h1 >>> 16; - h1 = (h1 * 0xca6b + (h1 & 0xffff) * 0x85eb0000) & 0xffffffff; - h1 ^= h1 >>> 13; - h1 = (h1 * 0xae35 + (h1 & 0xffff) * 0xc2b20000) & 0xffffffff; - h1 ^= h1 >>> 16; + return [l, a, b]; +}; - return h1 >>> 0; - }; +convert.rgb.ansi16 = function (args, saturation = null) { + const [r, g, b] = args; + let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization - // Reset the hash object for reuse - // - // @param {number} seed An optional positive integer - MurmurHash3.prototype.reset = function(seed) { - this.h1 = typeof seed === 'number' ? seed : 0; - this.rem = this.k1 = this.len = 0; - return this; - }; + value = Math.round(value / 50); - // A cached object to use. This can be safely used if you're in a single- - // threaded environment, otherwise you need to create new hashes to use. - cache = new MurmurHash3(); + if (value === 0) { + return 30; + } - if (true) { - module.exports = MurmurHash3; - } else {} -}()); + let ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); + if (value === 2) { + ansi += 60; + } -/***/ }), -/* 218 */ -/***/ (function(module, exports, __webpack_require__) { + return ansi; +}; -// Note: since nyc uses this module to output coverage, any lines -// that are in the direct sync flow of nyc's outputCoverage are -// ignored, since we can never get coverage for them. -var assert = __webpack_require__(138) -var signals = __webpack_require__(219) +convert.hsv.ansi16 = function (args) { + // Optimization here; we already know the value and don't need to get + // it converted for us. + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); +}; -var EE = __webpack_require__(154) -/* istanbul ignore if */ -if (typeof EE !== 'function') { - EE = EE.EventEmitter -} +convert.rgb.ansi256 = function (args) { + const r = args[0]; + const g = args[1]; + const b = args[2]; -var emitter -if (process.__signal_exit_emitter__) { - emitter = process.__signal_exit_emitter__ -} else { - emitter = process.__signal_exit_emitter__ = new EE() - emitter.count = 0 - emitter.emitted = {} -} + // We use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (r === g && g === b) { + if (r < 8) { + return 16; + } -// Because this emitter is a global, we have to check to see if a -// previous version of this library failed to enable infinite listeners. -// I know what you're about to say. But literally everything about -// signal-exit is a compromise with evil. Get used to it. -if (!emitter.infinite) { - emitter.setMaxListeners(Infinity) - emitter.infinite = true -} + if (r > 248) { + return 231; + } -module.exports = function (cb, opts) { - assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler') + return Math.round(((r - 8) / 247) * 24) + 232; + } - if (loaded === false) { - load() - } + const ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); - var ev = 'exit' - if (opts && opts.alwaysLast) { - ev = 'afterexit' - } + return ansi; +}; - var remove = function () { - emitter.removeListener(ev, cb) - if (emitter.listeners('exit').length === 0 && - emitter.listeners('afterexit').length === 0) { - unload() - } - } - emitter.on(ev, cb) +convert.ansi16.rgb = function (args) { + let color = args % 10; - return remove -} + // Handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } -module.exports.unload = unload -function unload () { - if (!loaded) { - return - } - loaded = false + color = color / 10.5 * 255; - signals.forEach(function (sig) { - try { - process.removeListener(sig, sigListeners[sig]) - } catch (er) {} - }) - process.emit = originalProcessEmit - process.reallyExit = originalProcessReallyExit - emitter.count -= 1 -} + return [color, color, color]; + } -function emit (event, code, signal) { - if (emitter.emitted[event]) { - return - } - emitter.emitted[event] = true - emitter.emit(event, code, signal) -} + const mult = (~~(args > 50) + 1) * 0.5; + const r = ((color & 1) * mult) * 255; + const g = (((color >> 1) & 1) * mult) * 255; + const b = (((color >> 2) & 1) * mult) * 255; -// { : , ... } -var sigListeners = {} -signals.forEach(function (sig) { - sigListeners[sig] = function listener () { - // If there are no other listeners, an exit is coming! - // Simplest way: remove us and then re-send the signal. - // We know that this will kill the process, so we can - // safely emit now. - var listeners = process.listeners(sig) - if (listeners.length === emitter.count) { - unload() - emit('exit', null, sig) - /* istanbul ignore next */ - emit('afterexit', null, sig) - /* istanbul ignore next */ - process.kill(process.pid, sig) - } - } -}) + return [r, g, b]; +}; -module.exports.signals = function () { - return signals -} +convert.ansi256.rgb = function (args) { + // Handle greyscale + if (args >= 232) { + const c = (args - 232) * 10 + 8; + return [c, c, c]; + } -module.exports.load = load + args -= 16; -var loaded = false + let rem; + const r = Math.floor(args / 36) / 5 * 255; + const g = Math.floor((rem = args % 36) / 6) / 5 * 255; + const b = (rem % 6) / 5 * 255; -function load () { - if (loaded) { - return - } - loaded = true + return [r, g, b]; +}; - // This is the number of onSignalExit's that are in play. - // It's important so that we can count the correct number of - // listeners on signals, and don't wait for the other one to - // handle it instead of us. - emitter.count += 1 +convert.rgb.hex = function (args) { + const integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); - signals = signals.filter(function (sig) { - try { - process.on(sig, sigListeners[sig]) - return true - } catch (er) { - return false - } - }) + const string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; - process.emit = processEmit - process.reallyExit = processReallyExit -} +convert.hex.rgb = function (args) { + const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; + } -var originalProcessReallyExit = process.reallyExit -function processReallyExit (code) { - process.exitCode = code || 0 - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - /* istanbul ignore next */ - originalProcessReallyExit.call(process, process.exitCode) -} + let colorString = match[0]; -var originalProcessEmit = process.emit -function processEmit (ev, arg) { - if (ev === 'exit') { - if (arg !== undefined) { - process.exitCode = arg - } - var ret = originalProcessEmit.apply(this, arguments) - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - return ret - } else { - return originalProcessEmit.apply(this, arguments) - } -} + if (match[0].length === 3) { + colorString = colorString.split('').map(char => { + return char + char; + }).join(''); + } + const integer = parseInt(colorString, 16); + const r = (integer >> 16) & 0xFF; + const g = (integer >> 8) & 0xFF; + const b = integer & 0xFF; -/***/ }), -/* 219 */ -/***/ (function(module, exports) { + return [r, g, b]; +}; -// This is not the set of all possible signals. -// -// It IS, however, the set of all signals that trigger -// an exit on either Linux or BSD systems. Linux is a -// superset of the signal names supported on BSD, and -// the unknown signals just fail to register, so we can -// catch that easily enough. -// -// Don't bother with SIGKILL. It's uncatchable, which -// means that we can't fire any callbacks anyway. -// -// If a user does happen to register a handler on a non- -// fatal signal like SIGWINCH or something, and then -// exit, it'll end up firing `process.emit('exit')`, so -// the handler will be fired anyway. -// -// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised -// artificially, inherently leave the process in a -// state from which it is not safe to try and enter JS -// listeners. -module.exports = [ - 'SIGABRT', - 'SIGALRM', - 'SIGHUP', - 'SIGINT', - 'SIGTERM' -] +convert.rgb.hcg = function (rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const max = Math.max(Math.max(r, g), b); + const min = Math.min(Math.min(r, g), b); + const chroma = (max - min); + let grayscale; + let hue; -if (process.platform !== 'win32') { - module.exports.push( - 'SIGVTALRM', - 'SIGXCPU', - 'SIGXFSZ', - 'SIGUSR2', - 'SIGTRAP', - 'SIGSYS', - 'SIGQUIT', - 'SIGIOT' - // should detect profiler and enable/disable accordingly. - // see #21 - // 'SIGPROF' - ) -} + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; + } -if (process.platform === 'linux') { - module.exports.push( - 'SIGIO', - 'SIGPOLL', - 'SIGPWR', - 'SIGSTKFLT', - 'SIGUNUSED' - ) -} + if (chroma <= 0) { + hue = 0; + } else + if (max === r) { + hue = ((g - b) / chroma) % 6; + } else + if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma; + } + hue /= 6; + hue %= 1; -/***/ }), -/* 220 */ -/***/ (function(module, exports) { + return [hue * 360, chroma * 100, grayscale * 100]; +}; -module.exports = require(undefined); +convert.hsl.hcg = function (hsl) { + const s = hsl[1] / 100; + const l = hsl[2] / 100; -/***/ }), -/* 221 */ -/***/ (function(module, exports, __webpack_require__) { + const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l)); -"use strict"; + let f = 0; + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); + } -const isPlainObj = __webpack_require__(222); + return [hsl[0], c * 100, f * 100]; +}; -module.exports = (obj, opts) => { - if (!isPlainObj(obj)) { - throw new TypeError('Expected a plain object'); +convert.hsv.hcg = function (hsv) { + const s = hsv[1] / 100; + const v = hsv[2] / 100; + + const c = s * v; + let f = 0; + + if (c < 1.0) { + f = (v - c) / (1 - c); } - opts = opts || {}; + return [hsv[0], c * 100, f * 100]; +}; - // DEPRECATED - if (typeof opts === 'function') { - throw new TypeError('Specify the compare function as an option instead'); +convert.hcg.rgb = function (hcg) { + const h = hcg[0] / 360; + const c = hcg[1] / 100; + const g = hcg[2] / 100; + + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; } - const deep = opts.deep; - const seenInput = []; - const seenOutput = []; + const pure = [0, 0, 0]; + const hi = (h % 1) * 6; + const v = hi % 1; + const w = 1 - v; + let mg = 0; - const sortKeys = x => { - const seenIndex = seenInput.indexOf(x); + /* eslint-disable max-statements-per-line */ + switch (Math.floor(hi)) { + case 0: + pure[0] = 1; pure[1] = v; pure[2] = 0; break; + case 1: + pure[0] = w; pure[1] = 1; pure[2] = 0; break; + case 2: + pure[0] = 0; pure[1] = 1; pure[2] = v; break; + case 3: + pure[0] = 0; pure[1] = w; pure[2] = 1; break; + case 4: + pure[0] = v; pure[1] = 0; pure[2] = 1; break; + default: + pure[0] = 1; pure[1] = 0; pure[2] = w; + } + /* eslint-enable max-statements-per-line */ - if (seenIndex !== -1) { - return seenOutput[seenIndex]; - } + mg = (1.0 - c) * g; - const ret = {}; - const keys = Object.keys(x).sort(opts.compare); + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; - seenInput.push(x); - seenOutput.push(ret); +convert.hcg.hsv = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - const val = x[key]; + const v = c + g * (1.0 - c); + let f = 0; - if (deep && Array.isArray(val)) { - const retArr = []; + if (v > 0.0) { + f = c / v; + } - for (let j = 0; j < val.length; j++) { - retArr[j] = isPlainObj(val[j]) ? sortKeys(val[j]) : val[j]; - } + return [hcg[0], f * 100, v * 100]; +}; - ret[key] = retArr; - continue; - } +convert.hcg.hsl = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; - ret[key] = deep && isPlainObj(val) ? sortKeys(val) : val; - } + const l = g * (1.0 - c) + 0.5 * c; + let s = 0; - return ret; - }; + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); + } - return sortKeys(obj); + return [hcg[0], s * 100, l * 100]; }; +convert.hcg.hwb = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; + const v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; -/***/ }), -/* 222 */ -/***/ (function(module, exports, __webpack_require__) { +convert.hwb.hcg = function (hwb) { + const w = hwb[1] / 100; + const b = hwb[2] / 100; + const v = 1 - b; + const c = v - w; + let g = 0; -"use strict"; + if (c < 1) { + g = (v - c) / (1 - c); + } -var toString = Object.prototype.toString; + return [hwb[0], c * 100, g * 100]; +}; -module.exports = function (x) { - var prototype; - return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({})); +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; }; +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; +}; -/***/ }), -/* 223 */ -/***/ (function(module, exports, __webpack_require__) { +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; -"use strict"; +convert.gray.hsl = function (args) { + return [0, 0, args[0]]; +}; -const fs = __webpack_require__(132); -const path = __webpack_require__(4); -const pify = __webpack_require__(224); -const semver = __webpack_require__(182); +convert.gray.hsv = convert.gray.hsl; -const defaults = { - mode: 0o777 & (~process.umask()), - fs +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; }; -const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); - -// https://github.com/nodejs/node/issues/8987 -// https://github.com/libuv/libuv/pull/1088 -const checkPath = pth => { - if (process.platform === 'win32') { - const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, '')); +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; - if (pathHasInvalidWinCharacters) { - const error = new Error(`Path contains invalid characters: ${pth}`); - error.code = 'EINVAL'; - throw error; - } - } +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; }; -const permissionError = pth => { - // This replicates the exception of `fs.mkdir` with native the - // `recusive` option when run on an invalid drive under Windows. - const error = new Error(`operation not permitted, mkdir '${pth}'`); - error.code = 'EPERM'; - error.errno = -4048; - error.path = pth; - error.syscall = 'mkdir'; - return error; +convert.gray.hex = function (gray) { + const val = Math.round(gray[0] / 100 * 255) & 0xFF; + const integer = (val << 16) + (val << 8) + val; + + const string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; }; -const makeDir = (input, options) => Promise.resolve().then(() => { - checkPath(input); - options = Object.assign({}, defaults, options); +convert.rgb.gray = function (rgb) { + const val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; +}; - // TODO: Use util.promisify when targeting Node.js 8 - const mkdir = pify(options.fs.mkdir); - const stat = pify(options.fs.stat); - if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) { - const pth = path.resolve(input); +/***/ }), +/* 239 */ +/***/ (function(module, exports, __webpack_require__) { - return mkdir(pth, { - mode: options.mode, - recursive: true - }).then(() => pth); - } +const conversions = __webpack_require__(238); - const make = pth => { - return mkdir(pth, options.mode) - .then(() => pth) - .catch(error => { - if (error.code === 'EPERM') { - throw error; - } +/* + This function routes a model to all other models. - if (error.code === 'ENOENT') { - if (path.dirname(pth) === pth) { - throw permissionError(pth); - } + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). - if (error.message.includes('null bytes')) { - throw error; - } + conversions that are not possible simply are not included. +*/ - return make(path.dirname(pth)).then(() => make(pth)); - } +function buildGraph() { + const graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + const models = Object.keys(conversions); - return stat(pth) - .then(stats => stats.isDirectory() ? pth : Promise.reject()) - .catch(() => { - throw error; - }); - }); - }; + for (let len = models.length, i = 0; i < len; i++) { + graph[models[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; + } - return make(path.resolve(input)); -}); + return graph; +} -module.exports = makeDir; -module.exports.default = makeDir; +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + const graph = buildGraph(); + const queue = [fromModel]; // Unshift -> queue -> pop -module.exports.sync = (input, options) => { - checkPath(input); - options = Object.assign({}, defaults, options); + graph[fromModel].distance = 0; - if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) { - const pth = path.resolve(input); + while (queue.length) { + const current = queue.pop(); + const adjacents = Object.keys(conversions[current]); - fs.mkdirSync(pth, { - mode: options.mode, - recursive: true - }); + for (let len = adjacents.length, i = 0; i < len; i++) { + const adjacent = adjacents[i]; + const node = graph[adjacent]; - return pth; + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } } - const make = pth => { - try { - options.fs.mkdirSync(pth, options.mode); - } catch (error) { - if (error.code === 'EPERM') { - throw error; - } + return graph; +} - if (error.code === 'ENOENT') { - if (path.dirname(pth) === pth) { - throw permissionError(pth); - } +function link(from, to) { + return function (args) { + return to(from(args)); + }; +} - if (error.message.includes('null bytes')) { - throw error; - } +function wrapConversion(toModel, graph) { + const path = [graph[toModel].parent, toModel]; + let fn = conversions[graph[toModel].parent][toModel]; - make(path.dirname(pth)); - return make(pth); - } + let cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions[graph[cur].parent][cur], fn); + cur = graph[cur].parent; + } - try { - if (!options.fs.statSync(pth).isDirectory()) { - throw new Error('The path is not a directory'); - } - } catch (_) { - throw error; - } + fn.conversion = path; + return fn; +} + +module.exports = function (fromModel) { + const graph = deriveBFS(fromModel); + const conversion = {}; + + const models = Object.keys(graph); + for (let len = models.length, i = 0; i < len; i++) { + const toModel = models[i]; + const node = graph[toModel]; + + if (node.parent === null) { + // No possible conversion, or this node is the source model. + continue; } - return pth; - }; + conversion[toModel] = wrapConversion(toModel, graph); + } - return make(path.resolve(input)); + return conversion; }; + /***/ }), -/* 224 */ +/* 240 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const os = __webpack_require__(120); +const tty = __webpack_require__(121); +const hasFlag = __webpack_require__(241); -const processFn = (fn, options) => function (...args) { - const P = options.promiseModule; - - return new P((resolve, reject) => { - if (options.multiArgs) { - args.push((...result) => { - if (options.errorFirst) { - if (result[0]) { - reject(result); - } else { - result.shift(); - resolve(result); - } - } else { - resolve(result); - } - }); - } else if (options.errorFirst) { - args.push((error, result) => { - if (error) { - reject(error); - } else { - resolve(result); - } - }); - } else { - args.push(resolve); - } +const {env} = process; - fn.apply(this, args); - }); -}; +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false') || + hasFlag('color=never')) { + forceColor = 0; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = 1; +} -module.exports = (input, options) => { - options = Object.assign({ - exclude: [/.+(Sync|Stream)$/], - errorFirst: true, - promiseModule: Promise - }, options); +if ('FORCE_COLOR' in env) { + if (env.FORCE_COLOR === 'true') { + forceColor = 1; + } else if (env.FORCE_COLOR === 'false') { + forceColor = 0; + } else { + forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); + } +} - const objType = typeof input; - if (!(input !== null && (objType === 'object' || objType === 'function'))) { - throw new TypeError(`Expected \`input\` to be a \`Function\` or \`Object\`, got \`${input === null ? 'null' : objType}\``); +function translateLevel(level) { + if (level === 0) { + return false; } - const filter = key => { - const match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key); - return options.include ? options.include.some(match) : !options.exclude.some(match); + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 }; +} - let ret; - if (objType === 'function') { - ret = function (...args) { - return options.excludeMain ? input(...args) : processFn(input, options).apply(this, args); - }; - } else { - ret = Object.create(Object.getPrototypeOf(input)); +function supportsColor(haveStream, streamIsTTY) { + if (forceColor === 0) { + return 0; } - for (const key in input) { // eslint-disable-line guard-for-in - const property = input[key]; - ret[key] = typeof property === 'function' && filter(key) ? processFn(property, options) : property; + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; } - return ret; -}; + if (hasFlag('color=256')) { + return 2; + } + if (haveStream && !streamIsTTY && forceColor === undefined) { + return 0; + } -/***/ }), -/* 225 */ -/***/ (function(module, exports, __webpack_require__) { + const min = forceColor || 0; -"use strict"; + if (env.TERM === 'dumb') { + return min; + } + if (process.platform === 'win32') { + // Windows 10 build 10586 is the first Windows release that supports 256 colors. + // Windows 10 build 14931 is the first release that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } -// detect either spaces or tabs but not both to properly handle tabs -// for indentation and spaces for alignment -const INDENT_RE = /^(?:( )+|\t+)/; + return 1; + } -function getMostUsed(indents) { - let result = 0; - let maxUsed = 0; - let maxWeight = 0; + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } - for (const entry of indents) { - // TODO: use destructuring when targeting Node.js 6 - const key = entry[0]; - const val = entry[1]; + return min; + } - const u = val[0]; - const w = val[1]; + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } - if (u > maxUsed || (u === maxUsed && w > maxWeight)) { - maxUsed = u; - maxWeight = w; - result = Number(key); + if ('GITHUB_ACTIONS' in env) { + return 1; + } + + if (env.COLORTERM === 'truecolor') { + return 3; + } + + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default } } - return result; -} + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } -module.exports = str => { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; } - // used to see if tabs or spaces are the most used - let tabs = 0; - let spaces = 0; + if ('COLORTERM' in env) { + return 1; + } - // remember the size of previous line's indentation - let prev = 0; + return min; +} - // remember how many indents/unindents as occurred for a given size - // and how much lines follow a given indentation - // - // indents = { - // 3: [1, 0], - // 4: [1, 5], - // 5: [1, 0], - // 12: [1, 0], - // } - const indents = new Map(); +function getSupportLevel(stream) { + const level = supportsColor(stream, stream && stream.isTTY); + return translateLevel(level); +} - // pointer to the array of last used indent - let current; +module.exports = { + supportsColor: getSupportLevel, + stdout: translateLevel(supportsColor(true, tty.isatty(1))), + stderr: translateLevel(supportsColor(true, tty.isatty(2))) +}; + + +/***/ }), +/* 241 */ +/***/ (function(module, exports, __webpack_require__) { - // whether the last action was an indent (opposed to an unindent) - let isIndent; +"use strict"; - for (const line of str.split(/\n/g)) { - if (!line) { - // ignore empty lines - continue; - } - let indent; - const matches = line.match(INDENT_RE); +module.exports = (flag, argv = process.argv) => { + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf('--'); + return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); +}; - if (matches) { - indent = matches[0].length; - if (matches[1]) { - spaces++; - } else { - tabs++; - } - } else { - indent = 0; - } +/***/ }), +/* 242 */ +/***/ (function(module, exports, __webpack_require__) { - const diff = indent - prev; - prev = indent; +"use strict"; - if (diff) { - // an indent or unindent has been detected - isIndent = diff > 0; +const stringReplaceAll = (string, substring, replacer) => { + let index = string.indexOf(substring); + if (index === -1) { + return string; + } - current = indents.get(isIndent ? diff : -diff); + const substringLength = substring.length; + let endIndex = 0; + let returnValue = ''; + do { + returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; + endIndex = index + substringLength; + index = string.indexOf(substring, endIndex); + } while (index !== -1); - if (current) { - current[0]++; - } else { - current = [1, 0]; - indents.set(diff, current); - } - } else if (current) { - // if the last action was an indent, increment the weight - current[1] += Number(isIndent); - } - } + returnValue += string.substr(endIndex); + return returnValue; +}; - const amount = getMostUsed(indents); +const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { + let endIndex = 0; + let returnValue = ''; + do { + const gotCR = string[index - 1] === '\r'; + returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; + endIndex = index + 1; + index = string.indexOf('\n', endIndex); + } while (index !== -1); - let type; - let indent; - if (!amount) { - type = null; - indent = ''; - } else if (spaces >= tabs) { - type = 'space'; - indent = ' '.repeat(amount); - } else { - type = 'tab'; - indent = '\t'.repeat(amount); - } + returnValue += string.substr(endIndex); + return returnValue; +}; - return { - amount, - type, - indent - }; +module.exports = { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex }; /***/ }), -/* 226 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 243 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "installInDir", function() { return installInDir; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackage", function() { return runScriptInPackage; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackageStreaming", function() { return runScriptInPackageStreaming; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yarnWorkspacesInfo", function() { return yarnWorkspacesInfo; }); -/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(227); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -const YARN_EXEC = process.env.npm_execpath || 'yarn'; +const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; +const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; +const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; +const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi; -/** - * Install all dependencies in the given directory - */ -async function installInDir(directory, extraArgs = []) { - const options = ['install', '--non-interactive', ...extraArgs]; // We pass the mutex flag to ensure only one instance of yarn runs at any - // given time (e.g. to avoid conflicts). +const ESCAPES = new Map([ + ['n', '\n'], + ['r', '\r'], + ['t', '\t'], + ['b', '\b'], + ['f', '\f'], + ['v', '\v'], + ['0', '\0'], + ['\\', '\\'], + ['e', '\u001B'], + ['a', '\u0007'] +]); - await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, options, { - cwd: directory - }); -} -/** - * Run script in the given directory - */ +function unescape(c) { + const u = c[0] === 'u'; + const bracket = c[1] === '{'; -async function runScriptInPackage(script, args, pkg) { - const execOpts = { - cwd: pkg.path - }; - await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, ['run', script, ...args], execOpts); -} -/** - * Run script in the given directory - */ + if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { + return String.fromCharCode(parseInt(c.slice(1), 16)); + } -function runScriptInPackageStreaming({ - script, - args, - pkg, - debug -}) { - const execOpts = { - cwd: pkg.path - }; - return Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawnStreaming"])(YARN_EXEC, ['run', script, ...args], execOpts, { - prefix: pkg.name, - debug - }); -} -async function yarnWorkspacesInfo(directory) { - const { - stdout - } = await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])(YARN_EXEC, ['--json', 'workspaces', 'info'], { - cwd: directory, - stdio: 'pipe' - }); + if (u && bracket) { + return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); + } - try { - return JSON.parse(JSON.parse(stdout).data); - } catch (error) { - throw new Error(`'yarn workspaces info --json' produced unexpected output: \n${stdout}`); - } + return ESCAPES.get(c) || c; } -/***/ }), -/* 227 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +function parseArguments(name, arguments_) { + const results = []; + const chunks = arguments_.trim().split(/\s*,\s*/g); + let matches; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawn", function() { return spawn; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawnStreaming", function() { return spawnStreaming; }); -/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(136); -/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(stream__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(112); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(228); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(263); -/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(142); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + for (const chunk of chunks) { + const number = Number(chunk); + if (!Number.isNaN(number)) { + results.push(number); + } else if ((matches = chunk.match(STRING_REGEX))) { + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); + } else { + throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); + } + } -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + return results; +} -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +function parseStyle(style) { + STYLE_REGEX.lastIndex = 0; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + const results = []; + let matches; + while ((matches = STYLE_REGEX.exec(style)) !== null) { + const name = matches[1]; + if (matches[2]) { + const args = parseArguments(name, matches[2]); + results.push([name].concat(args)); + } else { + results.push([name]); + } + } + return results; +} +function buildStyle(chalk, styles) { + const enabled = {}; -const colorWheel = [chalk__WEBPACK_IMPORTED_MODULE_1___default.a.cyan, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.magenta, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.blue, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.yellow, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.green]; + for (const layer of styles) { + for (const style of layer.styles) { + enabled[style[0]] = layer.inverse ? null : style.slice(1); + } + } -const getColor = () => { - const color = colorWheel.shift(); - colorWheel.push(color); - return color; -}; + let current = chalk; + for (const [styleName, styles] of Object.entries(enabled)) { + if (!Array.isArray(styles)) { + continue; + } -function spawn(command, args, opts) { - return execa__WEBPACK_IMPORTED_MODULE_2___default()(command, args, _objectSpread({ - stdio: 'inherit', - preferLocal: true - }, opts)); + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); + } + + current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; + } + + return current; } -function streamToLog(debug = true) { - return new stream__WEBPACK_IMPORTED_MODULE_0__["Writable"]({ - objectMode: true, +module.exports = (chalk, temporary) => { + const styles = []; + const chunks = []; + let chunk = []; - write(line, _, cb) { - if (line.endsWith('\n')) { - _log__WEBPACK_IMPORTED_MODULE_4__["log"][debug ? 'debug' : 'write'](line.slice(0, -1)); - } else { - _log__WEBPACK_IMPORTED_MODULE_4__["log"][debug ? 'debug' : 'write'](line); - } + // eslint-disable-next-line max-params + temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { + if (escapeCharacter) { + chunk.push(unescape(escapeCharacter)); + } else if (style) { + const string = chunk.join(''); + chunk = []; + chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); + styles.push({inverse, styles: parseStyle(style)}); + } else if (close) { + if (styles.length === 0) { + throw new Error('Found extraneous } in Chalk template literal'); + } - cb(); - } + chunks.push(buildStyle(chalk, styles)(chunk.join(''))); + chunk = []; + styles.pop(); + } else { + chunk.push(character); + } + }); - }); -} + chunks.push(chunk.join('')); + + if (styles.length > 0) { + const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errMessage); + } + + return chunks.join(''); +}; -function spawnStreaming(command, args, opts, { - prefix, - debug -}) { - const spawned = execa__WEBPACK_IMPORTED_MODULE_2___default()(command, args, _objectSpread({ - stdio: ['ignore', 'pipe', 'pipe'], - preferLocal: true - }, opts)); - const color = getColor(); - const prefixedStdout = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ - tag: color.bold(prefix) - }); - const prefixedStderr = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ - mergeMultiline: true, - tag: color.bold(prefix) - }); - spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); - spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); - return spawned; -} /***/ }), -/* 228 */ +/* 244 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const childProcess = __webpack_require__(229); -const crossSpawn = __webpack_require__(230); -const stripFinalNewline = __webpack_require__(243); -const npmRunPath = __webpack_require__(244); -const onetime = __webpack_require__(245); -const makeError = __webpack_require__(247); -const normalizeStdio = __webpack_require__(252); -const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(253); -const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(254); -const {mergePromise, getSpawnedPromise} = __webpack_require__(261); -const {joinCommand, parseCommand} = __webpack_require__(262); +const childProcess = __webpack_require__(245); +const crossSpawn = __webpack_require__(246); +const stripFinalNewline = __webpack_require__(259); +const npmRunPath = __webpack_require__(260); +const onetime = __webpack_require__(261); +const makeError = __webpack_require__(263); +const normalizeStdio = __webpack_require__(268); +const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(269); +const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(270); +const {mergePromise, getSpawnedPromise} = __webpack_require__(277); +const {joinCommand, parseCommand} = __webpack_require__(278); const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; @@ -24239,21 +27302,21 @@ module.exports.node = (scriptPath, args, options = {}) => { /***/ }), -/* 229 */ +/* 245 */ /***/ (function(module, exports) { module.exports = require("child_process"); /***/ }), -/* 230 */ +/* 246 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const cp = __webpack_require__(229); -const parse = __webpack_require__(231); -const enoent = __webpack_require__(242); +const cp = __webpack_require__(245); +const parse = __webpack_require__(247); +const enoent = __webpack_require__(258); function spawn(command, args, options) { // Parse the arguments @@ -24291,16 +27354,16 @@ module.exports._enoent = enoent; /***/ }), -/* 231 */ +/* 247 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const resolveCommand = __webpack_require__(232); -const escape = __webpack_require__(238); -const readShebang = __webpack_require__(239); +const resolveCommand = __webpack_require__(248); +const escape = __webpack_require__(254); +const readShebang = __webpack_require__(255); const isWin = process.platform === 'win32'; const isExecutableRegExp = /\.(?:com|exe)$/i; @@ -24389,15 +27452,15 @@ module.exports = parse; /***/ }), -/* 232 */ +/* 248 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const which = __webpack_require__(233); -const pathKey = __webpack_require__(237)(); +const which = __webpack_require__(249); +const pathKey = __webpack_require__(253)(); function resolveCommandAttempt(parsed, withoutPathExt) { const cwd = process.cwd(); @@ -24447,7 +27510,7 @@ module.exports = resolveCommand; /***/ }), -/* 233 */ +/* 249 */ /***/ (function(module, exports, __webpack_require__) { const isWindows = process.platform === 'win32' || @@ -24456,7 +27519,7 @@ const isWindows = process.platform === 'win32' || const path = __webpack_require__(4) const COLON = isWindows ? ';' : ':' -const isexe = __webpack_require__(234) +const isexe = __webpack_require__(250) const getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) @@ -24578,15 +27641,15 @@ which.sync = whichSync /***/ }), -/* 234 */ +/* 250 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(132) +var fs = __webpack_require__(133) var core if (process.platform === 'win32' || global.TESTING_WINDOWS) { - core = __webpack_require__(235) + core = __webpack_require__(251) } else { - core = __webpack_require__(236) + core = __webpack_require__(252) } module.exports = isexe @@ -24641,13 +27704,13 @@ function sync (path, options) { /***/ }), -/* 235 */ +/* 251 */ /***/ (function(module, exports, __webpack_require__) { module.exports = isexe isexe.sync = sync -var fs = __webpack_require__(132) +var fs = __webpack_require__(133) function checkPathExt (path, options) { var pathext = options.pathExt !== undefined ? @@ -24689,13 +27752,13 @@ function sync (path, options) { /***/ }), -/* 236 */ +/* 252 */ /***/ (function(module, exports, __webpack_require__) { module.exports = isexe isexe.sync = sync -var fs = __webpack_require__(132) +var fs = __webpack_require__(133) function isexe (path, options, cb) { fs.stat(path, function (er, stat) { @@ -24736,7 +27799,7 @@ function checkMode (stat, options) { /***/ }), -/* 237 */ +/* 253 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24759,7 +27822,7 @@ module.exports.default = pathKey; /***/ }), -/* 238 */ +/* 254 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24811,14 +27874,14 @@ module.exports.argument = escapeArgument; /***/ }), -/* 239 */ +/* 255 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(132); -const shebangCommand = __webpack_require__(240); +const fs = __webpack_require__(133); +const shebangCommand = __webpack_require__(256); function readShebang(command) { // Read the first 150 bytes from the file @@ -24841,12 +27904,12 @@ module.exports = readShebang; /***/ }), -/* 240 */ +/* 256 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const shebangRegex = __webpack_require__(241); +const shebangRegex = __webpack_require__(257); module.exports = (string = '') => { const match = string.match(shebangRegex); @@ -24867,7 +27930,7 @@ module.exports = (string = '') => { /***/ }), -/* 241 */ +/* 257 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24876,7 +27939,7 @@ module.exports = /^#!(.*)/; /***/ }), -/* 242 */ +/* 258 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24942,7 +28005,7 @@ module.exports = { /***/ }), -/* 243 */ +/* 259 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -24965,13 +28028,13 @@ module.exports = input => { /***/ }), -/* 244 */ +/* 260 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const pathKey = __webpack_require__(237); +const pathKey = __webpack_require__(253); const npmRunPath = options => { options = { @@ -25019,12 +28082,12 @@ module.exports.env = options => { /***/ }), -/* 245 */ +/* 261 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const mimicFn = __webpack_require__(246); +const mimicFn = __webpack_require__(262); const calledFunctions = new WeakMap(); @@ -25076,7 +28139,7 @@ module.exports.callCount = fn => { /***/ }), -/* 246 */ +/* 262 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -25096,12 +28159,12 @@ module.exports.default = mimicFn; /***/ }), -/* 247 */ +/* 263 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {signalsByName} = __webpack_require__(248); +const {signalsByName} = __webpack_require__(264); const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { if (timedOut) { @@ -25189,14 +28252,14 @@ module.exports = makeError; /***/ }), -/* 248 */ +/* 264 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.signalsByNumber=exports.signalsByName=void 0;var _os=__webpack_require__(121); +Object.defineProperty(exports,"__esModule",{value:true});exports.signalsByNumber=exports.signalsByName=void 0;var _os=__webpack_require__(120); -var _signals=__webpack_require__(249); -var _realtime=__webpack_require__(251); +var _signals=__webpack_require__(265); +var _realtime=__webpack_require__(267); @@ -25266,14 +28329,14 @@ const signalsByNumber=getSignalsByNumber();exports.signalsByNumber=signalsByNumb //# sourceMappingURL=main.js.map /***/ }), -/* 249 */ +/* 265 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(121); +Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(120); -var _core=__webpack_require__(250); -var _realtime=__webpack_require__(251); +var _core=__webpack_require__(266); +var _realtime=__webpack_require__(267); @@ -25307,7 +28370,7 @@ return{name,number,description,supported,action,forced,standard}; //# sourceMappingURL=signals.js.map /***/ }), -/* 250 */ +/* 266 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -25586,7 +28649,7 @@ standard:"other"}];exports.SIGNALS=SIGNALS; //# sourceMappingURL=core.js.map /***/ }), -/* 251 */ +/* 267 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -25611,7 +28674,7 @@ const SIGRTMAX=64;exports.SIGRTMAX=SIGRTMAX; //# sourceMappingURL=realtime.js.map /***/ }), -/* 252 */ +/* 268 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -25670,13 +28733,13 @@ module.exports.node = opts => { /***/ }), -/* 253 */ +/* 269 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(121); -const onExit = __webpack_require__(218); +const os = __webpack_require__(120); +const onExit = __webpack_require__(225); const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; @@ -25789,14 +28852,14 @@ module.exports = { /***/ }), -/* 254 */ +/* 270 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const isStream = __webpack_require__(255); -const getStream = __webpack_require__(256); -const mergeStream = __webpack_require__(260); +const isStream = __webpack_require__(271); +const getStream = __webpack_require__(272); +const mergeStream = __webpack_require__(276); // `input` option const handleInput = (spawned, input) => { @@ -25893,7 +28956,7 @@ module.exports = { /***/ }), -/* 255 */ +/* 271 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -25929,13 +28992,13 @@ module.exports = isStream; /***/ }), -/* 256 */ +/* 272 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pump = __webpack_require__(257); -const bufferStream = __webpack_require__(259); +const pump = __webpack_require__(273); +const bufferStream = __webpack_require__(275); class MaxBufferError extends Error { constructor() { @@ -25994,12 +29057,12 @@ module.exports.MaxBufferError = MaxBufferError; /***/ }), -/* 257 */ +/* 273 */ /***/ (function(module, exports, __webpack_require__) { -var once = __webpack_require__(160) -var eos = __webpack_require__(258) -var fs = __webpack_require__(132) // we only need fs to get the ReadStream and WriteStream prototypes +var once = __webpack_require__(161) +var eos = __webpack_require__(274) +var fs = __webpack_require__(133) // we only need fs to get the ReadStream and WriteStream prototypes var noop = function () {} var ancient = /^v?\.0/.test(process.version) @@ -26082,10 +29145,10 @@ module.exports = pump /***/ }), -/* 258 */ +/* 274 */ /***/ (function(module, exports, __webpack_require__) { -var once = __webpack_require__(160); +var once = __webpack_require__(161); var noop = function() {}; @@ -26175,12 +29238,12 @@ module.exports = eos; /***/ }), -/* 259 */ +/* 275 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {PassThrough: PassThroughStream} = __webpack_require__(136); +const {PassThrough: PassThroughStream} = __webpack_require__(137); module.exports = options => { options = {...options}; @@ -26234,13 +29297,13 @@ module.exports = options => { /***/ }), -/* 260 */ +/* 276 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const { PassThrough } = __webpack_require__(136); +const { PassThrough } = __webpack_require__(137); module.exports = function (/*streams...*/) { var sources = [] @@ -26282,7 +29345,7 @@ module.exports = function (/*streams...*/) { /***/ }), -/* 261 */ +/* 277 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -26335,7 +29398,7 @@ module.exports = { /***/ }), -/* 262 */ +/* 278 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -26380,7 +29443,7 @@ module.exports = { /***/ }), -/* 263 */ +/* 279 */ /***/ (function(module, exports, __webpack_require__) { // Copyright IBM Corp. 2014,2018. All Rights Reserved. @@ -26388,12 +29451,12 @@ module.exports = { // This file is licensed under the Apache License 2.0. // License text available at https://opensource.org/licenses/Apache-2.0 -module.exports = __webpack_require__(264); -module.exports.cli = __webpack_require__(268); +module.exports = __webpack_require__(280); +module.exports.cli = __webpack_require__(284); /***/ }), -/* 264 */ +/* 280 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -26404,13 +29467,13 @@ module.exports.cli = __webpack_require__(268); -var stream = __webpack_require__(136); +var stream = __webpack_require__(137); var util = __webpack_require__(111); -var fs = __webpack_require__(132); +var fs = __webpack_require__(133); -var through = __webpack_require__(265); -var duplexer = __webpack_require__(266); -var StringDecoder = __webpack_require__(267).StringDecoder; +var through = __webpack_require__(281); +var duplexer = __webpack_require__(282); +var StringDecoder = __webpack_require__(283).StringDecoder; module.exports = Logger; @@ -26599,10 +29662,10 @@ function lineMerger(host) { /***/ }), -/* 265 */ +/* 281 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(136) +var Stream = __webpack_require__(137) // through // @@ -26713,10 +29776,10 @@ function through (write, end, opts) { /***/ }), -/* 266 */ +/* 282 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(136) +var Stream = __webpack_require__(137) var writeMethods = ["write", "end", "destroy"] var readMethods = ["resume", "pause"] var readEvents = ["data", "close"] @@ -26806,13 +29869,13 @@ function duplex(writer, reader) { /***/ }), -/* 267 */ +/* 283 */ /***/ (function(module, exports) { module.exports = require("string_decoder"); /***/ }), -/* 268 */ +/* 284 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -26823,11 +29886,11 @@ module.exports = require("string_decoder"); -var minimist = __webpack_require__(269); +var minimist = __webpack_require__(285); var path = __webpack_require__(4); -var Logger = __webpack_require__(264); -var pkg = __webpack_require__(270); +var Logger = __webpack_require__(280); +var pkg = __webpack_require__(286); module.exports = cli; @@ -26881,7 +29944,7 @@ function usage($0, p) { /***/ }), -/* 269 */ +/* 285 */ /***/ (function(module, exports) { module.exports = function (args, opts) { @@ -27123,29 +30186,29 @@ function isNumber (x) { /***/ }), -/* 270 */ +/* 286 */ /***/ (function(module) { module.exports = JSON.parse("{\"name\":\"strong-log-transformer\",\"version\":\"2.1.0\",\"description\":\"Stream transformer that prefixes lines with timestamps and other things.\",\"author\":\"Ryan Graham \",\"license\":\"Apache-2.0\",\"repository\":{\"type\":\"git\",\"url\":\"git://github.com/strongloop/strong-log-transformer\"},\"keywords\":[\"logging\",\"streams\"],\"bugs\":{\"url\":\"https://github.com/strongloop/strong-log-transformer/issues\"},\"homepage\":\"https://github.com/strongloop/strong-log-transformer\",\"directories\":{\"test\":\"test\"},\"bin\":{\"sl-log-transformer\":\"bin/sl-log-transformer.js\"},\"main\":\"index.js\",\"scripts\":{\"test\":\"tap --100 test/test-*\"},\"dependencies\":{\"duplexer\":\"^0.1.1\",\"minimist\":\"^1.2.0\",\"through\":\"^2.3.4\"},\"devDependencies\":{\"tap\":\"^12.0.1\"},\"engines\":{\"node\":\">=4\"}}"); /***/ }), -/* 271 */ +/* 287 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "workspacePackagePaths", function() { return workspacePackagePaths; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return copyWorkspacePackages; }); -/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(145); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(146); /* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(111); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(272); -/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(129); -/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(163); -/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(144); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(288); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(130); +/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(164); +/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(145); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -27237,7 +30300,7 @@ function packagesFromGlobPattern({ } /***/ }), -/* 272 */ +/* 288 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -27307,21 +30370,21 @@ function getProjectPaths({ } /***/ }), -/* 273 */ +/* 289 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAllChecksums", function() { return getAllChecksums; }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(132); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(133); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(274); +/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(290); /* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(111); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(228); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(244); /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(275); +/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(291); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -27550,21 +30613,21 @@ async function getAllChecksums(kbn, log) { } /***/ }), -/* 274 */ +/* 290 */ /***/ (function(module, exports) { module.exports = require("crypto"); /***/ }), -/* 275 */ +/* 291 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readYarnLock", function() { return readYarnLock; }); -/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(276); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(292); /* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(129); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(130); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -27606,7 +30669,7 @@ async function readYarnLock(kbn) { } /***/ }), -/* 276 */ +/* 292 */ /***/ (function(module, exports, __webpack_require__) { module.exports = @@ -27738,7 +30801,7 @@ module.exports = __webpack_require__(111); /* 3 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(132); +module.exports = __webpack_require__(133); /***/ }), /* 4 */ @@ -29165,7 +32228,7 @@ module.exports = invariant; /* 9 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(274); +module.exports = __webpack_require__(290); /***/ }), /* 10 */, @@ -29591,7 +32654,7 @@ exports.default = Lockfile; /* 17 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(136); +module.exports = __webpack_require__(137); /***/ }), /* 18 */, @@ -29643,7 +32706,7 @@ function nullify(obj = {}) { /* 22 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(138); +module.exports = __webpack_require__(139); /***/ }), /* 23 */ @@ -29830,7 +32893,7 @@ module.exports = {}; /* 36 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(121); +module.exports = __webpack_require__(120); /***/ }), /* 37 */, @@ -30115,7 +33178,7 @@ exports.f = __webpack_require__(33) ? Object.defineProperty : function definePro /* 54 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(154); +module.exports = __webpack_require__(155); /***/ }), /* 55 */ @@ -31489,7 +34552,7 @@ function onceStrict (fn) { /* 63 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(277); +module.exports = __webpack_require__(293); /***/ }), /* 64 */, @@ -32427,7 +35490,7 @@ module.exports.win32 = win32; /* 79 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(278); +module.exports = __webpack_require__(121); /***/ }), /* 80 */, @@ -37884,25 +40947,19 @@ module.exports = process && support(supportLevel); /******/ ]); /***/ }), -/* 277 */ +/* 293 */ /***/ (function(module, exports) { module.exports = require("buffer"); /***/ }), -/* 278 */ -/***/ (function(module, exports) { - -module.exports = require("tty"); - -/***/ }), -/* 279 */ +/* 294 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BootstrapCacheFile", function() { return BootstrapCacheFile; }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(132); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(133); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); @@ -37993,20 +41050,20 @@ class BootstrapCacheFile { } /***/ }), -/* 280 */ +/* 295 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CleanCommand", function() { return CleanCommand; }); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(281); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(296); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(373); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(388); /* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(129); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(142); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(130); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -38101,21 +41158,21 @@ const CleanCommand = { }; /***/ }), -/* 281 */ +/* 296 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(111); const path = __webpack_require__(4); -const globby = __webpack_require__(282); -const isGlob = __webpack_require__(365); -const slash = __webpack_require__(363); -const gracefulFs = __webpack_require__(131); -const isPathCwd = __webpack_require__(366); -const isPathInside = __webpack_require__(367); -const rimraf = __webpack_require__(368); -const pMap = __webpack_require__(369); +const globby = __webpack_require__(297); +const isGlob = __webpack_require__(380); +const slash = __webpack_require__(378); +const gracefulFs = __webpack_require__(132); +const isPathCwd = __webpack_require__(381); +const isPathInside = __webpack_require__(382); +const rimraf = __webpack_require__(383); +const pMap = __webpack_require__(384); const rimrafP = promisify(rimraf); @@ -38229,19 +41286,19 @@ module.exports.sync = (patterns, {force, dryRun, cwd = process.cwd(), ...options /***/ }), -/* 282 */ +/* 297 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(132); -const arrayUnion = __webpack_require__(283); -const merge2 = __webpack_require__(284); -const glob = __webpack_require__(285); -const fastGlob = __webpack_require__(290); -const dirGlob = __webpack_require__(359); -const gitignore = __webpack_require__(361); -const {FilterStream, UniqueStream} = __webpack_require__(364); +const fs = __webpack_require__(133); +const arrayUnion = __webpack_require__(298); +const merge2 = __webpack_require__(299); +const glob = __webpack_require__(300); +const fastGlob = __webpack_require__(305); +const dirGlob = __webpack_require__(374); +const gitignore = __webpack_require__(376); +const {FilterStream, UniqueStream} = __webpack_require__(379); const DEFAULT_FILTER = () => false; @@ -38414,7 +41471,7 @@ module.exports.gitignore = gitignore; /***/ }), -/* 283 */ +/* 298 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -38426,7 +41483,7 @@ module.exports = (...arguments_) => { /***/ }), -/* 284 */ +/* 299 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -38438,7 +41495,7 @@ module.exports = (...arguments_) => { * Copyright (c) 2014-2020 Teambition * Licensed under the MIT license. */ -const Stream = __webpack_require__(136) +const Stream = __webpack_require__(137) const PassThrough = Stream.PassThrough const slice = Array.prototype.slice @@ -38577,7 +41634,7 @@ function pauseStreams (streams, options) { /***/ }), -/* 285 */ +/* 300 */ /***/ (function(module, exports, __webpack_require__) { // Approach: @@ -38622,27 +41679,27 @@ function pauseStreams (streams, options) { module.exports = glob -var fs = __webpack_require__(132) -var rp = __webpack_require__(146) -var minimatch = __webpack_require__(148) +var fs = __webpack_require__(133) +var rp = __webpack_require__(147) +var minimatch = __webpack_require__(149) var Minimatch = minimatch.Minimatch -var inherits = __webpack_require__(286) -var EE = __webpack_require__(154).EventEmitter +var inherits = __webpack_require__(301) +var EE = __webpack_require__(155).EventEmitter var path = __webpack_require__(4) -var assert = __webpack_require__(138) -var isAbsolute = __webpack_require__(155) -var globSync = __webpack_require__(288) -var common = __webpack_require__(289) +var assert = __webpack_require__(139) +var isAbsolute = __webpack_require__(156) +var globSync = __webpack_require__(303) +var common = __webpack_require__(304) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts var ownProp = common.ownProp -var inflight = __webpack_require__(158) +var inflight = __webpack_require__(159) var util = __webpack_require__(111) var childrenIgnored = common.childrenIgnored var isIgnored = common.isIgnored -var once = __webpack_require__(160) +var once = __webpack_require__(161) function glob (pattern, options, cb) { if (typeof options === 'function') cb = options, options = {} @@ -39373,7 +42430,7 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) { /***/ }), -/* 286 */ +/* 301 */ /***/ (function(module, exports, __webpack_require__) { try { @@ -39383,12 +42440,12 @@ try { module.exports = util.inherits; } catch (e) { /* istanbul ignore next */ - module.exports = __webpack_require__(287); + module.exports = __webpack_require__(302); } /***/ }), -/* 287 */ +/* 302 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -39421,22 +42478,22 @@ if (typeof Object.create === 'function') { /***/ }), -/* 288 */ +/* 303 */ /***/ (function(module, exports, __webpack_require__) { module.exports = globSync globSync.GlobSync = GlobSync -var fs = __webpack_require__(132) -var rp = __webpack_require__(146) -var minimatch = __webpack_require__(148) +var fs = __webpack_require__(133) +var rp = __webpack_require__(147) +var minimatch = __webpack_require__(149) var Minimatch = minimatch.Minimatch -var Glob = __webpack_require__(285).Glob +var Glob = __webpack_require__(300).Glob var util = __webpack_require__(111) var path = __webpack_require__(4) -var assert = __webpack_require__(138) -var isAbsolute = __webpack_require__(155) -var common = __webpack_require__(289) +var assert = __webpack_require__(139) +var isAbsolute = __webpack_require__(156) +var common = __webpack_require__(304) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts @@ -39913,7 +42970,7 @@ GlobSync.prototype._makeAbs = function (f) { /***/ }), -/* 289 */ +/* 304 */ /***/ (function(module, exports, __webpack_require__) { exports.alphasort = alphasort @@ -39931,8 +42988,8 @@ function ownProp (obj, field) { } var path = __webpack_require__(4) -var minimatch = __webpack_require__(148) -var isAbsolute = __webpack_require__(155) +var minimatch = __webpack_require__(149) +var isAbsolute = __webpack_require__(156) var Minimatch = minimatch.Minimatch function alphasorti (a, b) { @@ -40159,17 +43216,17 @@ function childrenIgnored (self, path) { /***/ }), -/* 290 */ +/* 305 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const taskManager = __webpack_require__(291); -const async_1 = __webpack_require__(320); -const stream_1 = __webpack_require__(355); -const sync_1 = __webpack_require__(356); -const settings_1 = __webpack_require__(358); -const utils = __webpack_require__(292); +const taskManager = __webpack_require__(306); +const async_1 = __webpack_require__(335); +const stream_1 = __webpack_require__(370); +const sync_1 = __webpack_require__(371); +const settings_1 = __webpack_require__(373); +const utils = __webpack_require__(307); async function FastGlob(source, options) { assertPatternsInput(source); const works = getWorks(source, async_1.default, options); @@ -40233,13 +43290,13 @@ module.exports = FastGlob; /***/ }), -/* 291 */ +/* 306 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(292); +const utils = __webpack_require__(307); function generate(patterns, settings) { const positivePatterns = getPositivePatterns(patterns); const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); @@ -40304,30 +43361,30 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 292 */ +/* 307 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const array = __webpack_require__(293); +const array = __webpack_require__(308); exports.array = array; -const errno = __webpack_require__(294); +const errno = __webpack_require__(309); exports.errno = errno; -const fs = __webpack_require__(295); +const fs = __webpack_require__(310); exports.fs = fs; -const path = __webpack_require__(296); +const path = __webpack_require__(311); exports.path = path; -const pattern = __webpack_require__(297); +const pattern = __webpack_require__(312); exports.pattern = pattern; -const stream = __webpack_require__(318); +const stream = __webpack_require__(333); exports.stream = stream; -const string = __webpack_require__(319); +const string = __webpack_require__(334); exports.string = string; /***/ }), -/* 293 */ +/* 308 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40355,7 +43412,7 @@ exports.splitWhen = splitWhen; /***/ }), -/* 294 */ +/* 309 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40368,7 +43425,7 @@ exports.isEnoentCodeError = isEnoentCodeError; /***/ }), -/* 295 */ +/* 310 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40393,7 +43450,7 @@ exports.createDirentFromStats = createDirentFromStats; /***/ }), -/* 296 */ +/* 311 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40432,16 +43489,16 @@ exports.removeLeadingDotSegment = removeLeadingDotSegment; /***/ }), -/* 297 */ +/* 312 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const globParent = __webpack_require__(298); -const micromatch = __webpack_require__(301); -const picomatch = __webpack_require__(312); +const globParent = __webpack_require__(313); +const micromatch = __webpack_require__(316); +const picomatch = __webpack_require__(327); const GLOBSTAR = '**'; const ESCAPE_SYMBOL = '\\'; const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/; @@ -40551,15 +43608,15 @@ exports.matchAny = matchAny; /***/ }), -/* 298 */ +/* 313 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isGlob = __webpack_require__(299); +var isGlob = __webpack_require__(314); var pathPosixDirname = __webpack_require__(4).posix.dirname; -var isWin32 = __webpack_require__(121).platform() === 'win32'; +var isWin32 = __webpack_require__(120).platform() === 'win32'; var slash = '/'; var backslash = /\\/g; @@ -40599,7 +43656,7 @@ module.exports = function globParent(str, opts) { /***/ }), -/* 299 */ +/* 314 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -40609,7 +43666,7 @@ module.exports = function globParent(str, opts) { * Released under the MIT License. */ -var isExtglob = __webpack_require__(300); +var isExtglob = __webpack_require__(315); var chars = { '{': '}', '(': ')', '[': ']'}; var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; @@ -40653,7 +43710,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 300 */ +/* 315 */ /***/ (function(module, exports) { /*! @@ -40679,16 +43736,16 @@ module.exports = function isExtglob(str) { /***/ }), -/* 301 */ +/* 316 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const util = __webpack_require__(111); -const braces = __webpack_require__(302); -const picomatch = __webpack_require__(312); -const utils = __webpack_require__(315); +const braces = __webpack_require__(317); +const picomatch = __webpack_require__(327); +const utils = __webpack_require__(330); const isEmptyString = val => typeof val === 'string' && (val === '' || val === './'); /** @@ -41153,16 +44210,16 @@ module.exports = micromatch; /***/ }), -/* 302 */ +/* 317 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringify = __webpack_require__(303); -const compile = __webpack_require__(305); -const expand = __webpack_require__(309); -const parse = __webpack_require__(310); +const stringify = __webpack_require__(318); +const compile = __webpack_require__(320); +const expand = __webpack_require__(324); +const parse = __webpack_require__(325); /** * Expand the given pattern or create a regex-compatible string. @@ -41330,13 +44387,13 @@ module.exports = braces; /***/ }), -/* 303 */ +/* 318 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const utils = __webpack_require__(304); +const utils = __webpack_require__(319); module.exports = (ast, options = {}) => { let stringify = (node, parent = {}) => { @@ -41369,7 +44426,7 @@ module.exports = (ast, options = {}) => { /***/ }), -/* 304 */ +/* 319 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41488,14 +44545,14 @@ exports.flatten = (...args) => { /***/ }), -/* 305 */ +/* 320 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fill = __webpack_require__(306); -const utils = __webpack_require__(304); +const fill = __webpack_require__(321); +const utils = __webpack_require__(319); const compile = (ast, options = {}) => { let walk = (node, parent = {}) => { @@ -41552,7 +44609,7 @@ module.exports = compile; /***/ }), -/* 306 */ +/* 321 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41566,7 +44623,7 @@ module.exports = compile; const util = __webpack_require__(111); -const toRegexRange = __webpack_require__(307); +const toRegexRange = __webpack_require__(322); const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); @@ -41808,7 +44865,7 @@ module.exports = fill; /***/ }), -/* 307 */ +/* 322 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41821,7 +44878,7 @@ module.exports = fill; -const isNumber = __webpack_require__(308); +const isNumber = __webpack_require__(323); const toRegexRange = (min, max, options) => { if (isNumber(min) === false) { @@ -42103,7 +45160,7 @@ module.exports = toRegexRange; /***/ }), -/* 308 */ +/* 323 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -42128,15 +45185,15 @@ module.exports = function(num) { /***/ }), -/* 309 */ +/* 324 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fill = __webpack_require__(306); -const stringify = __webpack_require__(303); -const utils = __webpack_require__(304); +const fill = __webpack_require__(321); +const stringify = __webpack_require__(318); +const utils = __webpack_require__(319); const append = (queue = '', stash = '', enclose = false) => { let result = []; @@ -42248,13 +45305,13 @@ module.exports = expand; /***/ }), -/* 310 */ +/* 325 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringify = __webpack_require__(303); +const stringify = __webpack_require__(318); /** * Constants @@ -42276,7 +45333,7 @@ const { CHAR_SINGLE_QUOTE, /* ' */ CHAR_NO_BREAK_SPACE, CHAR_ZERO_WIDTH_NOBREAK_SPACE -} = __webpack_require__(311); +} = __webpack_require__(326); /** * parse @@ -42588,7 +45645,7 @@ module.exports = parse; /***/ }), -/* 311 */ +/* 326 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -42652,27 +45709,27 @@ module.exports = { /***/ }), -/* 312 */ +/* 327 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = __webpack_require__(313); +module.exports = __webpack_require__(328); /***/ }), -/* 313 */ +/* 328 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const scan = __webpack_require__(314); -const parse = __webpack_require__(317); -const utils = __webpack_require__(315); -const constants = __webpack_require__(316); +const scan = __webpack_require__(329); +const parse = __webpack_require__(332); +const utils = __webpack_require__(330); +const constants = __webpack_require__(331); const isObject = val => val && typeof val === 'object' && !Array.isArray(val); /** @@ -43008,13 +46065,13 @@ module.exports = picomatch; /***/ }), -/* 314 */ +/* 329 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const utils = __webpack_require__(315); +const utils = __webpack_require__(330); const { CHAR_ASTERISK, /* * */ CHAR_AT, /* @ */ @@ -43031,7 +46088,7 @@ const { CHAR_RIGHT_CURLY_BRACE, /* } */ CHAR_RIGHT_PARENTHESES, /* ) */ CHAR_RIGHT_SQUARE_BRACKET /* ] */ -} = __webpack_require__(316); +} = __webpack_require__(331); const isPathSeparator = code => { return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; @@ -43398,7 +46455,7 @@ module.exports = scan; /***/ }), -/* 315 */ +/* 330 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -43411,7 +46468,7 @@ const { REGEX_REMOVE_BACKSLASH, REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL -} = __webpack_require__(316); +} = __webpack_require__(331); exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); @@ -43469,7 +46526,7 @@ exports.wrapOutput = (input, state = {}, options = {}) => { /***/ }), -/* 316 */ +/* 331 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -43655,14 +46712,14 @@ module.exports = { /***/ }), -/* 317 */ +/* 332 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const constants = __webpack_require__(316); -const utils = __webpack_require__(315); +const constants = __webpack_require__(331); +const utils = __webpack_require__(330); /** * Constants @@ -44740,13 +47797,13 @@ module.exports = parse; /***/ }), -/* 318 */ +/* 333 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const merge2 = __webpack_require__(284); +const merge2 = __webpack_require__(299); function merge(streams) { const mergedStream = merge2(streams); streams.forEach((stream) => { @@ -44763,7 +47820,7 @@ function propagateCloseEventToSources(streams) { /***/ }), -/* 319 */ +/* 334 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44780,14 +47837,14 @@ exports.isEmpty = isEmpty; /***/ }), -/* 320 */ +/* 335 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(321); -const provider_1 = __webpack_require__(348); +const stream_1 = __webpack_require__(336); +const provider_1 = __webpack_require__(363); class ProviderAsync extends provider_1.default { constructor() { super(...arguments); @@ -44815,16 +47872,16 @@ exports.default = ProviderAsync; /***/ }), -/* 321 */ +/* 336 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(136); -const fsStat = __webpack_require__(322); -const fsWalk = __webpack_require__(327); -const reader_1 = __webpack_require__(347); +const stream_1 = __webpack_require__(137); +const fsStat = __webpack_require__(337); +const fsWalk = __webpack_require__(342); +const reader_1 = __webpack_require__(362); class ReaderStream extends reader_1.default { constructor() { super(...arguments); @@ -44877,15 +47934,15 @@ exports.default = ReaderStream; /***/ }), -/* 322 */ +/* 337 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(323); -const sync = __webpack_require__(324); -const settings_1 = __webpack_require__(325); +const async = __webpack_require__(338); +const sync = __webpack_require__(339); +const settings_1 = __webpack_require__(340); exports.Settings = settings_1.default; function stat(path, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === 'function') { @@ -44908,7 +47965,7 @@ function getSettings(settingsOrOptions = {}) { /***/ }), -/* 323 */ +/* 338 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44946,7 +48003,7 @@ function callSuccessCallback(callback, result) { /***/ }), -/* 324 */ +/* 339 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44975,13 +48032,13 @@ exports.read = read; /***/ }), -/* 325 */ +/* 340 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(326); +const fs = __webpack_require__(341); class Settings { constructor(_options = {}) { this._options = _options; @@ -44998,13 +48055,13 @@ exports.default = Settings; /***/ }), -/* 326 */ +/* 341 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(132); +const fs = __webpack_require__(133); exports.FILE_SYSTEM_ADAPTER = { lstat: fs.lstat, stat: fs.stat, @@ -45021,16 +48078,16 @@ exports.createFileSystemAdapter = createFileSystemAdapter; /***/ }), -/* 327 */ +/* 342 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(328); -const stream_1 = __webpack_require__(343); -const sync_1 = __webpack_require__(344); -const settings_1 = __webpack_require__(346); +const async_1 = __webpack_require__(343); +const stream_1 = __webpack_require__(358); +const sync_1 = __webpack_require__(359); +const settings_1 = __webpack_require__(361); exports.Settings = settings_1.default; function walk(directory, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === 'function') { @@ -45060,13 +48117,13 @@ function getSettings(settingsOrOptions = {}) { /***/ }), -/* 328 */ +/* 343 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(329); +const async_1 = __webpack_require__(344); class AsyncProvider { constructor(_root, _settings) { this._root = _root; @@ -45097,17 +48154,17 @@ function callSuccessCallback(callback, entries) { /***/ }), -/* 329 */ +/* 344 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const events_1 = __webpack_require__(154); -const fsScandir = __webpack_require__(330); -const fastq = __webpack_require__(339); -const common = __webpack_require__(341); -const reader_1 = __webpack_require__(342); +const events_1 = __webpack_require__(155); +const fsScandir = __webpack_require__(345); +const fastq = __webpack_require__(354); +const common = __webpack_require__(356); +const reader_1 = __webpack_require__(357); class AsyncReader extends reader_1.default { constructor(_root, _settings) { super(_root, _settings); @@ -45197,15 +48254,15 @@ exports.default = AsyncReader; /***/ }), -/* 330 */ +/* 345 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(331); -const sync = __webpack_require__(336); -const settings_1 = __webpack_require__(337); +const async = __webpack_require__(346); +const sync = __webpack_require__(351); +const settings_1 = __webpack_require__(352); exports.Settings = settings_1.default; function scandir(path, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === 'function') { @@ -45228,16 +48285,16 @@ function getSettings(settingsOrOptions = {}) { /***/ }), -/* 331 */ +/* 346 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(322); -const rpl = __webpack_require__(332); -const constants_1 = __webpack_require__(333); -const utils = __webpack_require__(334); +const fsStat = __webpack_require__(337); +const rpl = __webpack_require__(347); +const constants_1 = __webpack_require__(348); +const utils = __webpack_require__(349); function read(directory, settings, callback) { if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { return readdirWithFileTypes(directory, settings, callback); @@ -45325,7 +48382,7 @@ function callSuccessCallback(callback, result) { /***/ }), -/* 332 */ +/* 347 */ /***/ (function(module, exports) { module.exports = runParallel @@ -45379,7 +48436,7 @@ function runParallel (tasks, cb) { /***/ }), -/* 333 */ +/* 348 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -45399,18 +48456,18 @@ exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_B /***/ }), -/* 334 */ +/* 349 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(335); +const fs = __webpack_require__(350); exports.fs = fs; /***/ }), -/* 335 */ +/* 350 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -45435,15 +48492,15 @@ exports.createDirentFromStats = createDirentFromStats; /***/ }), -/* 336 */ +/* 351 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(322); -const constants_1 = __webpack_require__(333); -const utils = __webpack_require__(334); +const fsStat = __webpack_require__(337); +const constants_1 = __webpack_require__(348); +const utils = __webpack_require__(349); function read(directory, settings) { if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { return readdirWithFileTypes(directory, settings); @@ -45494,15 +48551,15 @@ exports.readdir = readdir; /***/ }), -/* 337 */ +/* 352 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const fsStat = __webpack_require__(322); -const fs = __webpack_require__(338); +const fsStat = __webpack_require__(337); +const fs = __webpack_require__(353); class Settings { constructor(_options = {}) { this._options = _options; @@ -45525,13 +48582,13 @@ exports.default = Settings; /***/ }), -/* 338 */ +/* 353 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(132); +const fs = __webpack_require__(133); exports.FILE_SYSTEM_ADAPTER = { lstat: fs.lstat, stat: fs.stat, @@ -45550,13 +48607,13 @@ exports.createFileSystemAdapter = createFileSystemAdapter; /***/ }), -/* 339 */ +/* 354 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var reusify = __webpack_require__(340) +var reusify = __webpack_require__(355) function fastqueue (context, worker, concurrency) { if (typeof context === 'function') { @@ -45730,7 +48787,7 @@ module.exports = fastqueue /***/ }), -/* 340 */ +/* 355 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -45770,7 +48827,7 @@ module.exports = reusify /***/ }), -/* 341 */ +/* 356 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -45801,13 +48858,13 @@ exports.joinPathSegments = joinPathSegments; /***/ }), -/* 342 */ +/* 357 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const common = __webpack_require__(341); +const common = __webpack_require__(356); class Reader { constructor(_root, _settings) { this._root = _root; @@ -45819,14 +48876,14 @@ exports.default = Reader; /***/ }), -/* 343 */ +/* 358 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(136); -const async_1 = __webpack_require__(329); +const stream_1 = __webpack_require__(137); +const async_1 = __webpack_require__(344); class StreamProvider { constructor(_root, _settings) { this._root = _root; @@ -45856,13 +48913,13 @@ exports.default = StreamProvider; /***/ }), -/* 344 */ +/* 359 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(345); +const sync_1 = __webpack_require__(360); class SyncProvider { constructor(_root, _settings) { this._root = _root; @@ -45877,15 +48934,15 @@ exports.default = SyncProvider; /***/ }), -/* 345 */ +/* 360 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsScandir = __webpack_require__(330); -const common = __webpack_require__(341); -const reader_1 = __webpack_require__(342); +const fsScandir = __webpack_require__(345); +const common = __webpack_require__(356); +const reader_1 = __webpack_require__(357); class SyncReader extends reader_1.default { constructor() { super(...arguments); @@ -45943,14 +49000,14 @@ exports.default = SyncReader; /***/ }), -/* 346 */ +/* 361 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const fsScandir = __webpack_require__(330); +const fsScandir = __webpack_require__(345); class Settings { constructor(_options = {}) { this._options = _options; @@ -45976,15 +49033,15 @@ exports.default = Settings; /***/ }), -/* 347 */ +/* 362 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const fsStat = __webpack_require__(322); -const utils = __webpack_require__(292); +const fsStat = __webpack_require__(337); +const utils = __webpack_require__(307); class Reader { constructor(_settings) { this._settings = _settings; @@ -46016,17 +49073,17 @@ exports.default = Reader; /***/ }), -/* 348 */ +/* 363 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const deep_1 = __webpack_require__(349); -const entry_1 = __webpack_require__(352); -const error_1 = __webpack_require__(353); -const entry_2 = __webpack_require__(354); +const deep_1 = __webpack_require__(364); +const entry_1 = __webpack_require__(367); +const error_1 = __webpack_require__(368); +const entry_2 = __webpack_require__(369); class Provider { constructor(_settings) { this._settings = _settings; @@ -46071,14 +49128,14 @@ exports.default = Provider; /***/ }), -/* 349 */ +/* 364 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(292); -const partial_1 = __webpack_require__(350); +const utils = __webpack_require__(307); +const partial_1 = __webpack_require__(365); class DeepFilter { constructor(_settings, _micromatchOptions) { this._settings = _settings; @@ -46132,13 +49189,13 @@ exports.default = DeepFilter; /***/ }), -/* 350 */ +/* 365 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const matcher_1 = __webpack_require__(351); +const matcher_1 = __webpack_require__(366); class PartialMatcher extends matcher_1.default { match(filepath) { const parts = filepath.split('/'); @@ -46177,13 +49234,13 @@ exports.default = PartialMatcher; /***/ }), -/* 351 */ +/* 366 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(292); +const utils = __webpack_require__(307); class Matcher { constructor(_patterns, _settings, _micromatchOptions) { this._patterns = _patterns; @@ -46234,13 +49291,13 @@ exports.default = Matcher; /***/ }), -/* 352 */ +/* 367 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(292); +const utils = __webpack_require__(307); class EntryFilter { constructor(_settings, _micromatchOptions) { this._settings = _settings; @@ -46296,13 +49353,13 @@ exports.default = EntryFilter; /***/ }), -/* 353 */ +/* 368 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(292); +const utils = __webpack_require__(307); class ErrorFilter { constructor(_settings) { this._settings = _settings; @@ -46318,13 +49375,13 @@ exports.default = ErrorFilter; /***/ }), -/* 354 */ +/* 369 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(292); +const utils = __webpack_require__(307); class EntryTransformer { constructor(_settings) { this._settings = _settings; @@ -46351,15 +49408,15 @@ exports.default = EntryTransformer; /***/ }), -/* 355 */ +/* 370 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(136); -const stream_2 = __webpack_require__(321); -const provider_1 = __webpack_require__(348); +const stream_1 = __webpack_require__(137); +const stream_2 = __webpack_require__(336); +const provider_1 = __webpack_require__(363); class ProviderStream extends provider_1.default { constructor() { super(...arguments); @@ -46389,14 +49446,14 @@ exports.default = ProviderStream; /***/ }), -/* 356 */ +/* 371 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(357); -const provider_1 = __webpack_require__(348); +const sync_1 = __webpack_require__(372); +const provider_1 = __webpack_require__(363); class ProviderSync extends provider_1.default { constructor() { super(...arguments); @@ -46419,15 +49476,15 @@ exports.default = ProviderSync; /***/ }), -/* 357 */ +/* 372 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(322); -const fsWalk = __webpack_require__(327); -const reader_1 = __webpack_require__(347); +const fsStat = __webpack_require__(337); +const fsWalk = __webpack_require__(342); +const reader_1 = __webpack_require__(362); class ReaderSync extends reader_1.default { constructor() { super(...arguments); @@ -46469,14 +49526,14 @@ exports.default = ReaderSync; /***/ }), -/* 358 */ +/* 373 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(132); -const os = __webpack_require__(121); +const fs = __webpack_require__(133); +const os = __webpack_require__(120); const CPU_COUNT = os.cpus().length; exports.DEFAULT_FILE_SYSTEM_ADAPTER = { lstat: fs.lstat, @@ -46528,13 +49585,13 @@ exports.default = Settings; /***/ }), -/* 359 */ +/* 374 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const pathType = __webpack_require__(360); +const pathType = __webpack_require__(375); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -46610,13 +49667,13 @@ module.exports.sync = (input, options) => { /***/ }), -/* 360 */ +/* 375 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(132); +const fs = __webpack_require__(133); async function isType(fsStatType, statsMethodName, filePath) { if (typeof filePath !== 'string') { @@ -46660,17 +49717,17 @@ exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 361 */ +/* 376 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(132); +const fs = __webpack_require__(133); const path = __webpack_require__(4); -const fastGlob = __webpack_require__(290); -const gitIgnore = __webpack_require__(362); -const slash = __webpack_require__(363); +const fastGlob = __webpack_require__(305); +const gitIgnore = __webpack_require__(377); +const slash = __webpack_require__(378); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -46784,7 +49841,7 @@ module.exports.sync = options => { /***/ }), -/* 362 */ +/* 377 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -47387,7 +50444,7 @@ if ( /***/ }), -/* 363 */ +/* 378 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47405,12 +50462,12 @@ module.exports = path => { /***/ }), -/* 364 */ +/* 379 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {Transform} = __webpack_require__(136); +const {Transform} = __webpack_require__(137); class ObjectTransform extends Transform { constructor() { @@ -47458,7 +50515,7 @@ module.exports = { /***/ }), -/* 365 */ +/* 380 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -47468,7 +50525,7 @@ module.exports = { * Released under the MIT License. */ -var isExtglob = __webpack_require__(300); +var isExtglob = __webpack_require__(315); var chars = { '{': '}', '(': ')', '[': ']'}; var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; @@ -47512,7 +50569,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 366 */ +/* 381 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47534,7 +50591,7 @@ module.exports = path_ => { /***/ }), -/* 367 */ +/* 382 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47562,15 +50619,15 @@ module.exports = (childPath, parentPath) => { /***/ }), -/* 368 */ +/* 383 */ /***/ (function(module, exports, __webpack_require__) { -const assert = __webpack_require__(138) +const assert = __webpack_require__(139) const path = __webpack_require__(4) -const fs = __webpack_require__(132) +const fs = __webpack_require__(133) let glob = undefined try { - glob = __webpack_require__(285) + glob = __webpack_require__(300) } catch (_err) { // treat glob as optional. } @@ -47936,12 +50993,12 @@ rimraf.sync = rimrafSync /***/ }), -/* 369 */ +/* 384 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const AggregateError = __webpack_require__(370); +const AggregateError = __webpack_require__(385); module.exports = async ( iterable, @@ -48024,13 +51081,13 @@ module.exports = async ( /***/ }), -/* 370 */ +/* 385 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const indentString = __webpack_require__(371); -const cleanStack = __webpack_require__(372); +const indentString = __webpack_require__(386); +const cleanStack = __webpack_require__(387); const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); @@ -48078,7 +51135,7 @@ module.exports = AggregateError; /***/ }), -/* 371 */ +/* 386 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48120,12 +51177,12 @@ module.exports = (string, count = 1, options) => { /***/ }), -/* 372 */ +/* 387 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(121); +const os = __webpack_require__(120); const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; @@ -48167,15 +51224,15 @@ module.exports = (stack, options) => { /***/ }), -/* 373 */ +/* 388 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const chalk = __webpack_require__(374); -const cliCursor = __webpack_require__(378); -const cliSpinners = __webpack_require__(382); -const logSymbols = __webpack_require__(384); +const chalk = __webpack_require__(389); +const cliCursor = __webpack_require__(392); +const cliSpinners = __webpack_require__(396); +const logSymbols = __webpack_require__(398); class Ora { constructor(options) { @@ -48322,16 +51379,16 @@ module.exports.promise = (action, options) => { /***/ }), -/* 374 */ +/* 389 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const escapeStringRegexp = __webpack_require__(113); -const ansiStyles = __webpack_require__(375); -const stdoutColor = __webpack_require__(376).stdout; +const escapeStringRegexp = __webpack_require__(178); +const ansiStyles = __webpack_require__(390); +const stdoutColor = __webpack_require__(184).stdout; -const template = __webpack_require__(377); +const template = __webpack_require__(391); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -48557,12 +51614,12 @@ module.exports.default = module.exports; // For TypeScript /***/ }), -/* 375 */ +/* 390 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(116); +const colorConvert = __webpack_require__(180); const wrapAnsi16 = (fn, offset) => function () { const code = fn.apply(colorConvert, arguments); @@ -48727,152 +51784,10 @@ Object.defineProperty(module, 'exports', { get: assembleStyles }); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) - -/***/ }), -/* 376 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const os = __webpack_require__(121); -const hasFlag = __webpack_require__(122); - -const env = process.env; - -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; -} - -function translateLevel(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} - -function supportsColor(stream) { - if (forceColor === false) { - return 0; - } - - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } - - if (hasFlag('color=256')) { - return 2; - } - - if (stream && !stream.isTTY && forceColor !== true) { - // VS code debugger doesn't have isTTY set - if (env.VSCODE_PID) { - return 1; - } - return 0; - } - - const min = forceColor ? 1 : 0; - - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - - if ('COLORTERM' in env) { - return 1; - } - - if (env.TERM === 'dumb') { - return min; - } - - return min; -} - -function getSupportLevel(stream) { - const level = supportsColor(stream); - return translateLevel(level); -} - -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) -}; - +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 377 */ +/* 391 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49007,12 +51922,12 @@ module.exports = (chalk, tmp) => { /***/ }), -/* 378 */ +/* 392 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const restoreCursor = __webpack_require__(379); +const restoreCursor = __webpack_require__(393); let hidden = false; @@ -49053,13 +51968,13 @@ exports.toggle = (force, stream) => { /***/ }), -/* 379 */ +/* 393 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const onetime = __webpack_require__(380); -const signalExit = __webpack_require__(218); +const onetime = __webpack_require__(394); +const signalExit = __webpack_require__(225); module.exports = onetime(() => { signalExit(() => { @@ -49069,12 +51984,12 @@ module.exports = onetime(() => { /***/ }), -/* 380 */ +/* 394 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const mimicFn = __webpack_require__(381); +const mimicFn = __webpack_require__(395); module.exports = (fn, opts) => { // TODO: Remove this in v3 @@ -49115,7 +52030,7 @@ module.exports = (fn, opts) => { /***/ }), -/* 381 */ +/* 395 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49131,27 +52046,27 @@ module.exports = (to, from) => { /***/ }), -/* 382 */ +/* 396 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = __webpack_require__(383); +module.exports = __webpack_require__(397); /***/ }), -/* 383 */ +/* 397 */ /***/ (function(module) { module.exports = JSON.parse("{\"dots\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠹\",\"⠸\",\"⠼\",\"⠴\",\"⠦\",\"⠧\",\"⠇\",\"⠏\"]},\"dots2\":{\"interval\":80,\"frames\":[\"⣾\",\"⣽\",\"⣻\",\"⢿\",\"⡿\",\"⣟\",\"⣯\",\"⣷\"]},\"dots3\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠞\",\"⠖\",\"⠦\",\"⠴\",\"⠲\",\"⠳\",\"⠓\"]},\"dots4\":{\"interval\":80,\"frames\":[\"⠄\",\"⠆\",\"⠇\",\"⠋\",\"⠙\",\"⠸\",\"⠰\",\"⠠\",\"⠰\",\"⠸\",\"⠙\",\"⠋\",\"⠇\",\"⠆\"]},\"dots5\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\"]},\"dots6\":{\"interval\":80,\"frames\":[\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠴\",\"⠲\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠚\",\"⠙\",\"⠉\",\"⠁\"]},\"dots7\":{\"interval\":80,\"frames\":[\"⠈\",\"⠉\",\"⠋\",\"⠓\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠖\",\"⠦\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\"]},\"dots8\":{\"interval\":80,\"frames\":[\"⠁\",\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\",\"⠈\"]},\"dots9\":{\"interval\":80,\"frames\":[\"⢹\",\"⢺\",\"⢼\",\"⣸\",\"⣇\",\"⡧\",\"⡗\",\"⡏\"]},\"dots10\":{\"interval\":80,\"frames\":[\"⢄\",\"⢂\",\"⢁\",\"⡁\",\"⡈\",\"⡐\",\"⡠\"]},\"dots11\":{\"interval\":100,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⡀\",\"⢀\",\"⠠\",\"⠐\",\"⠈\"]},\"dots12\":{\"interval\":80,\"frames\":[\"⢀⠀\",\"⡀⠀\",\"⠄⠀\",\"⢂⠀\",\"⡂⠀\",\"⠅⠀\",\"⢃⠀\",\"⡃⠀\",\"⠍⠀\",\"⢋⠀\",\"⡋⠀\",\"⠍⠁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⢈⠩\",\"⡀⢙\",\"⠄⡙\",\"⢂⠩\",\"⡂⢘\",\"⠅⡘\",\"⢃⠨\",\"⡃⢐\",\"⠍⡐\",\"⢋⠠\",\"⡋⢀\",\"⠍⡁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⠈⠩\",\"⠀⢙\",\"⠀⡙\",\"⠀⠩\",\"⠀⢘\",\"⠀⡘\",\"⠀⠨\",\"⠀⢐\",\"⠀⡐\",\"⠀⠠\",\"⠀⢀\",\"⠀⡀\"]},\"line\":{\"interval\":130,\"frames\":[\"-\",\"\\\\\",\"|\",\"/\"]},\"line2\":{\"interval\":100,\"frames\":[\"⠂\",\"-\",\"–\",\"—\",\"–\",\"-\"]},\"pipe\":{\"interval\":100,\"frames\":[\"┤\",\"┘\",\"┴\",\"└\",\"├\",\"┌\",\"┬\",\"┐\"]},\"simpleDots\":{\"interval\":400,\"frames\":[\". \",\".. \",\"...\",\" \"]},\"simpleDotsScrolling\":{\"interval\":200,\"frames\":[\". \",\".. \",\"...\",\" ..\",\" .\",\" \"]},\"star\":{\"interval\":70,\"frames\":[\"✶\",\"✸\",\"✹\",\"✺\",\"✹\",\"✷\"]},\"star2\":{\"interval\":80,\"frames\":[\"+\",\"x\",\"*\"]},\"flip\":{\"interval\":70,\"frames\":[\"_\",\"_\",\"_\",\"-\",\"`\",\"`\",\"'\",\"´\",\"-\",\"_\",\"_\",\"_\"]},\"hamburger\":{\"interval\":100,\"frames\":[\"☱\",\"☲\",\"☴\"]},\"growVertical\":{\"interval\":120,\"frames\":[\"▁\",\"▃\",\"▄\",\"▅\",\"▆\",\"▇\",\"▆\",\"▅\",\"▄\",\"▃\"]},\"growHorizontal\":{\"interval\":120,\"frames\":[\"▏\",\"▎\",\"▍\",\"▌\",\"▋\",\"▊\",\"▉\",\"▊\",\"▋\",\"▌\",\"▍\",\"▎\"]},\"balloon\":{\"interval\":140,\"frames\":[\" \",\".\",\"o\",\"O\",\"@\",\"*\",\" \"]},\"balloon2\":{\"interval\":120,\"frames\":[\".\",\"o\",\"O\",\"°\",\"O\",\"o\",\".\"]},\"noise\":{\"interval\":100,\"frames\":[\"▓\",\"▒\",\"░\"]},\"bounce\":{\"interval\":120,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⠂\"]},\"boxBounce\":{\"interval\":120,\"frames\":[\"▖\",\"▘\",\"▝\",\"▗\"]},\"boxBounce2\":{\"interval\":100,\"frames\":[\"▌\",\"▀\",\"▐\",\"▄\"]},\"triangle\":{\"interval\":50,\"frames\":[\"◢\",\"◣\",\"◤\",\"◥\"]},\"arc\":{\"interval\":100,\"frames\":[\"◜\",\"◠\",\"◝\",\"◞\",\"◡\",\"◟\"]},\"circle\":{\"interval\":120,\"frames\":[\"◡\",\"⊙\",\"◠\"]},\"squareCorners\":{\"interval\":180,\"frames\":[\"◰\",\"◳\",\"◲\",\"◱\"]},\"circleQuarters\":{\"interval\":120,\"frames\":[\"◴\",\"◷\",\"◶\",\"◵\"]},\"circleHalves\":{\"interval\":50,\"frames\":[\"◐\",\"◓\",\"◑\",\"◒\"]},\"squish\":{\"interval\":100,\"frames\":[\"╫\",\"╪\"]},\"toggle\":{\"interval\":250,\"frames\":[\"⊶\",\"⊷\"]},\"toggle2\":{\"interval\":80,\"frames\":[\"▫\",\"▪\"]},\"toggle3\":{\"interval\":120,\"frames\":[\"□\",\"■\"]},\"toggle4\":{\"interval\":100,\"frames\":[\"■\",\"□\",\"▪\",\"▫\"]},\"toggle5\":{\"interval\":100,\"frames\":[\"▮\",\"▯\"]},\"toggle6\":{\"interval\":300,\"frames\":[\"ဝ\",\"၀\"]},\"toggle7\":{\"interval\":80,\"frames\":[\"⦾\",\"⦿\"]},\"toggle8\":{\"interval\":100,\"frames\":[\"◍\",\"◌\"]},\"toggle9\":{\"interval\":100,\"frames\":[\"◉\",\"◎\"]},\"toggle10\":{\"interval\":100,\"frames\":[\"㊂\",\"㊀\",\"㊁\"]},\"toggle11\":{\"interval\":50,\"frames\":[\"⧇\",\"⧆\"]},\"toggle12\":{\"interval\":120,\"frames\":[\"☗\",\"☖\"]},\"toggle13\":{\"interval\":80,\"frames\":[\"=\",\"*\",\"-\"]},\"arrow\":{\"interval\":100,\"frames\":[\"←\",\"↖\",\"↑\",\"↗\",\"→\",\"↘\",\"↓\",\"↙\"]},\"arrow2\":{\"interval\":80,\"frames\":[\"⬆️ \",\"↗️ \",\"➡️ \",\"↘️ \",\"⬇️ \",\"↙️ \",\"⬅️ \",\"↖️ \"]},\"arrow3\":{\"interval\":120,\"frames\":[\"▹▹▹▹▹\",\"▸▹▹▹▹\",\"▹▸▹▹▹\",\"▹▹▸▹▹\",\"▹▹▹▸▹\",\"▹▹▹▹▸\"]},\"bouncingBar\":{\"interval\":80,\"frames\":[\"[ ]\",\"[= ]\",\"[== ]\",\"[=== ]\",\"[ ===]\",\"[ ==]\",\"[ =]\",\"[ ]\",\"[ =]\",\"[ ==]\",\"[ ===]\",\"[====]\",\"[=== ]\",\"[== ]\",\"[= ]\"]},\"bouncingBall\":{\"interval\":80,\"frames\":[\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ●)\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"(● )\"]},\"smiley\":{\"interval\":200,\"frames\":[\"😄 \",\"😝 \"]},\"monkey\":{\"interval\":300,\"frames\":[\"🙈 \",\"🙈 \",\"🙉 \",\"🙊 \"]},\"hearts\":{\"interval\":100,\"frames\":[\"💛 \",\"💙 \",\"💜 \",\"💚 \",\"❤️ \"]},\"clock\":{\"interval\":100,\"frames\":[\"🕐 \",\"🕑 \",\"🕒 \",\"🕓 \",\"🕔 \",\"🕕 \",\"🕖 \",\"🕗 \",\"🕘 \",\"🕙 \",\"🕚 \"]},\"earth\":{\"interval\":180,\"frames\":[\"🌍 \",\"🌎 \",\"🌏 \"]},\"moon\":{\"interval\":80,\"frames\":[\"🌑 \",\"🌒 \",\"🌓 \",\"🌔 \",\"🌕 \",\"🌖 \",\"🌗 \",\"🌘 \"]},\"runner\":{\"interval\":140,\"frames\":[\"🚶 \",\"🏃 \"]},\"pong\":{\"interval\":80,\"frames\":[\"▐⠂ ▌\",\"▐⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂▌\",\"▐ ⠠▌\",\"▐ ⡀▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐⠠ ▌\"]},\"shark\":{\"interval\":120,\"frames\":[\"▐|\\\\____________▌\",\"▐_|\\\\___________▌\",\"▐__|\\\\__________▌\",\"▐___|\\\\_________▌\",\"▐____|\\\\________▌\",\"▐_____|\\\\_______▌\",\"▐______|\\\\______▌\",\"▐_______|\\\\_____▌\",\"▐________|\\\\____▌\",\"▐_________|\\\\___▌\",\"▐__________|\\\\__▌\",\"▐___________|\\\\_▌\",\"▐____________|\\\\▌\",\"▐____________/|▌\",\"▐___________/|_▌\",\"▐__________/|__▌\",\"▐_________/|___▌\",\"▐________/|____▌\",\"▐_______/|_____▌\",\"▐______/|______▌\",\"▐_____/|_______▌\",\"▐____/|________▌\",\"▐___/|_________▌\",\"▐__/|__________▌\",\"▐_/|___________▌\",\"▐/|____________▌\"]},\"dqpb\":{\"interval\":100,\"frames\":[\"d\",\"q\",\"p\",\"b\"]},\"weather\":{\"interval\":100,\"frames\":[\"☀️ \",\"☀️ \",\"☀️ \",\"🌤 \",\"⛅️ \",\"🌥 \",\"☁️ \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"⛈ \",\"🌨 \",\"🌧 \",\"🌨 \",\"☁️ \",\"🌥 \",\"⛅️ \",\"🌤 \",\"☀️ \",\"☀️ \"]},\"christmas\":{\"interval\":400,\"frames\":[\"🌲\",\"🎄\"]}}"); /***/ }), -/* 384 */ +/* 398 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const chalk = __webpack_require__(385); +const chalk = __webpack_require__(399); const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'; @@ -49173,16 +52088,16 @@ module.exports = isSupported ? main : fallbacks; /***/ }), -/* 385 */ +/* 399 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const escapeStringRegexp = __webpack_require__(113); -const ansiStyles = __webpack_require__(386); -const stdoutColor = __webpack_require__(387).stdout; +const escapeStringRegexp = __webpack_require__(178); +const ansiStyles = __webpack_require__(400); +const stdoutColor = __webpack_require__(184).stdout; -const template = __webpack_require__(388); +const template = __webpack_require__(401); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -49408,12 +52323,12 @@ module.exports.default = module.exports; // For TypeScript /***/ }), -/* 386 */ +/* 400 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(116); +const colorConvert = __webpack_require__(180); const wrapAnsi16 = (fn, offset) => function () { const code = fn.apply(colorConvert, arguments); @@ -49578,152 +52493,10 @@ Object.defineProperty(module, 'exports', { get: assembleStyles }); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 387 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const os = __webpack_require__(121); -const hasFlag = __webpack_require__(122); - -const env = process.env; - -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; -} - -function translateLevel(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} - -function supportsColor(stream) { - if (forceColor === false) { - return 0; - } - - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } - - if (hasFlag('color=256')) { - return 2; - } - - if (stream && !stream.isTTY && forceColor !== true) { - // VS code debugger doesn't have isTTY set - if (env.VSCODE_PID) { - return 1; - } - return 0; - } - - const min = forceColor ? 1 : 0; - - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - - if ('COLORTERM' in env) { - return 1; - } - - if (env.TERM === 'dumb') { - return min; - } - - return min; -} - -function getSupportLevel(stream) { - const level = supportsColor(stream); - return translateLevel(level); -} - -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) -}; - - -/***/ }), -/* 388 */ +/* 401 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49858,16 +52631,16 @@ module.exports = (chalk, tmp) => { /***/ }), -/* 389 */ +/* 402 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RunCommand", function() { return RunCommand; }); -/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(161); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(142); -/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(143); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144); +/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(162); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -49919,17 +52692,17 @@ const RunCommand = { }; /***/ }), -/* 390 */ +/* 403 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WatchCommand", function() { return WatchCommand; }); -/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(161); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(142); -/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(143); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144); -/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(391); +/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(162); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); +/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(404); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -50014,14 +52787,14 @@ const WatchCommand = { }; /***/ }), -/* 391 */ +/* 404 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waitUntilWatchIsReady", function() { return waitUntilWatchIsReady; }); /* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8); -/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(392); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(405); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -50088,141 +52861,141 @@ function waitUntilWatchIsReady(stream, opts = {}) { } /***/ }), -/* 392 */ +/* 405 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(393); +/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(406); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "audit", function() { return _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__["audit"]; }); -/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(394); +/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(407); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__["auditTime"]; }); -/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(395); +/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(408); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__["buffer"]; }); -/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(396); +/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(409); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__["bufferCount"]; }); -/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(397); +/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(410); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__["bufferTime"]; }); -/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(398); +/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(411); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__["bufferToggle"]; }); -/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(399); +/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(412); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__["bufferWhen"]; }); -/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(400); +/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(413); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__["catchError"]; }); -/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(401); +/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(414); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__["combineAll"]; }); -/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(402); +/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(415); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__["combineLatest"]; }); -/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(403); +/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(416); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__["concat"]; }); /* harmony import */ var _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(80); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatAll", function() { return _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__["concatAll"]; }); -/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(404); +/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(417); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__["concatMap"]; }); -/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(405); +/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(418); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__["concatMapTo"]; }); -/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(406); +/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(419); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "count", function() { return _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__["count"]; }); -/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(407); +/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(420); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__["debounce"]; }); -/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(408); +/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(421); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__["debounceTime"]; }); -/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(409); +/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(422); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__["defaultIfEmpty"]; }); -/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(410); +/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(423); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__["delay"]; }); -/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(412); +/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(425); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__["delayWhen"]; }); -/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(413); +/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(426); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__["dematerialize"]; }); -/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(414); +/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(427); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__["distinct"]; }); -/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(415); +/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(428); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__["distinctUntilChanged"]; }); -/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(416); +/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(429); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__["distinctUntilKeyChanged"]; }); -/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(417); +/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(430); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__["elementAt"]; }); -/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(420); +/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(433); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__["endWith"]; }); -/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(421); +/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(434); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "every", function() { return _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__["every"]; }); -/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(422); +/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(435); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__["exhaust"]; }); -/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(423); +/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(436); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__["exhaustMap"]; }); -/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(424); +/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(437); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__["expand"]; }); /* harmony import */ var _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(104); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__["filter"]; }); -/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(425); +/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(438); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__["finalize"]; }); -/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(426); +/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(439); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "find", function() { return _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__["find"]; }); -/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(427); +/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(440); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__["findIndex"]; }); -/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(428); +/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(441); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "first", function() { return _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__["first"]; }); /* harmony import */ var _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(31); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "groupBy", function() { return _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__["groupBy"]; }); -/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(429); +/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(442); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__["ignoreElements"]; }); -/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(430); +/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(443); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__["isEmpty"]; }); -/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(431); +/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(444); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "last", function() { return _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__["last"]; }); /* harmony import */ var _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(66); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "map", function() { return _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__["map"]; }); -/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(433); +/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(446); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__["mapTo"]; }); -/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(434); +/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(447); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__["materialize"]; }); -/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(435); +/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(448); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "max", function() { return _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__["max"]; }); -/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(438); +/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(451); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__["merge"]; }); /* harmony import */ var _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(81); @@ -50233,175 +53006,175 @@ __webpack_require__.r(__webpack_exports__); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["mergeMap"]; }); -/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(439); +/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(452); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__["mergeMapTo"]; }); -/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(440); +/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(453); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__["mergeScan"]; }); -/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(441); +/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(454); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "min", function() { return _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__["min"]; }); -/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(442); +/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(455); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__["multicast"]; }); /* harmony import */ var _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(41); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "observeOn", function() { return _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__["observeOn"]; }); -/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(443); +/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(456); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__["onErrorResumeNext"]; }); -/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(444); +/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(457); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__["pairwise"]; }); -/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(445); +/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(458); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__["partition"]; }); -/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(446); +/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(459); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__["pluck"]; }); -/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(447); +/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(460); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__["publish"]; }); -/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(448); +/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(461); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__["publishBehavior"]; }); -/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(449); +/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(462); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__["publishLast"]; }); -/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(450); +/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(463); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__["publishReplay"]; }); -/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(451); +/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(464); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__["race"]; }); -/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(436); +/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(449); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__["reduce"]; }); -/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(452); +/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(465); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__["repeat"]; }); -/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(453); +/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(466); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__["repeatWhen"]; }); -/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(454); +/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(467); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__["retry"]; }); -/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(455); +/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(468); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__["retryWhen"]; }); /* harmony import */ var _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__ = __webpack_require__(30); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "refCount", function() { return _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__["refCount"]; }); -/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(456); +/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(469); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__["sample"]; }); -/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(457); +/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(470); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__["sampleTime"]; }); -/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(437); +/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(450); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__["scan"]; }); -/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(458); +/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(471); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__["sequenceEqual"]; }); -/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(459); +/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(472); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "share", function() { return _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__["share"]; }); -/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(460); +/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(473); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__["shareReplay"]; }); -/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(461); +/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(474); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "single", function() { return _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__["single"]; }); -/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(462); +/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(475); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__["skip"]; }); -/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(463); +/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(476); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__["skipLast"]; }); -/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(464); +/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(477); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__["skipUntil"]; }); -/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(465); +/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(478); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__["skipWhile"]; }); -/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(466); +/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(479); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__["startWith"]; }); -/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(467); +/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(480); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__["subscribeOn"]; }); -/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(469); +/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(482); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__["switchAll"]; }); -/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(470); +/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(483); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__["switchMap"]; }); -/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(471); +/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(484); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__["switchMapTo"]; }); -/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(419); +/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(432); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "take", function() { return _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__["take"]; }); -/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(432); +/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(445); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__["takeLast"]; }); -/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(472); +/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(485); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__["takeUntil"]; }); -/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(473); +/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(486); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__["takeWhile"]; }); -/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(474); +/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(487); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__["tap"]; }); -/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(475); +/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(488); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__["throttle"]; }); -/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(476); +/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(489); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__["throttleTime"]; }); -/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(418); +/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(431); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__["throwIfEmpty"]; }); -/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(477); +/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(490); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__["timeInterval"]; }); -/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(478); +/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(491); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__["timeout"]; }); -/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(479); +/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(492); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__["timeoutWith"]; }); -/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(480); +/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(493); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__["timestamp"]; }); -/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(481); +/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(494); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__["toArray"]; }); -/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(482); +/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(495); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "window", function() { return _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__["window"]; }); -/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(483); +/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(496); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__["windowCount"]; }); -/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(484); +/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(497); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__["windowTime"]; }); -/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(485); +/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(498); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__["windowToggle"]; }); -/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(486); +/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(499); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__["windowWhen"]; }); -/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(487); +/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(500); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__["withLatestFrom"]; }); -/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(488); +/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(501); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__["zip"]; }); -/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(489); +/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(502); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__["zipAll"]; }); /** PURE_IMPORTS_START PURE_IMPORTS_END */ @@ -50513,7 +53286,7 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/* 393 */ +/* 406 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -50594,14 +53367,14 @@ var AuditSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 394 */ +/* 407 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return auditTime; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(393); +/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(406); /* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(107); /** PURE_IMPORTS_START _scheduler_async,_audit,_observable_timer PURE_IMPORTS_END */ @@ -50617,7 +53390,7 @@ function auditTime(duration, scheduler) { /***/ }), -/* 395 */ +/* 408 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -50666,7 +53439,7 @@ var BufferSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 396 */ +/* 409 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -50767,7 +53540,7 @@ var BufferSkipCountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 397 */ +/* 410 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -50928,7 +53701,7 @@ function dispatchBufferClose(arg) { /***/ }), -/* 398 */ +/* 411 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51048,7 +53821,7 @@ var BufferToggleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 399 */ +/* 412 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51143,7 +53916,7 @@ var BufferWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 400 */ +/* 413 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51207,7 +53980,7 @@ var CatchSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 401 */ +/* 414 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51223,7 +53996,7 @@ function combineAll(project) { /***/ }), -/* 402 */ +/* 415 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51255,7 +54028,7 @@ function combineLatest() { /***/ }), -/* 403 */ +/* 416 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51275,7 +54048,7 @@ function concat() { /***/ }), -/* 404 */ +/* 417 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51291,13 +54064,13 @@ function concatMap(project, resultSelector) { /***/ }), -/* 405 */ +/* 418 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return concatMapTo; }); -/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(404); +/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(417); /** PURE_IMPORTS_START _concatMap PURE_IMPORTS_END */ function concatMapTo(innerObservable, resultSelector) { @@ -51307,7 +54080,7 @@ function concatMapTo(innerObservable, resultSelector) { /***/ }), -/* 406 */ +/* 419 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51372,7 +54145,7 @@ var CountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 407 */ +/* 420 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51460,7 +54233,7 @@ var DebounceSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 408 */ +/* 421 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51536,7 +54309,7 @@ function dispatchNext(subscriber) { /***/ }), -/* 409 */ +/* 422 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51586,7 +54359,7 @@ var DefaultIfEmptySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 410 */ +/* 423 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51594,7 +54367,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return delay; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(411); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(424); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11); /* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(42); /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_Subscriber,_Notification PURE_IMPORTS_END */ @@ -51693,7 +54466,7 @@ var DelayMessage = /*@__PURE__*/ (function () { /***/ }), -/* 411 */ +/* 424 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51707,7 +54480,7 @@ function isDate(value) { /***/ }), -/* 412 */ +/* 425 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51853,7 +54626,7 @@ var SubscriptionDelaySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 413 */ +/* 426 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51891,7 +54664,7 @@ var DeMaterializeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 414 */ +/* 427 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51969,7 +54742,7 @@ var DistinctSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 415 */ +/* 428 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52040,13 +54813,13 @@ var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 416 */ +/* 429 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return distinctUntilKeyChanged; }); -/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(415); +/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(428); /** PURE_IMPORTS_START _distinctUntilChanged PURE_IMPORTS_END */ function distinctUntilKeyChanged(key, compare) { @@ -52056,7 +54829,7 @@ function distinctUntilKeyChanged(key, compare) { /***/ }), -/* 417 */ +/* 430 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52064,9 +54837,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return elementAt; }); /* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(62); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(418); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(409); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(419); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(431); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(422); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(432); /** PURE_IMPORTS_START _util_ArgumentOutOfRangeError,_filter,_throwIfEmpty,_defaultIfEmpty,_take PURE_IMPORTS_END */ @@ -52088,7 +54861,7 @@ function elementAt(index, defaultValue) { /***/ }), -/* 418 */ +/* 431 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52154,7 +54927,7 @@ function defaultErrorFactory() { /***/ }), -/* 419 */ +/* 432 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52216,7 +54989,7 @@ var TakeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 420 */ +/* 433 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52238,7 +55011,7 @@ function endWith() { /***/ }), -/* 421 */ +/* 434 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52300,7 +55073,7 @@ var EverySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 422 */ +/* 435 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52357,7 +55130,7 @@ var SwitchFirstSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 423 */ +/* 436 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52457,7 +55230,7 @@ var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 424 */ +/* 437 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52576,7 +55349,7 @@ var ExpandSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 425 */ +/* 438 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52614,7 +55387,7 @@ var FinallySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 426 */ +/* 439 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52686,13 +55459,13 @@ var FindValueSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 427 */ +/* 440 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return findIndex; }); -/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(426); +/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(439); /** PURE_IMPORTS_START _operators_find PURE_IMPORTS_END */ function findIndex(predicate, thisArg) { @@ -52702,7 +55475,7 @@ function findIndex(predicate, thisArg) { /***/ }), -/* 428 */ +/* 441 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52710,9 +55483,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "first", function() { return first; }); /* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(419); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(409); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(418); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(432); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(422); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(431); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /** PURE_IMPORTS_START _util_EmptyError,_filter,_take,_defaultIfEmpty,_throwIfEmpty,_util_identity PURE_IMPORTS_END */ @@ -52729,7 +55502,7 @@ function first(predicate, defaultValue) { /***/ }), -/* 429 */ +/* 442 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52766,7 +55539,7 @@ var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 430 */ +/* 443 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52810,7 +55583,7 @@ var IsEmptySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 431 */ +/* 444 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52818,9 +55591,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "last", function() { return last; }); /* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(432); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(418); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(409); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(445); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(431); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(422); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /** PURE_IMPORTS_START _util_EmptyError,_filter,_takeLast,_throwIfEmpty,_defaultIfEmpty,_util_identity PURE_IMPORTS_END */ @@ -52837,7 +55610,7 @@ function last(predicate, defaultValue) { /***/ }), -/* 432 */ +/* 445 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52914,7 +55687,7 @@ var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 433 */ +/* 446 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52953,7 +55726,7 @@ var MapToSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 434 */ +/* 447 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53003,13 +55776,13 @@ var MaterializeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 435 */ +/* 448 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "max", function() { return max; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(436); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(449); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function max(comparer) { @@ -53022,15 +55795,15 @@ function max(comparer) { /***/ }), -/* 436 */ +/* 449 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return reduce; }); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(437); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(432); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(409); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(450); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(445); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(422); /* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(24); /** PURE_IMPORTS_START _scan,_takeLast,_defaultIfEmpty,_util_pipe PURE_IMPORTS_END */ @@ -53051,7 +55824,7 @@ function reduce(accumulator, seed) { /***/ }), -/* 437 */ +/* 450 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53133,7 +55906,7 @@ var ScanSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 438 */ +/* 451 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53153,7 +55926,7 @@ function merge() { /***/ }), -/* 439 */ +/* 452 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53178,7 +55951,7 @@ function mergeMapTo(innerObservable, resultSelector, concurrent) { /***/ }), -/* 440 */ +/* 453 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53293,13 +56066,13 @@ var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 441 */ +/* 454 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "min", function() { return min; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(436); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(449); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function min(comparer) { @@ -53312,7 +56085,7 @@ function min(comparer) { /***/ }), -/* 442 */ +/* 455 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53361,7 +56134,7 @@ var MulticastOperator = /*@__PURE__*/ (function () { /***/ }), -/* 443 */ +/* 456 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53455,7 +56228,7 @@ var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 444 */ +/* 457 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53503,7 +56276,7 @@ var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 445 */ +/* 458 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53526,7 +56299,7 @@ function partition(predicate, thisArg) { /***/ }), -/* 446 */ +/* 459 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53566,14 +56339,14 @@ function plucker(props, length) { /***/ }), -/* 447 */ +/* 460 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return publish; }); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(442); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(455); /** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ @@ -53586,14 +56359,14 @@ function publish(selector) { /***/ }), -/* 448 */ +/* 461 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return publishBehavior; }); /* harmony import */ var _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(32); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(442); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(455); /** PURE_IMPORTS_START _BehaviorSubject,_multicast PURE_IMPORTS_END */ @@ -53604,14 +56377,14 @@ function publishBehavior(value) { /***/ }), -/* 449 */ +/* 462 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return publishLast; }); /* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(442); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(455); /** PURE_IMPORTS_START _AsyncSubject,_multicast PURE_IMPORTS_END */ @@ -53622,14 +56395,14 @@ function publishLast() { /***/ }), -/* 450 */ +/* 463 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return publishReplay; }); /* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(442); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(455); /** PURE_IMPORTS_START _ReplaySubject,_multicast PURE_IMPORTS_END */ @@ -53645,7 +56418,7 @@ function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) { /***/ }), -/* 451 */ +/* 464 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53672,7 +56445,7 @@ function race() { /***/ }), -/* 452 */ +/* 465 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53737,7 +56510,7 @@ var RepeatSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 453 */ +/* 466 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53833,7 +56606,7 @@ var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 454 */ +/* 467 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53886,7 +56659,7 @@ var RetrySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 455 */ +/* 468 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53974,7 +56747,7 @@ var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 456 */ +/* 469 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54031,7 +56804,7 @@ var SampleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 457 */ +/* 470 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54091,7 +56864,7 @@ function dispatchNotification(state) { /***/ }), -/* 458 */ +/* 471 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54214,13 +56987,13 @@ var SequenceEqualCompareToSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 459 */ +/* 472 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "share", function() { return share; }); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(442); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(455); /* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27); /** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ @@ -54237,7 +57010,7 @@ function share() { /***/ }), -/* 460 */ +/* 473 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54302,7 +57075,7 @@ function shareReplayOperator(_a) { /***/ }), -/* 461 */ +/* 474 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54382,7 +57155,7 @@ var SingleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 462 */ +/* 475 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54424,7 +57197,7 @@ var SkipSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 463 */ +/* 476 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54486,7 +57259,7 @@ var SkipLastSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 464 */ +/* 477 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54547,7 +57320,7 @@ var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 465 */ +/* 478 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54603,7 +57376,7 @@ var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 466 */ +/* 479 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54632,13 +57405,13 @@ function startWith() { /***/ }), -/* 467 */ +/* 480 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return subscribeOn; }); -/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(468); +/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(481); /** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ function subscribeOn(scheduler, delay) { @@ -54663,7 +57436,7 @@ var SubscribeOnOperator = /*@__PURE__*/ (function () { /***/ }), -/* 468 */ +/* 481 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54727,13 +57500,13 @@ var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { /***/ }), -/* 469 */ +/* 482 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return switchAll; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(470); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(483); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25); /** PURE_IMPORTS_START _switchMap,_util_identity PURE_IMPORTS_END */ @@ -54745,7 +57518,7 @@ function switchAll() { /***/ }), -/* 470 */ +/* 483 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54839,13 +57612,13 @@ var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 471 */ +/* 484 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return switchMapTo; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(470); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(483); /** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ function switchMapTo(innerObservable, resultSelector) { @@ -54855,7 +57628,7 @@ function switchMapTo(innerObservable, resultSelector) { /***/ }), -/* 472 */ +/* 485 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54905,7 +57678,7 @@ var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 473 */ +/* 486 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54973,7 +57746,7 @@ var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 474 */ +/* 487 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55061,7 +57834,7 @@ var TapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 475 */ +/* 488 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55165,7 +57938,7 @@ var ThrottleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 476 */ +/* 489 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55174,7 +57947,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55); -/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(475); +/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(488); /** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async,_throttle PURE_IMPORTS_END */ @@ -55263,7 +58036,7 @@ function dispatchNext(arg) { /***/ }), -/* 477 */ +/* 490 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55271,7 +58044,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return timeInterval; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimeInterval", function() { return TimeInterval; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(437); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(450); /* harmony import */ var _observable_defer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); /* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66); /** PURE_IMPORTS_START _scheduler_async,_scan,_observable_defer,_map PURE_IMPORTS_END */ @@ -55307,7 +58080,7 @@ var TimeInterval = /*@__PURE__*/ (function () { /***/ }), -/* 478 */ +/* 491 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55315,7 +58088,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return timeout; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); /* harmony import */ var _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(64); -/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(479); +/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(492); /* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49); /** PURE_IMPORTS_START _scheduler_async,_util_TimeoutError,_timeoutWith,_observable_throwError PURE_IMPORTS_END */ @@ -55332,7 +58105,7 @@ function timeout(due, scheduler) { /***/ }), -/* 479 */ +/* 492 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55340,7 +58113,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return timeoutWith; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(411); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(424); /* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(69); /* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(70); /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ @@ -55414,7 +58187,7 @@ var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 480 */ +/* 493 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55444,13 +58217,13 @@ var Timestamp = /*@__PURE__*/ (function () { /***/ }), -/* 481 */ +/* 494 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return toArray; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(436); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(449); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function toArrayReducer(arr, item, index) { @@ -55467,7 +58240,7 @@ function toArray() { /***/ }), -/* 482 */ +/* 495 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55547,7 +58320,7 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 483 */ +/* 496 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55637,7 +58410,7 @@ var WindowCountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 484 */ +/* 497 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55807,7 +58580,7 @@ function dispatchWindowClose(state) { /***/ }), -/* 485 */ +/* 498 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55950,7 +58723,7 @@ var WindowToggleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 486 */ +/* 499 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56047,7 +58820,7 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 487 */ +/* 500 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56142,7 +58915,7 @@ var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 488 */ +/* 501 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56164,7 +58937,7 @@ function zip() { /***/ }), -/* 489 */ +/* 502 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56180,17 +58953,17 @@ function zipAll(project) { /***/ }), -/* 490 */ +/* 503 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runCommand", function() { return runCommand; }); -/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(161); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(142); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); -/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(491); -/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(492); +/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(162); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); +/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(504); +/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(505); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -56272,13 +59045,13 @@ function toArray(value) { } /***/ }), -/* 491 */ +/* 504 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderProjectsTree", function() { return renderProjectsTree; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(112); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(235); /* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); @@ -56425,7 +59198,7 @@ function addProjectToTree(tree, pathParts, project) { } /***/ }), -/* 492 */ +/* 505 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56433,12 +59206,12 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Kibana", function() { return Kibana; }); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(493); +/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(506); /* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(multimatch__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(497); +/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(510); /* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(is_path_inside__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(272); +/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(288); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -56579,15 +59352,15 @@ class Kibana { } /***/ }), -/* 493 */ +/* 506 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const minimatch = __webpack_require__(148); -const arrayUnion = __webpack_require__(494); -const arrayDiffer = __webpack_require__(495); -const arrify = __webpack_require__(496); +const minimatch = __webpack_require__(149); +const arrayUnion = __webpack_require__(507); +const arrayDiffer = __webpack_require__(508); +const arrify = __webpack_require__(509); module.exports = (list, patterns, options = {}) => { list = arrify(list); @@ -56611,7 +59384,7 @@ module.exports = (list, patterns, options = {}) => { /***/ }), -/* 494 */ +/* 507 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56623,7 +59396,7 @@ module.exports = (...arguments_) => { /***/ }), -/* 495 */ +/* 508 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56638,7 +59411,7 @@ module.exports = arrayDiffer; /***/ }), -/* 496 */ +/* 509 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56668,7 +59441,7 @@ module.exports = arrify; /***/ }), -/* 497 */ +/* 510 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56696,15 +59469,15 @@ module.exports = (childPath, parentPath) => { /***/ }), -/* 498 */ +/* 511 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(499); +/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(512); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); -/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(735); +/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(748); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); /* @@ -56729,23 +59502,23 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/* 499 */ +/* 512 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return buildProductionProjects; }); -/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(500); +/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(513); /* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cpy__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(281); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(296); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(272); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(129); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(142); -/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(163); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(144); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(288); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(130); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(143); +/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(164); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(145); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -56877,21 +59650,21 @@ async function copyToBuild(project, kibanaRoot, buildRoot) { } /***/ }), -/* 500 */ +/* 513 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const EventEmitter = __webpack_require__(154); +const EventEmitter = __webpack_require__(155); const path = __webpack_require__(4); -const os = __webpack_require__(121); -const pAll = __webpack_require__(501); -const arrify = __webpack_require__(503); -const globby = __webpack_require__(504); -const isGlob = __webpack_require__(719); -const cpFile = __webpack_require__(720); -const junk = __webpack_require__(732); -const CpyError = __webpack_require__(733); +const os = __webpack_require__(120); +const pAll = __webpack_require__(514); +const arrify = __webpack_require__(516); +const globby = __webpack_require__(517); +const isGlob = __webpack_require__(732); +const cpFile = __webpack_require__(733); +const junk = __webpack_require__(745); +const CpyError = __webpack_require__(746); const defaultOptions = { ignoreJunk: true @@ -57010,12 +59783,12 @@ module.exports = (source, destination, { /***/ }), -/* 501 */ +/* 514 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pMap = __webpack_require__(502); +const pMap = __webpack_require__(515); module.exports = (iterable, options) => pMap(iterable, element => element(), options); // TODO: Remove this for the next major release @@ -57023,7 +59796,7 @@ module.exports.default = module.exports; /***/ }), -/* 502 */ +/* 515 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57102,7 +59875,7 @@ module.exports.default = pMap; /***/ }), -/* 503 */ +/* 516 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57132,17 +59905,17 @@ module.exports = arrify; /***/ }), -/* 504 */ +/* 517 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(132); -const arrayUnion = __webpack_require__(505); -const glob = __webpack_require__(507); -const fastGlob = __webpack_require__(512); -const dirGlob = __webpack_require__(712); -const gitignore = __webpack_require__(715); +const fs = __webpack_require__(133); +const arrayUnion = __webpack_require__(518); +const glob = __webpack_require__(520); +const fastGlob = __webpack_require__(525); +const dirGlob = __webpack_require__(725); +const gitignore = __webpack_require__(728); const DEFAULT_FILTER = () => false; @@ -57287,12 +60060,12 @@ module.exports.gitignore = gitignore; /***/ }), -/* 505 */ +/* 518 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var arrayUniq = __webpack_require__(506); +var arrayUniq = __webpack_require__(519); module.exports = function () { return arrayUniq([].concat.apply([], arguments)); @@ -57300,7 +60073,7 @@ module.exports = function () { /***/ }), -/* 506 */ +/* 519 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57369,7 +60142,7 @@ if ('Set' in global) { /***/ }), -/* 507 */ +/* 520 */ /***/ (function(module, exports, __webpack_require__) { // Approach: @@ -57414,27 +60187,27 @@ if ('Set' in global) { module.exports = glob -var fs = __webpack_require__(132) -var rp = __webpack_require__(146) -var minimatch = __webpack_require__(148) +var fs = __webpack_require__(133) +var rp = __webpack_require__(147) +var minimatch = __webpack_require__(149) var Minimatch = minimatch.Minimatch -var inherits = __webpack_require__(508) -var EE = __webpack_require__(154).EventEmitter +var inherits = __webpack_require__(521) +var EE = __webpack_require__(155).EventEmitter var path = __webpack_require__(4) -var assert = __webpack_require__(138) -var isAbsolute = __webpack_require__(155) -var globSync = __webpack_require__(510) -var common = __webpack_require__(511) +var assert = __webpack_require__(139) +var isAbsolute = __webpack_require__(156) +var globSync = __webpack_require__(523) +var common = __webpack_require__(524) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts var ownProp = common.ownProp -var inflight = __webpack_require__(158) +var inflight = __webpack_require__(159) var util = __webpack_require__(111) var childrenIgnored = common.childrenIgnored var isIgnored = common.isIgnored -var once = __webpack_require__(160) +var once = __webpack_require__(161) function glob (pattern, options, cb) { if (typeof options === 'function') cb = options, options = {} @@ -58165,7 +60938,7 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) { /***/ }), -/* 508 */ +/* 521 */ /***/ (function(module, exports, __webpack_require__) { try { @@ -58175,12 +60948,12 @@ try { module.exports = util.inherits; } catch (e) { /* istanbul ignore next */ - module.exports = __webpack_require__(509); + module.exports = __webpack_require__(522); } /***/ }), -/* 509 */ +/* 522 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -58213,22 +60986,22 @@ if (typeof Object.create === 'function') { /***/ }), -/* 510 */ +/* 523 */ /***/ (function(module, exports, __webpack_require__) { module.exports = globSync globSync.GlobSync = GlobSync -var fs = __webpack_require__(132) -var rp = __webpack_require__(146) -var minimatch = __webpack_require__(148) +var fs = __webpack_require__(133) +var rp = __webpack_require__(147) +var minimatch = __webpack_require__(149) var Minimatch = minimatch.Minimatch -var Glob = __webpack_require__(507).Glob +var Glob = __webpack_require__(520).Glob var util = __webpack_require__(111) var path = __webpack_require__(4) -var assert = __webpack_require__(138) -var isAbsolute = __webpack_require__(155) -var common = __webpack_require__(511) +var assert = __webpack_require__(139) +var isAbsolute = __webpack_require__(156) +var common = __webpack_require__(524) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts @@ -58705,7 +61478,7 @@ GlobSync.prototype._makeAbs = function (f) { /***/ }), -/* 511 */ +/* 524 */ /***/ (function(module, exports, __webpack_require__) { exports.alphasort = alphasort @@ -58723,8 +61496,8 @@ function ownProp (obj, field) { } var path = __webpack_require__(4) -var minimatch = __webpack_require__(148) -var isAbsolute = __webpack_require__(155) +var minimatch = __webpack_require__(149) +var isAbsolute = __webpack_require__(156) var Minimatch = minimatch.Minimatch function alphasorti (a, b) { @@ -58951,10 +61724,10 @@ function childrenIgnored (self, path) { /***/ }), -/* 512 */ +/* 525 */ /***/ (function(module, exports, __webpack_require__) { -const pkg = __webpack_require__(513); +const pkg = __webpack_require__(526); module.exports = pkg.async; module.exports.default = pkg.async; @@ -58967,19 +61740,19 @@ module.exports.generateTasks = pkg.generateTasks; /***/ }), -/* 513 */ +/* 526 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var optionsManager = __webpack_require__(514); -var taskManager = __webpack_require__(515); -var reader_async_1 = __webpack_require__(683); -var reader_stream_1 = __webpack_require__(707); -var reader_sync_1 = __webpack_require__(708); -var arrayUtils = __webpack_require__(710); -var streamUtils = __webpack_require__(711); +var optionsManager = __webpack_require__(527); +var taskManager = __webpack_require__(528); +var reader_async_1 = __webpack_require__(696); +var reader_stream_1 = __webpack_require__(720); +var reader_sync_1 = __webpack_require__(721); +var arrayUtils = __webpack_require__(723); +var streamUtils = __webpack_require__(724); /** * Synchronous API. */ @@ -59045,7 +61818,7 @@ function isString(source) { /***/ }), -/* 514 */ +/* 527 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59083,13 +61856,13 @@ exports.prepare = prepare; /***/ }), -/* 515 */ +/* 528 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var patternUtils = __webpack_require__(516); +var patternUtils = __webpack_require__(529); /** * Generate tasks based on parent directory of each pattern. */ @@ -59180,16 +61953,16 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 516 */ +/* 529 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var globParent = __webpack_require__(517); -var isGlob = __webpack_require__(520); -var micromatch = __webpack_require__(521); +var globParent = __webpack_require__(530); +var isGlob = __webpack_require__(533); +var micromatch = __webpack_require__(534); var GLOBSTAR = '**'; /** * Return true for static pattern. @@ -59335,16 +62108,16 @@ exports.matchAny = matchAny; /***/ }), -/* 517 */ +/* 530 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var path = __webpack_require__(4); -var isglob = __webpack_require__(518); -var pathDirname = __webpack_require__(519); -var isWin32 = __webpack_require__(121).platform() === 'win32'; +var isglob = __webpack_require__(531); +var pathDirname = __webpack_require__(532); +var isWin32 = __webpack_require__(120).platform() === 'win32'; module.exports = function globParent(str) { // flip windows path separators @@ -59366,7 +62139,7 @@ module.exports = function globParent(str) { /***/ }), -/* 518 */ +/* 531 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -59376,7 +62149,7 @@ module.exports = function globParent(str) { * Licensed under the MIT License. */ -var isExtglob = __webpack_require__(300); +var isExtglob = __webpack_require__(315); module.exports = function isGlob(str) { if (typeof str !== 'string' || str === '') { @@ -59397,7 +62170,7 @@ module.exports = function isGlob(str) { /***/ }), -/* 519 */ +/* 532 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59547,7 +62320,7 @@ module.exports.win32 = win32; /***/ }), -/* 520 */ +/* 533 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -59557,7 +62330,7 @@ module.exports.win32 = win32; * Released under the MIT License. */ -var isExtglob = __webpack_require__(300); +var isExtglob = __webpack_require__(315); var chars = { '{': '}', '(': ')', '[': ']'}; module.exports = function isGlob(str, options) { @@ -59599,7 +62372,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 521 */ +/* 534 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59610,18 +62383,18 @@ module.exports = function isGlob(str, options) { */ var util = __webpack_require__(111); -var braces = __webpack_require__(522); -var toRegex = __webpack_require__(635); -var extend = __webpack_require__(643); +var braces = __webpack_require__(535); +var toRegex = __webpack_require__(648); +var extend = __webpack_require__(656); /** * Local dependencies */ -var compilers = __webpack_require__(646); -var parsers = __webpack_require__(679); -var cache = __webpack_require__(680); -var utils = __webpack_require__(681); +var compilers = __webpack_require__(659); +var parsers = __webpack_require__(692); +var cache = __webpack_require__(693); +var utils = __webpack_require__(694); var MAX_LENGTH = 1024 * 64; /** @@ -60483,7 +63256,7 @@ module.exports = micromatch; /***/ }), -/* 522 */ +/* 535 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60493,18 +63266,18 @@ module.exports = micromatch; * Module dependencies */ -var toRegex = __webpack_require__(523); -var unique = __webpack_require__(537); -var extend = __webpack_require__(532); +var toRegex = __webpack_require__(536); +var unique = __webpack_require__(550); +var extend = __webpack_require__(545); /** * Local dependencies */ -var compilers = __webpack_require__(538); -var parsers = __webpack_require__(555); -var Braces = __webpack_require__(565); -var utils = __webpack_require__(539); +var compilers = __webpack_require__(551); +var parsers = __webpack_require__(568); +var Braces = __webpack_require__(578); +var utils = __webpack_require__(552); var MAX_LENGTH = 1024 * 64; var cache = {}; @@ -60808,15 +63581,15 @@ module.exports = braces; /***/ }), -/* 523 */ +/* 536 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(524); -var extend = __webpack_require__(532); -var not = __webpack_require__(534); +var define = __webpack_require__(537); +var extend = __webpack_require__(545); +var not = __webpack_require__(547); var MAX_LENGTH = 1024 * 64; /** @@ -60963,7 +63736,7 @@ module.exports.makeRe = makeRe; /***/ }), -/* 524 */ +/* 537 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60976,7 +63749,7 @@ module.exports.makeRe = makeRe; -var isDescriptor = __webpack_require__(525); +var isDescriptor = __webpack_require__(538); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -61001,7 +63774,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 525 */ +/* 538 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61014,9 +63787,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(526); -var isAccessor = __webpack_require__(527); -var isData = __webpack_require__(530); +var typeOf = __webpack_require__(539); +var isAccessor = __webpack_require__(540); +var isData = __webpack_require__(543); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -61030,7 +63803,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 526 */ +/* 539 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -61183,7 +63956,7 @@ function isBuffer(val) { /***/ }), -/* 527 */ +/* 540 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61196,7 +63969,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(528); +var typeOf = __webpack_require__(541); // accessor descriptor properties var accessor = { @@ -61259,10 +64032,10 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 528 */ +/* 541 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(542); var toString = Object.prototype.toString; /** @@ -61381,7 +64154,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 529 */ +/* 542 */ /***/ (function(module, exports) { /*! @@ -61408,7 +64181,7 @@ function isSlowBuffer (obj) { /***/ }), -/* 530 */ +/* 543 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61421,7 +64194,7 @@ function isSlowBuffer (obj) { -var typeOf = __webpack_require__(531); +var typeOf = __webpack_require__(544); // data descriptor properties var data = { @@ -61470,10 +64243,10 @@ module.exports = isDataDescriptor; /***/ }), -/* 531 */ +/* 544 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(542); var toString = Object.prototype.toString; /** @@ -61592,13 +64365,13 @@ module.exports = function kindOf(val) { /***/ }), -/* 532 */ +/* 545 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(533); +var isObject = __webpack_require__(546); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -61632,7 +64405,7 @@ function hasOwn(obj, key) { /***/ }), -/* 533 */ +/* 546 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61652,13 +64425,13 @@ module.exports = function isExtendable(val) { /***/ }), -/* 534 */ +/* 547 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(535); +var extend = __webpack_require__(548); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -61725,13 +64498,13 @@ module.exports = toRegex; /***/ }), -/* 535 */ +/* 548 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(536); +var isObject = __webpack_require__(549); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -61765,7 +64538,7 @@ function hasOwn(obj, key) { /***/ }), -/* 536 */ +/* 549 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61785,7 +64558,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 537 */ +/* 550 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61835,13 +64608,13 @@ module.exports.immutable = function uniqueImmutable(arr) { /***/ }), -/* 538 */ +/* 551 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(539); +var utils = __webpack_require__(552); module.exports = function(braces, options) { braces.compiler @@ -62124,25 +64897,25 @@ function hasQueue(node) { /***/ }), -/* 539 */ +/* 552 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var splitString = __webpack_require__(540); +var splitString = __webpack_require__(553); var utils = module.exports; /** * Module dependencies */ -utils.extend = __webpack_require__(532); -utils.flatten = __webpack_require__(546); -utils.isObject = __webpack_require__(544); -utils.fillRange = __webpack_require__(547); -utils.repeat = __webpack_require__(554); -utils.unique = __webpack_require__(537); +utils.extend = __webpack_require__(545); +utils.flatten = __webpack_require__(559); +utils.isObject = __webpack_require__(557); +utils.fillRange = __webpack_require__(560); +utils.repeat = __webpack_require__(567); +utils.unique = __webpack_require__(550); utils.define = function(obj, key, val) { Object.defineProperty(obj, key, { @@ -62474,7 +65247,7 @@ utils.escapeRegex = function(str) { /***/ }), -/* 540 */ +/* 553 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62487,7 +65260,7 @@ utils.escapeRegex = function(str) { -var extend = __webpack_require__(541); +var extend = __webpack_require__(554); module.exports = function(str, options, fn) { if (typeof str !== 'string') { @@ -62652,14 +65425,14 @@ function keepEscaping(opts, str, idx) { /***/ }), -/* 541 */ +/* 554 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(542); -var assignSymbols = __webpack_require__(545); +var isExtendable = __webpack_require__(555); +var assignSymbols = __webpack_require__(558); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -62719,7 +65492,7 @@ function isEnum(obj, key) { /***/ }), -/* 542 */ +/* 555 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62732,7 +65505,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(543); +var isPlainObject = __webpack_require__(556); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -62740,7 +65513,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 543 */ +/* 556 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62753,7 +65526,7 @@ module.exports = function isExtendable(val) { -var isObject = __webpack_require__(544); +var isObject = __webpack_require__(557); function isObjectObject(o) { return isObject(o) === true @@ -62784,7 +65557,7 @@ module.exports = function isPlainObject(o) { /***/ }), -/* 544 */ +/* 557 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62803,7 +65576,7 @@ module.exports = function isObject(val) { /***/ }), -/* 545 */ +/* 558 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62850,7 +65623,7 @@ module.exports = function(receiver, objects) { /***/ }), -/* 546 */ +/* 559 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62879,7 +65652,7 @@ function flat(arr, res) { /***/ }), -/* 547 */ +/* 560 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62893,10 +65666,10 @@ function flat(arr, res) { var util = __webpack_require__(111); -var isNumber = __webpack_require__(548); -var extend = __webpack_require__(550); -var repeat = __webpack_require__(552); -var toRegex = __webpack_require__(553); +var isNumber = __webpack_require__(561); +var extend = __webpack_require__(563); +var repeat = __webpack_require__(565); +var toRegex = __webpack_require__(566); /** * Return a range of numbers or letters. @@ -63094,7 +65867,7 @@ module.exports = fillRange; /***/ }), -/* 548 */ +/* 561 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63107,7 +65880,7 @@ module.exports = fillRange; -var typeOf = __webpack_require__(549); +var typeOf = __webpack_require__(562); module.exports = function isNumber(num) { var type = typeOf(num); @@ -63123,10 +65896,10 @@ module.exports = function isNumber(num) { /***/ }), -/* 549 */ +/* 562 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(542); var toString = Object.prototype.toString; /** @@ -63245,13 +66018,13 @@ module.exports = function kindOf(val) { /***/ }), -/* 550 */ +/* 563 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(551); +var isObject = __webpack_require__(564); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -63285,7 +66058,7 @@ function hasOwn(obj, key) { /***/ }), -/* 551 */ +/* 564 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63305,7 +66078,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 552 */ +/* 565 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63382,7 +66155,7 @@ function repeat(str, num) { /***/ }), -/* 553 */ +/* 566 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63395,8 +66168,8 @@ function repeat(str, num) { -var repeat = __webpack_require__(552); -var isNumber = __webpack_require__(548); +var repeat = __webpack_require__(565); +var isNumber = __webpack_require__(561); var cache = {}; function toRegexRange(min, max, options) { @@ -63683,7 +66456,7 @@ module.exports = toRegexRange; /***/ }), -/* 554 */ +/* 567 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63708,14 +66481,14 @@ module.exports = function repeat(ele, num) { /***/ }), -/* 555 */ +/* 568 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Node = __webpack_require__(556); -var utils = __webpack_require__(539); +var Node = __webpack_require__(569); +var utils = __webpack_require__(552); /** * Braces parsers @@ -64075,15 +66848,15 @@ function concatNodes(pos, node, parent, options) { /***/ }), -/* 556 */ +/* 569 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(544); -var define = __webpack_require__(557); -var utils = __webpack_require__(564); +var isObject = __webpack_require__(557); +var define = __webpack_require__(570); +var utils = __webpack_require__(577); var ownNames; /** @@ -64574,7 +67347,7 @@ exports = module.exports = Node; /***/ }), -/* 557 */ +/* 570 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64587,7 +67360,7 @@ exports = module.exports = Node; -var isDescriptor = __webpack_require__(558); +var isDescriptor = __webpack_require__(571); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -64612,7 +67385,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 558 */ +/* 571 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64625,9 +67398,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(559); -var isAccessor = __webpack_require__(560); -var isData = __webpack_require__(562); +var typeOf = __webpack_require__(572); +var isAccessor = __webpack_require__(573); +var isData = __webpack_require__(575); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -64641,7 +67414,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 559 */ +/* 572 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -64776,7 +67549,7 @@ function isBuffer(val) { /***/ }), -/* 560 */ +/* 573 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64789,7 +67562,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(561); +var typeOf = __webpack_require__(574); // accessor descriptor properties var accessor = { @@ -64852,7 +67625,7 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 561 */ +/* 574 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -64987,7 +67760,7 @@ function isBuffer(val) { /***/ }), -/* 562 */ +/* 575 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -65000,7 +67773,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(563); +var typeOf = __webpack_require__(576); module.exports = function isDataDescriptor(obj, prop) { // data descriptor properties @@ -65043,7 +67816,7 @@ module.exports = function isDataDescriptor(obj, prop) { /***/ }), -/* 563 */ +/* 576 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -65178,13 +67951,13 @@ function isBuffer(val) { /***/ }), -/* 564 */ +/* 577 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(549); +var typeOf = __webpack_require__(562); var utils = module.exports; /** @@ -66204,17 +68977,17 @@ function assert(val, message) { /***/ }), -/* 565 */ +/* 578 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(532); -var Snapdragon = __webpack_require__(566); -var compilers = __webpack_require__(538); -var parsers = __webpack_require__(555); -var utils = __webpack_require__(539); +var extend = __webpack_require__(545); +var Snapdragon = __webpack_require__(579); +var compilers = __webpack_require__(551); +var parsers = __webpack_require__(568); +var utils = __webpack_require__(552); /** * Customize Snapdragon parser and renderer @@ -66315,17 +69088,17 @@ module.exports = Braces; /***/ }), -/* 566 */ +/* 579 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Base = __webpack_require__(567); -var define = __webpack_require__(593); -var Compiler = __webpack_require__(603); -var Parser = __webpack_require__(632); -var utils = __webpack_require__(612); +var Base = __webpack_require__(580); +var define = __webpack_require__(606); +var Compiler = __webpack_require__(616); +var Parser = __webpack_require__(645); +var utils = __webpack_require__(625); var regexCache = {}; var cache = {}; @@ -66496,20 +69269,20 @@ module.exports.Parser = Parser; /***/ }), -/* 567 */ +/* 580 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(111); -var define = __webpack_require__(568); -var CacheBase = __webpack_require__(569); -var Emitter = __webpack_require__(570); -var isObject = __webpack_require__(544); -var merge = __webpack_require__(587); -var pascal = __webpack_require__(590); -var cu = __webpack_require__(591); +var define = __webpack_require__(581); +var CacheBase = __webpack_require__(582); +var Emitter = __webpack_require__(583); +var isObject = __webpack_require__(557); +var merge = __webpack_require__(600); +var pascal = __webpack_require__(603); +var cu = __webpack_require__(604); /** * Optionally define a custom `cache` namespace to use. @@ -66938,7 +69711,7 @@ module.exports.namespace = namespace; /***/ }), -/* 568 */ +/* 581 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66951,7 +69724,7 @@ module.exports.namespace = namespace; -var isDescriptor = __webpack_require__(558); +var isDescriptor = __webpack_require__(571); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -66976,21 +69749,21 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 569 */ +/* 582 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(544); -var Emitter = __webpack_require__(570); -var visit = __webpack_require__(571); -var toPath = __webpack_require__(574); -var union = __webpack_require__(575); -var del = __webpack_require__(579); -var get = __webpack_require__(577); -var has = __webpack_require__(584); -var set = __webpack_require__(578); +var isObject = __webpack_require__(557); +var Emitter = __webpack_require__(583); +var visit = __webpack_require__(584); +var toPath = __webpack_require__(587); +var union = __webpack_require__(588); +var del = __webpack_require__(592); +var get = __webpack_require__(590); +var has = __webpack_require__(597); +var set = __webpack_require__(591); /** * Create a `Cache` constructor that when instantiated will @@ -67244,7 +70017,7 @@ module.exports.namespace = namespace; /***/ }), -/* 570 */ +/* 583 */ /***/ (function(module, exports, __webpack_require__) { @@ -67413,7 +70186,7 @@ Emitter.prototype.hasListeners = function(event){ /***/ }), -/* 571 */ +/* 584 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67426,8 +70199,8 @@ Emitter.prototype.hasListeners = function(event){ -var visit = __webpack_require__(572); -var mapVisit = __webpack_require__(573); +var visit = __webpack_require__(585); +var mapVisit = __webpack_require__(586); module.exports = function(collection, method, val) { var result; @@ -67450,7 +70223,7 @@ module.exports = function(collection, method, val) { /***/ }), -/* 572 */ +/* 585 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67463,7 +70236,7 @@ module.exports = function(collection, method, val) { -var isObject = __webpack_require__(544); +var isObject = __webpack_require__(557); module.exports = function visit(thisArg, method, target, val) { if (!isObject(thisArg) && typeof thisArg !== 'function') { @@ -67490,14 +70263,14 @@ module.exports = function visit(thisArg, method, target, val) { /***/ }), -/* 573 */ +/* 586 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(111); -var visit = __webpack_require__(572); +var visit = __webpack_require__(585); /** * Map `visit` over an array of objects. @@ -67534,7 +70307,7 @@ function isObject(val) { /***/ }), -/* 574 */ +/* 587 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67547,7 +70320,7 @@ function isObject(val) { -var typeOf = __webpack_require__(549); +var typeOf = __webpack_require__(562); module.exports = function toPath(args) { if (typeOf(args) !== 'arguments') { @@ -67574,16 +70347,16 @@ function filter(arr) { /***/ }), -/* 575 */ +/* 588 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(536); -var union = __webpack_require__(576); -var get = __webpack_require__(577); -var set = __webpack_require__(578); +var isObject = __webpack_require__(549); +var union = __webpack_require__(589); +var get = __webpack_require__(590); +var set = __webpack_require__(591); module.exports = function unionValue(obj, prop, value) { if (!isObject(obj)) { @@ -67611,7 +70384,7 @@ function arrayify(val) { /***/ }), -/* 576 */ +/* 589 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67647,7 +70420,7 @@ module.exports = function union(init) { /***/ }), -/* 577 */ +/* 590 */ /***/ (function(module, exports) { /*! @@ -67703,7 +70476,7 @@ function toString(val) { /***/ }), -/* 578 */ +/* 591 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67716,10 +70489,10 @@ function toString(val) { -var split = __webpack_require__(540); -var extend = __webpack_require__(535); -var isPlainObject = __webpack_require__(543); -var isObject = __webpack_require__(536); +var split = __webpack_require__(553); +var extend = __webpack_require__(548); +var isPlainObject = __webpack_require__(556); +var isObject = __webpack_require__(549); module.exports = function(obj, prop, val) { if (!isObject(obj)) { @@ -67765,7 +70538,7 @@ function isValidKey(key) { /***/ }), -/* 579 */ +/* 592 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67778,8 +70551,8 @@ function isValidKey(key) { -var isObject = __webpack_require__(544); -var has = __webpack_require__(580); +var isObject = __webpack_require__(557); +var has = __webpack_require__(593); module.exports = function unset(obj, prop) { if (!isObject(obj)) { @@ -67804,7 +70577,7 @@ module.exports = function unset(obj, prop) { /***/ }), -/* 580 */ +/* 593 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67817,9 +70590,9 @@ module.exports = function unset(obj, prop) { -var isObject = __webpack_require__(581); -var hasValues = __webpack_require__(583); -var get = __webpack_require__(577); +var isObject = __webpack_require__(594); +var hasValues = __webpack_require__(596); +var get = __webpack_require__(590); module.exports = function(obj, prop, noZero) { if (isObject(obj)) { @@ -67830,7 +70603,7 @@ module.exports = function(obj, prop, noZero) { /***/ }), -/* 581 */ +/* 594 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67843,7 +70616,7 @@ module.exports = function(obj, prop, noZero) { -var isArray = __webpack_require__(582); +var isArray = __webpack_require__(595); module.exports = function isObject(val) { return val != null && typeof val === 'object' && isArray(val) === false; @@ -67851,7 +70624,7 @@ module.exports = function isObject(val) { /***/ }), -/* 582 */ +/* 595 */ /***/ (function(module, exports) { var toString = {}.toString; @@ -67862,7 +70635,7 @@ module.exports = Array.isArray || function (arr) { /***/ }), -/* 583 */ +/* 596 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67905,7 +70678,7 @@ module.exports = function hasValue(o, noZero) { /***/ }), -/* 584 */ +/* 597 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67918,9 +70691,9 @@ module.exports = function hasValue(o, noZero) { -var isObject = __webpack_require__(544); -var hasValues = __webpack_require__(585); -var get = __webpack_require__(577); +var isObject = __webpack_require__(557); +var hasValues = __webpack_require__(598); +var get = __webpack_require__(590); module.exports = function(val, prop) { return hasValues(isObject(val) && prop ? get(val, prop) : val); @@ -67928,7 +70701,7 @@ module.exports = function(val, prop) { /***/ }), -/* 585 */ +/* 598 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67941,8 +70714,8 @@ module.exports = function(val, prop) { -var typeOf = __webpack_require__(586); -var isNumber = __webpack_require__(548); +var typeOf = __webpack_require__(599); +var isNumber = __webpack_require__(561); module.exports = function hasValue(val) { // is-number checks for NaN and other edge cases @@ -67995,10 +70768,10 @@ module.exports = function hasValue(val) { /***/ }), -/* 586 */ +/* 599 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(542); var toString = Object.prototype.toString; /** @@ -68120,14 +70893,14 @@ module.exports = function kindOf(val) { /***/ }), -/* 587 */ +/* 600 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(588); -var forIn = __webpack_require__(589); +var isExtendable = __webpack_require__(601); +var forIn = __webpack_require__(602); function mixinDeep(target, objects) { var len = arguments.length, i = 0; @@ -68191,7 +70964,7 @@ module.exports = mixinDeep; /***/ }), -/* 588 */ +/* 601 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68204,7 +70977,7 @@ module.exports = mixinDeep; -var isPlainObject = __webpack_require__(543); +var isPlainObject = __webpack_require__(556); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -68212,7 +70985,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 589 */ +/* 602 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68235,7 +71008,7 @@ module.exports = function forIn(obj, fn, thisArg) { /***/ }), -/* 590 */ +/* 603 */ /***/ (function(module, exports) { /*! @@ -68262,14 +71035,14 @@ module.exports = pascalcase; /***/ }), -/* 591 */ +/* 604 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(111); -var utils = __webpack_require__(592); +var utils = __webpack_require__(605); /** * Expose class utils @@ -68634,7 +71407,7 @@ cu.bubble = function(Parent, events) { /***/ }), -/* 592 */ +/* 605 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68648,10 +71421,10 @@ var utils = {}; * Lazily required module dependencies */ -utils.union = __webpack_require__(576); -utils.define = __webpack_require__(593); -utils.isObj = __webpack_require__(544); -utils.staticExtend = __webpack_require__(600); +utils.union = __webpack_require__(589); +utils.define = __webpack_require__(606); +utils.isObj = __webpack_require__(557); +utils.staticExtend = __webpack_require__(613); /** @@ -68662,7 +71435,7 @@ module.exports = utils; /***/ }), -/* 593 */ +/* 606 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68675,7 +71448,7 @@ module.exports = utils; -var isDescriptor = __webpack_require__(594); +var isDescriptor = __webpack_require__(607); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -68700,7 +71473,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 594 */ +/* 607 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68713,9 +71486,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(595); -var isAccessor = __webpack_require__(596); -var isData = __webpack_require__(598); +var typeOf = __webpack_require__(608); +var isAccessor = __webpack_require__(609); +var isData = __webpack_require__(611); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -68729,7 +71502,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 595 */ +/* 608 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -68882,7 +71655,7 @@ function isBuffer(val) { /***/ }), -/* 596 */ +/* 609 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68895,7 +71668,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(597); +var typeOf = __webpack_require__(610); // accessor descriptor properties var accessor = { @@ -68958,10 +71731,10 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 597 */ +/* 610 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(542); var toString = Object.prototype.toString; /** @@ -69080,7 +71853,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 598 */ +/* 611 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69093,7 +71866,7 @@ module.exports = function kindOf(val) { -var typeOf = __webpack_require__(599); +var typeOf = __webpack_require__(612); // data descriptor properties var data = { @@ -69142,10 +71915,10 @@ module.exports = isDataDescriptor; /***/ }), -/* 599 */ +/* 612 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(542); var toString = Object.prototype.toString; /** @@ -69264,7 +72037,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 600 */ +/* 613 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69277,8 +72050,8 @@ module.exports = function kindOf(val) { -var copy = __webpack_require__(601); -var define = __webpack_require__(593); +var copy = __webpack_require__(614); +var define = __webpack_require__(606); var util = __webpack_require__(111); /** @@ -69361,15 +72134,15 @@ module.exports = extend; /***/ }), -/* 601 */ +/* 614 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(549); -var copyDescriptor = __webpack_require__(602); -var define = __webpack_require__(593); +var typeOf = __webpack_require__(562); +var copyDescriptor = __webpack_require__(615); +var define = __webpack_require__(606); /** * Copy static properties, prototype properties, and descriptors from one object to another. @@ -69542,7 +72315,7 @@ module.exports.has = has; /***/ }), -/* 602 */ +/* 615 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69630,16 +72403,16 @@ function isObject(val) { /***/ }), -/* 603 */ +/* 616 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(604); -var define = __webpack_require__(593); -var debug = __webpack_require__(606)('snapdragon:compiler'); -var utils = __webpack_require__(612); +var use = __webpack_require__(617); +var define = __webpack_require__(606); +var debug = __webpack_require__(619)('snapdragon:compiler'); +var utils = __webpack_require__(625); /** * Create a new `Compiler` with the given `options`. @@ -69793,7 +72566,7 @@ Compiler.prototype = { // source map support if (opts.sourcemap) { - var sourcemaps = __webpack_require__(631); + var sourcemaps = __webpack_require__(644); sourcemaps(this); this.mapVisit(this.ast.nodes); this.applySourceMaps(); @@ -69814,7 +72587,7 @@ module.exports = Compiler; /***/ }), -/* 604 */ +/* 617 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69827,7 +72600,7 @@ module.exports = Compiler; -var utils = __webpack_require__(605); +var utils = __webpack_require__(618); module.exports = function base(app, opts) { if (!utils.isObject(app) && typeof app !== 'function') { @@ -69942,7 +72715,7 @@ module.exports = function base(app, opts) { /***/ }), -/* 605 */ +/* 618 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69956,8 +72729,8 @@ var utils = {}; * Lazily required module dependencies */ -utils.define = __webpack_require__(593); -utils.isObject = __webpack_require__(544); +utils.define = __webpack_require__(606); +utils.isObject = __webpack_require__(557); utils.isString = function(val) { @@ -69972,7 +72745,7 @@ module.exports = utils; /***/ }), -/* 606 */ +/* 619 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -69981,14 +72754,14 @@ module.exports = utils; */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(607); + module.exports = __webpack_require__(620); } else { - module.exports = __webpack_require__(610); + module.exports = __webpack_require__(623); } /***/ }), -/* 607 */ +/* 620 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -69997,7 +72770,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(608); +exports = module.exports = __webpack_require__(621); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -70179,7 +72952,7 @@ function localstorage() { /***/ }), -/* 608 */ +/* 621 */ /***/ (function(module, exports, __webpack_require__) { @@ -70195,7 +72968,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(609); +exports.humanize = __webpack_require__(622); /** * The currently active debug mode names, and names to skip. @@ -70387,7 +73160,7 @@ function coerce(val) { /***/ }), -/* 609 */ +/* 622 */ /***/ (function(module, exports) { /** @@ -70545,14 +73318,14 @@ function plural(ms, n, name) { /***/ }), -/* 610 */ +/* 623 */ /***/ (function(module, exports, __webpack_require__) { /** * Module dependencies. */ -var tty = __webpack_require__(278); +var tty = __webpack_require__(121); var util = __webpack_require__(111); /** @@ -70561,7 +73334,7 @@ var util = __webpack_require__(111); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(608); +exports = module.exports = __webpack_require__(621); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -70733,14 +73506,14 @@ function createWritableStdioStream (fd) { break; case 'FILE': - var fs = __webpack_require__(132); + var fs = __webpack_require__(133); stream = new fs.SyncWriteStream(fd, { autoClose: false }); stream._type = 'fs'; break; case 'PIPE': case 'TCP': - var net = __webpack_require__(611); + var net = __webpack_require__(624); stream = new net.Socket({ fd: fd, readable: false, @@ -70799,13 +73572,13 @@ exports.enable(load()); /***/ }), -/* 611 */ +/* 624 */ /***/ (function(module, exports) { module.exports = require("net"); /***/ }), -/* 612 */ +/* 625 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -70815,9 +73588,9 @@ module.exports = require("net"); * Module dependencies */ -exports.extend = __webpack_require__(535); -exports.SourceMap = __webpack_require__(613); -exports.sourceMapResolve = __webpack_require__(624); +exports.extend = __webpack_require__(548); +exports.SourceMap = __webpack_require__(626); +exports.sourceMapResolve = __webpack_require__(637); /** * Convert backslash in the given string to forward slashes @@ -70860,7 +73633,7 @@ exports.last = function(arr, n) { /***/ }), -/* 613 */ +/* 626 */ /***/ (function(module, exports, __webpack_require__) { /* @@ -70868,13 +73641,13 @@ exports.last = function(arr, n) { * Licensed under the New BSD license. See LICENSE.txt or: * http://opensource.org/licenses/BSD-3-Clause */ -exports.SourceMapGenerator = __webpack_require__(614).SourceMapGenerator; -exports.SourceMapConsumer = __webpack_require__(620).SourceMapConsumer; -exports.SourceNode = __webpack_require__(623).SourceNode; +exports.SourceMapGenerator = __webpack_require__(627).SourceMapGenerator; +exports.SourceMapConsumer = __webpack_require__(633).SourceMapConsumer; +exports.SourceNode = __webpack_require__(636).SourceNode; /***/ }), -/* 614 */ +/* 627 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -70884,10 +73657,10 @@ exports.SourceNode = __webpack_require__(623).SourceNode; * http://opensource.org/licenses/BSD-3-Clause */ -var base64VLQ = __webpack_require__(615); -var util = __webpack_require__(617); -var ArraySet = __webpack_require__(618).ArraySet; -var MappingList = __webpack_require__(619).MappingList; +var base64VLQ = __webpack_require__(628); +var util = __webpack_require__(630); +var ArraySet = __webpack_require__(631).ArraySet; +var MappingList = __webpack_require__(632).MappingList; /** * An instance of the SourceMapGenerator represents a source map which is @@ -71296,7 +74069,7 @@ exports.SourceMapGenerator = SourceMapGenerator; /***/ }), -/* 615 */ +/* 628 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71336,7 +74109,7 @@ exports.SourceMapGenerator = SourceMapGenerator; * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var base64 = __webpack_require__(616); +var base64 = __webpack_require__(629); // A single base 64 digit can contain 6 bits of data. For the base 64 variable // length quantities we use in the source map spec, the first bit is the sign, @@ -71442,7 +74215,7 @@ exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { /***/ }), -/* 616 */ +/* 629 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71515,7 +74288,7 @@ exports.decode = function (charCode) { /***/ }), -/* 617 */ +/* 630 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71938,7 +74711,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate /***/ }), -/* 618 */ +/* 631 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71948,7 +74721,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(617); +var util = __webpack_require__(630); var has = Object.prototype.hasOwnProperty; var hasNativeMap = typeof Map !== "undefined"; @@ -72065,7 +74838,7 @@ exports.ArraySet = ArraySet; /***/ }), -/* 619 */ +/* 632 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -72075,7 +74848,7 @@ exports.ArraySet = ArraySet; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(617); +var util = __webpack_require__(630); /** * Determine whether mappingB is after mappingA with respect to generated @@ -72150,7 +74923,7 @@ exports.MappingList = MappingList; /***/ }), -/* 620 */ +/* 633 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -72160,11 +74933,11 @@ exports.MappingList = MappingList; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(617); -var binarySearch = __webpack_require__(621); -var ArraySet = __webpack_require__(618).ArraySet; -var base64VLQ = __webpack_require__(615); -var quickSort = __webpack_require__(622).quickSort; +var util = __webpack_require__(630); +var binarySearch = __webpack_require__(634); +var ArraySet = __webpack_require__(631).ArraySet; +var base64VLQ = __webpack_require__(628); +var quickSort = __webpack_require__(635).quickSort; function SourceMapConsumer(aSourceMap) { var sourceMap = aSourceMap; @@ -73238,7 +76011,7 @@ exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; /***/ }), -/* 621 */ +/* 634 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -73355,7 +76128,7 @@ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { /***/ }), -/* 622 */ +/* 635 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -73475,7 +76248,7 @@ exports.quickSort = function (ary, comparator) { /***/ }), -/* 623 */ +/* 636 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -73485,8 +76258,8 @@ exports.quickSort = function (ary, comparator) { * http://opensource.org/licenses/BSD-3-Clause */ -var SourceMapGenerator = __webpack_require__(614).SourceMapGenerator; -var util = __webpack_require__(617); +var SourceMapGenerator = __webpack_require__(627).SourceMapGenerator; +var util = __webpack_require__(630); // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other // operating systems these days (capturing the result). @@ -73894,17 +76667,17 @@ exports.SourceNode = SourceNode; /***/ }), -/* 624 */ +/* 637 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014, 2015, 2016, 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var sourceMappingURL = __webpack_require__(625) -var resolveUrl = __webpack_require__(626) -var decodeUriComponent = __webpack_require__(627) -var urix = __webpack_require__(629) -var atob = __webpack_require__(630) +var sourceMappingURL = __webpack_require__(638) +var resolveUrl = __webpack_require__(639) +var decodeUriComponent = __webpack_require__(640) +var urix = __webpack_require__(642) +var atob = __webpack_require__(643) @@ -74202,7 +76975,7 @@ module.exports = { /***/ }), -/* 625 */ +/* 638 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell @@ -74265,13 +77038,13 @@ void (function(root, factory) { /***/ }), -/* 626 */ +/* 639 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var url = __webpack_require__(189) +var url = __webpack_require__(196) function resolveUrl(/* ...urls */) { return Array.prototype.reduce.call(arguments, function(resolved, nextUrl) { @@ -74283,13 +77056,13 @@ module.exports = resolveUrl /***/ }), -/* 627 */ +/* 640 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var decodeUriComponent = __webpack_require__(628) +var decodeUriComponent = __webpack_require__(641) function customDecodeUriComponent(string) { // `decodeUriComponent` turns `+` into ` `, but that's not wanted. @@ -74300,7 +77073,7 @@ module.exports = customDecodeUriComponent /***/ }), -/* 628 */ +/* 641 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74401,7 +77174,7 @@ module.exports = function (encodedURI) { /***/ }), -/* 629 */ +/* 642 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -74424,7 +77197,7 @@ module.exports = urix /***/ }), -/* 630 */ +/* 643 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74438,16 +77211,16 @@ module.exports = atob.atob = atob; /***/ }), -/* 631 */ +/* 644 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var fs = __webpack_require__(132); +var fs = __webpack_require__(133); var path = __webpack_require__(4); -var define = __webpack_require__(593); -var utils = __webpack_require__(612); +var define = __webpack_require__(606); +var utils = __webpack_require__(625); /** * Expose `mixin()`. @@ -74590,19 +77363,19 @@ exports.comment = function(node) { /***/ }), -/* 632 */ +/* 645 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(604); +var use = __webpack_require__(617); var util = __webpack_require__(111); -var Cache = __webpack_require__(633); -var define = __webpack_require__(593); -var debug = __webpack_require__(606)('snapdragon:parser'); -var Position = __webpack_require__(634); -var utils = __webpack_require__(612); +var Cache = __webpack_require__(646); +var define = __webpack_require__(606); +var debug = __webpack_require__(619)('snapdragon:parser'); +var Position = __webpack_require__(647); +var utils = __webpack_require__(625); /** * Create a new `Parser` with the given `input` and `options`. @@ -75130,7 +77903,7 @@ module.exports = Parser; /***/ }), -/* 633 */ +/* 646 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75237,13 +78010,13 @@ MapCache.prototype.del = function mapDelete(key) { /***/ }), -/* 634 */ +/* 647 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(593); +var define = __webpack_require__(606); /** * Store position for a node @@ -75258,16 +78031,16 @@ module.exports = function Position(start, parser) { /***/ }), -/* 635 */ +/* 648 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var safe = __webpack_require__(636); -var define = __webpack_require__(642); -var extend = __webpack_require__(643); -var not = __webpack_require__(645); +var safe = __webpack_require__(649); +var define = __webpack_require__(655); +var extend = __webpack_require__(656); +var not = __webpack_require__(658); var MAX_LENGTH = 1024 * 64; /** @@ -75420,10 +78193,10 @@ module.exports.makeRe = makeRe; /***/ }), -/* 636 */ +/* 649 */ /***/ (function(module, exports, __webpack_require__) { -var parse = __webpack_require__(637); +var parse = __webpack_require__(650); var types = parse.types; module.exports = function (re, opts) { @@ -75469,13 +78242,13 @@ function isRegExp (x) { /***/ }), -/* 637 */ +/* 650 */ /***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(638); -var types = __webpack_require__(639); -var sets = __webpack_require__(640); -var positions = __webpack_require__(641); +var util = __webpack_require__(651); +var types = __webpack_require__(652); +var sets = __webpack_require__(653); +var positions = __webpack_require__(654); module.exports = function(regexpStr) { @@ -75757,11 +78530,11 @@ module.exports.types = types; /***/ }), -/* 638 */ +/* 651 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(639); -var sets = __webpack_require__(640); +var types = __webpack_require__(652); +var sets = __webpack_require__(653); // All of these are private and only used by randexp. @@ -75874,7 +78647,7 @@ exports.error = function(regexp, msg) { /***/ }), -/* 639 */ +/* 652 */ /***/ (function(module, exports) { module.exports = { @@ -75890,10 +78663,10 @@ module.exports = { /***/ }), -/* 640 */ +/* 653 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(639); +var types = __webpack_require__(652); var INTS = function() { return [{ type: types.RANGE , from: 48, to: 57 }]; @@ -75978,10 +78751,10 @@ exports.anyChar = function() { /***/ }), -/* 641 */ +/* 654 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(639); +var types = __webpack_require__(652); exports.wordBoundary = function() { return { type: types.POSITION, value: 'b' }; @@ -76001,7 +78774,7 @@ exports.end = function() { /***/ }), -/* 642 */ +/* 655 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76014,8 +78787,8 @@ exports.end = function() { -var isobject = __webpack_require__(544); -var isDescriptor = __webpack_require__(558); +var isobject = __webpack_require__(557); +var isDescriptor = __webpack_require__(571); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -76046,14 +78819,14 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 643 */ +/* 656 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(644); -var assignSymbols = __webpack_require__(545); +var isExtendable = __webpack_require__(657); +var assignSymbols = __webpack_require__(558); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -76113,7 +78886,7 @@ function isEnum(obj, key) { /***/ }), -/* 644 */ +/* 657 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76126,7 +78899,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(543); +var isPlainObject = __webpack_require__(556); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -76134,14 +78907,14 @@ module.exports = function isExtendable(val) { /***/ }), -/* 645 */ +/* 658 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(643); -var safe = __webpack_require__(636); +var extend = __webpack_require__(656); +var safe = __webpack_require__(649); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -76213,14 +78986,14 @@ module.exports = toRegex; /***/ }), -/* 646 */ +/* 659 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var nanomatch = __webpack_require__(647); -var extglob = __webpack_require__(663); +var nanomatch = __webpack_require__(660); +var extglob = __webpack_require__(676); module.exports = function(snapdragon) { var compilers = snapdragon.compiler.compilers; @@ -76297,7 +79070,7 @@ function escapeExtglobs(compiler) { /***/ }), -/* 647 */ +/* 660 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76308,17 +79081,17 @@ function escapeExtglobs(compiler) { */ var util = __webpack_require__(111); -var toRegex = __webpack_require__(648); -var extend = __webpack_require__(649); +var toRegex = __webpack_require__(661); +var extend = __webpack_require__(662); /** * Local dependencies */ -var compilers = __webpack_require__(651); -var parsers = __webpack_require__(652); -var cache = __webpack_require__(655); -var utils = __webpack_require__(657); +var compilers = __webpack_require__(664); +var parsers = __webpack_require__(665); +var cache = __webpack_require__(668); +var utils = __webpack_require__(670); var MAX_LENGTH = 1024 * 64; /** @@ -77142,15 +79915,15 @@ module.exports = nanomatch; /***/ }), -/* 648 */ +/* 661 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(593); -var extend = __webpack_require__(535); -var not = __webpack_require__(534); +var define = __webpack_require__(606); +var extend = __webpack_require__(548); +var not = __webpack_require__(547); var MAX_LENGTH = 1024 * 64; /** @@ -77297,14 +80070,14 @@ module.exports.makeRe = makeRe; /***/ }), -/* 649 */ +/* 662 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(650); -var assignSymbols = __webpack_require__(545); +var isExtendable = __webpack_require__(663); +var assignSymbols = __webpack_require__(558); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -77364,7 +80137,7 @@ function isEnum(obj, key) { /***/ }), -/* 650 */ +/* 663 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77377,7 +80150,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(543); +var isPlainObject = __webpack_require__(556); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -77385,7 +80158,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 651 */ +/* 664 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77731,15 +80504,15 @@ module.exports = function(nanomatch, options) { /***/ }), -/* 652 */ +/* 665 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regexNot = __webpack_require__(534); -var toRegex = __webpack_require__(648); -var isOdd = __webpack_require__(653); +var regexNot = __webpack_require__(547); +var toRegex = __webpack_require__(661); +var isOdd = __webpack_require__(666); /** * Characters to use in negation regex (we want to "not" match @@ -78125,7 +80898,7 @@ module.exports.not = NOT_REGEX; /***/ }), -/* 653 */ +/* 666 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78138,7 +80911,7 @@ module.exports.not = NOT_REGEX; -var isNumber = __webpack_require__(654); +var isNumber = __webpack_require__(667); module.exports = function isOdd(i) { if (!isNumber(i)) { @@ -78152,7 +80925,7 @@ module.exports = function isOdd(i) { /***/ }), -/* 654 */ +/* 667 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78180,14 +80953,14 @@ module.exports = function isNumber(num) { /***/ }), -/* 655 */ +/* 668 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(656))(); +module.exports = new (__webpack_require__(669))(); /***/ }), -/* 656 */ +/* 669 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78200,7 +80973,7 @@ module.exports = new (__webpack_require__(656))(); -var MapCache = __webpack_require__(633); +var MapCache = __webpack_require__(646); /** * Create a new `FragmentCache` with an optional object to use for `caches`. @@ -78322,7 +81095,7 @@ exports = module.exports = FragmentCache; /***/ }), -/* 657 */ +/* 670 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78335,14 +81108,14 @@ var path = __webpack_require__(4); * Module dependencies */ -var isWindows = __webpack_require__(658)(); -var Snapdragon = __webpack_require__(566); -utils.define = __webpack_require__(659); -utils.diff = __webpack_require__(660); -utils.extend = __webpack_require__(649); -utils.pick = __webpack_require__(661); -utils.typeOf = __webpack_require__(662); -utils.unique = __webpack_require__(537); +var isWindows = __webpack_require__(671)(); +var Snapdragon = __webpack_require__(579); +utils.define = __webpack_require__(672); +utils.diff = __webpack_require__(673); +utils.extend = __webpack_require__(662); +utils.pick = __webpack_require__(674); +utils.typeOf = __webpack_require__(675); +utils.unique = __webpack_require__(550); /** * Returns true if the given value is effectively an empty string @@ -78708,7 +81481,7 @@ utils.unixify = function(options) { /***/ }), -/* 658 */ +/* 671 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @@ -78736,7 +81509,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ /***/ }), -/* 659 */ +/* 672 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78749,8 +81522,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ -var isobject = __webpack_require__(544); -var isDescriptor = __webpack_require__(558); +var isobject = __webpack_require__(557); +var isDescriptor = __webpack_require__(571); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -78781,7 +81554,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 660 */ +/* 673 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78835,7 +81608,7 @@ function diffArray(one, two) { /***/ }), -/* 661 */ +/* 674 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78848,7 +81621,7 @@ function diffArray(one, two) { -var isObject = __webpack_require__(544); +var isObject = __webpack_require__(557); module.exports = function pick(obj, keys) { if (!isObject(obj) && typeof obj !== 'function') { @@ -78877,7 +81650,7 @@ module.exports = function pick(obj, keys) { /***/ }), -/* 662 */ +/* 675 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -79012,7 +81785,7 @@ function isBuffer(val) { /***/ }), -/* 663 */ +/* 676 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79022,18 +81795,18 @@ function isBuffer(val) { * Module dependencies */ -var extend = __webpack_require__(535); -var unique = __webpack_require__(537); -var toRegex = __webpack_require__(648); +var extend = __webpack_require__(548); +var unique = __webpack_require__(550); +var toRegex = __webpack_require__(661); /** * Local dependencies */ -var compilers = __webpack_require__(664); -var parsers = __webpack_require__(675); -var Extglob = __webpack_require__(678); -var utils = __webpack_require__(677); +var compilers = __webpack_require__(677); +var parsers = __webpack_require__(688); +var Extglob = __webpack_require__(691); +var utils = __webpack_require__(690); var MAX_LENGTH = 1024 * 64; /** @@ -79350,13 +82123,13 @@ module.exports = extglob; /***/ }), -/* 664 */ +/* 677 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(665); +var brackets = __webpack_require__(678); /** * Extglob compilers @@ -79526,7 +82299,7 @@ module.exports = function(extglob) { /***/ }), -/* 665 */ +/* 678 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79536,17 +82309,17 @@ module.exports = function(extglob) { * Local dependencies */ -var compilers = __webpack_require__(666); -var parsers = __webpack_require__(668); +var compilers = __webpack_require__(679); +var parsers = __webpack_require__(681); /** * Module dependencies */ -var debug = __webpack_require__(670)('expand-brackets'); -var extend = __webpack_require__(535); -var Snapdragon = __webpack_require__(566); -var toRegex = __webpack_require__(648); +var debug = __webpack_require__(683)('expand-brackets'); +var extend = __webpack_require__(548); +var Snapdragon = __webpack_require__(579); +var toRegex = __webpack_require__(661); /** * Parses the given POSIX character class `pattern` and returns a @@ -79744,13 +82517,13 @@ module.exports = brackets; /***/ }), -/* 666 */ +/* 679 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var posix = __webpack_require__(667); +var posix = __webpack_require__(680); module.exports = function(brackets) { brackets.compiler @@ -79838,7 +82611,7 @@ module.exports = function(brackets) { /***/ }), -/* 667 */ +/* 680 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79867,14 +82640,14 @@ module.exports = { /***/ }), -/* 668 */ +/* 681 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(669); -var define = __webpack_require__(593); +var utils = __webpack_require__(682); +var define = __webpack_require__(606); /** * Text regex @@ -80093,14 +82866,14 @@ module.exports.TEXT_REGEX = TEXT_REGEX; /***/ }), -/* 669 */ +/* 682 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var toRegex = __webpack_require__(648); -var regexNot = __webpack_require__(534); +var toRegex = __webpack_require__(661); +var regexNot = __webpack_require__(547); var cached; /** @@ -80134,7 +82907,7 @@ exports.createRegex = function(pattern, include) { /***/ }), -/* 670 */ +/* 683 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -80143,14 +82916,14 @@ exports.createRegex = function(pattern, include) { */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(671); + module.exports = __webpack_require__(684); } else { - module.exports = __webpack_require__(674); + module.exports = __webpack_require__(687); } /***/ }), -/* 671 */ +/* 684 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -80159,7 +82932,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(672); +exports = module.exports = __webpack_require__(685); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -80341,7 +83114,7 @@ function localstorage() { /***/ }), -/* 672 */ +/* 685 */ /***/ (function(module, exports, __webpack_require__) { @@ -80357,7 +83130,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(673); +exports.humanize = __webpack_require__(686); /** * The currently active debug mode names, and names to skip. @@ -80549,7 +83322,7 @@ function coerce(val) { /***/ }), -/* 673 */ +/* 686 */ /***/ (function(module, exports) { /** @@ -80707,14 +83480,14 @@ function plural(ms, n, name) { /***/ }), -/* 674 */ +/* 687 */ /***/ (function(module, exports, __webpack_require__) { /** * Module dependencies. */ -var tty = __webpack_require__(278); +var tty = __webpack_require__(121); var util = __webpack_require__(111); /** @@ -80723,7 +83496,7 @@ var util = __webpack_require__(111); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(672); +exports = module.exports = __webpack_require__(685); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -80895,14 +83668,14 @@ function createWritableStdioStream (fd) { break; case 'FILE': - var fs = __webpack_require__(132); + var fs = __webpack_require__(133); stream = new fs.SyncWriteStream(fd, { autoClose: false }); stream._type = 'fs'; break; case 'PIPE': case 'TCP': - var net = __webpack_require__(611); + var net = __webpack_require__(624); stream = new net.Socket({ fd: fd, readable: false, @@ -80961,15 +83734,15 @@ exports.enable(load()); /***/ }), -/* 675 */ +/* 688 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(665); -var define = __webpack_require__(676); -var utils = __webpack_require__(677); +var brackets = __webpack_require__(678); +var define = __webpack_require__(689); +var utils = __webpack_require__(690); /** * Characters to use in text regex (we want to "not" match @@ -81124,7 +83897,7 @@ module.exports = parsers; /***/ }), -/* 676 */ +/* 689 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81137,7 +83910,7 @@ module.exports = parsers; -var isDescriptor = __webpack_require__(558); +var isDescriptor = __webpack_require__(571); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -81162,14 +83935,14 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 677 */ +/* 690 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regex = __webpack_require__(534); -var Cache = __webpack_require__(656); +var regex = __webpack_require__(547); +var Cache = __webpack_require__(669); /** * Utils @@ -81238,7 +84011,7 @@ utils.createRegex = function(str) { /***/ }), -/* 678 */ +/* 691 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81248,16 +84021,16 @@ utils.createRegex = function(str) { * Module dependencies */ -var Snapdragon = __webpack_require__(566); -var define = __webpack_require__(676); -var extend = __webpack_require__(535); +var Snapdragon = __webpack_require__(579); +var define = __webpack_require__(689); +var extend = __webpack_require__(548); /** * Local dependencies */ -var compilers = __webpack_require__(664); -var parsers = __webpack_require__(675); +var compilers = __webpack_require__(677); +var parsers = __webpack_require__(688); /** * Customize Snapdragon parser and renderer @@ -81323,16 +84096,16 @@ module.exports = Extglob; /***/ }), -/* 679 */ +/* 692 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extglob = __webpack_require__(663); -var nanomatch = __webpack_require__(647); -var regexNot = __webpack_require__(534); -var toRegex = __webpack_require__(635); +var extglob = __webpack_require__(676); +var nanomatch = __webpack_require__(660); +var regexNot = __webpack_require__(547); +var toRegex = __webpack_require__(648); var not; /** @@ -81413,14 +84186,14 @@ function textRegex(pattern) { /***/ }), -/* 680 */ +/* 693 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(656))(); +module.exports = new (__webpack_require__(669))(); /***/ }), -/* 681 */ +/* 694 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81433,13 +84206,13 @@ var path = __webpack_require__(4); * Module dependencies */ -var Snapdragon = __webpack_require__(566); -utils.define = __webpack_require__(642); -utils.diff = __webpack_require__(660); -utils.extend = __webpack_require__(643); -utils.pick = __webpack_require__(661); -utils.typeOf = __webpack_require__(682); -utils.unique = __webpack_require__(537); +var Snapdragon = __webpack_require__(579); +utils.define = __webpack_require__(655); +utils.diff = __webpack_require__(673); +utils.extend = __webpack_require__(656); +utils.pick = __webpack_require__(674); +utils.typeOf = __webpack_require__(695); +utils.unique = __webpack_require__(550); /** * Returns true if the platform is windows, or `path.sep` is `\\`. @@ -81736,7 +84509,7 @@ utils.unixify = function(options) { /***/ }), -/* 682 */ +/* 695 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -81871,7 +84644,7 @@ function isBuffer(val) { /***/ }), -/* 683 */ +/* 696 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81890,9 +84663,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(684); -var reader_1 = __webpack_require__(697); -var fs_stream_1 = __webpack_require__(701); +var readdir = __webpack_require__(697); +var reader_1 = __webpack_require__(710); +var fs_stream_1 = __webpack_require__(714); var ReaderAsync = /** @class */ (function (_super) { __extends(ReaderAsync, _super); function ReaderAsync() { @@ -81953,15 +84726,15 @@ exports.default = ReaderAsync; /***/ }), -/* 684 */ +/* 697 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(685); -const readdirAsync = __webpack_require__(693); -const readdirStream = __webpack_require__(696); +const readdirSync = __webpack_require__(698); +const readdirAsync = __webpack_require__(706); +const readdirStream = __webpack_require__(709); module.exports = exports = readdirAsyncPath; exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath; @@ -82045,7 +84818,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 685 */ +/* 698 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82053,11 +84826,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(686); +const DirectoryReader = __webpack_require__(699); let syncFacade = { - fs: __webpack_require__(691), - forEach: __webpack_require__(692), + fs: __webpack_require__(704), + forEach: __webpack_require__(705), sync: true }; @@ -82086,18 +84859,18 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 686 */ +/* 699 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const Readable = __webpack_require__(136).Readable; -const EventEmitter = __webpack_require__(154).EventEmitter; +const Readable = __webpack_require__(137).Readable; +const EventEmitter = __webpack_require__(155).EventEmitter; const path = __webpack_require__(4); -const normalizeOptions = __webpack_require__(687); -const stat = __webpack_require__(689); -const call = __webpack_require__(690); +const normalizeOptions = __webpack_require__(700); +const stat = __webpack_require__(702); +const call = __webpack_require__(703); /** * Asynchronously reads the contents of a directory and streams the results @@ -82473,14 +85246,14 @@ module.exports = DirectoryReader; /***/ }), -/* 687 */ +/* 700 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const globToRegExp = __webpack_require__(688); +const globToRegExp = __webpack_require__(701); module.exports = normalizeOptions; @@ -82657,7 +85430,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 688 */ +/* 701 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -82794,13 +85567,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 689 */ +/* 702 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(690); +const call = __webpack_require__(703); module.exports = stat; @@ -82875,7 +85648,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 690 */ +/* 703 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82936,14 +85709,14 @@ function callOnce (fn) { /***/ }), -/* 691 */ +/* 704 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(132); -const call = __webpack_require__(690); +const fs = __webpack_require__(133); +const call = __webpack_require__(703); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -83007,7 +85780,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 692 */ +/* 705 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83036,7 +85809,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 693 */ +/* 706 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83044,12 +85817,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(694); -const DirectoryReader = __webpack_require__(686); +const maybe = __webpack_require__(707); +const DirectoryReader = __webpack_require__(699); let asyncFacade = { - fs: __webpack_require__(132), - forEach: __webpack_require__(695), + fs: __webpack_require__(133), + forEach: __webpack_require__(708), async: true }; @@ -83091,7 +85864,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 694 */ +/* 707 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83118,7 +85891,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 695 */ +/* 708 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83154,7 +85927,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 696 */ +/* 709 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83162,11 +85935,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(686); +const DirectoryReader = __webpack_require__(699); let streamFacade = { - fs: __webpack_require__(132), - forEach: __webpack_require__(695), + fs: __webpack_require__(133), + forEach: __webpack_require__(708), async: true }; @@ -83186,16 +85959,16 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 697 */ +/* 710 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var deep_1 = __webpack_require__(698); -var entry_1 = __webpack_require__(700); -var pathUtil = __webpack_require__(699); +var deep_1 = __webpack_require__(711); +var entry_1 = __webpack_require__(713); +var pathUtil = __webpack_require__(712); var Reader = /** @class */ (function () { function Reader(options) { this.options = options; @@ -83261,14 +86034,14 @@ exports.default = Reader; /***/ }), -/* 698 */ +/* 711 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(699); -var patternUtils = __webpack_require__(516); +var pathUtils = __webpack_require__(712); +var patternUtils = __webpack_require__(529); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { this.options = options; @@ -83351,7 +86124,7 @@ exports.default = DeepFilter; /***/ }), -/* 699 */ +/* 712 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83382,14 +86155,14 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 700 */ +/* 713 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(699); -var patternUtils = __webpack_require__(516); +var pathUtils = __webpack_require__(712); +var patternUtils = __webpack_require__(529); var EntryFilter = /** @class */ (function () { function EntryFilter(options, micromatchOptions) { this.options = options; @@ -83474,7 +86247,7 @@ exports.default = EntryFilter; /***/ }), -/* 701 */ +/* 714 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83493,9 +86266,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var stream = __webpack_require__(136); -var fsStat = __webpack_require__(702); -var fs_1 = __webpack_require__(706); +var stream = __webpack_require__(137); +var fsStat = __webpack_require__(715); +var fs_1 = __webpack_require__(719); var FileSystemStream = /** @class */ (function (_super) { __extends(FileSystemStream, _super); function FileSystemStream() { @@ -83545,14 +86318,14 @@ exports.default = FileSystemStream; /***/ }), -/* 702 */ +/* 715 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const optionsManager = __webpack_require__(703); -const statProvider = __webpack_require__(705); +const optionsManager = __webpack_require__(716); +const statProvider = __webpack_require__(718); /** * Asynchronous API. */ @@ -83583,13 +86356,13 @@ exports.statSync = statSync; /***/ }), -/* 703 */ +/* 716 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsAdapter = __webpack_require__(704); +const fsAdapter = __webpack_require__(717); function prepare(opts) { const options = Object.assign({ fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined), @@ -83602,13 +86375,13 @@ exports.prepare = prepare; /***/ }), -/* 704 */ +/* 717 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(132); +const fs = __webpack_require__(133); exports.FILE_SYSTEM_ADAPTER = { lstat: fs.lstat, stat: fs.stat, @@ -83625,7 +86398,7 @@ exports.getFileSystemAdapter = getFileSystemAdapter; /***/ }), -/* 705 */ +/* 718 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83677,7 +86450,7 @@ exports.isFollowedSymlink = isFollowedSymlink; /***/ }), -/* 706 */ +/* 719 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83708,7 +86481,7 @@ exports.default = FileSystem; /***/ }), -/* 707 */ +/* 720 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83727,10 +86500,10 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var stream = __webpack_require__(136); -var readdir = __webpack_require__(684); -var reader_1 = __webpack_require__(697); -var fs_stream_1 = __webpack_require__(701); +var stream = __webpack_require__(137); +var readdir = __webpack_require__(697); +var reader_1 = __webpack_require__(710); +var fs_stream_1 = __webpack_require__(714); var TransformStream = /** @class */ (function (_super) { __extends(TransformStream, _super); function TransformStream(reader) { @@ -83798,7 +86571,7 @@ exports.default = ReaderStream; /***/ }), -/* 708 */ +/* 721 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83817,9 +86590,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(684); -var reader_1 = __webpack_require__(697); -var fs_sync_1 = __webpack_require__(709); +var readdir = __webpack_require__(697); +var reader_1 = __webpack_require__(710); +var fs_sync_1 = __webpack_require__(722); var ReaderSync = /** @class */ (function (_super) { __extends(ReaderSync, _super); function ReaderSync() { @@ -83879,7 +86652,7 @@ exports.default = ReaderSync; /***/ }), -/* 709 */ +/* 722 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83898,8 +86671,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var fsStat = __webpack_require__(702); -var fs_1 = __webpack_require__(706); +var fsStat = __webpack_require__(715); +var fs_1 = __webpack_require__(719); var FileSystemSync = /** @class */ (function (_super) { __extends(FileSystemSync, _super); function FileSystemSync() { @@ -83945,7 +86718,7 @@ exports.default = FileSystemSync; /***/ }), -/* 710 */ +/* 723 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83961,13 +86734,13 @@ exports.flatten = flatten; /***/ }), -/* 711 */ +/* 724 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var merge2 = __webpack_require__(284); +var merge2 = __webpack_require__(299); /** * Merge multiple streams and propagate their errors into one stream in parallel. */ @@ -83982,13 +86755,13 @@ exports.merge = merge; /***/ }), -/* 712 */ +/* 725 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const pathType = __webpack_require__(713); +const pathType = __webpack_require__(726); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -84054,13 +86827,13 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 713 */ +/* 726 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(132); -const pify = __webpack_require__(714); +const fs = __webpack_require__(133); +const pify = __webpack_require__(727); function type(fn, fn2, fp) { if (typeof fp !== 'string') { @@ -84103,7 +86876,7 @@ exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 714 */ +/* 727 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84194,17 +86967,17 @@ module.exports = (obj, opts) => { /***/ }), -/* 715 */ +/* 728 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(132); +const fs = __webpack_require__(133); const path = __webpack_require__(4); -const fastGlob = __webpack_require__(512); -const gitIgnore = __webpack_require__(716); -const pify = __webpack_require__(717); -const slash = __webpack_require__(718); +const fastGlob = __webpack_require__(525); +const gitIgnore = __webpack_require__(729); +const pify = __webpack_require__(730); +const slash = __webpack_require__(731); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -84302,7 +87075,7 @@ module.exports.sync = options => { /***/ }), -/* 716 */ +/* 729 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -84771,7 +87544,7 @@ module.exports = options => new IgnoreBase(options) /***/ }), -/* 717 */ +/* 730 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84846,7 +87619,7 @@ module.exports = (input, options) => { /***/ }), -/* 718 */ +/* 731 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84864,7 +87637,7 @@ module.exports = input => { /***/ }), -/* 719 */ +/* 732 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -84874,7 +87647,7 @@ module.exports = input => { * Released under the MIT License. */ -var isExtglob = __webpack_require__(300); +var isExtglob = __webpack_require__(315); var chars = { '{': '}', '(': ')', '[': ']'}; var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; @@ -84918,17 +87691,17 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 720 */ +/* 733 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const {constants: fsConstants} = __webpack_require__(132); -const pEvent = __webpack_require__(721); -const CpFileError = __webpack_require__(724); -const fs = __webpack_require__(728); -const ProgressEmitter = __webpack_require__(731); +const {constants: fsConstants} = __webpack_require__(133); +const pEvent = __webpack_require__(734); +const CpFileError = __webpack_require__(737); +const fs = __webpack_require__(741); +const ProgressEmitter = __webpack_require__(744); const cpFileAsync = async (source, destination, options, progressEmitter) => { let readError; @@ -85042,12 +87815,12 @@ module.exports.sync = (source, destination, options) => { /***/ }), -/* 721 */ +/* 734 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pTimeout = __webpack_require__(722); +const pTimeout = __webpack_require__(735); const symbolAsyncIterator = Symbol.asyncIterator || '@@asyncIterator'; @@ -85338,12 +88111,12 @@ module.exports.iterator = (emitter, event, options) => { /***/ }), -/* 722 */ +/* 735 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pFinally = __webpack_require__(723); +const pFinally = __webpack_require__(736); class TimeoutError extends Error { constructor(message) { @@ -85389,7 +88162,7 @@ module.exports.TimeoutError = TimeoutError; /***/ }), -/* 723 */ +/* 736 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85411,12 +88184,12 @@ module.exports = (promise, onFinally) => { /***/ }), -/* 724 */ +/* 737 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(725); +const NestedError = __webpack_require__(738); class CpFileError extends NestedError { constructor(message, nested) { @@ -85430,10 +88203,10 @@ module.exports = CpFileError; /***/ }), -/* 725 */ +/* 738 */ /***/ (function(module, exports, __webpack_require__) { -var inherits = __webpack_require__(726); +var inherits = __webpack_require__(739); var NestedError = function (message, nested) { this.nested = nested; @@ -85484,7 +88257,7 @@ module.exports = NestedError; /***/ }), -/* 726 */ +/* 739 */ /***/ (function(module, exports, __webpack_require__) { try { @@ -85492,12 +88265,12 @@ try { if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { - module.exports = __webpack_require__(727); + module.exports = __webpack_require__(740); } /***/ }), -/* 727 */ +/* 740 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -85526,16 +88299,16 @@ if (typeof Object.create === 'function') { /***/ }), -/* 728 */ +/* 741 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(131); -const makeDir = __webpack_require__(729); -const pEvent = __webpack_require__(721); -const CpFileError = __webpack_require__(724); +const fs = __webpack_require__(132); +const makeDir = __webpack_require__(742); +const pEvent = __webpack_require__(734); +const CpFileError = __webpack_require__(737); const stat = promisify(fs.stat); const lstat = promisify(fs.lstat); @@ -85632,15 +88405,15 @@ exports.copyFileSync = (source, destination, flags) => { /***/ }), -/* 729 */ +/* 742 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(132); +const fs = __webpack_require__(133); const path = __webpack_require__(4); const {promisify} = __webpack_require__(111); -const semver = __webpack_require__(730); +const semver = __webpack_require__(743); const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); @@ -85795,7 +88568,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 730 */ +/* 743 */ /***/ (function(module, exports) { exports = module.exports = SemVer @@ -87397,12 +90170,12 @@ function coerce (version, options) { /***/ }), -/* 731 */ +/* 744 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const EventEmitter = __webpack_require__(154); +const EventEmitter = __webpack_require__(155); const written = new WeakMap(); @@ -87438,7 +90211,7 @@ module.exports = ProgressEmitter; /***/ }), -/* 732 */ +/* 745 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87484,12 +90257,12 @@ exports.default = module.exports; /***/ }), -/* 733 */ +/* 746 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(734); +const NestedError = __webpack_require__(747); class CpyError extends NestedError { constructor(message, nested) { @@ -87503,7 +90276,7 @@ module.exports = CpyError; /***/ }), -/* 734 */ +/* 747 */ /***/ (function(module, exports, __webpack_require__) { var inherits = __webpack_require__(111).inherits; @@ -87559,14 +90332,14 @@ module.exports = NestedError; /***/ }), -/* 735 */ +/* 748 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return prepareExternalProjectDependencies; }); -/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(163); -/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(162); +/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(164); +/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(163); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with diff --git a/packages/kbn-pm/package.json b/packages/kbn-pm/package.json index 3e40bf40222e6..78fa48979c1b5 100644 --- a/packages/kbn-pm/package.json +++ b/packages/kbn-pm/package.json @@ -35,7 +35,7 @@ "@kbn/dev-utils": "1.0.0", "@yarnpkg/lockfile": "^1.1.0", "babel-loader": "^8.0.6", - "chalk": "^2.4.2", + "chalk": "^4.1.0", "cmd-shim": "^2.1.0", "cpy": "^8.0.0", "dedent": "^0.7.0", diff --git a/packages/kbn-test/package.json b/packages/kbn-test/package.json index 9482ea83cc257..f86bcfd2bb7b2 100644 --- a/packages/kbn-test/package.json +++ b/packages/kbn-test/package.json @@ -21,7 +21,7 @@ "diff": "^4.0.1" }, "dependencies": { - "chalk": "^2.4.2", + "chalk": "^4.1.0", "dedent": "^0.7.0", "del": "^5.1.0", "exit-hook": "^2.2.0", diff --git a/packages/kbn-ui-framework/package.json b/packages/kbn-ui-framework/package.json index a095d9ac2a77f..a2151ca3381bc 100644 --- a/packages/kbn-ui-framework/package.json +++ b/packages/kbn-ui-framework/package.json @@ -36,7 +36,7 @@ "@kbn/optimizer": "1.0.0", "babel-loader": "^8.0.6", "brace": "0.11.1", - "chalk": "^2.4.2", + "chalk": "^4.1.0", "chokidar": "3.2.1", "core-js": "^3.6.4", "css-loader": "^3.4.2", diff --git a/src/dev/typescript/exec_in_projects.ts b/src/dev/typescript/exec_in_projects.ts index 5197aa67c7268..92f71b9bb864a 100644 --- a/src/dev/typescript/exec_in_projects.ts +++ b/src/dev/typescript/exec_in_projects.ts @@ -43,7 +43,7 @@ export function execInProjects( // execute in the current working directory so that relative paths in errors // are relative from the right location cwd: process.cwd(), - env: chalk.enabled ? { FORCE_COLOR: 'true' } : {}, + env: chalk.level > 0 ? { FORCE_COLOR: 'true' } : {}, stdio: ['ignore', 'pipe', 'pipe'], preferLocal: true, }).catch((error) => { diff --git a/x-pack/package.json b/x-pack/package.json index 7533741391f8e..962233a3a3973 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -131,7 +131,7 @@ "base64-js": "^1.3.1", "base64url": "^3.0.1", "canvas": "^2.6.1", - "chalk": "^2.4.2", + "chalk": "^4.1.0", "chance": "1.0.18", "cheerio": "0.22.0", "commander": "3.0.2", diff --git a/yarn.lock b/yarn.lock index 6f82c8126ac06..101f735355f0b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9905,14 +9905,14 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.8.2, color-convert@^1.9.0: +color-convert@^1.8.2: version "1.9.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" integrity sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ== dependencies: color-name "^1.1.1" -color-convert@^1.9.1: +color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -28888,14 +28888,14 @@ supports-color@^3.1.2: dependencies: has-flag "^1.0.0" -supports-color@^5.0.0, supports-color@^5.4.0, supports-color@^5.5.0: +supports-color@^5.0.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" -supports-color@^5.2.0, supports-color@^5.3.0: +supports-color@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" integrity sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg== From 67025579ba6650154e5b565f6d8e2c6d35c8fec0 Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Tue, 11 Aug 2020 15:00:02 +0100 Subject: [PATCH 095/106] [Event log] Use Alerts client & Actions client when fetching these types of SOs (#73257) Introduces a pluggable API to Event Log which allows custom Providers for Saved Objects which is used to ensure a user is authorised to get the Saved Object referenced in the Event Log whenever the find api is called. --- x-pack/.i18nrc.json | 1 + x-pack/plugins/actions/server/plugin.ts | 7 ++ x-pack/plugins/alerts/server/plugin.ts | 7 ++ .../event_log/server/event_log_client.test.ts | 55 ++++++----- .../event_log/server/event_log_client.ts | 18 ++-- .../server/event_log_service.mock.ts | 1 + .../server/event_log_service.test.ts | 25 +++++ .../event_log/server/event_log_service.ts | 16 ++- .../server/event_log_start_service.test.ts | 11 +-- .../server/event_log_start_service.ts | 29 +++--- .../event_log/server/event_logger.test.ts | 2 + x-pack/plugins/event_log/server/plugin.ts | 11 ++- .../saved_object_provider_registry.mock.ts | 19 ++++ .../saved_object_provider_registry.test.ts | 98 +++++++++++++++++++ .../server/saved_object_provider_registry.ts | 68 +++++++++++++ x-pack/plugins/event_log/server/types.ts | 3 +- .../plugins/alerts/server/alert_types.ts | 4 +- .../fixtures/plugins/alerts/server/plugin.ts | 6 ++ 18 files changed, 319 insertions(+), 62 deletions(-) create mode 100644 x-pack/plugins/event_log/server/saved_object_provider_registry.mock.ts create mode 100644 x-pack/plugins/event_log/server/saved_object_provider_registry.test.ts create mode 100644 x-pack/plugins/event_log/server/saved_object_provider_registry.ts diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index d0055008eb9bf..69ad9ad33bf72 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -4,6 +4,7 @@ "xpack.actions": "plugins/actions", "xpack.uiActionsEnhanced": ["plugins/ui_actions_enhanced", "examples/ui_actions_enhanced_examples"], "xpack.alerts": "plugins/alerts", + "xpack.eventLog": "plugins/event_log", "xpack.alertingBuiltins": "plugins/alerting_builtins", "xpack.apm": ["legacy/plugins/apm", "plugins/apm"], "xpack.beatsManagement": ["legacy/plugins/beats_management", "plugins/beats_management"], diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index 54d137cc0f617..ee50ee81d507c 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -123,6 +123,7 @@ export class ActionsPlugin implements Plugin, Plugi private licenseState: ILicenseState | null = null; private spaces?: SpacesServiceSetup; private security?: SecurityPluginSetup; + private eventLogService?: IEventLogService; private eventLogger?: IEventLogger; private isESOUsingEphemeralEncryptionKey?: boolean; private readonly telemetryLogger: Logger; @@ -160,6 +161,7 @@ export class ActionsPlugin implements Plugin, Plugi plugins.features.registerFeature(ACTIONS_FEATURE); setupSavedObjects(core.savedObjects, plugins.encryptedSavedObjects); + this.eventLogService = plugins.eventLog; plugins.eventLog.registerProviderActions(EVENT_LOG_PROVIDER, Object.values(EVENT_LOG_ACTIONS)); this.eventLogger = plugins.eventLog.getLogger({ event: { provider: EVENT_LOG_PROVIDER }, @@ -295,6 +297,11 @@ export class ActionsPlugin implements Plugin, Plugi }); }; + this.eventLogService!.registerSavedObjectProvider('action', (request) => { + const client = getActionsClientWithRequest(request); + return async (type: string, id: string) => (await client).get({ id }); + }); + const getScopedSavedObjectsClientWithoutAccessToActions = (request: KibanaRequest) => core.savedObjects.getScopedClient(request); diff --git a/x-pack/plugins/alerts/server/plugin.ts b/x-pack/plugins/alerts/server/plugin.ts index 2f0df44197553..5d69887bd5bf0 100644 --- a/x-pack/plugins/alerts/server/plugin.ts +++ b/x-pack/plugins/alerts/server/plugin.ts @@ -106,6 +106,7 @@ export class AlertingPlugin { private readonly alertsClientFactory: AlertsClientFactory; private readonly telemetryLogger: Logger; private readonly kibanaIndex: Promise; + private eventLogService?: IEventLogService; private eventLogger?: IEventLogger; constructor(initializerContext: PluginInitializerContext) { @@ -150,6 +151,7 @@ export class AlertingPlugin { setupSavedObjects(core.savedObjects, plugins.encryptedSavedObjects); + this.eventLogService = plugins.eventLog; plugins.eventLog.registerProviderActions(EVENT_LOG_PROVIDER, Object.values(EVENT_LOG_ACTIONS)); this.eventLogger = plugins.eventLog.getLogger({ event: { provider: EVENT_LOG_PROVIDER }, @@ -255,6 +257,11 @@ export class AlertingPlugin { eventLogger: this.eventLogger!, }); + this.eventLogService!.registerSavedObjectProvider('alert', (request) => { + const client = getAlertsClientWithRequest(request); + return (type: string, id: string) => client.get({ id }); + }); + scheduleAlertingTelemetry(this.telemetryLogger, plugins.taskManager); return { diff --git a/x-pack/plugins/event_log/server/event_log_client.test.ts b/x-pack/plugins/event_log/server/event_log_client.test.ts index 917d517a6e27d..3273fe847080f 100644 --- a/x-pack/plugins/event_log/server/event_log_client.test.ts +++ b/x-pack/plugins/event_log/server/event_log_client.test.ts @@ -7,7 +7,6 @@ import { KibanaRequest } from 'src/core/server'; import { EventLogClient } from './event_log_client'; import { contextMock } from './es/context.mock'; -import { savedObjectsClientMock } from 'src/core/server/mocks'; import { merge } from 'lodash'; import moment from 'moment'; @@ -15,14 +14,15 @@ describe('EventLogStart', () => { describe('findEventsBySavedObject', () => { test('verifies that the user can access the specified saved object', async () => { const esContext = contextMock.create(); - const savedObjectsClient = savedObjectsClientMock.create(); + const savedObjectGetter = jest.fn(); + const eventLogClient = new EventLogClient({ esContext, - savedObjectsClient, + savedObjectGetter, request: FakeRequest(), }); - savedObjectsClient.get.mockResolvedValueOnce({ + savedObjectGetter.mockResolvedValueOnce({ id: 'saved-object-id', type: 'saved-object-type', attributes: {}, @@ -31,19 +31,21 @@ describe('EventLogStart', () => { await eventLogClient.findEventsBySavedObject('saved-object-type', 'saved-object-id'); - expect(savedObjectsClient.get).toHaveBeenCalledWith('saved-object-type', 'saved-object-id'); + expect(savedObjectGetter).toHaveBeenCalledWith('saved-object-type', 'saved-object-id'); }); test('throws when the user doesnt have permission to access the specified saved object', async () => { const esContext = contextMock.create(); - const savedObjectsClient = savedObjectsClientMock.create(); + + const savedObjectGetter = jest.fn(); + const eventLogClient = new EventLogClient({ esContext, - savedObjectsClient, + savedObjectGetter, request: FakeRequest(), }); - savedObjectsClient.get.mockRejectedValue(new Error('Fail')); + savedObjectGetter.mockRejectedValue(new Error('Fail')); expect( eventLogClient.findEventsBySavedObject('saved-object-type', 'saved-object-id') @@ -52,14 +54,16 @@ describe('EventLogStart', () => { test('fetches all event that reference the saved object', async () => { const esContext = contextMock.create(); - const savedObjectsClient = savedObjectsClientMock.create(); + + const savedObjectGetter = jest.fn(); + const eventLogClient = new EventLogClient({ esContext, - savedObjectsClient, + savedObjectGetter, request: FakeRequest(), }); - savedObjectsClient.get.mockResolvedValueOnce({ + savedObjectGetter.mockResolvedValueOnce({ id: 'saved-object-id', type: 'saved-object-type', attributes: {}, @@ -125,14 +129,16 @@ describe('EventLogStart', () => { test('fetches all events in time frame that reference the saved object', async () => { const esContext = contextMock.create(); - const savedObjectsClient = savedObjectsClientMock.create(); + + const savedObjectGetter = jest.fn(); + const eventLogClient = new EventLogClient({ esContext, - savedObjectsClient, + savedObjectGetter, request: FakeRequest(), }); - savedObjectsClient.get.mockResolvedValueOnce({ + savedObjectGetter.mockResolvedValueOnce({ id: 'saved-object-id', type: 'saved-object-type', attributes: {}, @@ -206,14 +212,16 @@ describe('EventLogStart', () => { test('validates that the start date is valid', async () => { const esContext = contextMock.create(); - const savedObjectsClient = savedObjectsClientMock.create(); + + const savedObjectGetter = jest.fn(); + const eventLogClient = new EventLogClient({ esContext, - savedObjectsClient, + savedObjectGetter, request: FakeRequest(), }); - savedObjectsClient.get.mockResolvedValueOnce({ + savedObjectGetter.mockResolvedValueOnce({ id: 'saved-object-id', type: 'saved-object-type', attributes: {}, @@ -236,14 +244,16 @@ describe('EventLogStart', () => { test('validates that the end date is valid', async () => { const esContext = contextMock.create(); - const savedObjectsClient = savedObjectsClientMock.create(); + + const savedObjectGetter = jest.fn(); + const eventLogClient = new EventLogClient({ esContext, - savedObjectsClient, + savedObjectGetter, request: FakeRequest(), }); - savedObjectsClient.get.mockResolvedValueOnce({ + savedObjectGetter.mockResolvedValueOnce({ id: 'saved-object-id', type: 'saved-object-type', attributes: {}, @@ -297,7 +307,8 @@ function fakeEvent(overrides = {}) { } function FakeRequest(): KibanaRequest { - const savedObjectsClient = savedObjectsClientMock.create(); + const savedObjectGetter = jest.fn(); + return ({ headers: {}, getBasePath: () => '', @@ -311,6 +322,6 @@ function FakeRequest(): KibanaRequest { url: '/', }, }, - getSavedObjectsClient: () => savedObjectsClient, + getSavedObjectsClient: () => savedObjectGetter, } as unknown) as KibanaRequest; } diff --git a/x-pack/plugins/event_log/server/event_log_client.ts b/x-pack/plugins/event_log/server/event_log_client.ts index f4115e06160d7..32fd99d170026 100644 --- a/x-pack/plugins/event_log/server/event_log_client.ts +++ b/x-pack/plugins/event_log/server/event_log_client.ts @@ -6,12 +6,13 @@ import { Observable } from 'rxjs'; import { schema, TypeOf } from '@kbn/config-schema'; -import { LegacyClusterClient, SavedObjectsClientContract, KibanaRequest } from 'src/core/server'; +import { LegacyClusterClient, KibanaRequest } from 'src/core/server'; import { SpacesServiceSetup } from '../../spaces/server'; import { EsContext } from './es'; import { IEventLogClient } from './types'; import { QueryEventsBySavedObjectResult } from './es/cluster_client_adapter'; +import { SavedObjectGetter } from './saved_object_provider_registry'; export type PluginClusterClient = Pick; export type AdminClusterClient$ = Observable; @@ -58,7 +59,7 @@ export type FindOptionsType = Pick< interface EventLogServiceCtorParams { esContext: EsContext; - savedObjectsClient: SavedObjectsClientContract; + savedObjectGetter: SavedObjectGetter; spacesService?: SpacesServiceSetup; request: KibanaRequest; } @@ -66,18 +67,13 @@ interface EventLogServiceCtorParams { // note that clusterClient may be null, indicating we can't write to ES export class EventLogClient implements IEventLogClient { private esContext: EsContext; - private savedObjectsClient: SavedObjectsClientContract; + private savedObjectGetter: SavedObjectGetter; private spacesService?: SpacesServiceSetup; private request: KibanaRequest; - constructor({ - esContext, - savedObjectsClient, - spacesService, - request, - }: EventLogServiceCtorParams) { + constructor({ esContext, savedObjectGetter, spacesService, request }: EventLogServiceCtorParams) { this.esContext = esContext; - this.savedObjectsClient = savedObjectsClient; + this.savedObjectGetter = savedObjectGetter; this.spacesService = spacesService; this.request = request; } @@ -93,7 +89,7 @@ export class EventLogClient implements IEventLogClient { const namespace = space && this.spacesService?.spaceIdToNamespace(space.id); // verify the user has the required permissions to view this saved object - await this.savedObjectsClient.get(type, id); + await this.savedObjectGetter(type, id); return await this.esContext.esAdapter.queryEventsBySavedObject( this.esContext.esNames.alias, diff --git a/x-pack/plugins/event_log/server/event_log_service.mock.ts b/x-pack/plugins/event_log/server/event_log_service.mock.ts index 805c241414a2e..877e5d59a1831 100644 --- a/x-pack/plugins/event_log/server/event_log_service.mock.ts +++ b/x-pack/plugins/event_log/server/event_log_service.mock.ts @@ -15,6 +15,7 @@ const createEventLogServiceMock = () => { registerProviderActions: jest.fn(), isProviderActionRegistered: jest.fn(), getProviderActions: jest.fn(), + registerSavedObjectProvider: jest.fn(), getLogger: jest.fn().mockReturnValue(eventLoggerMock.create()), }; return mock; diff --git a/x-pack/plugins/event_log/server/event_log_service.test.ts b/x-pack/plugins/event_log/server/event_log_service.test.ts index 2cf68592f2fa1..2b92443569f4f 100644 --- a/x-pack/plugins/event_log/server/event_log_service.test.ts +++ b/x-pack/plugins/event_log/server/event_log_service.test.ts @@ -8,9 +8,11 @@ import { IEventLogConfig } from './types'; import { EventLogService } from './event_log_service'; import { contextMock } from './es/context.mock'; import { loggingSystemMock } from 'src/core/server/mocks'; +import { savedObjectProviderRegistryMock } from './saved_object_provider_registry.mock'; const loggingService = loggingSystemMock.create(); const systemLogger = loggingService.get(); +const savedObjectProviderRegistry = savedObjectProviderRegistryMock.create(); describe('EventLogService', () => { const esContext = contextMock.create(); @@ -21,6 +23,7 @@ describe('EventLogService', () => { esContext, systemLogger, kibanaUUID: '42', + savedObjectProviderRegistry, config: { enabled, logEntries, @@ -65,6 +68,7 @@ describe('EventLogService', () => { esContext, systemLogger, kibanaUUID: '42', + savedObjectProviderRegistry, config: { enabled: true, logEntries: true, @@ -102,6 +106,7 @@ describe('EventLogService', () => { esContext, systemLogger, kibanaUUID: '42', + savedObjectProviderRegistry, config: { enabled: true, logEntries: true, @@ -112,4 +117,24 @@ describe('EventLogService', () => { const eventLogger = service.getLogger({}); expect(eventLogger).toBeTruthy(); }); + + describe('registerSavedObjectProvider', () => { + test('register SavedObject Providers in the registry', () => { + const params = { + esContext, + systemLogger, + kibanaUUID: '42', + savedObjectProviderRegistry, + config: { + enabled: true, + logEntries: true, + indexEntries: true, + }, + }; + const service = new EventLogService(params); + const provider = jest.fn(); + service.registerSavedObjectProvider('myType', provider); + expect(savedObjectProviderRegistry.registerProvider).toHaveBeenCalledWith('myType', provider); + }); + }); }); diff --git a/x-pack/plugins/event_log/server/event_log_service.ts b/x-pack/plugins/event_log/server/event_log_service.ts index f7f915f1cf0ef..9249288d33939 100644 --- a/x-pack/plugins/event_log/server/event_log_service.ts +++ b/x-pack/plugins/event_log/server/event_log_service.ts @@ -11,6 +11,7 @@ import { Plugin } from './plugin'; import { EsContext } from './es'; import { IEvent, IEventLogger, IEventLogService, IEventLogConfig } from './types'; import { EventLogger } from './event_logger'; +import { SavedObjectProvider, SavedObjectProviderRegistry } from './saved_object_provider_registry'; export type PluginClusterClient = Pick; export type AdminClusterClient$ = Observable; @@ -21,6 +22,7 @@ interface EventLogServiceCtorParams { esContext: EsContext; kibanaUUID: string; systemLogger: SystemLogger; + savedObjectProviderRegistry: SavedObjectProviderRegistry; } // note that clusterClient may be null, indicating we can't write to ES @@ -29,15 +31,23 @@ export class EventLogService implements IEventLogService { private esContext: EsContext; private systemLogger: SystemLogger; private registeredProviderActions: Map>; + private savedObjectProviderRegistry: SavedObjectProviderRegistry; public readonly kibanaUUID: string; - constructor({ config, esContext, kibanaUUID, systemLogger }: EventLogServiceCtorParams) { + constructor({ + config, + esContext, + kibanaUUID, + systemLogger, + savedObjectProviderRegistry, + }: EventLogServiceCtorParams) { this.config = config; this.esContext = esContext; this.kibanaUUID = kibanaUUID; this.systemLogger = systemLogger; this.registeredProviderActions = new Map>(); + this.savedObjectProviderRegistry = savedObjectProviderRegistry; } public isEnabled(): boolean { @@ -77,6 +87,10 @@ export class EventLogService implements IEventLogService { return new Map(this.registeredProviderActions.entries()); } + registerSavedObjectProvider(type: string, provider: SavedObjectProvider) { + return this.savedObjectProviderRegistry.registerProvider(type, provider); + } + getLogger(initialProperties: IEvent): IEventLogger { return new EventLogger({ esContext: this.esContext, diff --git a/x-pack/plugins/event_log/server/event_log_start_service.test.ts b/x-pack/plugins/event_log/server/event_log_start_service.test.ts index 3bd5ef7c0b3ba..cbdc168a8ffde 100644 --- a/x-pack/plugins/event_log/server/event_log_start_service.test.ts +++ b/x-pack/plugins/event_log/server/event_log_start_service.test.ts @@ -5,10 +5,11 @@ */ import { KibanaRequest } from 'src/core/server'; -import { savedObjectsClientMock, savedObjectsServiceMock } from 'src/core/server/mocks'; +import { savedObjectsClientMock } from 'src/core/server/mocks'; import { EventLogClientService } from './event_log_start_service'; import { contextMock } from './es/context.mock'; +import { savedObjectProviderRegistryMock } from './saved_object_provider_registry.mock'; jest.mock('./event_log_client'); @@ -17,19 +18,17 @@ describe('EventLogClientService', () => { describe('getClient', () => { test('creates a client with a scoped SavedObjects client', () => { - const savedObjectsService = savedObjectsServiceMock.createStartContract(); + const savedObjectProviderRegistry = savedObjectProviderRegistryMock.create(); const request = fakeRequest(); const eventLogStartService = new EventLogClientService({ esContext, - savedObjectsService, + savedObjectProviderRegistry, }); eventLogStartService.getClient(request); - expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { - includedHiddenTypes: ['action', 'alert'], - }); + expect(savedObjectProviderRegistry.getProvidersClient).toHaveBeenCalledWith(request); }); }); }); diff --git a/x-pack/plugins/event_log/server/event_log_start_service.ts b/x-pack/plugins/event_log/server/event_log_start_service.ts index 8b752684c1cc3..5cadab4df3ed7 100644 --- a/x-pack/plugins/event_log/server/event_log_start_service.ts +++ b/x-pack/plugins/event_log/server/event_log_start_service.ts @@ -5,49 +5,42 @@ */ import { Observable } from 'rxjs'; -import { - LegacyClusterClient, - KibanaRequest, - SavedObjectsServiceStart, - SavedObjectsClientContract, -} from 'src/core/server'; +import { LegacyClusterClient, KibanaRequest } from 'src/core/server'; import { SpacesServiceSetup } from '../../spaces/server'; import { EsContext } from './es'; import { IEventLogClientService } from './types'; import { EventLogClient } from './event_log_client'; +import { SavedObjectProviderRegistry } from './saved_object_provider_registry'; export type PluginClusterClient = Pick; export type AdminClusterClient$ = Observable; -const includedHiddenTypes = ['action', 'alert']; - interface EventLogServiceCtorParams { esContext: EsContext; - savedObjectsService: SavedObjectsServiceStart; + savedObjectProviderRegistry: SavedObjectProviderRegistry; spacesService?: SpacesServiceSetup; } // note that clusterClient may be null, indicating we can't write to ES export class EventLogClientService implements IEventLogClientService { private esContext: EsContext; - private savedObjectsService: SavedObjectsServiceStart; + private savedObjectProviderRegistry: SavedObjectProviderRegistry; private spacesService?: SpacesServiceSetup; - constructor({ esContext, savedObjectsService, spacesService }: EventLogServiceCtorParams) { + constructor({ + esContext, + savedObjectProviderRegistry, + spacesService, + }: EventLogServiceCtorParams) { this.esContext = esContext; - this.savedObjectsService = savedObjectsService; + this.savedObjectProviderRegistry = savedObjectProviderRegistry; this.spacesService = spacesService; } getClient(request: KibanaRequest) { - const savedObjectsClient: SavedObjectsClientContract = this.savedObjectsService.getScopedClient( - request, - { includedHiddenTypes } - ); - return new EventLogClient({ esContext: this.esContext, - savedObjectsClient, + savedObjectGetter: this.savedObjectProviderRegistry.getProvidersClient(request), spacesService: this.spacesService, request, }); diff --git a/x-pack/plugins/event_log/server/event_logger.test.ts b/x-pack/plugins/event_log/server/event_logger.test.ts index fde3b2de8dd36..0ab3071f70efa 100644 --- a/x-pack/plugins/event_log/server/event_logger.test.ts +++ b/x-pack/plugins/event_log/server/event_logger.test.ts @@ -12,6 +12,7 @@ import { contextMock } from './es/context.mock'; import { loggingSystemMock } from 'src/core/server/mocks'; import { delay } from './lib/delay'; import { EVENT_LOGGED_PREFIX } from './event_logger'; +import { savedObjectProviderRegistryMock } from './saved_object_provider_registry.mock'; const KIBANA_SERVER_UUID = '424-24-2424'; const WRITE_LOG_WAIT_MILLIS = 3000; @@ -31,6 +32,7 @@ describe('EventLogger', () => { systemLogger, config: { enabled: true, logEntries: true, indexEntries: true }, kibanaUUID: KIBANA_SERVER_UUID, + savedObjectProviderRegistry: savedObjectProviderRegistryMock.create(), }); eventLogger = service.getLogger({}); }); diff --git a/x-pack/plugins/event_log/server/plugin.ts b/x-pack/plugins/event_log/server/plugin.ts index 9e36ca10b71f2..1353877fa4629 100644 --- a/x-pack/plugins/event_log/server/plugin.ts +++ b/x-pack/plugins/event_log/server/plugin.ts @@ -30,6 +30,7 @@ import { findRoute } from './routes'; import { EventLogService } from './event_log_service'; import { createEsContext, EsContext } from './es'; import { EventLogClientService } from './event_log_start_service'; +import { SavedObjectProviderRegistry } from './saved_object_provider_registry'; export type PluginClusterClient = Pick; @@ -53,11 +54,13 @@ export class Plugin implements CorePlugin; private eventLogClientService?: EventLogClientService; private spacesService?: SpacesServiceSetup; + private savedObjectProviderRegistry: SavedObjectProviderRegistry; constructor(private readonly context: PluginInitializerContext) { this.systemLogger = this.context.logger.get(); this.config$ = this.context.config.create(); this.globalConfig$ = this.context.config.legacy.globalConfig$; + this.savedObjectProviderRegistry = new SavedObjectProviderRegistry(); } async setup(core: CoreSetup, { spaces }: PluginSetupDeps): Promise { @@ -83,6 +86,7 @@ export class Plugin implements CorePlugin { + const client = core.savedObjects.getScopedClient(request); + return client.get.bind(client); + }); + this.eventLogClientService = new EventLogClientService({ esContext: this.esContext, - savedObjectsService: core.savedObjects, + savedObjectProviderRegistry: this.savedObjectProviderRegistry, spacesService: this.spacesService, }); return this.eventLogClientService; diff --git a/x-pack/plugins/event_log/server/saved_object_provider_registry.mock.ts b/x-pack/plugins/event_log/server/saved_object_provider_registry.mock.ts new file mode 100644 index 0000000000000..433deaf7bff72 --- /dev/null +++ b/x-pack/plugins/event_log/server/saved_object_provider_registry.mock.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SavedObjectProviderRegistry } from './saved_object_provider_registry'; + +const createSavedObjectProviderRegistryMock = () => { + return ({ + registerProvider: jest.fn(), + registerDefaultProvider: jest.fn(), + getProvidersClient: jest.fn(), + } as unknown) as jest.Mocked; +}; + +export const savedObjectProviderRegistryMock = { + create: createSavedObjectProviderRegistryMock, +}; diff --git a/x-pack/plugins/event_log/server/saved_object_provider_registry.test.ts b/x-pack/plugins/event_log/server/saved_object_provider_registry.test.ts new file mode 100644 index 0000000000000..6a02d54c87514 --- /dev/null +++ b/x-pack/plugins/event_log/server/saved_object_provider_registry.test.ts @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SavedObjectProviderRegistry } from './saved_object_provider_registry'; +import uuid from 'uuid'; +import { KibanaRequest } from 'src/core/server'; +import { savedObjectsClientMock } from 'src/core/server/mocks'; + +describe('SavedObjectProviderRegistry', () => { + beforeEach(() => jest.resetAllMocks()); + + describe('registerProvider()', () => { + test('should register providers', () => { + const registry = new SavedObjectProviderRegistry(); + registry.registerProvider('alert', jest.fn()); + }); + + test('should throw an error if type is already registered', () => { + const registry = new SavedObjectProviderRegistry(); + registry.registerProvider('alert', jest.fn()); + expect(() => + registry.registerProvider('alert', jest.fn()) + ).toThrowErrorMatchingInlineSnapshot( + `"The Event Log has already registered a Provider for the Save Object type \\"alert\\"."` + ); + }); + }); + + describe('getProvidersClient()', () => { + test('should get SavedObject using the registered provider by type', async () => { + const registry = new SavedObjectProviderRegistry(); + registry.registerDefaultProvider(jest.fn()); + + const getter = jest.fn(); + const provider = jest.fn().mockReturnValue(getter); + registry.registerProvider('alert', provider); + + const request = fakeRequest(); + const alert = { + id: uuid.v4(), + }; + + getter.mockResolvedValue(alert); + + expect(await registry.getProvidersClient(request)('alert', alert.id)).toMatchObject(alert); + + expect(provider).toHaveBeenCalledWith(request); + expect(getter).toHaveBeenCalledWith('alert', alert.id); + }); + + test('should get SavedObject using the default provider for unregistered types', async () => { + const registry = new SavedObjectProviderRegistry(); + const defaultProvider = jest.fn(); + registry.registerDefaultProvider(defaultProvider); + + registry.registerProvider('alert', jest.fn().mockReturnValue(jest.fn())); + + const request = fakeRequest(); + const action = { + id: uuid.v4(), + type: 'action', + attributes: {}, + references: [], + }; + + const getter = jest.fn(); + defaultProvider.mockReturnValue(getter); + getter.mockResolvedValue(action); + + expect(await registry.getProvidersClient(request)('action', action.id)).toMatchObject(action); + + expect(getter).toHaveBeenCalledWith('action', action.id); + expect(defaultProvider).toHaveBeenCalledWith(request); + }); + }); +}); + +function fakeRequest(): KibanaRequest { + const savedObjectsClient = savedObjectsClientMock.create(); + return ({ + headers: {}, + getBasePath: () => '', + path: '/', + route: { settings: {} }, + url: { + href: '/', + }, + raw: { + req: { + url: '/', + }, + }, + getSavedObjectsClient: () => savedObjectsClient, + } as unknown) as KibanaRequest; +} diff --git a/x-pack/plugins/event_log/server/saved_object_provider_registry.ts b/x-pack/plugins/event_log/server/saved_object_provider_registry.ts new file mode 100644 index 0000000000000..87a1da5dd6f4a --- /dev/null +++ b/x-pack/plugins/event_log/server/saved_object_provider_registry.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { KibanaRequest, SavedObjectsClientContract } from 'src/core/server'; + +import { fromNullable, getOrElse } from 'fp-ts/lib/Option'; +import { pipe } from 'fp-ts/lib/pipeable'; + +export type SavedObjectGetter = ( + ...params: Parameters +) => Promise; +export type SavedObjectProvider = (request: KibanaRequest) => SavedObjectGetter; + +export class SavedObjectProviderRegistry { + private providers = new Map(); + private defaultProvider?: SavedObjectProvider; + + constructor() {} + + public registerDefaultProvider(provider: SavedObjectProvider) { + this.defaultProvider = provider; + } + + public registerProvider(type: string, provider: SavedObjectProvider) { + if (this.providers.has(type)) { + throw new Error( + `The Event Log has already registered a Provider for the Save Object type "${type}".` + ); + } + this.providers.set(type, provider); + } + + public getProvidersClient(request: KibanaRequest): SavedObjectGetter { + if (!this.defaultProvider) { + throw new Error( + i18n.translate( + 'xpack.eventLog.savedObjectProviderRegistry.getProvidersClient.noDefaultProvider', + { + defaultMessage: 'The Event Log requires a default Provider.', + } + ) + ); + } + + // `scopedProviders` is a cache of providers which are scoped t othe current request. + // The client will only instantiate a provider on-demand and it will cache each + // one to enable the request to reuse each provider. + const scopedProviders = new Map(); + const defaultGetter = this.defaultProvider(request); + return (type: string, id: string) => { + const getter = pipe( + fromNullable(scopedProviders.get(type)), + getOrElse(() => { + const client = this.providers.has(type) + ? this.providers.get(type)!(request) + : defaultGetter; + scopedProviders.set(type, client); + return client; + }) + ); + return getter(type, id); + }; + } +} diff --git a/x-pack/plugins/event_log/server/types.ts b/x-pack/plugins/event_log/server/types.ts index 1a37c4e58d079..cda9579220623 100644 --- a/x-pack/plugins/event_log/server/types.ts +++ b/x-pack/plugins/event_log/server/types.ts @@ -12,6 +12,7 @@ export { IEvent, IValidatedEvent, EventSchema, ECS_VERSION } from '../generated/ import { IEvent } from '../generated/schemas'; import { FindOptionsType } from './event_log_client'; import { QueryEventsBySavedObjectResult } from './es/cluster_client_adapter'; +import { SavedObjectProvider } from './saved_object_provider_registry'; export const SAVED_OBJECT_REL_PRIMARY = 'primary'; @@ -40,7 +41,7 @@ export interface IEventLogService { registerProviderActions(provider: string, actions: string[]): void; isProviderActionRegistered(provider: string, action: string): boolean; getProviderActions(): Map>; - + registerSavedObjectProvider(type: string, provider: SavedObjectProvider): void; getLogger(properties: IEvent): IEventLogger; } diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/alert_types.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/alert_types.ts index ebf639067518f..269a9d3a504a2 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/alert_types.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/alert_types.ts @@ -296,7 +296,7 @@ export function defineAlertTypes( name: 'Default', }, ], - producer: 'alerting', + producer: 'alertsFixture', defaultActionGroupId: 'default', async executor({ services, params, state }: AlertExecutorOptions) { throw new Error('this alert is intended to fail'); @@ -306,7 +306,7 @@ export function defineAlertTypes( id: 'test.patternFiring', name: 'Test: Firing on a Pattern', actionGroups: [{ id: 'default', name: 'Default' }], - producer: 'alerting', + producer: 'alertsFixture', defaultActionGroupId: 'default', async executor(alertExecutorOptions: AlertExecutorOptions) { const { services, state, params } = alertExecutorOptions; diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/plugin.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/plugin.ts index 5881201a82e09..1b8a380eaaeb2 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/plugin.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/plugin.ts @@ -40,6 +40,8 @@ export class FixturePlugin implements Plugin Date: Tue, 11 Aug 2020 10:03:41 -0400 Subject: [PATCH 096/106] [Ingest pipelines] Implement tabs in processor flyout (#74469) --- .../pipeline_processors_editor.test.tsx | 2 +- .../components/index.ts | 6 +- .../documentation_button.tsx | 0 .../field_components/index.ts | 0 .../field_components/xjson_editor.tsx | 0 .../index.ts | 6 +- .../manage_processor_form.container.tsx} | 8 +- .../manage_processor_form.tsx} | 122 +++++++++++------- .../processor_settings_fields.tsx | 52 ++++++++ .../common_fields/common_processor_fields.tsx | 0 .../processors/common_fields/index.ts | 0 .../common_fields/processor_type_field.tsx | 0 .../processors/custom.tsx | 0 .../processors/gsub.tsx | 0 .../processors/set.tsx | 0 .../pipeline_processors_editor_item.tsx | 43 +++--- .../context/processors_context.tsx | 10 +- .../pipeline_processors_editor/types.ts | 2 +- .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - 20 files changed, 159 insertions(+), 98 deletions(-) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => manage_processor_form}/documentation_button.tsx (100%) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => manage_processor_form}/field_components/index.ts (100%) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => manage_processor_form}/field_components/xjson_editor.tsx (100%) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => manage_processor_form}/index.ts (71%) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form/processor_settings_form.container.tsx => manage_processor_form/manage_processor_form.container.tsx} (85%) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form/processor_settings_form.tsx => manage_processor_form/manage_processor_form.tsx} (60%) create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => manage_processor_form}/processors/common_fields/common_processor_fields.tsx (100%) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => manage_processor_form}/processors/common_fields/index.ts (100%) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => manage_processor_form}/processors/common_fields/processor_type_field.tsx (100%) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => manage_processor_form}/processors/custom.tsx (100%) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => manage_processor_form}/processors/gsub.tsx (100%) rename x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/{processor_settings_form => manage_processor_form}/processors/set.tsx (100%) diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx index a45a677846b2e..d3c5df02c837e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx @@ -186,7 +186,7 @@ describe('Pipeline Editor', () => { it('prevents moving a processor while in edit mode', () => { const { find, exists } = testBed; - find('processors>0.editItemButton').simulate('click'); + find('processors>0.manageItemButton').simulate('click'); expect(exists('processorSettingsForm')).toBe(true); expect(find('processors>0.moveItemButton').props().disabled).toBe(true); expect(find('processors>1.moveItemButton').props().disabled).toBe(true); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts index bf724be950fdf..3b0ae477c871f 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts @@ -5,10 +5,10 @@ */ export { - ProcessorSettingsForm, - ProcessorSettingsFromOnSubmitArg, + ManageProcessorForm, + ManageProcessorFormOnSubmitArg, OnSubmitHandler, -} from './processor_settings_form'; +} from './manage_processor_form'; export { ProcessorsTree, ProcessorInfo, OnActionHandler } from './processors_tree'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/documentation_button.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/documentation_button.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/documentation_button.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/documentation_button.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/field_components/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/index.ts similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/field_components/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/index.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/field_components/xjson_editor.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/xjson_editor.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/field_components/xjson_editor.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/xjson_editor.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/index.ts similarity index 71% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/index.ts index 1a7da4891967a..986bd52e911bf 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/index.ts @@ -5,7 +5,7 @@ */ export { - ProcessorSettingsForm, - ProcessorSettingsFromOnSubmitArg, + ManageProcessorForm, + ManageProcessorFormOnSubmitArg, OnSubmitHandler, -} from './processor_settings_form.container'; +} from './manage_processor_form.container'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.container.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.container.tsx similarity index 85% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.container.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.container.tsx index 2a537ba082eec..ea137b87e66d5 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.container.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.container.tsx @@ -9,12 +9,12 @@ import React, { FunctionComponent, useCallback, useEffect } from 'react'; import { useForm, OnFormUpdateArg, FormData } from '../../../../../shared_imports'; import { ProcessorInternal } from '../../types'; -import { ProcessorSettingsForm as ViewComponent } from './processor_settings_form'; +import { ManageProcessorForm as ViewComponent } from './manage_processor_form'; import { usePipelineProcessorsContext } from '../../context'; -export type ProcessorSettingsFromOnSubmitArg = Omit; +export type ManageProcessorFormOnSubmitArg = Omit; -export type OnSubmitHandler = (processor: ProcessorSettingsFromOnSubmitArg) => void; +export type OnSubmitHandler = (processor: ManageProcessorFormOnSubmitArg) => void; export type OnFormUpdateHandler = (form: OnFormUpdateArg) => void; @@ -27,7 +27,7 @@ interface Props { processor?: ProcessorInternal; } -export const ProcessorSettingsForm: FunctionComponent = ({ +export const ManageProcessorForm: FunctionComponent = ({ processor, onFormUpdate, onSubmit, diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.tsx similarity index 60% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.tsx index b5b3a38bb6a6c..4e172cce63027 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processor_settings_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.tsx @@ -6,15 +6,17 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import React, { FunctionComponent, memo, useEffect } from 'react'; +import React, { FunctionComponent, memo, useEffect, useState } from 'react'; import { EuiButton, EuiButtonEmpty, - EuiHorizontalRule, EuiFlyout, EuiFlyoutHeader, EuiFlyoutBody, EuiFlyoutFooter, + EuiSpacer, + EuiTabs, + EuiTab, EuiTitle, EuiFlexGroup, EuiFlexItem, @@ -22,12 +24,10 @@ import { import { Form, FormDataProvider, FormHook } from '../../../../../shared_imports'; import { ProcessorInternal } from '../../types'; - import { getProcessorDescriptor } from '../shared'; +import { ProcessorSettingsFields } from './processor_settings_fields'; import { DocumentationButton } from './documentation_button'; -import { CommonProcessorFields, ProcessorTypeField } from './processors/common_fields'; -import { Custom } from './processors/custom'; export interface Props { isOnFailure: boolean; @@ -42,6 +42,7 @@ const updateButtonLabel = i18n.translate( 'xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel', { defaultMessage: 'Update' } ); + const addButtonLabel = i18n.translate( 'xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel', { defaultMessage: 'Add' } @@ -52,20 +53,55 @@ const cancelButtonLabel = i18n.translate( { defaultMessage: 'Cancel' } ); -export const ProcessorSettingsForm: FunctionComponent = memo( - ({ processor, form, isOnFailure, onClose, onOpen, esDocsBasePath }) => { - const flyoutTitleContent = isOnFailure ? ( +export type TabType = 'configuration'; + +interface Tab { + id: TabType; + name: string; +} + +const tabs: Tab[] = [ + { + id: 'configuration', + name: i18n.translate( + 'xpack.ingestPipelines.settingsFormOnFailureFlyout.configurationTabTitle', + { + defaultMessage: 'Configuration', + } + ), + }, +]; + +const getFlyoutTitle = (isOnFailure: boolean, isExistingProcessor: boolean) => { + if (isExistingProcessor) { + return isOnFailure ? ( ) : ( ); + } + return isOnFailure ? ( + + ) : ( + + ); +}; + +export const ManageProcessorForm: FunctionComponent = memo( + ({ processor, form, isOnFailure, onClose, onOpen, esDocsBasePath }) => { useEffect( () => { onOpen(); @@ -73,6 +109,10 @@ export const ProcessorSettingsForm: FunctionComponent = memo( [] /* eslint-disable-line react-hooks/exhaustive-deps */ ); + const [activeTab, setActiveTab] = useState('configuration'); + + const flyoutContent = ; + return ( @@ -81,11 +121,10 @@ export const ProcessorSettingsForm: FunctionComponent = memo(
    -

    {flyoutTitleContent}

    +

    {getFlyoutTitle(isOnFailure, Boolean(processor))}

    - {({ type }) => { @@ -106,32 +145,27 @@ export const ProcessorSettingsForm: FunctionComponent = memo( - - - - - - {(arg: any) => { - const { type } = arg; - - if (type?.length) { - const formDescriptor = getProcessorDescriptor(type as any); - - if (formDescriptor?.FieldsComponent) { - return ( - <> - - - - ); - } - return ; - } - - // If the user has not yet defined a type, we do not show any settings fields - return null; - }} - + {processor ? ( + <> + + {tabs.map((tab) => ( + { + setActiveTab(tab.id); + }} + isSelected={tab.id === activeTab} + key={tab.id} + data-test-subj={`${tab.id}Tab`} + > + {tab.name} + + ))} + + + + ) : undefined} + + {flyoutContent} @@ -139,13 +173,7 @@ export const ProcessorSettingsForm: FunctionComponent = memo( {cancelButtonLabel} - { - form.submit(); - }} - > + {processor ? updateButtonLabel : addButtonLabel} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx new file mode 100644 index 0000000000000..6b2568bad3afc --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { EuiHorizontalRule } from '@elastic/eui'; + +import { FormDataProvider } from '../../../../../shared_imports'; +import { ProcessorInternal } from '../../types'; + +import { getProcessorDescriptor } from '../shared'; +import { CommonProcessorFields, ProcessorTypeField } from './processors/common_fields'; +import { Custom } from './processors/custom'; + +export interface Props { + processor?: ProcessorInternal; +} + +export const ProcessorSettingsFields: FunctionComponent = ({ processor }) => { + return ( + <> + + + + + + {(arg: any) => { + const { type } = arg; + + if (type?.length) { + const formDescriptor = getProcessorDescriptor(type as any); + + if (formDescriptor?.FieldsComponent) { + return ( + <> + + + + ); + } + return ; + } + + // If the user has not yet defined a type, we do not show any settings fields + return null; + }} + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/common_processor_fields.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/common_processor_fields.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/index.ts similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/index.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/processor_type_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/processor_type_field.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/common_fields/processor_type_field.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/processor_type_field.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/custom.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/custom.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/custom.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/custom.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/gsub.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/gsub.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/set.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_settings_form/processors/set.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx index edabbe277e5d9..a13321c38c193 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx @@ -7,10 +7,10 @@ import classNames from 'classnames'; import React, { FunctionComponent, memo } from 'react'; import { - EuiButtonIcon, EuiButtonToggle, EuiFlexGroup, EuiFlexItem, + EuiLink, EuiPanel, EuiText, EuiToolTip, @@ -57,9 +57,9 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( const isInMoveMode = Boolean(movingProcessor); const isMovingThisProcessor = processor.id === movingProcessor?.id; const isEditingThisProcessor = - editor.mode.id === 'editingProcessor' && processor.id === editor.mode.arg.processor.id; + editor.mode.id === 'managingProcessor' && processor.id === editor.mode.arg.processor.id; const isEditingOtherProcessor = - editor.mode.id === 'editingProcessor' && !isEditingThisProcessor; + editor.mode.id === 'managingProcessor' && !isEditingThisProcessor; const isMovingOtherProcessor = editor.mode.id === 'movingProcessor' && !isMovingThisProcessor; const isDimmed = isEditingOtherProcessor || isMovingOtherProcessor; @@ -70,11 +70,6 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( 'pipelineProcessorsEditor__item--dimmed': isDimmed, }); - const actionElementClasses = classNames({ - // eslint-disable-next-line @typescript-eslint/naming-convention - 'pipelineProcessorsEditor__item--displayNone': isInMoveMode, - }); - const inlineTextInputContainerClasses = classNames({ // eslint-disable-next-line @typescript-eslint/naming-convention 'pipelineProcessorsEditor__item--displayNone': isInMoveMode && !processor.options.description, @@ -141,7 +136,18 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( className="pipelineProcessorsEditor__item__processorTypeLabel" color={isDimmed ? 'subdued' : undefined} > - {getProcessorDescriptor(processor.type)?.label ?? processor.type} + { + editor.setMode({ + id: 'managingProcessor', + arg: { processor, selector }, + }); + }} + data-test-subj="manageItemButton" + > + {getProcessorDescriptor(processor.type)?.label ?? processor.type} +
    @@ -174,25 +180,6 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( placeholder={i18nTexts.descriptionPlaceholder} /> - - {!isInMoveMode && ( - - { - editor.setMode({ - id: 'editingProcessor', - arg: { processor, selector }, - }); - }} - /> - - )} - diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx index db4629823ef52..7124efc4905a7 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/processors_context.tsx @@ -42,7 +42,7 @@ import { OnActionHandler } from '../components/processors_tree'; import { ProcessorRemoveModal, PipelineProcessorsItemTooltip, - ProcessorSettingsForm, + ManageProcessorForm, OnSubmitHandler, } from '../components'; @@ -148,7 +148,7 @@ export const PipelineProcessorsContextProvider: FunctionComponent = ({ }, }); break; - case 'editingProcessor': + case 'managingProcessor': processorsDispatch({ type: 'updateProcessor', payload: { @@ -229,10 +229,10 @@ export const PipelineProcessorsContextProvider: FunctionComponent = ({ /> )} - {mode.id === 'editingProcessor' || mode.id === 'creatingProcessor' ? ( - void; export type EditorMode = | { id: 'creatingProcessor'; arg: { selector: ProcessorSelector } } | { id: 'movingProcessor'; arg: ProcessorInfo } - | { id: 'editingProcessor'; arg: { processor: ProcessorInternal; selector: ProcessorSelector } } + | { id: 'managingProcessor'; arg: { processor: ProcessorInternal; selector: ProcessorSelector } } | { id: 'removingProcessor'; arg: { selector: ProcessorSelector } } | { id: 'idle' }; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index c796aacda10a0..720ec2892093b 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9837,11 +9837,8 @@ "xpack.ingestPipelines.requestFlyout.descriptionText": "このElasticsearchリクエストは、このパイプラインを作成または更新します。", "xpack.ingestPipelines.requestFlyout.namedTitle": "「{name}」のリクエスト", "xpack.ingestPipelines.requestFlyout.unnamedTitle": "リクエスト", - "xpack.ingestPipelines.settingsFormFlyout.title": "プロセッサーの構成", "xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel": "追加", "xpack.ingestPipelines.settingsFormOnFailureFlyout.cancelButtonLabel": "キャンセル", - "xpack.ingestPipelines.settingsFormOnFailureFlyout.title": "エラープロセッサーの構成", - "xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel": "更新", "xpack.ingestPipelines.tabs.documentsTabTitle": "ドキュメント", "xpack.ingestPipelines.tabs.outputTabTitle": "アウトプット", "xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsFieldLabel": "ドキュメント", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 4c48a66b3c3c8..69820834cad5d 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9839,11 +9839,8 @@ "xpack.ingestPipelines.requestFlyout.descriptionText": "此 Elasticsearch 请求将创建或更新管道。", "xpack.ingestPipelines.requestFlyout.namedTitle": "对“{name}”的请求", "xpack.ingestPipelines.requestFlyout.unnamedTitle": "请求", - "xpack.ingestPipelines.settingsFormFlyout.title": "配置处理器", "xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel": "添加", "xpack.ingestPipelines.settingsFormOnFailureFlyout.cancelButtonLabel": "取消", - "xpack.ingestPipelines.settingsFormOnFailureFlyout.title": "配置失败时处理器", - "xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel": "更新", "xpack.ingestPipelines.tabs.documentsTabTitle": "文档", "xpack.ingestPipelines.tabs.outputTabTitle": "输出", "xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsFieldLabel": "文档", From f9c303675978934efa41c50aecf7c8ade3cc02ce Mon Sep 17 00:00:00 2001 From: Stacey Gammon Date: Tue, 11 Aug 2020 10:18:12 -0400 Subject: [PATCH 097/106] Update links that pointed to CONTRIBUTING.md (#74757) * Update links that pointed to CONTRIBUTING.md * Update .github/PULL_REQUEST_TEMPLATE.md point to master instead of 7.x --- .github/PULL_REQUEST_TEMPLATE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 754043ee0ef77..534b1cea6242f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,12 +7,12 @@ Summarize your PR. If it involves visual changes include a screenshot or gif. Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md) -- [ ] [Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials -- [ ] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios +- [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials +- [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] This was checked for [keyboard-only and screenreader accessibility](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Accessibility_testing_checklist) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers -- [ ] This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process) +- [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) From f621b0e2b68cd47341074a93c96ab7a5ede3d9bc Mon Sep 17 00:00:00 2001 From: Brittany Joiner Date: Tue, 11 Aug 2020 09:20:15 -0500 Subject: [PATCH 098/106] pluralized for occurrences vs occurrence (#74564) Co-authored-by: Elastic Machine --- .../components/app/ErrorGroupDetails/Distribution/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx index 80c749e58c88c..ecdd52e31730c 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx @@ -107,7 +107,8 @@ export function ErrorDistribution({ distribution, title }: Props) { } formatYLong={(value: number) => i18n.translate('xpack.apm.errorGroupDetails.occurrencesLongLabel', { - defaultMessage: '{occCount} occurrences', + defaultMessage: + '{occCount} {occCount, plural, one {occurrence} other {occurrences}}', values: { occCount: value }, }) } From 461d68418c01e2b9e822c971d875993a80524e84 Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Tue, 11 Aug 2020 09:25:04 -0600 Subject: [PATCH 099/106] [security solutions][lists] Adds end to end tests (#74473) ## Summary Adds initial set of end to end tests for lists You can run all of these with the command from kibana root: ```ts node scripts/functional_tests --config x-pack/test/lists_api_integration/security_and_spaces/config.ts ``` Fixes a few minor bugs found such as... * Validation for importing lists was not checking if the indexes were created first * Some wording for the error messages had duplicate words within them ### Checklist - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios --- x-pack/plugins/lists/common/constants.mock.ts | 1 + .../request/create_list_item_schema.mock.ts | 17 ++ .../request/create_list_schema.mock.ts | 19 +++ .../request/import_list_item_schema.mock.ts | 9 + .../request/update_list_item_schema.mock.ts | 10 +- .../request/update_list_schema.mock.ts | 27 +++ .../request/update_list_schema.test.ts | 48 ++++++ .../schemas/response/list_item_schema.mock.ts | 13 ++ .../schemas/response/list_schema.mock.ts | 15 ++ .../server/routes/create_list_item_route.ts | 9 + .../server/routes/delete_list_item_route.ts | 2 +- .../server/routes/import_list_item_route.ts | 7 + .../lists/server/routes/patch_list_route.ts | 2 +- .../routes/update_exception_list_route.ts | 2 +- .../lists/server/routes/update_list_route.ts | 2 +- .../common/config.ts | 1 - .../lists_api_integration/common/config.ts | 69 ++++++++ .../common/ftr_provider_context.d.ts | 11 ++ .../lists_api_integration/common/services.ts | 7 + .../security_and_spaces/config.ts | 14 ++ .../tests/create_list_items.ts | 115 +++++++++++++ .../security_and_spaces/tests/create_lists.ts | 95 +++++++++++ .../tests/delete_list_items.ts | 98 +++++++++++ .../security_and_spaces/tests/delete_lists.ts | 83 ++++++++++ .../tests/export_list_items.ts | 104 ++++++++++++ .../tests/find_list_items.ts | 116 +++++++++++++ .../security_and_spaces/tests/find_lists.ts | 77 +++++++++ .../tests/import_list_items.ts | 112 +++++++++++++ .../security_and_spaces/tests/index.ts | 27 +++ .../tests/read_list_items.ts | 98 +++++++++++ .../security_and_spaces/tests/read_lists.ts | 84 ++++++++++ .../tests/update_list_items.ts | 154 ++++++++++++++++++ .../security_and_spaces/tests/update_lists.ts | 141 ++++++++++++++++ x-pack/test/lists_api_integration/utils.ts | 126 ++++++++++++++ 34 files changed, 1709 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/lists/common/schemas/request/update_list_schema.mock.ts create mode 100644 x-pack/plugins/lists/common/schemas/request/update_list_schema.test.ts create mode 100644 x-pack/test/lists_api_integration/common/config.ts create mode 100644 x-pack/test/lists_api_integration/common/ftr_provider_context.d.ts create mode 100644 x-pack/test/lists_api_integration/common/services.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/config.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/create_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/create_lists.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/delete_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/delete_lists.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/export_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/find_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/find_lists.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/import_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/read_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/read_lists.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/update_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/update_lists.ts create mode 100644 x-pack/test/lists_api_integration/utils.ts diff --git a/x-pack/plugins/lists/common/constants.mock.ts b/x-pack/plugins/lists/common/constants.mock.ts index b7609b5a3602a..428cc90d2908b 100644 --- a/x-pack/plugins/lists/common/constants.mock.ts +++ b/x-pack/plugins/lists/common/constants.mock.ts @@ -9,6 +9,7 @@ import { EntriesArray } from './schemas/types'; export const DATE_NOW = '2020-04-20T15:25:31.830Z'; export const OLD_DATE_RELATIVE_TO_DATE_NOW = '2020-04-19T15:25:31.830Z'; export const USER = 'some user'; +export const ELASTIC_USER = 'elastic'; export const LIST_INDEX = '.lists'; export const LIST_ITEM_INDEX = '.items'; export const NAME = 'some name'; diff --git a/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.mock.ts index f0d4af520bdbb..5a9e50554865b 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.mock.ts @@ -14,3 +14,20 @@ export const getCreateListItemSchemaMock = (): CreateListItemSchema => ({ meta: META, value: VALUE, }); + +/** + * Useful for end to end testing + */ +export const getCreateMinimalListItemSchemaMock = (): CreateListItemSchema => ({ + id: LIST_ITEM_ID, + list_id: LIST_ID, + value: VALUE, +}); + +/** + * Useful for end to end testing + */ +export const getCreateMinimalListItemSchemaMockWithoutId = (): CreateListItemSchema => ({ + list_id: LIST_ID, + value: VALUE, +}); diff --git a/x-pack/plugins/lists/common/schemas/request/create_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/create_list_schema.mock.ts index 461890b944bfa..194625c09fb79 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_list_schema.mock.ts @@ -18,3 +18,22 @@ export const getCreateListSchemaMock = (): CreateListSchema => ({ type: TYPE, version: VERSION, }); + +/** + * Useful for end to end tests and other mechanisms which want to fill in the values + */ +export const getCreateMinimalListSchemaMock = (): CreateListSchema => ({ + description: DESCRIPTION, + id: LIST_ID, + name: NAME, + type: TYPE, +}); + +/** + * Useful for end to end tests and other mechanisms which want to fill in the values + */ +export const getCreateMinimalListSchemaMockWithoutId = (): CreateListSchema => ({ + description: DESCRIPTION, + name: NAME, + type: TYPE, +}); diff --git a/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.mock.ts index 69e4d2f8293c7..57bb66f746f67 100644 --- a/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.mock.ts @@ -9,3 +9,12 @@ import { ImportListItemSchema } from './import_list_item_schema'; export const getImportListItemSchemaMock = (): ImportListItemSchema => ({ file: {}, }); + +/** + * This is useful for end to end tests, it will return a buffer given a string array + * of things to import. + * @param input Array of strings of things to import + */ +export const getImportListItemAsBuffer = (input: string[]): Buffer => { + return Buffer.from(input.join('\r\n')); +}; diff --git a/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.mock.ts index c95de1e99b4f0..be8ba3516a754 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.mock.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ID, META, VALUE } from '../../constants.mock'; +import { ID, LIST_ITEM_ID, META, VALUE } from '../../constants.mock'; import { UpdateListItemSchema } from './update_list_item_schema'; @@ -13,3 +13,11 @@ export const getUpdateListItemSchemaMock = (): UpdateListItemSchema => ({ meta: META, value: VALUE, }); + +/** + * Useful for end to end testing + */ +export const getUpdateMinimalListItemSchemaMock = (): UpdateListItemSchema => ({ + id: LIST_ITEM_ID, + value: VALUE, +}); diff --git a/x-pack/plugins/lists/common/schemas/request/update_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/update_list_schema.mock.ts new file mode 100644 index 0000000000000..b044d40a5d88f --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/request/update_list_schema.mock.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DESCRIPTION, LIST_ID, META, NAME, _VERSION } from '../../constants.mock'; + +import { UpdateListSchema } from './update_list_schema'; + +export const getUpdateListSchemaMock = (): UpdateListSchema => ({ + _version: _VERSION, + description: DESCRIPTION, + id: LIST_ID, + meta: META, + name: NAME, +}); + +/** + * Useful for end to end tests and other mechanisms which want to fill in the values + * after doing a get of the structure. + */ +export const getUpdateMinimalListSchemaMock = (): UpdateListSchema => ({ + description: DESCRIPTION, + id: LIST_ID, + name: NAME, +}); diff --git a/x-pack/plugins/lists/common/schemas/request/update_list_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/update_list_schema.test.ts new file mode 100644 index 0000000000000..21d20a6b85bce --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/request/update_list_schema.test.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { left } from 'fp-ts/lib/Either'; +import { pipe } from 'fp-ts/lib/pipeable'; + +import { exactCheck, foldLeftRight, getPaths } from '../../shared_imports'; + +import { UpdateListSchema, updateListSchema } from './update_list_schema'; +import { getUpdateListSchemaMock } from './update_list_schema.mock'; + +describe('update_list_schema', () => { + test('it should validate a typical list request', () => { + const payload = getUpdateListSchemaMock(); + const decoded = updateListSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should accept an undefined for "meta" but strip it out', () => { + const payload = getUpdateListSchemaMock(); + const outputPayload = getUpdateListSchemaMock(); + delete payload.meta; + const decoded = updateListSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + delete outputPayload.meta; + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(outputPayload); + }); + + test('it should not allow an extra key to be sent in', () => { + const payload: UpdateListSchema & { + extraKey?: string; + } = getUpdateListSchemaMock(); + payload.extraKey = 'some new value'; + const decoded = updateListSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "extraKey"']); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/response/list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/list_item_schema.mock.ts index e122f6a2bbe3b..f4e36d1d060c0 100644 --- a/x-pack/plugins/lists/common/schemas/response/list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/list_item_schema.mock.ts @@ -7,6 +7,7 @@ import { ListItemSchema } from '../../../common/schemas'; import { DATE_NOW, + ELASTIC_USER, LIST_ID, LIST_ITEM_ID, META, @@ -31,3 +32,15 @@ export const getListItemResponseMock = (): ListItemSchema => ({ updated_by: USER, value: VALUE, }); + +/** + * This is useful for end to end tests where we remove the auto generated parts for comparisons + * such as created_at, updated_at, and id. + */ +export const getListItemResponseMockWithoutAutoGeneratedValues = (): Partial => ({ + created_by: ELASTIC_USER, + list_id: LIST_ID, + type: TYPE, + updated_by: ELASTIC_USER, + value: VALUE, +}); diff --git a/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts index 900c7ea4322a3..4ae77e12a8294 100644 --- a/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts @@ -8,6 +8,7 @@ import { ListSchema } from '../../../common/schemas'; import { DATE_NOW, DESCRIPTION, + ELASTIC_USER, IMMUTABLE, LIST_ID, META, @@ -35,3 +36,17 @@ export const getListResponseMock = (): ListSchema => ({ updated_by: USER, version: VERSION, }); + +/** + * This is useful for end to end tests where we remove the auto generated parts for comparisons + * such as created_at, updated_at, and id. + */ +export const getListResponseMockWithoutAutoGeneratedValues = (): Partial => ({ + created_by: ELASTIC_USER, + description: DESCRIPTION, + immutable: IMMUTABLE, + name: NAME, + type: TYPE, + updated_by: ELASTIC_USER, + version: VERSION, +}); diff --git a/x-pack/plugins/lists/server/routes/create_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_list_item_route.ts index 0a4a1c739ae7c..bd2828d331d83 100644 --- a/x-pack/plugins/lists/server/routes/create_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_item_route.ts @@ -36,6 +36,15 @@ export const createListItemRoute = (router: IRouter): void => { statusCode: 404, }); } else { + if (id != null) { + const listItem = await lists.getListItem({ id }); + if (listItem != null) { + return siemResponse.error({ + body: `list item id: "${id}" already exists`, + statusCode: 409, + }); + } + } const createdListItem = await lists.createListItem({ deserializer: list.deserializer, id, diff --git a/x-pack/plugins/lists/server/routes/delete_list_item_route.ts b/x-pack/plugins/lists/server/routes/delete_list_item_route.ts index 2284068552485..fa1adf8a39ed8 100644 --- a/x-pack/plugins/lists/server/routes/delete_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_list_item_route.ts @@ -33,7 +33,7 @@ export const deleteListItemRoute = (router: IRouter): void => { const deleted = await lists.deleteListItem({ id }); if (deleted == null) { return siemResponse.error({ - body: `list item with id: "${id}" item not found`, + body: `list item with id: "${id}" not found`, statusCode: 404, }); } else { diff --git a/x-pack/plugins/lists/server/routes/import_list_item_route.ts b/x-pack/plugins/lists/server/routes/import_list_item_route.ts index ce5fdaccae251..d46c943d95fe9 100644 --- a/x-pack/plugins/lists/server/routes/import_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/import_list_item_route.ts @@ -41,6 +41,13 @@ export const importListItemRoute = (router: IRouter, config: ConfigType): void = const stream = createStreamFromBuffer(request.body); const { deserializer, list_id: listId, serializer, type } = request.query; const lists = getListClient(context); + const listExists = await lists.getListIndexExists(); + if (!listExists) { + return siemResponse.error({ + body: `To import a list item, the index must exist first. Index "${lists.getListIndex()}" does not exist`, + statusCode: 400, + }); + } if (listId != null) { const list = await lists.getList({ id: listId }); if (list == null) { diff --git a/x-pack/plugins/lists/server/routes/patch_list_route.ts b/x-pack/plugins/lists/server/routes/patch_list_route.ts index e33d8d7c9c598..763f3f495ca17 100644 --- a/x-pack/plugins/lists/server/routes/patch_list_route.ts +++ b/x-pack/plugins/lists/server/routes/patch_list_route.ts @@ -32,7 +32,7 @@ export const patchListRoute = (router: IRouter): void => { const list = await lists.updateList({ _version, description, id, meta, name, version }); if (list == null) { return siemResponse.error({ - body: `list id: "${id}" found found`, + body: `list id: "${id}" not found`, statusCode: 404, }); } else { diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts index bead10802df4f..8102210b8430d 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts @@ -69,7 +69,7 @@ export const updateExceptionListRoute = (router: IRouter): void => { }); if (list == null) { return siemResponse.error({ - body: `exception list id: "${id}" found found`, + body: `exception list id: "${id}" not found`, statusCode: 404, }); } else { diff --git a/x-pack/plugins/lists/server/routes/update_list_route.ts b/x-pack/plugins/lists/server/routes/update_list_route.ts index 816ad13d3770e..8d7d08be4130b 100644 --- a/x-pack/plugins/lists/server/routes/update_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_list_route.ts @@ -32,7 +32,7 @@ export const updateListRoute = (router: IRouter): void => { const list = await lists.updateList({ _version, description, id, meta, name, version }); if (list == null) { return siemResponse.error({ - body: `list id: "${id}" found found`, + body: `list id: "${id}" not found`, statusCode: 404, }); } else { diff --git a/x-pack/test/detection_engine_api_integration/common/config.ts b/x-pack/test/detection_engine_api_integration/common/config.ts index bb9b3d9e96664..46fb877e94f23 100644 --- a/x-pack/test/detection_engine_api_integration/common/config.ts +++ b/x-pack/test/detection_engine_api_integration/common/config.ts @@ -73,7 +73,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) ])}`, `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, '--xpack.eventLog.logEntries=true', - '--xpack.lists.enabled=true', ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'alerts')}`, `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'actions')}`, diff --git a/x-pack/test/lists_api_integration/common/config.ts b/x-pack/test/lists_api_integration/common/config.ts new file mode 100644 index 0000000000000..ca3cc3a5eee2f --- /dev/null +++ b/x-pack/test/lists_api_integration/common/config.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import path from 'path'; +import { CA_CERT_PATH } from '@kbn/dev-utils'; +import { FtrConfigProviderContext } from '@kbn/test/types/ftr'; +import { services } from './services'; + +interface CreateTestConfigOptions { + license: string; + disabledPlugins?: string[]; + ssl?: boolean; +} + +export function createTestConfig(name: string, options: CreateTestConfigOptions) { + const { license = 'trial', disabledPlugins = [], ssl = false } = options; + + return async ({ readConfigFile }: FtrConfigProviderContext) => { + const xPackApiIntegrationTestsConfig = await readConfigFile( + require.resolve('../../api_integration/config.ts') + ); + const servers = { + ...xPackApiIntegrationTestsConfig.get('servers'), + elasticsearch: { + ...xPackApiIntegrationTestsConfig.get('servers.elasticsearch'), + protocol: ssl ? 'https' : 'http', + }, + }; + + return { + testFiles: [require.resolve(`../${name}/tests/`)], + servers, + services, + junit: { + reportName: 'X-Pack Lists Integration Tests', + }, + esArchiver: xPackApiIntegrationTestsConfig.get('esArchiver'), + esTestCluster: { + ...xPackApiIntegrationTestsConfig.get('esTestCluster'), + license, + ssl, + serverArgs: [ + `xpack.license.self_generated.type=${license}`, + `xpack.security.enabled=${!disabledPlugins.includes('security')}`, + ], + }, + kbnTestServer: { + ...xPackApiIntegrationTestsConfig.get('kbnTestServer'), + serverArgs: [ + ...xPackApiIntegrationTestsConfig.get('kbnTestServer.serverArgs'), + ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), + `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'alerts')}`, + `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'actions')}`, + `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'task_manager')}`, + `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'aad')}`, + ...(ssl + ? [ + `--elasticsearch.hosts=${servers.elasticsearch.protocol}://${servers.elasticsearch.hostname}:${servers.elasticsearch.port}`, + `--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`, + ] + : []), + ], + }, + }; + }; +} diff --git a/x-pack/test/lists_api_integration/common/ftr_provider_context.d.ts b/x-pack/test/lists_api_integration/common/ftr_provider_context.d.ts new file mode 100644 index 0000000000000..e3add3748f56d --- /dev/null +++ b/x-pack/test/lists_api_integration/common/ftr_provider_context.d.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { GenericFtrProviderContext } from '@kbn/test/types/ftr'; + +import { services } from './services'; + +export type FtrProviderContext = GenericFtrProviderContext; diff --git a/x-pack/test/lists_api_integration/common/services.ts b/x-pack/test/lists_api_integration/common/services.ts new file mode 100644 index 0000000000000..a927a31469bab --- /dev/null +++ b/x-pack/test/lists_api_integration/common/services.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { services } from '../../api_integration/services'; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/config.ts b/x-pack/test/lists_api_integration/security_and_spaces/config.ts new file mode 100644 index 0000000000000..081b901c47fc3 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/config.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { createTestConfig } from '../common/config'; + +// eslint-disable-next-line import/no-default-export +export default createTestConfig('security_and_spaces', { + disabledPlugins: [], + license: 'trial', + ssl: true, +}); diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/create_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/create_list_items.ts new file mode 100644 index 0000000000000..906e9a9ef4456 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/create_list_items.ts @@ -0,0 +1,115 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { LIST_URL, LIST_ITEM_URL } from '../../../../plugins/lists/common/constants'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; + +import { getCreateMinimalListSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; + +import { + getCreateMinimalListItemSchemaMock, + getCreateMinimalListItemSchemaMockWithoutId, +} from '../../../../plugins/lists/common/schemas/request/create_list_item_schema.mock'; +import { getListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_item_schema.mock'; + +import { + createListsIndex, + deleteListsIndex, + removeListItemServerGeneratedProperties, +} from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + + describe('create_list_items', () => { + describe('validation errors', () => { + it('should give a 404 error that the list must exist first before being able to add a list item', async () => { + const { body } = await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(404); + + expect(body).to.eql({ + message: 'list id: "some-list-id" does not exist', + status_code: 404, + }); + }); + }); + + describe('creating list items', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should create a simple list item with a list item id', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + const { body } = await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + const bodyToCompare = removeListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListItemResponseMockWithoutAutoGeneratedValues()); + }); + + it('should create a simple list item without an id', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + const { body } = await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMockWithoutId()) + .expect(200); + + const bodyToCompare = removeListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListItemResponseMockWithoutAutoGeneratedValues()); + }); + + it('should cause a 409 conflict if we attempt to create the same list item twice', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + const { body } = await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(409); + + expect(body).to.eql({ + message: 'list item id: "some-list-item-id" already exists', + status_code: 409, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/create_lists.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/create_lists.ts new file mode 100644 index 0000000000000..b9d61eeacfee8 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/create_lists.ts @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { LIST_URL } from '../../../../plugins/lists/common/constants'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { + getCreateMinimalListSchemaMock, + getCreateMinimalListSchemaMockWithoutId, +} from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; +import { getListResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_schema.mock'; + +import { + createListsIndex, + deleteListsIndex, + removeListServerGeneratedProperties, +} from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + + describe('create_lists', () => { + describe('validation errors', () => { + it('should give an error that the index must exist first if it does not exist before creating a list', async () => { + const { body } = await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(400); + + expect(body).to.eql({ + message: + 'To create a list, the index must exist first. Index ".lists-default" does not exist', + status_code: 400, + }); + }); + }); + + describe('creating lists', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should create a simple list with a list_id', async () => { + const { body } = await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + const bodyToCompare = removeListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListResponseMockWithoutAutoGeneratedValues()); + }); + + it('should create a simple list without a list_id', async () => { + const { body } = await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMockWithoutId()) + .expect(200); + + const bodyToCompare = removeListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListResponseMockWithoutAutoGeneratedValues()); + }); + + it('should cause a 409 conflict if we attempt to create the same list_id twice', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + const { body } = await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(409); + + expect(body).to.eql({ + message: 'list id: "some-list-id" already exists', + status_code: 409, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_list_items.ts new file mode 100644 index 0000000000000..83ba9728efdc9 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_list_items.ts @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { getListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_item_schema.mock'; +import { getCreateMinimalListItemSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_item_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { LIST_URL, LIST_ITEM_URL } from '../../../../plugins/lists/common/constants'; + +import { getCreateMinimalListSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; +import { + createListsIndex, + deleteListsIndex, + removeListItemServerGeneratedProperties, +} from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + + describe('delete_list_items', () => { + describe('deleting list items', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should delete a single list item with a list item id', async () => { + // create a list + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + // create a list item + await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + // delete the list item by its list item id + const { body } = await supertest + .delete(`${LIST_ITEM_URL}?id=${getCreateMinimalListItemSchemaMock().id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListItemResponseMockWithoutAutoGeneratedValues()); + }); + + it('should delete a single list using an auto generated id', async () => { + // create a list + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + // create a list item + const { body: bodyWithCreateListItem } = await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + // delete that list by its auto-generated id + const { body } = await supertest + .delete(`${LIST_ITEM_URL}?id=${bodyWithCreateListItem.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListItemResponseMockWithoutAutoGeneratedValues()); + }); + + it('should return an error if the id does not exist when trying to delete it', async () => { + const { body } = await supertest + .delete(`${LIST_ITEM_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + message: 'list item with id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" not found', + status_code: 404, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_lists.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_lists.ts new file mode 100644 index 0000000000000..3703e1b6ca306 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_lists.ts @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { LIST_URL } from '../../../../plugins/lists/common/constants'; + +import { getCreateMinimalListSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; +import { + createListsIndex, + deleteListsIndex, + removeListServerGeneratedProperties, +} from '../../utils'; +import { getListResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_schema.mock'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + + describe('delete_lists', () => { + describe('deleting lists', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should delete a single list with a list id', async () => { + // create a list + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + // delete the list by its list id + const { body } = await supertest + .delete(`${LIST_URL}?id=${getCreateMinimalListSchemaMock().id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListResponseMockWithoutAutoGeneratedValues()); + }); + + it('should delete a single list using an auto generated id', async () => { + // add a list + const { body: bodyWithCreatedList } = await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + // delete that list by its auto-generated id + const { body } = await supertest + .delete(`${LIST_URL}?id=${bodyWithCreatedList.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListResponseMockWithoutAutoGeneratedValues()); + }); + + it('should return an error if the id does not exist when trying to delete it', async () => { + const { body } = await supertest + .delete(`${LIST_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + message: 'list id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" was not found', + status_code: 404, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/export_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/export_list_items.ts new file mode 100644 index 0000000000000..6fe783fc497f2 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/export_list_items.ts @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import { getCreateMinimalListItemSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_item_schema.mock'; +import { getCreateMinimalListSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; +import { LIST_ID, NAME } from '../../../../plugins/lists/common/constants.mock'; +import { CreateListItemSchema } from '../../../../plugins/lists/common/schemas'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; + +import { LIST_ITEM_URL, LIST_URL } from '../../../../plugins/lists/common/constants'; + +import { createListsIndex, deleteListsIndex, binaryToString } from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + + describe('export_list_items', () => { + describe('exporting lists', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should set the response content types to be expected', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + await supertest + .post(`${LIST_ITEM_URL}/_export?list_id=${LIST_ID}`) + .set('kbn-xsrf', 'true') + .expect('Content-Disposition', `attachment; filename="${NAME}"`) + .expect(200); + }); + + it('should export a single list item with a list id', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + const { body } = await supertest + .post(`${LIST_ITEM_URL}/_export?list_id=${LIST_ID}`) + .set('kbn-xsrf', 'true') + .expect(200) + .parse(binaryToString); + + expect(body.toString()).to.eql('127.0.0.1\n'); + }); + + it('should export two list items with a list id', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + const secondList: CreateListItemSchema = { + ...getCreateMinimalListItemSchemaMock(), + id: 'list-item-2', + value: '127.0.0.2', + }; + await supertest.post(LIST_ITEM_URL).set('kbn-xsrf', 'true').send(secondList).expect(200); + + const { body } = await supertest + .post(`${LIST_ITEM_URL}/_export?list_id=${LIST_ID}`) + .set('kbn-xsrf', 'true') + .expect(200) + .parse(binaryToString); + + expect(body.toString()).to.eql('127.0.0.2\n127.0.0.1\n'); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/find_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/find_list_items.ts new file mode 100644 index 0000000000000..4c1f3dfdb6703 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/find_list_items.ts @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { LIST_ITEM_ID, LIST_ID } from '../../../../plugins/lists/common/constants.mock'; +import { getListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_item_schema.mock'; +import { getCreateMinimalListItemSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_item_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { LIST_URL, LIST_ITEM_URL } from '../../../../plugins/lists/common/constants'; + +import { getCreateMinimalListSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; +import { + createListsIndex, + deleteListsIndex, + removeListItemServerGeneratedProperties, +} from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + + describe('find_list_items', () => { + describe('find list items', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should give a validation error if the list_id is not supplied', async () => { + const { body } = await supertest + .get(`${LIST_ITEM_URL}/_find`) + .set('kbn-xsrf', 'true') + .send() + .expect(400); + + expect(body).to.eql({ + error: 'Bad Request', + message: '[request query]: Invalid value "undefined" supplied to "list_id"', + statusCode: 400, + }); + }); + + it('should give a 404 if the list has not been created yet', async () => { + const { body } = await supertest + .get(`${LIST_ITEM_URL}/_find?list_id=${LIST_ITEM_ID}`) + .set('kbn-xsrf', 'true') + .send() + .expect(404); + + expect(body).to.eql({ + message: 'list id: "some-list-item-id" does not exist', + status_code: 404, + }); + }); + + it('should return an empty find body correctly if no list items are loaded', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + const { body } = await supertest + .get(`${LIST_ITEM_URL}/_find?list_id=${LIST_ID}`) + .set('kbn-xsrf', 'true') + .send() + .expect(200); + + expect(body).to.eql({ + cursor: 'WzBd', + data: [], + page: 1, + per_page: 20, + total: 0, + }); + }); + + it('should return a single list item when a single list item is loaded from a find with defaults added', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + const { body } = await supertest + .get(`${LIST_ITEM_URL}/_find?list_id=${LIST_ID}`) + .set('kbn-xsrf', 'true') + .send() + .expect(200); + + body.data = [removeListItemServerGeneratedProperties(body.data[0])]; + // cursor is a constant changing value so we have to delete it as well. + delete body.cursor; + expect(body).to.eql({ + data: [getListItemResponseMockWithoutAutoGeneratedValues()], + page: 1, + per_page: 20, + total: 1, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/find_lists.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/find_lists.ts new file mode 100644 index 0000000000000..7efe28a0b01a1 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/find_lists.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { LIST_URL } from '../../../../plugins/lists/common/constants'; + +import { getCreateMinimalListSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; +import { + createListsIndex, + deleteListsIndex, + removeListServerGeneratedProperties, +} from '../../utils'; +import { getListResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_schema.mock'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + + describe('find_lists', () => { + describe('find lists', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should return an empty find body correctly if no lists are loaded', async () => { + const { body } = await supertest + .get(`${LIST_URL}/_find`) + .set('kbn-xsrf', 'true') + .send() + .expect(200); + + expect(body).to.eql({ + cursor: 'WzBd', + data: [], + page: 1, + per_page: 20, + total: 0, + }); + }); + + it('should return a single list when a single list is loaded from a find with defaults added', async () => { + // add a single list + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + // query the single list from _find + const { body } = await supertest + .get(`${LIST_URL}/_find`) + .set('kbn-xsrf', 'true') + .send() + .expect(200); + + body.data = [removeListServerGeneratedProperties(body.data[0])]; + // cursor is a constant changing value so we have to delete it as well. + delete body.cursor; + expect(body).to.eql({ + data: [getListResponseMockWithoutAutoGeneratedValues()], + page: 1, + per_page: 20, + total: 1, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/import_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/import_list_items.ts new file mode 100644 index 0000000000000..4befb6bbaf050 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/import_list_items.ts @@ -0,0 +1,112 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import { ListItemSchema } from '../../../../plugins/lists/common/schemas'; +import { getListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_item_schema.mock'; +import { ListSchema } from '../../../../plugins/lists/common'; +import { getListResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; + +import { LIST_ITEM_URL } from '../../../../plugins/lists/common/constants'; + +import { + createListsIndex, + deleteListsIndex, + removeListServerGeneratedProperties, + removeListItemServerGeneratedProperties, + waitFor, +} from '../../utils'; + +import { getImportListItemAsBuffer } from '../../../../plugins/lists/common/schemas/request/import_list_item_schema.mock'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + + describe('import_list_items', () => { + describe('importing list items without an index', () => { + it('should not import a list item if the index does not exist yet', async () => { + const { body } = await supertest + .post(`${LIST_ITEM_URL}/_import?type=ip`) + .set('kbn-xsrf', 'true') + .attach('file', getImportListItemAsBuffer(['127.0.0.1', '127.0.0.2']), 'list_items.txt') + .expect('Content-Type', 'application/json; charset=utf-8') + .expect(400); + + expect(body).to.eql({ + status_code: 400, + message: + 'To import a list item, the index must exist first. Index ".lists-default" does not exist', + }); + }); + }); + + describe('importing rules with an index', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should set the response content types to be expected when importing two items', async () => { + await supertest + .post(`${LIST_ITEM_URL}/_import?type=ip`) + .set('kbn-xsrf', 'true') + .attach('file', getImportListItemAsBuffer(['127.0.0.1', '127.0.0.2']), 'list_items.txt') + .expect('Content-Type', 'application/json; charset=utf-8') + .expect(200); + }); + + it('should report that it imported a simple list successfully', async () => { + const { body } = await supertest + .post(`${LIST_ITEM_URL}/_import?type=ip`) + .set('kbn-xsrf', 'true') + .attach('file', getImportListItemAsBuffer(['127.0.0.1', '127.0.0.2']), 'list_items.txt') + .expect('Content-Type', 'application/json; charset=utf-8') + .expect(200); + + const bodyToCompare = removeListServerGeneratedProperties(body); + const outputtedList: Partial = { + ...getListResponseMockWithoutAutoGeneratedValues(), + name: 'list_items.txt', + description: 'File uploaded from file system of list_items.txt', + }; + expect(bodyToCompare).to.eql(outputtedList); + }); + + it('should be able to read imported list items back out correctly', async () => { + await supertest + .post(`${LIST_ITEM_URL}/_import?type=ip`) + .set('kbn-xsrf', 'true') + .attach('file', getImportListItemAsBuffer(['127.0.0.1', '127.0.0.2']), 'list_items.txt') + .expect(200); + + // Although we try to be aggressive with waitFor in the lists code base, there is still not guarantees + // that we will have the data just yet so we have to do a waitFor here for when it shows up + await waitFor(async () => { + const { status } = await supertest + .get(`${LIST_ITEM_URL}?list_id=list_items.txt&value=127.0.0.1`) + .send(); + return status !== 404; + }); + const { body } = await supertest + .get(`${LIST_ITEM_URL}?list_id=list_items.txt&value=127.0.0.1`) + .send() + .expect(200); + + const bodyToCompare = removeListItemServerGeneratedProperties(body[0]); + const outputtedList: Partial = { + ...getListItemResponseMockWithoutAutoGeneratedValues(), + list_id: 'list_items.txt', + }; + expect(bodyToCompare).to.eql(outputtedList); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts new file mode 100644 index 0000000000000..302877a680aa6 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FtrProviderContext } from '../../common/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default ({ loadTestFile }: FtrProviderContext): void => { + describe('lists api security and spaces enabled', function () { + this.tags('ciGroup1'); + + loadTestFile(require.resolve('./create_lists')); + loadTestFile(require.resolve('./create_list_items')); + loadTestFile(require.resolve('./read_lists')); + loadTestFile(require.resolve('./read_list_items')); + loadTestFile(require.resolve('./update_lists')); + loadTestFile(require.resolve('./update_list_items')); + loadTestFile(require.resolve('./delete_lists')); + loadTestFile(require.resolve('./delete_list_items')); + loadTestFile(require.resolve('./find_lists')); + loadTestFile(require.resolve('./find_list_items')); + loadTestFile(require.resolve('./import_list_items')); + loadTestFile(require.resolve('./export_list_items')); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/read_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/read_list_items.ts new file mode 100644 index 0000000000000..5469973d70e50 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/read_list_items.ts @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { getListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_item_schema.mock'; +import { getCreateMinimalListItemSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_item_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { LIST_URL, LIST_ITEM_URL } from '../../../../plugins/lists/common/constants'; + +import { getCreateMinimalListSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; +import { + createListsIndex, + deleteListsIndex, + removeListItemServerGeneratedProperties, +} from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + + describe('read_list_items', () => { + describe('reading list items', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should be able to read a single list item using id', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + const { body } = await supertest + .get(`${LIST_ITEM_URL}?id=${getCreateMinimalListItemSchemaMock().id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListItemResponseMockWithoutAutoGeneratedValues()); + }); + + it('should be able to read a single list item with an auto-generated list id', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + const { body: createListBody } = await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + const { body } = await supertest + .get(`${LIST_ITEM_URL}?id=${createListBody.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListItemResponseMockWithoutAutoGeneratedValues()); + }); + + it('should return 404 if given a fake id', async () => { + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + const { body } = await supertest + .get(`${LIST_ITEM_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'list item id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist', + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/read_lists.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/read_lists.ts new file mode 100644 index 0000000000000..c3c8cb39d023b --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/read_lists.ts @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { LIST_URL } from '../../../../plugins/lists/common/constants'; + +import { + getCreateMinimalListSchemaMock, + getCreateMinimalListSchemaMockWithoutId, +} from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; +import { + createListsIndex, + deleteListsIndex, + removeListServerGeneratedProperties, +} from '../../utils'; +import { getListResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_schema.mock'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + + describe('read_lists', () => { + describe('reading lists', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should be able to read a single list using id', async () => { + // create a simple list to read + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + const { body } = await supertest + .get(`${LIST_URL}?id=${getCreateMinimalListSchemaMock().id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListResponseMockWithoutAutoGeneratedValues()); + }); + + it('should be able to read a single list with an auto-generated list id', async () => { + // create a simple list to read + const { body: createListBody } = await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMockWithoutId()) + .expect(200); + + const { body } = await supertest + .get(`${LIST_URL}?id=${createListBody.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getListResponseMockWithoutAutoGeneratedValues()); + }); + + it('should return 404 if given a fake id', async () => { + const { body } = await supertest + .get(`${LIST_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'list id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist', + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/update_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/update_list_items.ts new file mode 100644 index 0000000000000..3ff496216eb71 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/update_list_items.ts @@ -0,0 +1,154 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { getListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_item_schema.mock'; +import { getCreateMinimalListItemSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_item_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { LIST_URL, LIST_ITEM_URL } from '../../../../plugins/lists/common/constants'; + +import { getCreateMinimalListSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; +import { + createListsIndex, + deleteListsIndex, + removeListItemServerGeneratedProperties, +} from '../../utils'; +import { getUpdateMinimalListItemSchemaMock } from '../../../../plugins/lists/common/schemas/request/update_list_item_schema.mock'; +import { + UpdateListItemSchema, + CreateListItemSchema, + ListItemSchema, +} from '../../../../plugins/lists/common/schemas'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + + describe('update_list_items', () => { + describe('update list items', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should update a single list item property of value using an id', async () => { + // create a simple list + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + // create a simple list item + await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + // update a simple list item's value + const updatedListItem: UpdateListItemSchema = { + ...getUpdateMinimalListItemSchemaMock(), + value: '192.168.0.2', + }; + + const { body } = await supertest + .put(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(updatedListItem) + .expect(200); + + const outputListItem: Partial = { + ...getListItemResponseMockWithoutAutoGeneratedValues(), + value: '192.168.0.2', + }; + const bodyToCompare = removeListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputListItem); + }); + + it('should update a single list item of value using an auto-generated id of both list and list item', async () => { + const { id, ...listNoId } = getCreateMinimalListSchemaMock(); + // create a simple list with no id which will use an auto-generated id + const { body: createListBody } = await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(listNoId) + .expect(200); + + // create a simple list item also with an auto-generated id using the list's auto-generated id + const listItem: CreateListItemSchema = { + ...getCreateMinimalListItemSchemaMock(), + list_id: createListBody.id, + }; + const { body: createListItemBody } = await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(listItem) + .expect(200); + + // update a simple list item's value + const updatedList: UpdateListItemSchema = { + ...getUpdateMinimalListItemSchemaMock(), + id: createListItemBody.id, + value: '192.168.0.2', + }; + const { body } = await supertest + .put(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(200); + + const outputListItem: Partial = { + ...getListItemResponseMockWithoutAutoGeneratedValues(), + value: '192.168.0.2', + }; + const bodyToCompare = { + ...removeListItemServerGeneratedProperties(body), + list_id: outputListItem.list_id, + }; + expect(bodyToCompare).to.eql(outputListItem); + }); + + it('should give a 404 if it is given a fake id', async () => { + // create a simple list + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + // create a simple list item + await supertest + .post(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListItemSchemaMock()) + .expect(200); + + // update a simple list item's value + const updatedListItem: UpdateListItemSchema = { + ...getUpdateMinimalListItemSchemaMock(), + id: 'some-other-id', + value: '192.168.0.2', + }; + + const { body } = await supertest + .put(LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(updatedListItem) + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'list item id: "some-other-id" not found', + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/update_lists.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/update_lists.ts new file mode 100644 index 0000000000000..04d77ffe21370 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/update_lists.ts @@ -0,0 +1,141 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { LIST_URL } from '../../../../plugins/lists/common/constants'; + +import { getCreateMinimalListSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_list_schema.mock'; +import { + createListsIndex, + deleteListsIndex, + removeListServerGeneratedProperties, +} from '../../utils'; +import { getListResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/list_schema.mock'; +import { getUpdateMinimalListSchemaMock } from '../../../../plugins/lists/common/schemas/request/update_list_schema.mock'; +import { UpdateListSchema, ListSchema } from '../../../../plugins/lists/common/schemas'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + + describe('update_lists', () => { + describe('update lists', () => { + beforeEach(async () => { + await createListsIndex(supertest); + }); + + afterEach(async () => { + await deleteListsIndex(supertest); + }); + + it('should update a single list property of name using an id', async () => { + // create a simple list + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + // update a simple list's name + const updatedList: UpdateListSchema = { + ...getUpdateMinimalListSchemaMock(), + name: 'some other name', + }; + + const { body } = await supertest + .put(LIST_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(200); + + const outputList: Partial = { + ...getListResponseMockWithoutAutoGeneratedValues(), + name: 'some other name', + version: 2, + }; + const bodyToCompare = removeListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputList); + }); + + it('should update a single list property of name using an auto-generated id', async () => { + const { id, ...listNoId } = getCreateMinimalListSchemaMock(); + // create a simple list with no id which will use an auto-generated id + const { body: createListBody } = await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(listNoId) + .expect(200); + + // update a simple list's name + const updatedList: UpdateListSchema = { + ...getUpdateMinimalListSchemaMock(), + id: createListBody.id, + name: 'some other name', + }; + const { body } = await supertest + .put(LIST_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(200); + + const outputList: Partial = { + ...getListResponseMockWithoutAutoGeneratedValues(), + name: 'some other name', + version: 2, + }; + const bodyToCompare = removeListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputList); + }); + + it('should change the version of a list when it updates a property', async () => { + // create a simple list + await supertest + .post(LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateMinimalListSchemaMock()) + .expect(200); + + // update a simple list property of name and description + const updatedList: UpdateListSchema = { + ...getUpdateMinimalListSchemaMock(), + name: 'some other name', + description: 'some other description', + }; + + const { body } = await supertest.put(LIST_URL).set('kbn-xsrf', 'true').send(updatedList); + + const outputList: Partial = { + ...getListResponseMockWithoutAutoGeneratedValues(), + name: 'some other name', + description: 'some other description', + version: 2, + }; + + const bodyToCompare = removeListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputList); + }); + + it('should give a 404 if it is given a fake id', async () => { + const simpleList: UpdateListSchema = { + ...getUpdateMinimalListSchemaMock(), + id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', + }; + const { body } = await supertest + .put(LIST_URL) + .set('kbn-xsrf', 'true') + .send(simpleList) + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'list id: "5096dec6-b6b9-4d8d-8f93-6c2602079d9d" not found', + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/utils.ts b/x-pack/test/lists_api_integration/utils.ts new file mode 100644 index 0000000000000..272768fdf50b3 --- /dev/null +++ b/x-pack/test/lists_api_integration/utils.ts @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SuperTest } from 'supertest'; +import supertestAsPromised from 'supertest-as-promised'; + +import { ListItemSchema } from '../../plugins/lists/common/schemas'; +import { ListSchema } from '../../plugins/lists/common'; +import { LIST_INDEX } from '../../plugins/lists/common/constants'; + +/** + * Creates the lists and lists items index for use inside of beforeEach blocks of tests + * This will retry 20 times before giving up and hopefully still not interfere with other tests + * @param supertest The supertest client library + */ +export const createListsIndex = async ( + supertest: SuperTest, + retryCount = 20 +): Promise => { + if (retryCount > 0) { + try { + await supertest.post(LIST_INDEX).set('kbn-xsrf', 'true').send(); + } catch (err) { + // eslint-disable-next-line no-console + console.log( + `Failure trying to create the lists index, retries left are: ${retryCount - 1}`, + err + ); + await createListsIndex(supertest, retryCount - 1); + } + } else { + // eslint-disable-next-line no-console + console.log('Could not createListsIndex, no retries are left'); + } +}; + +/** + * Deletes the lists index for use inside of afterEach blocks of tests + * @param supertest The supertest client library + */ +export const deleteListsIndex = async ( + supertest: SuperTest, + retryCount = 20 +): Promise => { + if (retryCount > 0) { + try { + await supertest.delete(LIST_INDEX).set('kbn-xsrf', 'true').send(); + } catch (err) { + // eslint-disable-next-line no-console + console.log(`Failure trying to deleteListsIndex, retries left are: ${retryCount - 1}`, err); + await deleteListsIndex(supertest, retryCount - 1); + } + } else { + // eslint-disable-next-line no-console + console.log('Could not deleteListsIndex, no retries are left'); + } +}; + +/** + * This will remove server generated properties such as date times, etc... + * @param list List to pass in to remove typical server generated properties + */ +export const removeListServerGeneratedProperties = ( + list: Partial +): Partial => { + /* eslint-disable-next-line @typescript-eslint/naming-convention */ + const { created_at, updated_at, id, tie_breaker_id, _version, ...removedProperties } = list; + return removedProperties; +}; + +/** + * This will remove server generated properties such as date times, etc... + * @param list List to pass in to remove typical server generated properties + */ +export const removeListItemServerGeneratedProperties = ( + list: Partial +): Partial => { + /* eslint-disable-next-line @typescript-eslint/naming-convention */ + const { created_at, updated_at, id, tie_breaker_id, _version, ...removedProperties } = list; + return removedProperties; +}; + +// Similar to ReactJs's waitFor from here: https://testing-library.com/docs/dom-testing-library/api-async#waitfor +export const waitFor = async ( + functionToTest: () => Promise, + maxTimeout: number = 5000, + timeoutWait: number = 10 +) => { + await new Promise(async (resolve, reject) => { + let found = false; + let numberOfTries = 0; + while (!found && numberOfTries < Math.floor(maxTimeout / timeoutWait)) { + const itPasses = await functionToTest(); + if (itPasses) { + found = true; + } else { + numberOfTries++; + } + await new Promise((resolveTimeout) => setTimeout(resolveTimeout, timeoutWait)); + } + if (found) { + resolve(); + } else { + reject(new Error('timed out waiting for function condition to be true')); + } + }); +}; + +/** + * Useful for export_api testing to convert from a multi-part binary back to a string + * @param res Response + * @param callback Callback + */ +export const binaryToString = (res: any, callback: any): void => { + res.setEncoding('binary'); + res.data = ''; + res.on('data', (chunk: any) => { + res.data += chunk; + }); + res.on('end', () => { + callback(null, Buffer.from(res.data)); + }); +}; From bc0b4821ad747aeae82422316da5505d361be46f Mon Sep 17 00:00:00 2001 From: Corey Robertson Date: Tue, 11 Aug 2020 11:36:08 -0400 Subject: [PATCH 100/106] [Canvas][tech-debt] Convert renderers (#74134) * Convert renderers to typescript * Fix typo * Fix type issues * Fixes * Fix issue with data table render Co-authored-by: Elastic Machine --- .../functions/browser/markdown.ts | 2 +- .../functions/common/containerStyle.ts | 1 - .../functions/common/image.ts | 3 +- .../functions/common/index.ts | 2 +- .../canvas_plugin_src/functions/common/pie.ts | 2 +- .../functions/common/progress.ts | 6 ++- .../functions/common/repeat_image.test.js | 2 +- .../{repeatImage.ts => repeat_image.ts} | 9 +++- .../functions/common/revealImage.ts | 10 +++- .../functions/common/shape.ts | 2 +- .../functions/common/table.ts | 4 +- .../lib/{elastic_logo.js => elastic_logo.ts} | 0 ...{elastic_outline.js => elastic_outline.ts} | 0 .../canvas/canvas_plugin_src/plugin.ts | 1 - .../renderers/{core.js => core.ts} | 0 .../renderers/{debug.js => debug.tsx} | 3 +- .../renderers/embeddable/embeddable.tsx | 13 +++-- .../renderers/error/{index.js => index.tsx} | 11 +++-- .../filters/advanced_filter/index.tsx | 2 +- .../renderers/filters/{index.js => index.ts} | 0 .../renderers/{image.js => image.tsx} | 4 +- .../renderers/{index.js => index.ts} | 0 .../markdown/{index.js => index.tsx} | 8 +-- .../renderers/pie/{index.js => index.tsx} | 26 +++++++--- .../renderers/plot/{index.js => index.ts} | 12 +++-- .../renderers/progress/{index.js => index.ts} | 49 ++++++++++--------- .../progress/shapes/{index.js => index.ts} | 0 .../{repeat_image.js => repeat_image.ts} | 14 +++--- .../reveal_image/{index.js => index.ts} | 19 ++++--- .../renderers/shape/{index.js => index.ts} | 28 ++++++----- .../renderers/{table.js => table.tsx} | 20 +++++--- .../renderers/{text.js => text.tsx} | 7 +-- x-pack/plugins/canvas/common/lib/index.ts | 2 - .../{missing_asset.js => missing_asset.ts} | 0 .../common/lib/{url.test.js => url.test.ts} | 0 .../canvas/common/lib/{url.js => url.ts} | 2 +- .../i18n/functions/dict/repeat_image.ts | 2 +- .../components/error/{error.js => error.tsx} | 10 +++- .../components/error/{index.js => index.ts} | 0 .../{show_debugging.js => show_debugging.tsx} | 17 +++---- x-pack/plugins/canvas/public/plugin_api.ts | 12 +++-- .../public/services/stubs/expressions.ts | 13 ++--- .../__stories__/rendered_element.stories.tsx | 1 - .../components/rendered_element.tsx | 4 +- x-pack/plugins/canvas/types/renderers.ts | 3 ++ 45 files changed, 197 insertions(+), 129 deletions(-) rename x-pack/plugins/canvas/canvas_plugin_src/functions/common/{repeatImage.ts => repeat_image.ts} (93%) rename x-pack/plugins/canvas/canvas_plugin_src/lib/{elastic_logo.js => elastic_logo.ts} (100%) rename x-pack/plugins/canvas/canvas_plugin_src/lib/{elastic_outline.js => elastic_outline.ts} (100%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/{core.js => core.ts} (100%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/{debug.js => debug.tsx} (91%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/error/{index.js => index.tsx} (84%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/{index.js => index.ts} (100%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/{image.js => image.tsx} (86%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/{index.js => index.ts} (100%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/markdown/{index.js => index.tsx} (78%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/{index.js => index.tsx} (74%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/{index.js => index.ts} (82%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/{index.js => index.ts} (64%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/shapes/{index.js => index.ts} (100%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/{repeat_image.js => repeat_image.ts} (81%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/reveal_image/{index.js => index.ts} (80%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/shape/{index.js => index.ts} (73%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/{table.js => table.tsx} (61%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/{text.js => text.tsx} (71%) rename x-pack/plugins/canvas/common/lib/{missing_asset.js => missing_asset.ts} (100%) rename x-pack/plugins/canvas/common/lib/{url.test.js => url.test.ts} (100%) rename x-pack/plugins/canvas/common/lib/{url.js => url.ts} (90%) rename x-pack/plugins/canvas/public/components/error/{error.js => error.tsx} (86%) rename x-pack/plugins/canvas/public/components/error/{index.js => index.ts} (100%) rename x-pack/plugins/canvas/public/components/error/{show_debugging.js => show_debugging.tsx} (64%) diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.ts index e44fb903ef042..947106fd9397a 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.ts @@ -22,7 +22,7 @@ interface Arguments { openLinksInNewTab: boolean; } -interface Return { +export interface Return { content: string; font: Style; openLinksInNewTab: boolean; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/containerStyle.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/containerStyle.ts index 09ce2b2bf1755..93e4a3636b914 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/containerStyle.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/containerStyle.ts @@ -6,7 +6,6 @@ import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common'; import { ContainerStyle, Overflow, BackgroundRepeat, BackgroundSize } from '../../../types'; import { getFunctionHelp, getFunctionErrors } from '../../../i18n'; -// @ts-expect-error untyped local import { isValidUrl } from '../../../common/lib/url'; interface Output extends ContainerStyle { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/image.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/image.ts index 3ef956b41ce20..21157660ed414 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/image.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/image.ts @@ -8,7 +8,6 @@ import { getFunctionHelp, getFunctionErrors } from '../../../i18n'; // @ts-expect-error untyped local import { resolveWithMissingImage } from '../../../common/lib/resolve_dataurl'; -// @ts-expect-error .png file import { elasticLogo } from '../../lib/elastic_logo'; export enum ImageMode { @@ -22,7 +21,7 @@ interface Arguments { mode: ImageMode | null; } -interface Return { +export interface Return { type: 'image'; mode: string; dataurl: string; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/index.ts index 79538941bbbfa..5ec831efbe35f 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/index.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/index.ts @@ -46,7 +46,7 @@ import { render } from './render'; import { replace } from './replace'; import { rounddate } from './rounddate'; import { rowCount } from './rowCount'; -import { repeatImage } from './repeatImage'; +import { repeatImage } from './repeat_image'; import { revealImage } from './revealImage'; import { seriesStyle } from './seriesStyle'; import { shape } from './shape'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/pie.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/pie.ts index c32c553fffc1b..16eee349475ef 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/pie.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/pie.ts @@ -57,7 +57,7 @@ interface PieData { color?: string; } -interface Pie { +export interface Pie { font: Style; data: PieData[]; options: PieOptions; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/progress.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/progress.ts index 6fc1e509cd5e6..4c4dba3ef7a3b 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/progress.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/progress.ts @@ -20,7 +20,7 @@ export enum Shape { WHEEL = 'wheel', } -interface Arguments { +export interface Arguments { barColor: string; barWeight: number; font: Style; @@ -31,6 +31,10 @@ interface Arguments { valueWeight: number; } +export type Output = Arguments & { + value: number; +}; + export function progress(): ExpressionFunctionDefinition< 'progress', number, diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/repeat_image.test.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/repeat_image.test.js index 723c5eb4c6823..f7c1ecc94a240 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/repeat_image.test.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/repeat_image.test.js @@ -7,7 +7,7 @@ import { functionWrapper } from '../../../__tests__/helpers/function_wrapper'; import { elasticOutline } from '../../lib/elastic_outline'; import { elasticLogo } from '../../lib/elastic_logo'; -import { repeatImage } from './repeatImage'; +import { repeatImage } from './repeat_image'; describe('repeatImage', () => { const fn = functionWrapper(repeatImage); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/repeatImage.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/repeat_image.ts similarity index 93% rename from x-pack/plugins/canvas/canvas_plugin_src/functions/common/repeatImage.ts rename to x-pack/plugins/canvas/canvas_plugin_src/functions/common/repeat_image.ts index 9e296f2b9a92a..cbb118c0db807 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/repeatImage.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/repeat_image.ts @@ -7,7 +7,6 @@ import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common'; // @ts-expect-error untyped local import { resolveWithMissingImage } from '../../../common/lib/resolve_dataurl'; -// @ts-expect-error .png file import { elasticOutline } from '../../lib/elastic_outline'; import { Render } from '../../../types'; import { getFunctionHelp } from '../../../i18n'; @@ -19,6 +18,14 @@ interface Arguments { emptyImage: string | null; } +export interface Return { + count: number; + image: string; + size: number; + max: number; + emptyImage: string | null; +} + export function repeatImage(): ExpressionFunctionDefinition< 'repeatImage', number, diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/revealImage.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/revealImage.ts index 3e721cc49b411..9288a417f9d29 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/revealImage.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/revealImage.ts @@ -7,7 +7,6 @@ import { ExpressionFunctionDefinition, ExpressionValueRender } from 'src/plugins/expressions'; // @ts-expect-error untyped local import { resolveWithMissingImage } from '../../../common/lib/resolve_dataurl'; -// @ts-expect-error .png file import { elasticOutline } from '../../lib/elastic_outline'; import { getFunctionHelp, getFunctionErrors } from '../../../i18n'; @@ -24,11 +23,18 @@ interface Arguments { origin: Origin; } +export interface Output { + image: string; + emptyImage: string; + origin: Origin; + percent: number; +} + export function revealImage(): ExpressionFunctionDefinition< 'revealImage', number, Arguments, - ExpressionValueRender + ExpressionValueRender > { const { help, args: argHelp } = getFunctionHelp().revealImage; const errors = getFunctionErrors().revealImage; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/shape.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/shape.ts index a3fedebd36cfe..e7178ab4eef5b 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/shape.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/shape.ts @@ -34,7 +34,7 @@ interface Arguments { maintainAspect: boolean; } -interface Output extends Arguments { +export interface Output extends Arguments { type: 'shape'; } diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/table.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/table.ts index 689f3f969d1c8..744d426d3bc6c 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/table.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/table.ts @@ -15,11 +15,13 @@ interface Arguments { showHeader: boolean; } +export type Return = { datatable: Datatable } & Arguments; + export function table(): ExpressionFunctionDefinition< 'table', Datatable, Arguments, - Render + Render > { const { help, args: argHelp } = getFunctionHelp().table; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/lib/elastic_logo.js b/x-pack/plugins/canvas/canvas_plugin_src/lib/elastic_logo.ts similarity index 100% rename from x-pack/plugins/canvas/canvas_plugin_src/lib/elastic_logo.js rename to x-pack/plugins/canvas/canvas_plugin_src/lib/elastic_logo.ts diff --git a/x-pack/plugins/canvas/canvas_plugin_src/lib/elastic_outline.js b/x-pack/plugins/canvas/canvas_plugin_src/lib/elastic_outline.ts similarity index 100% rename from x-pack/plugins/canvas/canvas_plugin_src/lib/elastic_outline.js rename to x-pack/plugins/canvas/canvas_plugin_src/lib/elastic_outline.ts diff --git a/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts b/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts index 59f0287805eac..55f5319bbadb7 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts @@ -12,7 +12,6 @@ import { Start as InspectorStart } from '../../../../src/plugins/inspector/publi import { functions } from './functions/browser'; import { typeFunctions } from './expression_types'; -// @ts-expect-error: untyped local import { renderFunctions, renderFunctionFactories } from './renderers'; import { initializeElements } from './elements'; // @ts-expect-error untyped local diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/core.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/core.ts similarity index 100% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/core.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/core.ts diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/debug.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/debug.tsx similarity index 91% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/debug.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/debug.tsx index 79ec0078fa98a..b4fbba96e8dfb 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/debug.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/debug.tsx @@ -8,10 +8,11 @@ import ReactDOM from 'react-dom'; import React from 'react'; import { Debug } from '../../public/components/debug'; import { RendererStrings } from '../../i18n'; +import { RendererFactory } from '../../types'; const { debug: strings } = RendererStrings; -export const debug = () => ({ +export const debug: RendererFactory = () => ({ name: 'debug', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx index ad368a912cd8c..641580d9c58a5 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx @@ -17,7 +17,7 @@ import { EmbeddableExpression } from '../../expression_types/embeddable'; import { RendererStrings } from '../../../i18n'; import { embeddableInputToExpression } from './embeddable_input_to_expression'; import { EmbeddableInput } from '../../expression_types'; -import { RendererHandlers } from '../../../types'; +import { RendererFactory } from '../../../types'; import { CANVAS_EMBEDDABLE_CLASSNAME } from '../../../common/lib'; const { embeddable: strings } = RendererStrings; @@ -43,18 +43,17 @@ const renderEmbeddableFactory = (core: CoreStart, plugins: StartDeps) => { }; }; -export const embeddableRendererFactory = (core: CoreStart, plugins: StartDeps) => { +export const embeddableRendererFactory = ( + core: CoreStart, + plugins: StartDeps +): RendererFactory> => { const renderEmbeddable = renderEmbeddableFactory(core, plugins); return () => ({ name: 'embeddable', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), reuseDomNode: true, - render: async ( - domNode: HTMLElement, - { input, embeddableType }: EmbeddableExpression, - handlers: RendererHandlers - ) => { + render: async (domNode, { input, embeddableType }, handlers) => { const uniqueId = handlers.getElementId(); if (!embeddablesRegistry[uniqueId]) { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/error/index.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/error/index.tsx similarity index 84% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/error/index.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/error/index.tsx index b7e3fc300a189..a9296bd9a1241 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/error/index.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/error/index.tsx @@ -5,15 +5,20 @@ */ import ReactDOM from 'react-dom'; -import React from 'react'; +import React, { MouseEventHandler } from 'react'; import { EuiIcon } from '@elastic/eui'; import { Error } from '../../../public/components/error'; import { Popover } from '../../../public/components/popover'; import { RendererStrings } from '../../../i18n'; +import { RendererFactory } from '../../../types'; + +interface Config { + error: Error; +} const { error: strings } = RendererStrings; -export const error = () => ({ +export const error: RendererFactory = () => ({ name: 'error', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), @@ -21,7 +26,7 @@ export const error = () => ({ render(domNode, config, handlers) { const draw = () => { const buttonSize = Math.min(domNode.clientHeight, domNode.clientWidth); - const button = (handleClick) => ( + const button = (handleClick: MouseEventHandler) => ( ({ +export const advancedFilter: RendererFactory<{}> = () => ({ name: 'advanced_filter', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/index.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/index.ts similarity index 100% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/index.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/index.ts diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/image.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/image.tsx similarity index 86% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/image.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/image.tsx index fd76f0106f7d5..cbd81f0143da8 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/image.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/image.tsx @@ -8,11 +8,13 @@ import ReactDOM from 'react-dom'; import React from 'react'; import { elasticLogo } from '../lib/elastic_logo'; import { isValidUrl } from '../../common/lib/url'; +import { Return as Arguments } from '../functions/common/image'; import { RendererStrings } from '../../i18n'; +import { RendererFactory } from '../../types'; const { image: strings } = RendererStrings; -export const image = () => ({ +export const image: RendererFactory = () => ({ name: 'image', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/index.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/index.ts similarity index 100% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/index.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/index.ts diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/markdown/index.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/markdown/index.tsx similarity index 78% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/markdown/index.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/markdown/index.tsx index a7b0f620cf710..1ce05b77a5109 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/markdown/index.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/markdown/index.tsx @@ -4,14 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { CSSProperties } from 'react'; import ReactDOM from 'react-dom'; import { RendererStrings } from '../../../i18n'; +import { Return as Config } from '../../functions/browser/markdown'; import { Markdown } from '../../../../../../src/plugins/kibana_react/public'; +import { RendererFactory } from '../../../types'; const { markdown: strings } = RendererStrings; -export const markdown = () => ({ +export const markdown: RendererFactory = () => ({ name: 'markdown', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), @@ -22,7 +24,7 @@ export const markdown = () => ({ ReactDOM.render( , diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/index.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/index.tsx similarity index 74% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/index.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/index.tsx index cb423af30094c..622e73ccf2223 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/index.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/index.tsx @@ -10,11 +10,14 @@ import '../../lib/flot-charts'; import { debounce, includes } from 'lodash'; import { RendererStrings } from '../../../i18n'; +// @ts-expect-error Untyped local: Will not convert import { pie as piePlugin } from './plugins/pie'; +import { Pie } from '../../functions/common/pie'; +import { RendererFactory } from '../../../types'; const { pie: strings } = RendererStrings; -export const pie = () => ({ +export const pie: RendererFactory = () => ({ name: 'pie', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), @@ -27,7 +30,10 @@ export const pie = () => ({ config.options.legend.labelBoxBorderColor = 'transparent'; if (config.font) { - const labelFormatter = (label, slice) => { + const labelFormatter = ( + label: string, + slice: jquery.flot.dataSeries & { percent: number } + ) => { // font color defaults to slice color if not specified const fontSpec = { ...config.font.spec, color: config.font.spec.color || slice.color }; const labelDiv = document.createElement('div'); @@ -36,23 +42,28 @@ export const pie = () => ({ const lineBreak = document.createElement('br'); const percentText = document.createTextNode(`${Math.round(slice.percent)}%`); - labelDiv.appendChild(labelSpan); + if (labelSpan) { + labelDiv.appendChild(labelSpan); + } labelDiv.appendChild(lineBreak); labelDiv.appendChild(percentText); return labelDiv.outerHTML; }; + // @ts-ignore ignoring missing propery config.options.series.pie.label.formatter = labelFormatter; - const legendFormatter = (label) => { + const legendFormatter = (label: string) => { const labelSpan = document.createElement('span'); Object.assign(labelSpan.style, config.font.spec); labelSpan.textContent = label; return labelSpan.outerHTML; }; + // @ts-ignore ignoring missing propery config.options.legend.labelFormatter = legendFormatter; } - let plot; + let plot: jquery.flot.plot; + function draw() { if (domNode.clientHeight < 1 || domNode.clientWidth < 1) { return; @@ -63,10 +74,11 @@ export const pie = () => ({ if (!config.data || !config.data.length) { $(domNode).empty(); } else { - plot = $.plot($(domNode), config.data, config.options); + // Casting config.options to any here as the flot typings do not appear to be accurate. + // For example, it does not have colors as a valid option. + plot = $.plot($(domNode), config.data, config.options as any); } } catch (e) { - console.log(e); // Nope } } diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/index.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/index.ts similarity index 82% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/index.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/index.ts index ab523f1526e16..8c84f54f8746b 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/index.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/index.ts @@ -10,12 +10,15 @@ import '../../lib/flot-charts'; import { debounce, includes } from 'lodash'; import { RendererStrings } from '../../../i18n'; +import { RendererFactory, RendererSpec } from '../../../types'; +// @ts-expect-error Not going to convert import { size } from './plugins/size'; +// @ts-expect-error Not going to convert import { text } from './plugins/text'; const { plot: strings } = RendererStrings; -const render = (domNode, config, handlers) => { +const render: RendererSpec['render'] = (domNode, config, handlers) => { // TODO: OH NOES if (!includes($.plot.plugins, size)) { $.plot.plugins.push(size); @@ -24,14 +27,14 @@ const render = (domNode, config, handlers) => { $.plot.plugins.push(text); } - let plot; + let plot: jquery.flot.plot; function draw() { if (domNode.clientHeight < 1 || domNode.clientWidth < 1) { return; } if (config.font) { - const legendFormatter = (label) => { + const legendFormatter = (label: string) => { const labelSpan = document.createElement('span'); Object.assign(labelSpan.style, config.font.spec); labelSpan.textContent = label; @@ -67,9 +70,10 @@ const render = (domNode, config, handlers) => { return handlers.done(); }; -export const plot = () => ({ +export const plot: RendererFactory = () => ({ name: 'plot', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), + reuseDomNode: false, render, }); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/index.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/index.ts similarity index 64% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/index.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/index.ts index 67d0abb65837d..ea57655c230b9 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/index.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/index.ts @@ -7,10 +7,12 @@ import { getId } from '../../../public/lib/get_id'; import { RendererStrings } from '../../../i18n'; import { shapes } from './shapes'; +import { Output as Arguments } from '../../functions/common/progress'; +import { RendererFactory } from '../../../types'; const { progress: strings } = RendererStrings; -export const progress = () => ({ +export const progress: RendererFactory = () => ({ name: 'progress', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), @@ -23,12 +25,13 @@ export const progress = () => ({ if (shapeDef) { const parser = new DOMParser(); - const [shapeSvg] = parser - .parseFromString(shapes[shape], 'image/svg+xml') - .getElementsByTagName('svg'); + const shapeSvg = parser + .parseFromString(shapeDef, 'image/svg+xml') + .getElementsByTagName('svg') + .item(0)!; const initialViewBox = shapeSvg - .getAttribute('viewBox') + .getAttribute('viewBox')! .split(' ') .map((v) => parseInt(v, 10)); let [minX, minY, width, height] = initialViewBox; @@ -51,35 +54,35 @@ export const progress = () => ({ const svgId = getId('svg'); shapeSvg.id = svgId; - const [bar] = shapeSvg.getElementsByTagName('path'); + const bar = shapeSvg.getElementsByTagName('path').item(0)!; bar.setAttribute('className', 'canvasProgress__background'); bar.setAttribute('fill', 'none'); bar.setAttribute('stroke', barColor); bar.setAttribute('stroke-width', `${barWeight}px`); - const value = bar.cloneNode(true); - value.setAttribute('className', 'canvasProgress__value'); - value.setAttribute('stroke', valueColor); - value.setAttribute('stroke-width', `${valueWeight}px`); + const valueSvg = bar.cloneNode(true) as SVGPathElement; + valueSvg.setAttribute('className', 'canvasProgress__value'); + valueSvg.setAttribute('stroke', valueColor); + valueSvg.setAttribute('stroke-width', `${valueWeight}px`); - const length = value.getTotalLength(); + const length = valueSvg.getTotalLength(); const to = length * (1 - percent); - value.setAttribute('stroke-dasharray', length); - value.setAttribute('stroke-dashoffset', Math.max(0, to)); + valueSvg.setAttribute('stroke-dasharray', String(length)); + valueSvg.setAttribute('stroke-dashoffset', String(Math.max(0, to))); - shapeSvg.appendChild(value); + shapeSvg.appendChild(valueSvg); - const [text] = shapeSvg.getElementsByTagName('text'); + const text = shapeSvg.getElementsByTagName('text').item(0); if (label && text) { - text.textContent = label; + text.textContent = String(label); text.setAttribute('className', 'canvasProgress__label'); if (shape === 'horizontalPill') { - text.setAttribute('x', parseInt(text.getAttribute('x'), 10) + offset / 2); + text.setAttribute('x', String(parseInt(text.getAttribute('x')!, 10) + offset / 2)); } if (shape === 'verticalPill') { - text.setAttribute('y', parseInt(text.getAttribute('y'), 10) - offset / 2); + text.setAttribute('y', String(parseInt(text.getAttribute('y')!, 10) - offset / 2)); } Object.assign(text.style, font.spec); @@ -89,7 +92,7 @@ export const progress = () => ({ const { width: labelWidth, height: labelHeight } = text.getBBox(); if (shape === 'horizontalBar' || shape === 'horizontalPill') { - text.setAttribute('x', parseInt(text.getAttribute('x'), 10)); + text.setAttribute('x', String(parseInt(text.getAttribute('x')!, 10))); width += labelWidth; } if (shape === 'verticalBar' || shape === 'verticalPill') { @@ -103,8 +106,8 @@ export const progress = () => ({ } shapeSvg.setAttribute('viewBox', [minX, minY, width, height].join(' ')); - shapeSvg.setAttribute('width', domNode.offsetWidth); - shapeSvg.setAttribute('height', domNode.offsetHeight); + shapeSvg.setAttribute('width', String(domNode.offsetWidth)); + shapeSvg.setAttribute('height', String(domNode.offsetHeight)); if (domNode.firstChild) { domNode.removeChild(domNode.firstChild); @@ -112,8 +115,8 @@ export const progress = () => ({ domNode.appendChild(shapeSvg); handlers.onResize(() => { - shapeSvg.setAttribute('width', domNode.offsetWidth); - shapeSvg.setAttribute('height', domNode.offsetHeight); + shapeSvg.setAttribute('width', String(domNode.offsetWidth)); + shapeSvg.setAttribute('height', String(domNode.offsetHeight)); }); } diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/shapes/index.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/shapes/index.ts similarity index 100% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/shapes/index.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/progress/shapes/index.ts diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/repeat_image.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/repeat_image.ts similarity index 81% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/repeat_image.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/repeat_image.ts index 2e48c8a2d5ec3..ff37ca7a0e3dd 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/repeat_image.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/repeat_image.ts @@ -9,25 +9,27 @@ import { times } from 'lodash'; import { elasticOutline } from '../lib/elastic_outline'; import { isValidUrl } from '../../common/lib/url'; import { RendererStrings, ErrorStrings } from '../../i18n'; +import { Return as Arguments } from '../functions/common/repeat_image'; +import { RendererFactory } from '../../types'; const { repeatImage: strings } = RendererStrings; const { RepeatImage: errors } = ErrorStrings; -export const repeatImage = () => ({ +export const repeatImage: RendererFactory = () => ({ name: 'repeatImage', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), reuseDomNode: true, render(domNode, config, handlers) { const settings = { - count: 10, ...config, image: isValidUrl(config.image) ? config.image : elasticOutline, + emptyImage: config.emptyImage || '', }; const container = $('
    '); - function setSize(img) { + function setSize(img: HTMLImageElement) { if (img.naturalHeight > img.naturalWidth) { img.height = settings.size; } else { @@ -36,7 +38,7 @@ export const repeatImage = () => ({ } function finish() { - $(domNode).html(container); + $(domNode).append(container); handlers.done(); } @@ -46,7 +48,7 @@ export const repeatImage = () => ({ if (settings.max && settings.count > settings.max) { settings.count = settings.max; } - times(settings.count, () => container.append(img.cloneNode(true))); + times(settings.count, () => container.append($(img).clone())); if (isValidUrl(settings.emptyImage)) { if (settings.max == null) { @@ -56,7 +58,7 @@ export const repeatImage = () => ({ const emptyImage = new Image(); emptyImage.onload = function () { setSize(emptyImage); - times(settings.max - settings.count, () => container.append(emptyImage.cloneNode(true))); + times(settings.max - settings.count, () => container.append($(emptyImage).clone())); finish(); }; emptyImage.src = settings.emptyImage; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/reveal_image/index.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/reveal_image/index.ts similarity index 80% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/reveal_image/index.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/reveal_image/index.ts index 96c8d80794c0c..c52556f8564c1 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/reveal_image/index.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/reveal_image/index.ts @@ -7,10 +7,12 @@ import { elasticOutline } from '../../lib/elastic_outline'; import { isValidUrl } from '../../../common/lib/url'; import { RendererStrings } from '../../../i18n'; +import { RendererFactory } from '../../../types'; +import { Output as Arguments } from '../../functions/common/revealImage'; const { revealImage: strings } = RendererStrings; -export const revealImage = () => ({ +export const revealImage: RendererFactory = () => ({ name: 'revealImage', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), @@ -23,16 +25,17 @@ export const revealImage = () => ({ domNode.className = 'revealImage'; // set up the overlay image - img.onload = function () { + function onLoad() { setSize(); finish(); - }; + } + img.onload = onLoad; img.className = 'revealImage__image'; img.style.clipPath = getClipPath(config.percent, config.origin); - img.style['-webkit-clip-path'] = getClipPath(config.percent, config.origin); + img.style.setProperty('-webkit-clip-path', getClipPath(config.percent, config.origin)); img.src = isValidUrl(config.image) ? config.image : elasticOutline; - handlers.onResize(img.onload); + handlers.onResize(onLoad); // set up the underlay, "empty" image aligner.className = 'revealImageAligner'; @@ -52,9 +55,9 @@ export const revealImage = () => ({ handlers.done(); } - function getClipPath(percent, origin = 'bottom') { - const directions = { bottom: 0, left: 1, top: 2, right: 3 }; - const values = [0, 0, 0, 0]; + function getClipPath(percent: number, origin = 'bottom') { + const directions: Record = { bottom: 0, left: 1, top: 2, right: 3 }; + const values: Array = [0, 0, 0, 0]; values[directions[origin]] = `${100 - percent * 100}%`; return `inset(${values.join(' ')})`; } diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/shape/index.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/shape/index.ts similarity index 73% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/shape/index.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/shape/index.ts index 5684c8c4602b5..7c61ff69b18e0 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/shape/index.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/shape/index.ts @@ -6,22 +6,26 @@ import { RendererStrings } from '../../../i18n'; import { shapes } from './shapes'; +import { RendererFactory } from '../../../types'; +import { Output } from '../../functions/common/shape'; const { shape: strings } = RendererStrings; -export const shape = () => ({ +export const shape: RendererFactory = () => ({ name: 'shape', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), reuseDomNode: true, render(domNode, config, handlers) { - const { shape, fill, border, borderWidth, maintainAspect } = config; + const { shape: shapeType, fill, border, borderWidth, maintainAspect } = config; + const parser = new DOMParser(); - const [shapeSvg] = parser - .parseFromString(shapes[shape], 'image/svg+xml') - .getElementsByTagName('svg'); + const shapeSvg = parser + .parseFromString(shapes[shapeType], 'image/svg+xml') + .getElementsByTagName('svg') + .item(0)!; - const shapeContent = shapeSvg.firstElementChild; + const shapeContent = shapeSvg.firstElementChild!; if (fill) { shapeContent.setAttribute('fill', fill); @@ -30,15 +34,15 @@ export const shape = () => ({ shapeContent.setAttribute('stroke', border); } const strokeWidth = Math.max(borderWidth, 0); - shapeContent.setAttribute('stroke-width', strokeWidth); - shapeContent.setAttribute('stroke-miterlimit', 999); + shapeContent.setAttribute('stroke-width', String(strokeWidth)); + shapeContent.setAttribute('stroke-miterlimit', '999'); shapeContent.setAttribute('vector-effect', 'non-scaling-stroke'); shapeSvg.setAttribute('preserveAspectRatio', maintainAspect ? 'xMidYMid meet' : 'none'); shapeSvg.setAttribute('overflow', 'visible'); const initialViewBox = shapeSvg - .getAttribute('viewBox') + .getAttribute('viewBox')! .split(' ') .map((v) => parseInt(v, 10)); @@ -66,8 +70,8 @@ export const shape = () => ({ shapeHeight = 0; } - shapeSvg.setAttribute('width', width); - shapeSvg.setAttribute('height', height); + shapeSvg.setAttribute('width', String(width)); + shapeSvg.setAttribute('height', String(height)); shapeSvg.setAttribute('viewBox', [minX, minY, shapeWidth, shapeHeight].join(' ')); const oldShape = domNode.firstElementChild; @@ -75,7 +79,7 @@ export const shape = () => ({ domNode.removeChild(oldShape); } - domNode.style.lineHeight = 0; + domNode.style.lineHeight = '0'; domNode.appendChild(shapeSvg); }; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/table.js b/x-pack/plugins/canvas/canvas_plugin_src/renderers/table.tsx similarity index 61% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/table.js rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/table.tsx index 971ba577643ed..ada159e07f6ae 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/table.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/table.tsx @@ -6,22 +6,30 @@ import ReactDOM from 'react-dom'; import React from 'react'; -import { get } from 'lodash'; -import { Datatable } from '../../public/components/datatable'; +import { Datatable as DatatableComponent } from '../../public/components/datatable'; import { RendererStrings } from '../../i18n'; +import { RendererFactory, Style, Datatable } from '../../types'; const { dropdownFilter: strings } = RendererStrings; -export const table = () => ({ +interface TableArguments { + font?: Style; + paginate: boolean; + perPage: number; + showHeader: boolean; + datatable: Datatable; +} + +export const table: RendererFactory = () => ({ name: 'table', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), reuseDomNode: true, render(domNode, config, handlers) { - const { datatable, paginate, perPage, font, showHeader } = config; + const { datatable, paginate, perPage, font = { spec: {} }, showHeader } = config; ReactDOM.render( -
    - + ({ +export const text: RendererFactory<{ text: string }> = () => ({ name: 'text', displayName: strings.getDisplayName(), help: strings.getHelpDescription(), reuseDomNode: true, - render(domNode, { text }, handlers) { - ReactDOM.render(
    {text}
    , domNode, () => handlers.done()); + render(domNode, { text: textString }, handlers) { + ReactDOM.render(
    {textString}
    , domNode, () => handlers.done()); handlers.onDestroy(() => ReactDOM.unmountComponentAtNode(domNode)); }, }); diff --git a/x-pack/plugins/canvas/common/lib/index.ts b/x-pack/plugins/canvas/common/lib/index.ts index 6bd7e0bc9948f..055f6ce7739b7 100644 --- a/x-pack/plugins/canvas/common/lib/index.ts +++ b/x-pack/plugins/canvas/common/lib/index.ts @@ -24,12 +24,10 @@ export * from './get_legend_config'; export * from './handlebars'; export * from './hex_to_rgb'; export * from './httpurl'; -// @ts-expect-error missing local definition export * from './missing_asset'; export * from './palettes'; export * from './pivot_object_array'; // @ts-expect-error missing local definition export * from './resolve_dataurl'; export * from './unquote_string'; -// @ts-expect-error missing local definition export * from './url'; diff --git a/x-pack/plugins/canvas/common/lib/missing_asset.js b/x-pack/plugins/canvas/common/lib/missing_asset.ts similarity index 100% rename from x-pack/plugins/canvas/common/lib/missing_asset.js rename to x-pack/plugins/canvas/common/lib/missing_asset.ts diff --git a/x-pack/plugins/canvas/common/lib/url.test.js b/x-pack/plugins/canvas/common/lib/url.test.ts similarity index 100% rename from x-pack/plugins/canvas/common/lib/url.test.js rename to x-pack/plugins/canvas/common/lib/url.test.ts diff --git a/x-pack/plugins/canvas/common/lib/url.js b/x-pack/plugins/canvas/common/lib/url.ts similarity index 90% rename from x-pack/plugins/canvas/common/lib/url.js rename to x-pack/plugins/canvas/common/lib/url.ts index bed5e30cbff3b..d2e031159d969 100644 --- a/x-pack/plugins/canvas/common/lib/url.js +++ b/x-pack/plugins/canvas/common/lib/url.ts @@ -7,6 +7,6 @@ import { isValidDataUrl } from '../../common/lib/dataurl'; import { isValidHttpUrl } from '../../common/lib/httpurl'; -export function isValidUrl(url) { +export function isValidUrl(url: string) { return isValidDataUrl(url) || isValidHttpUrl(url); } diff --git a/x-pack/plugins/canvas/i18n/functions/dict/repeat_image.ts b/x-pack/plugins/canvas/i18n/functions/dict/repeat_image.ts index aafaec11c4d1d..222947779a758 100644 --- a/x-pack/plugins/canvas/i18n/functions/dict/repeat_image.ts +++ b/x-pack/plugins/canvas/i18n/functions/dict/repeat_image.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { repeatImage } from '../../../canvas_plugin_src/functions/common/repeatImage'; +import { repeatImage } from '../../../canvas_plugin_src/functions/common/repeat_image'; import { FunctionHelp } from '../function_help'; import { FunctionFactory } from '../../../types'; import { CONTEXT, BASE64, URL } from '../../constants'; diff --git a/x-pack/plugins/canvas/public/components/error/error.js b/x-pack/plugins/canvas/public/components/error/error.tsx similarity index 86% rename from x-pack/plugins/canvas/public/components/error/error.js rename to x-pack/plugins/canvas/public/components/error/error.tsx index 2f82e7d669bd5..93650df93cbeb 100644 --- a/x-pack/plugins/canvas/public/components/error/error.js +++ b/x-pack/plugins/canvas/public/components/error/error.tsx @@ -4,16 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { FC } from 'react'; import PropTypes from 'prop-types'; import { EuiCallOut } from '@elastic/eui'; import { get } from 'lodash'; import { ComponentStrings } from '../../../i18n'; import { ShowDebugging } from './show_debugging'; +export interface Props { + payload: { + error: Error; + }; +} + const { Error: strings } = ComponentStrings; -export const Error = ({ payload }) => { +export const Error: FC = ({ payload }) => { const message = get(payload, 'error.message'); return ( diff --git a/x-pack/plugins/canvas/public/components/error/index.js b/x-pack/plugins/canvas/public/components/error/index.ts similarity index 100% rename from x-pack/plugins/canvas/public/components/error/index.js rename to x-pack/plugins/canvas/public/components/error/index.ts diff --git a/x-pack/plugins/canvas/public/components/error/show_debugging.js b/x-pack/plugins/canvas/public/components/error/show_debugging.tsx similarity index 64% rename from x-pack/plugins/canvas/public/components/error/show_debugging.js rename to x-pack/plugins/canvas/public/components/error/show_debugging.tsx index 102ebc3f8a7e8..0d5d74903828b 100644 --- a/x-pack/plugins/canvas/public/components/error/show_debugging.js +++ b/x-pack/plugins/canvas/public/components/error/show_debugging.tsx @@ -4,14 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { FC, useState } from 'react'; import PropTypes from 'prop-types'; -import { withState } from 'recompose'; import { EuiButtonEmpty } from '@elastic/eui'; import { Debug } from '../debug'; +import { Props } from './error'; -const ShowDebuggingComponent = ({ payload, expanded, setExpanded }) => - process.env.NODE_ENV === 'production' ? null : ( +export const ShowDebugging: FC = ({ payload }) => { + const [expanded, setExpanded] = useState(false); + + return process.env.NODE_ENV === 'production' ? null : (
    )}
    ); +}; -ShowDebuggingComponent.propTypes = { - expanded: PropTypes.bool.isRequired, - setExpanded: PropTypes.func.isRequired, +ShowDebugging.propTypes = { payload: PropTypes.object.isRequired, }; - -export const ShowDebugging = withState('expanded', 'setExpanded', false)(ShowDebuggingComponent); diff --git a/x-pack/plugins/canvas/public/plugin_api.ts b/x-pack/plugins/canvas/public/plugin_api.ts index 4074d240c06e9..62e82df4b0d04 100644 --- a/x-pack/plugins/canvas/public/plugin_api.ts +++ b/x-pack/plugins/canvas/public/plugin_api.ts @@ -6,7 +6,8 @@ import { AnyExpressionFunctionDefinition, AnyExpressionTypeDefinition, - RendererFactory, + AnyExpressionRenderDefinition, + AnyRendererFactory, } from '../types'; import { ElementFactory } from '../types'; import { ExpressionsSetup } from '../../../../src/plugins/expressions/public'; @@ -19,7 +20,7 @@ export interface CanvasApi { addElements: AddToRegistry; addFunctions: AddToRegistry<() => AnyExpressionFunctionDefinition>; addModelUIs: AddToRegistry; - addRenderers: AddToRegistry; + addRenderers: AddToRegistry; addTagUIs: AddToRegistry; addTransformUIs: AddToRegistry; addTransitions: AddToRegistry; @@ -65,8 +66,11 @@ export function getPluginApi( }); }, addRenderers: (renderers) => { - renderers.forEach((r: any) => { - expressionsPluginSetup.registerRenderer(r); + renderers.forEach((r) => { + // There is an issue of the canvas render definition not matching the expression render definition + // due to our handlers needing additional methods. For now, we are going to cast to get to the proper + // type, but we should work with AppArch to figure out how the Handlers can be genericized + expressionsPluginSetup.registerRenderer((r as unknown) as AnyExpressionRenderDefinition); }); }, diff --git a/x-pack/plugins/canvas/public/services/stubs/expressions.ts b/x-pack/plugins/canvas/public/services/stubs/expressions.ts index 26a90670106d0..ee332e20c4ca3 100644 --- a/x-pack/plugins/canvas/public/services/stubs/expressions.ts +++ b/x-pack/plugins/canvas/public/services/stubs/expressions.ts @@ -4,13 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ +import { AnyExpressionRenderDefinition } from 'src/plugins/expressions'; import { ExpressionsService } from '../'; -import { - plugin, - ExpressionRenderDefinition, -} from '../../../../../../src/plugins/expressions/public'; +import { plugin } from '../../../../../../src/plugins/expressions/public'; import { functions as functionDefinitions } from '../../../canvas_plugin_src/functions/common'; -// @ts-expect-error untyped local import { renderFunctions } from '../../../canvas_plugin_src/renderers/core'; const placeholder = {} as any; @@ -22,6 +19,6 @@ const setup = expressionsPlugin.setup(placeholder, { export const expressionsService: ExpressionsService = setup.fork(); functionDefinitions.forEach((fn) => expressionsService.registerFunction(fn)); -renderFunctions.forEach((fn: ExpressionRenderDefinition) => - expressionsService.registerRenderer(fn) -); +renderFunctions.forEach((fn) => { + expressionsService.registerRenderer((fn as unknown) as AnyExpressionRenderDefinition); +}); diff --git a/x-pack/plugins/canvas/shareable_runtime/components/__stories__/rendered_element.stories.tsx b/x-pack/plugins/canvas/shareable_runtime/components/__stories__/rendered_element.stories.tsx index 899edee7f0481..aba510b8e736a 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/__stories__/rendered_element.stories.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/__stories__/rendered_element.stories.tsx @@ -7,7 +7,6 @@ import { storiesOf } from '@storybook/react'; import React from 'react'; import { ExampleContext } from '../../test/context_example'; -// @ts-expect-error import { image } from '../../../canvas_plugin_src/renderers/image'; import { sharedWorkpads } from '../../test'; import { RenderedElement, RenderedElementComponent } from '../rendered_element'; diff --git a/x-pack/plugins/canvas/shareable_runtime/components/rendered_element.tsx b/x-pack/plugins/canvas/shareable_runtime/components/rendered_element.tsx index 6bcc0db92f1cc..2291eff0db0ec 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/rendered_element.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/rendered_element.tsx @@ -12,7 +12,7 @@ import { Positionable } from '../../public/components/positionable/positionable' import { elementToShape } from '../../public/components/workpad_page/utils'; import { CanvasRenderedElement } from '../types'; import { CanvasShareableContext, useCanvasShareableState } from '../context'; -import { RendererSpec } from '../../types'; +import { AnyRendererSpec } from '../../types'; import { createHandlers } from '../../public/lib/create_handlers'; import css from './rendered_element.module.scss'; @@ -33,7 +33,7 @@ export interface Props { * The Expression function that evaluates the state of the Element and renders * it to the Page. */ - fn: RendererSpec; + fn: AnyRendererSpec; } /** diff --git a/x-pack/plugins/canvas/types/renderers.ts b/x-pack/plugins/canvas/types/renderers.ts index 772a16aa94c60..7dcb94507b632 100644 --- a/x-pack/plugins/canvas/types/renderers.ts +++ b/x-pack/plugins/canvas/types/renderers.ts @@ -47,3 +47,6 @@ export interface RendererSpec { } export type RendererFactory = () => RendererSpec; + +export type AnyRendererFactory = RendererFactory; +export type AnyRendererSpec = RendererSpec; From d84777f053f6e2be1a6b7b8f19ba498cc6972730 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Tue, 11 Aug 2020 09:53:42 -0600 Subject: [PATCH 101/106] [data.search.SearchSource] Move some SearchSource dependencies to the server. (#74607) --- ...-plugins-data-public.getsearcherrortype.md | 22 ------- .../kibana-plugin-plugins-data-public.md | 3 +- ...s-data-public.searcherror._constructor_.md | 20 ------ ...-plugin-plugins-data-public.searcherror.md | 26 +++----- src/plugins/data/public/index.ts | 1 - src/plugins/data/public/public.api.md | 39 +++++------- src/plugins/data/public/search/fetch/index.ts | 1 - .../data/public/search/fetch/request_error.ts | 4 +- .../data/public/search/fetch/search_error.ts | 62 ------------------- src/plugins/data/public/search/fetch/types.ts | 9 +++ src/plugins/data/public/search/index.ts | 1 - .../search_source/create_search_source.ts | 2 +- .../public/search/search_source/parse_json.ts | 2 +- .../search/search_source/search_source.ts | 2 +- .../common}/index.ts | 3 +- .../utils => common}/migrate_legacy_query.ts | 0 src/plugins/kibana_legacy/kibana.json | 2 +- src/plugins/kibana_legacy/public/index.ts | 2 +- .../kibana_legacy/public/utils/index.ts | 1 - src/plugins/kibana_legacy/server/index.ts | 2 +- .../field_wildcard.test.ts | 0 .../field_wildcard.ts | 1 + src/plugins/kibana_utils/common/index.ts | 1 + src/plugins/kibana_utils/public/index.ts | 3 +- src/plugins/kibana_utils/server/index.ts | 9 ++- 25 files changed, 58 insertions(+), 160 deletions(-) delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearcherrortype.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror._constructor_.md delete mode 100644 src/plugins/data/public/search/fetch/search_error.ts rename src/plugins/{kibana_utils/public/field_wildcard => kibana_legacy/common}/index.ts (91%) rename src/plugins/kibana_legacy/{public/utils => common}/migrate_legacy_query.ts (100%) rename src/plugins/kibana_utils/{public/field_wildcard => common}/field_wildcard.test.ts (100%) rename src/plugins/kibana_utils/{public/field_wildcard => common}/field_wildcard.ts (99%) diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearcherrortype.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearcherrortype.md deleted file mode 100644 index b46728c093792..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearcherrortype.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [getSearchErrorType](./kibana-plugin-plugins-data-public.getsearcherrortype.md) - -## getSearchErrorType() function - -Signature: - -```typescript -export declare function getSearchErrorType({ message }: Pick): "UNSUPPORTED_QUERY" | undefined; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| { message } | Pick<SearchError, 'message'> | | - -Returns: - -`"UNSUPPORTED_QUERY" | undefined` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index c8d45804a3729..53c30b52cb985 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -18,7 +18,6 @@ | [OptionedParamType](./kibana-plugin-plugins-data-public.optionedparamtype.md) | | | [Plugin](./kibana-plugin-plugins-data-public.plugin.md) | | | [RequestTimeoutError](./kibana-plugin-plugins-data-public.requesttimeouterror.md) | Class used to signify that a request timed out. Useful for applications to conditionally handle this type of error differently than other errors. | -| [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) | | | [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) | | | [TimeHistory](./kibana-plugin-plugins-data-public.timehistory.md) | | @@ -39,7 +38,6 @@ | --- | --- | | [getDefaultQuery(language)](./kibana-plugin-plugins-data-public.getdefaultquery.md) | | | [getEsPreference(uiSettings, sessionId)](./kibana-plugin-plugins-data-public.getespreference.md) | | -| [getSearchErrorType({ message })](./kibana-plugin-plugins-data-public.getsearcherrortype.md) | | | [getSearchParamsFromRequest(searchRequest, dependencies)](./kibana-plugin-plugins-data-public.getsearchparamsfromrequest.md) | | | [getTime(indexPattern, timeRange, options)](./kibana-plugin-plugins-data-public.gettime.md) | | | [plugin(initializerContext)](./kibana-plugin-plugins-data-public.plugin.md) | | @@ -80,6 +78,7 @@ | [RefreshInterval](./kibana-plugin-plugins-data-public.refreshinterval.md) | | | [SavedQuery](./kibana-plugin-plugins-data-public.savedquery.md) | | | [SavedQueryService](./kibana-plugin-plugins-data-public.savedqueryservice.md) | | +| [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) | | | [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) | | | [SearchSourceFields](./kibana-plugin-plugins-data-public.searchsourcefields.md) | | | [TabbedAggColumn](./kibana-plugin-plugins-data-public.tabbedaggcolumn.md) | \* | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror._constructor_.md deleted file mode 100644 index 4d7691d24a79d..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror._constructor_.md +++ /dev/null @@ -1,20 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) > [(constructor)](./kibana-plugin-plugins-data-public.searcherror._constructor_.md) - -## SearchError.(constructor) - -Constructs a new instance of the `SearchError` class - -Signature: - -```typescript -constructor({ status, title, message, path, type }: SearchErrorOptions); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| { status, title, message, path, type } | SearchErrorOptions | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.md index 06e60cadf4a85..65b46bf6cba4d 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.md @@ -2,28 +2,22 @@ [Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) -## SearchError class +## SearchError interface Signature: ```typescript -export declare class SearchError extends Error +export interface SearchError ``` -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)({ status, title, message, path, type })](./kibana-plugin-plugins-data-public.searcherror._constructor_.md) | | Constructs a new instance of the SearchError class | - ## Properties -| Property | Modifiers | Type | Description | -| --- | --- | --- | --- | -| [message](./kibana-plugin-plugins-data-public.searcherror.message.md) | | string | | -| [name](./kibana-plugin-plugins-data-public.searcherror.name.md) | | string | | -| [path](./kibana-plugin-plugins-data-public.searcherror.path.md) | | string | | -| [status](./kibana-plugin-plugins-data-public.searcherror.status.md) | | string | | -| [title](./kibana-plugin-plugins-data-public.searcherror.title.md) | | string | | -| [type](./kibana-plugin-plugins-data-public.searcherror.type.md) | | string | | +| Property | Type | Description | +| --- | --- | --- | +| [message](./kibana-plugin-plugins-data-public.searcherror.message.md) | string | | +| [name](./kibana-plugin-plugins-data-public.searcherror.name.md) | string | | +| [path](./kibana-plugin-plugins-data-public.searcherror.path.md) | string | | +| [status](./kibana-plugin-plugins-data-public.searcherror.status.md) | string | | +| [title](./kibana-plugin-plugins-data-public.searcherror.title.md) | string | | +| [type](./kibana-plugin-plugins-data-public.searcherror.type.md) | string | | diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index 5a9930d2b6b56..f036d5f30a0e2 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -337,7 +337,6 @@ export { // search ES_SEARCH_STRATEGY, getEsPreference, - getSearchErrorType, ISearch, ISearchOptions, ISearchGeneric, diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index adff7b205b931..216ed018957e0 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -703,11 +703,6 @@ export function getEsPreference(uiSettings: IUiSettingsClient_2, sessionId?: str // @public export const getKbnTypeNames: () => string[]; -// Warning: (ae-missing-release-tag) "getSearchErrorType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export function getSearchErrorType({ message }: Pick): "UNSUPPORTED_QUERY" | undefined; - // Warning: (ae-forgotten-export) The symbol "ISearchRequestParams" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "getSearchParamsFromRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1696,9 +1691,7 @@ export type SearchBarProps = SearchBarOwnProps & SearchBarInjectedDeps; // Warning: (ae-missing-release-tag) "SearchError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export class SearchError extends Error { - // Warning: (ae-forgotten-export) The symbol "SearchErrorOptions" needs to be exported by the entry point index.d.ts - constructor({ status, title, message, path, type }: SearchErrorOptions); +export interface SearchError { // (undocumented) message: string; // (undocumented) @@ -1968,21 +1961,21 @@ export const UI_SETTINGS: { // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "getFromSavedObject" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:370:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:370:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:370:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:370:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:372:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:373:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:382:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:383:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:384:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:385:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:393:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:394:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:397:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:369:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:369:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:369:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:369:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:371:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:372:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:381:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:382:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:383:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:384:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:388:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:392:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:393:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:396:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:45:5 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts // src/plugins/data/public/types.ts:54:5 - (ae-forgotten-export) The symbol "createFiltersFromValueClickAction" needs to be exported by the entry point index.d.ts // src/plugins/data/public/types.ts:55:5 - (ae-forgotten-export) The symbol "createFiltersFromRangeSelectAction" needs to be exported by the entry point index.d.ts diff --git a/src/plugins/data/public/search/fetch/index.ts b/src/plugins/data/public/search/fetch/index.ts index ab856d681ba12..79cdad1897f9c 100644 --- a/src/plugins/data/public/search/fetch/index.ts +++ b/src/plugins/data/public/search/fetch/index.ts @@ -27,6 +27,5 @@ export { getMaxConcurrentShardRequests, } from './get_search_params'; -export { SearchError, getSearchErrorType } from './search_error'; export { RequestFailure } from './request_error'; export { handleResponse } from './handle_response'; diff --git a/src/plugins/data/public/search/fetch/request_error.ts b/src/plugins/data/public/search/fetch/request_error.ts index e216d32e127cd..5e42a6fcf5b65 100644 --- a/src/plugins/data/public/search/fetch/request_error.ts +++ b/src/plugins/data/public/search/fetch/request_error.ts @@ -17,8 +17,8 @@ * under the License. */ -import { KbnError } from '../../../../kibana_utils/public'; -import { SearchResponse, SearchError } from '..'; +import { KbnError } from '../../../../kibana_utils/common'; +import { SearchError, SearchResponse } from './types'; /** * Request Failure - When an entire multi request fails diff --git a/src/plugins/data/public/search/fetch/search_error.ts b/src/plugins/data/public/search/fetch/search_error.ts deleted file mode 100644 index d4042fb17499c..0000000000000 --- a/src/plugins/data/public/search/fetch/search_error.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -interface SearchErrorOptions { - status: string; - title: string; - message: string; - path: string; - type: string; -} - -export class SearchError extends Error { - public name: string; - public status: string; - public title: string; - public message: string; - public path: string; - public type: string; - - constructor({ status, title, message, path, type }: SearchErrorOptions) { - super(message); - this.name = 'SearchError'; - this.status = status; - this.title = title; - this.message = message; - this.path = path; - this.type = type; - - // captureStackTrace is only available in the V8 engine, so any browser using - // a different JS engine won't have access to this method. - if (Error.captureStackTrace) { - Error.captureStackTrace(this, SearchError); - } - - // Babel doesn't support traditional `extends` syntax for built-in classes. - // https://babeljs.io/docs/en/caveats/#classes - Object.setPrototypeOf(this, SearchError.prototype); - } -} - -export function getSearchErrorType({ message }: Pick) { - const msg = message.toLowerCase(); - if (msg.indexOf('unsupported query') > -1) { - return 'UNSUPPORTED_QUERY'; - } -} diff --git a/src/plugins/data/public/search/fetch/types.ts b/src/plugins/data/public/search/fetch/types.ts index 1aba4f66bb4d7..dda66d6b5238d 100644 --- a/src/plugins/data/public/search/fetch/types.ts +++ b/src/plugins/data/public/search/fetch/types.ts @@ -33,3 +33,12 @@ export interface FetchHandlers { config: IUiSettingsClient; esShardTimeout: number; } + +export interface SearchError { + name: string; + status: string; + title: string; + message: string; + path: string; + type: string; +} diff --git a/src/plugins/data/public/search/index.ts b/src/plugins/data/public/search/index.ts index 40d45ab88ea9f..96445e5367147 100644 --- a/src/plugins/data/public/search/index.ts +++ b/src/plugins/data/public/search/index.ts @@ -34,7 +34,6 @@ export { FetchOptions, SearchRequest, SearchResponse, - getSearchErrorType, getSearchParamsFromRequest, } from './fetch'; diff --git a/src/plugins/data/public/search/search_source/create_search_source.ts b/src/plugins/data/public/search/search_source/create_search_source.ts index 3466d60e5dd7e..4c44f4d62d469 100644 --- a/src/plugins/data/public/search/search_source/create_search_source.ts +++ b/src/plugins/data/public/search/search_source/create_search_source.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { migrateLegacyQuery } from '../../../../kibana_legacy/public'; +import { migrateLegacyQuery } from '../../../../kibana_legacy/common'; import { SearchSource, SearchSourceDependencies } from './search_source'; import { IndexPatternsContract } from '../../index_patterns/index_patterns'; import { SearchSourceFields } from './types'; diff --git a/src/plugins/data/public/search/search_source/parse_json.ts b/src/plugins/data/public/search/search_source/parse_json.ts index f0eb377cedc77..8f46525311424 100644 --- a/src/plugins/data/public/search/search_source/parse_json.ts +++ b/src/plugins/data/public/search/search_source/parse_json.ts @@ -18,7 +18,7 @@ */ import { SearchSourceFields } from './types'; -import { InvalidJSONProperty } from '../../../../kibana_utils/public'; +import { InvalidJSONProperty } from '../../../../kibana_utils/common'; export const parseSearchSourceJSON = (searchSourceJSON: string) => { // if we have a searchSource, set its values based on the searchSourceJson field diff --git a/src/plugins/data/public/search/search_source/search_source.ts b/src/plugins/data/public/search/search_source/search_source.ts index c97a5d0638a6a..847dc8853d6ba 100644 --- a/src/plugins/data/public/search/search_source/search_source.ts +++ b/src/plugins/data/public/search/search_source/search_source.ts @@ -75,7 +75,7 @@ import { map } from 'rxjs/operators'; import { CoreStart } from 'kibana/public'; import { normalizeSortRequest } from './normalize_sort_request'; import { filterDocvalueFields } from './filter_docvalue_fields'; -import { fieldWildcardFilter } from '../../../../kibana_utils/public'; +import { fieldWildcardFilter } from '../../../../kibana_utils/common'; import { IIndexPattern, ISearchGeneric, SearchRequest } from '../..'; import { SearchSourceOptions, SearchSourceFields } from './types'; import { FetchOptions, RequestFailure, handleResponse, getSearchParamsFromRequest } from '../fetch'; diff --git a/src/plugins/kibana_utils/public/field_wildcard/index.ts b/src/plugins/kibana_legacy/common/index.ts similarity index 91% rename from src/plugins/kibana_utils/public/field_wildcard/index.ts rename to src/plugins/kibana_legacy/common/index.ts index db9f830e450b8..9c16d7b273862 100644 --- a/src/plugins/kibana_utils/public/field_wildcard/index.ts +++ b/src/plugins/kibana_legacy/common/index.ts @@ -17,4 +17,5 @@ * under the License. */ -export * from './field_wildcard'; +export * from './kbn_base_url'; +export * from './migrate_legacy_query'; diff --git a/src/plugins/kibana_legacy/public/utils/migrate_legacy_query.ts b/src/plugins/kibana_legacy/common/migrate_legacy_query.ts similarity index 100% rename from src/plugins/kibana_legacy/public/utils/migrate_legacy_query.ts rename to src/plugins/kibana_legacy/common/migrate_legacy_query.ts diff --git a/src/plugins/kibana_legacy/kibana.json b/src/plugins/kibana_legacy/kibana.json index 606acd8b88b05..79264d95dcc27 100644 --- a/src/plugins/kibana_legacy/kibana.json +++ b/src/plugins/kibana_legacy/kibana.json @@ -3,5 +3,5 @@ "version": "kibana", "server": true, "ui": true, - "extraPublicDirs": ["common/kbn_base_url"] + "extraPublicDirs": ["common", "common/kbn_base_url"] } diff --git a/src/plugins/kibana_legacy/public/index.ts b/src/plugins/kibana_legacy/public/index.ts index 75e81b0505747..27b940b0a456b 100644 --- a/src/plugins/kibana_legacy/public/index.ts +++ b/src/plugins/kibana_legacy/public/index.ts @@ -24,7 +24,7 @@ export const plugin = (initializerContext: PluginInitializerContext) => new KibanaLegacyPlugin(initializerContext); export * from './plugin'; -export { kbnBaseUrl } from '../common/kbn_base_url'; +export { kbnBaseUrl, migrateLegacyQuery } from '../common'; export { initAngularBootstrap } from './angular_bootstrap'; export { PaginateDirectiveProvider, PaginateControlsDirectiveProvider } from './paginate/paginate'; diff --git a/src/plugins/kibana_legacy/public/utils/index.ts b/src/plugins/kibana_legacy/public/utils/index.ts index e7dd55ec5582b..a32cd5e40a047 100644 --- a/src/plugins/kibana_legacy/public/utils/index.ts +++ b/src/plugins/kibana_legacy/public/utils/index.ts @@ -17,7 +17,6 @@ * under the License. */ -export * from './migrate_legacy_query'; export * from './system_api'; export * from './normalize_path'; // @ts-ignore diff --git a/src/plugins/kibana_legacy/server/index.ts b/src/plugins/kibana_legacy/server/index.ts index 0188f9b1ec515..3ddcac1517f74 100644 --- a/src/plugins/kibana_legacy/server/index.ts +++ b/src/plugins/kibana_legacy/server/index.ts @@ -50,7 +50,7 @@ export const config: PluginConfigDescriptor = { ], }; -export { kbnBaseUrl } from '../common/kbn_base_url'; +export { kbnBaseUrl, migrateLegacyQuery } from '../common'; class Plugin { public setup(core: CoreSetup) {} diff --git a/src/plugins/kibana_utils/public/field_wildcard/field_wildcard.test.ts b/src/plugins/kibana_utils/common/field_wildcard.test.ts similarity index 100% rename from src/plugins/kibana_utils/public/field_wildcard/field_wildcard.test.ts rename to src/plugins/kibana_utils/common/field_wildcard.test.ts diff --git a/src/plugins/kibana_utils/public/field_wildcard/field_wildcard.ts b/src/plugins/kibana_utils/common/field_wildcard.ts similarity index 99% rename from src/plugins/kibana_utils/public/field_wildcard/field_wildcard.ts rename to src/plugins/kibana_utils/common/field_wildcard.ts index 2aa9a255bd5cf..bfe5a0f3a0a8e 100644 --- a/src/plugins/kibana_utils/public/field_wildcard/field_wildcard.ts +++ b/src/plugins/kibana_utils/common/field_wildcard.ts @@ -19,6 +19,7 @@ import { escapeRegExp, memoize } from 'lodash'; +// @internal export const makeRegEx = memoize(function makeRegEx(glob: string) { const globRegex = glob.split('*').map(escapeRegExp).join('.*'); return new RegExp(`^${globRegex}$`); diff --git a/src/plugins/kibana_utils/common/index.ts b/src/plugins/kibana_utils/common/index.ts index c94021872b4e1..1ec5737c5a38b 100644 --- a/src/plugins/kibana_utils/common/index.ts +++ b/src/plugins/kibana_utils/common/index.ts @@ -18,6 +18,7 @@ */ export * from './defer'; +export * from './field_wildcard'; export * from './of'; export * from './ui'; export * from './state_containers'; diff --git a/src/plugins/kibana_utils/public/index.ts b/src/plugins/kibana_utils/public/index.ts index d1c9eec0e9906..7edf62ce04e81 100644 --- a/src/plugins/kibana_utils/public/index.ts +++ b/src/plugins/kibana_utils/public/index.ts @@ -21,6 +21,8 @@ export { calculateObjectHash, defer, Defer, + fieldWildcardFilter, + fieldWildcardMatcher, Get, JsonArray, JsonObject, @@ -34,7 +36,6 @@ export { } from '../common'; export * from './core'; export * from '../common/errors'; -export * from './field_wildcard'; export * from './render_complete'; export * from './resize_checker'; export * from '../common/state_containers'; diff --git a/src/plugins/kibana_utils/server/index.ts b/src/plugins/kibana_utils/server/index.ts index b8b768da0192e..bf3361d1e5369 100644 --- a/src/plugins/kibana_utils/server/index.ts +++ b/src/plugins/kibana_utils/server/index.ts @@ -17,4 +17,11 @@ * under the License. */ -export { Get, Set, createGetterSetter, url } from '../common'; +export { + createGetterSetter, + fieldWildcardFilter, + fieldWildcardMatcher, + Get, + Set, + url, +} from '../common'; From 910c8836078264a7a6f362271f7185887be0ab83 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Tue, 11 Aug 2020 09:55:09 -0600 Subject: [PATCH 102/106] [data.ui.query] Write filters to query log from default editor. (#74474) --- .../query_string_input.test.tsx | 38 +++++++++++++++++++ .../query_string_input/query_string_input.tsx | 5 ++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.test.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.test.tsx index 0397c34d0c2b8..bb0a8b848c89e 100644 --- a/src/plugins/data/public/ui/query_string_input/query_string_input.test.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_string_input.test.tsx @@ -186,6 +186,44 @@ describe('QueryStringInput', () => { expect(mockCallback).toHaveBeenCalledWith({ query: 'response:200', language: 'kuery' }); }); + it('Should fire onBlur callback on input blur', () => { + const mockCallback = jest.fn(); + + const component = mount( + wrapQueryStringInputInContext({ + query: kqlQuery, + onBlur: mockCallback, + indexPatterns: [stubIndexPatternWithFields], + disableAutoFocus: true, + }) + ); + + const inputWrapper = component.find(EuiTextArea).find('textarea'); + inputWrapper.simulate('blur'); + + expect(mockCallback).toHaveBeenCalledTimes(1); + expect(mockCallback).toHaveBeenCalledWith(); + }); + + it('Should fire onChangeQueryInputFocus callback on input blur', () => { + const mockCallback = jest.fn(); + + const component = mount( + wrapQueryStringInputInContext({ + query: kqlQuery, + onChangeQueryInputFocus: mockCallback, + indexPatterns: [stubIndexPatternWithFields], + disableAutoFocus: true, + }) + ); + + const inputWrapper = component.find(EuiTextArea).find('textarea'); + inputWrapper.simulate('blur'); + + expect(mockCallback).toHaveBeenCalledTimes(1); + expect(mockCallback).toHaveBeenCalledWith(false); + }); + it('Should use PersistedLog for recent search suggestions', async () => { const component = mount( wrapQueryStringInputInContext({ diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx index 6f72aa829d8f3..86ee98b7af9d8 100644 --- a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx @@ -33,7 +33,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { debounce, compact, isEqual } from 'lodash'; +import { debounce, compact, isEqual, isFunction } from 'lodash'; import { Toast } from 'src/core/public'; import { IDataPluginServices, IIndexPattern, Query } from '../..'; import { QuerySuggestion, QuerySuggestionTypes } from '../../autocomplete'; @@ -460,6 +460,9 @@ export class QueryStringInputUI extends Component { if (this.props.onChangeQueryInputFocus) { this.props.onChangeQueryInputFocus(false); } + if (isFunction(this.props.onBlur)) { + this.props.onBlur(); + } }; private onClickSuggestion = (suggestion: QuerySuggestion) => { From 0ef17f92a61b406e13b67af7752af7d2a146a270 Mon Sep 17 00:00:00 2001 From: Peter Pisljar Date: Tue, 11 Aug 2020 17:58:47 +0200 Subject: [PATCH 103/106] theme function (#73451) --- .../common/expression_functions/specs/font.ts | 15 +-- .../expression_functions/specs/index.ts | 3 + .../specs/tests/font.test.ts | 97 ++++++------------- .../specs/tests/theme.test.ts | 63 ++++++++++++ .../expression_functions/specs/theme.ts | 65 +++++++++++++ .../common/expression_functions/types.ts | 2 + 6 files changed, 172 insertions(+), 73 deletions(-) create mode 100644 src/plugins/expressions/common/expression_functions/specs/tests/theme.test.ts create mode 100644 src/plugins/expressions/common/expression_functions/specs/theme.ts diff --git a/src/plugins/expressions/common/expression_functions/specs/font.ts b/src/plugins/expressions/common/expression_functions/specs/font.ts index c46ce0adadef0..52692f72cebb2 100644 --- a/src/plugins/expressions/common/expression_functions/specs/font.ts +++ b/src/plugins/expressions/common/expression_functions/specs/font.ts @@ -64,7 +64,7 @@ export const font: ExpressionFunctionFont = { inputTypes: ['null'], args: { align: { - default: 'left', + default: '{ theme "font.align" default="left" }', help: i18n.translate('expressions.functions.font.args.alignHelpText', { defaultMessage: 'The horizontal text alignment.', }), @@ -72,13 +72,14 @@ export const font: ExpressionFunctionFont = { types: ['string'], }, color: { + default: `{ theme "font.color" }`, help: i18n.translate('expressions.functions.font.args.colorHelpText', { defaultMessage: 'The text color.', }), types: ['string'], }, family: { - default: `"${openSans.value}"`, + default: `{ theme "font.family" default="${openSans.value}" }`, help: i18n.translate('expressions.functions.font.args.familyHelpText', { defaultMessage: 'An acceptable {css} web font string', values: { @@ -88,7 +89,7 @@ export const font: ExpressionFunctionFont = { types: ['string'], }, italic: { - default: false, + default: `{ theme "font.italic" default=false }`, help: i18n.translate('expressions.functions.font.args.italicHelpText', { defaultMessage: 'Italicize the text?', }), @@ -96,7 +97,7 @@ export const font: ExpressionFunctionFont = { types: ['boolean'], }, lHeight: { - default: null, + default: `{ theme "font.lHeight" }`, aliases: ['lineHeight'], help: i18n.translate('expressions.functions.font.args.lHeightHelpText', { defaultMessage: 'The line height in pixels', @@ -104,14 +105,14 @@ export const font: ExpressionFunctionFont = { types: ['number', 'null'], }, size: { - default: 14, + default: `{ theme "font.size" default=14 }`, help: i18n.translate('expressions.functions.font.args.sizeHelpText', { defaultMessage: 'The font size in pixels', }), types: ['number'], }, underline: { - default: false, + default: `{ theme "font.underline" default=false }`, help: i18n.translate('expressions.functions.font.args.underlineHelpText', { defaultMessage: 'Underline the text?', }), @@ -119,7 +120,7 @@ export const font: ExpressionFunctionFont = { types: ['boolean'], }, weight: { - default: 'normal', + default: `{ theme "font.weight" default="normal" }`, help: i18n.translate('expressions.functions.font.args.weightHelpText', { defaultMessage: 'The font weight. For example, {list}, or {end}.', values: { diff --git a/src/plugins/expressions/common/expression_functions/specs/index.ts b/src/plugins/expressions/common/expression_functions/specs/index.ts index f7471a8fd9d75..5b9562dae5f2e 100644 --- a/src/plugins/expressions/common/expression_functions/specs/index.ts +++ b/src/plugins/expressions/common/expression_functions/specs/index.ts @@ -24,6 +24,7 @@ import { kibanaContextFunction } from './kibana_context'; import { variableSet } from './var_set'; import { variable } from './var'; import { AnyExpressionFunctionDefinition } from '../types'; +import { theme } from './theme'; export const functionSpecs: AnyExpressionFunctionDefinition[] = [ clog, @@ -32,6 +33,7 @@ export const functionSpecs: AnyExpressionFunctionDefinition[] = [ kibanaContextFunction, variableSet, variable, + theme, ]; export * from './clog'; @@ -40,3 +42,4 @@ export * from './kibana'; export * from './kibana_context'; export * from './var_set'; export * from './var'; +export * from './theme'; diff --git a/src/plugins/expressions/common/expression_functions/specs/tests/font.test.ts b/src/plugins/expressions/common/expression_functions/specs/tests/font.test.ts index 62e5fd4e0b668..ca4570e9589ca 100644 --- a/src/plugins/expressions/common/expression_functions/specs/tests/font.test.ts +++ b/src/plugins/expressions/common/expression_functions/specs/tests/font.test.ts @@ -24,8 +24,19 @@ import { functionWrapper } from './utils'; describe('font', () => { const fn = functionWrapper(font); + const args = { + align: 'left', + color: null, + family: openSans.value, + italic: false, + lHeight: null, + size: 14, + underline: false, + weight: 'normal', + }; + describe('default output', () => { - const result = fn(null); + const result = fn(null, args); it('returns a style', () => { expect(result).toMatchObject({ @@ -39,7 +50,7 @@ describe('font', () => { describe('args', () => { describe('size', () => { it('sets font size', () => { - const result = fn(null, { size: 20 }); + const result = fn(null, { ...args, size: 20 }); expect(result).toMatchObject({ spec: { fontSize: '20px', @@ -47,21 +58,11 @@ describe('font', () => { }); expect(result.css).toContain('font-size:20px'); }); - - it('defaults to 14px', () => { - const result = fn(null); - expect(result).toMatchObject({ - spec: { - fontSize: '14px', - }, - }); - expect(result.css).toContain('font-size:14px'); - }); }); describe('lHeight', () => { it('sets line height', () => { - const result = fn(null, { lHeight: 30 }); + const result = fn(null, { ...args, lHeight: 30 }); expect(result).toMatchObject({ spec: { lineHeight: '30px', @@ -69,31 +70,19 @@ describe('font', () => { }); expect(result.css).toContain('line-height:30px'); }); - - it('defaults to 1', () => { - const result = fn(null); - expect(result.spec.lineHeight).toBe('1'); - expect(result.css).toContain('line-height:1'); - }); }); describe('family', () => { it('sets font family', () => { - const result = fn(null, { family: 'Optima, serif' }); + const result = fn(null, { ...args, family: 'Optima, serif' }); expect(result.spec.fontFamily).toBe('Optima, serif'); expect(result.css).toContain('font-family:Optima, serif'); }); - - it(`defaults to "${openSans.value}"`, () => { - const result = fn(null); - expect(result.spec.fontFamily).toBe(`"${openSans.value}"`); - expect(result.css).toContain(`font-family:"${openSans.value}"`); - }); }); describe('color', () => { it('sets font color', () => { - const result = fn(null, { color: 'blue' }); + const result = fn(null, { ...args, color: 'blue' }); expect(result.spec.color).toBe('blue'); expect(result.css).toContain('color:blue'); }); @@ -101,51 +90,39 @@ describe('font', () => { describe('weight', () => { it('sets font weight', () => { - let result = fn(null, { weight: 'normal' }); + let result = fn(null, { ...args, weight: 'normal' }); expect(result.spec.fontWeight).toBe('normal'); expect(result.css).toContain('font-weight:normal'); - result = fn(null, { weight: 'bold' }); + result = fn(null, { ...args, weight: 'bold' }); expect(result.spec.fontWeight).toBe('bold'); expect(result.css).toContain('font-weight:bold'); - result = fn(null, { weight: 'bolder' }); + result = fn(null, { ...args, weight: 'bolder' }); expect(result.spec.fontWeight).toBe('bolder'); expect(result.css).toContain('font-weight:bolder'); - result = fn(null, { weight: 'lighter' }); + result = fn(null, { ...args, weight: 'lighter' }); expect(result.spec.fontWeight).toBe('lighter'); expect(result.css).toContain('font-weight:lighter'); - result = fn(null, { weight: '400' }); + result = fn(null, { ...args, weight: '400' }); expect(result.spec.fontWeight).toBe('400'); expect(result.css).toContain('font-weight:400'); }); - it("defaults to 'normal'", () => { - const result = fn(null); - expect(result.spec.fontWeight).toBe('normal'); - expect(result.css).toContain('font-weight:normal'); - }); - it('throws when provided an invalid weight', () => { - expect(() => fn(null, { weight: 'foo' })).toThrow(); + expect(() => fn(null, { ...args, weight: 'foo' })).toThrow(); }); }); describe('underline', () => { it('sets text underline', () => { - let result = fn(null, { underline: true }); + let result = fn(null, { ...args, underline: true }); expect(result.spec.textDecoration).toBe('underline'); expect(result.css).toContain('text-decoration:underline'); - result = fn(null, { underline: false }); - expect(result.spec.textDecoration).toBe('none'); - expect(result.css).toContain('text-decoration:none'); - }); - - it('defaults to false', () => { - const result = fn(null); + result = fn(null, { ...args, underline: false }); expect(result.spec.textDecoration).toBe('none'); expect(result.css).toContain('text-decoration:none'); }); @@ -153,17 +130,11 @@ describe('font', () => { describe('italic', () => { it('sets italic', () => { - let result = fn(null, { italic: true }); + let result = fn(null, { ...args, italic: true }); expect(result.spec.fontStyle).toBe('italic'); expect(result.css).toContain('font-style:italic'); - result = fn(null, { italic: false }); - expect(result.spec.fontStyle).toBe('normal'); - expect(result.css).toContain('font-style:normal'); - }); - - it('defaults to false', () => { - const result = fn(null); + result = fn(null, { ...args, italic: false }); expect(result.spec.fontStyle).toBe('normal'); expect(result.css).toContain('font-style:normal'); }); @@ -171,31 +142,25 @@ describe('font', () => { describe('align', () => { it('sets text alignment', () => { - let result = fn(null, { align: 'left' }); + let result = fn(null, { ...args, align: 'left' }); expect(result.spec.textAlign).toBe('left'); expect(result.css).toContain('text-align:left'); - result = fn(null, { align: 'center' }); + result = fn(null, { ...args, align: 'center' }); expect(result.spec.textAlign).toBe('center'); expect(result.css).toContain('text-align:center'); - result = fn(null, { align: 'right' }); + result = fn(null, { ...args, align: 'right' }); expect(result.spec.textAlign).toBe('right'); expect(result.css).toContain('text-align:right'); - result = fn(null, { align: 'justify' }); + result = fn(null, { ...args, align: 'justify' }); expect(result.spec.textAlign).toBe('justify'); expect(result.css).toContain('text-align:justify'); }); - it(`defaults to 'left'`, () => { - const result = fn(null); - expect(result.spec.textAlign).toBe('left'); - expect(result.css).toContain('text-align:left'); - }); - it('throws when provided an invalid alignment', () => { - expect(() => fn(null, { align: 'foo' })).toThrow(); + expect(() => fn(null, { ...args, align: 'foo' })).toThrow(); }); }); }); diff --git a/src/plugins/expressions/common/expression_functions/specs/tests/theme.test.ts b/src/plugins/expressions/common/expression_functions/specs/tests/theme.test.ts new file mode 100644 index 0000000000000..263409f0caca2 --- /dev/null +++ b/src/plugins/expressions/common/expression_functions/specs/tests/theme.test.ts @@ -0,0 +1,63 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { functionWrapper } from './utils'; +import { theme } from '../theme'; +import { ExecutionContext } from '../../../execution/types'; + +describe('expression_functions', () => { + describe('theme', () => { + const fn = functionWrapper(theme); + let context: ExecutionContext; + + let themeProps; + + beforeEach(() => { + themeProps = { + font: { + family: 'Arial', + size: 14, + }, + }; + + context = { + getInitialInput: () => {}, + types: {}, + variables: { theme: themeProps }, + abortSignal: {} as any, + inspectorAdapters: {} as any, + }; + }); + + it('returns the selected variable', () => { + const actual = fn(null, { variable: 'font.family' }, context); + expect(actual).toEqual('Arial'); + }); + + it('returns undefined if variable does not exist', () => { + const actual = fn(null, { variable: 'font.weight' }, context); + expect(actual).toEqual(undefined); + }); + + it('returns default if variable does not exist and default is provided', () => { + const actual = fn(null, { variable: 'font.weight', default: 'normal' }, context); + expect(actual).toEqual('normal'); + }); + }); +}); diff --git a/src/plugins/expressions/common/expression_functions/specs/theme.ts b/src/plugins/expressions/common/expression_functions/specs/theme.ts new file mode 100644 index 0000000000000..e27b01674cb5e --- /dev/null +++ b/src/plugins/expressions/common/expression_functions/specs/theme.ts @@ -0,0 +1,65 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; +import { ExpressionFunctionDefinition } from '../types'; + +interface Arguments { + variable: string; + default: string | number | boolean; +} + +type Output = any; + +export type ExpressionFunctionTheme = ExpressionFunctionDefinition< + 'theme', + null, + Arguments, + Output +>; + +export const theme: ExpressionFunctionTheme = { + name: 'theme', + aliases: [], + help: i18n.translate('expressions.functions.themeHelpText', { + defaultMessage: 'Reads a theme setting.', + }), + inputTypes: ['null'], + args: { + variable: { + aliases: ['_'], + help: i18n.translate('expressions.functions.theme.args.variableHelpText', { + defaultMessage: 'Name of the theme variable to read.', + }), + required: true, + types: ['string'], + }, + default: { + help: i18n.translate('expressions.functions.theme.args.defaultHelpText', { + defaultMessage: 'default value in case theming info is not available.', + }), + }, + }, + fn: (input, args, handlers) => { + // currently we use variable `theme`, but external theme service would be preferable + const vars = handlers.variables.theme || {}; + return get(vars, args.variable, args.default); + }, +}; diff --git a/src/plugins/expressions/common/expression_functions/types.ts b/src/plugins/expressions/common/expression_functions/types.ts index 5979bcffb3175..d58d872aff722 100644 --- a/src/plugins/expressions/common/expression_functions/types.ts +++ b/src/plugins/expressions/common/expression_functions/types.ts @@ -28,6 +28,7 @@ import { ExpressionFunctionKibana, ExpressionFunctionVarSet, ExpressionFunctionVar, + ExpressionFunctionTheme, } from './specs'; /** @@ -122,4 +123,5 @@ export interface ExpressionFunctionDefinitions { kibana: ExpressionFunctionKibana; var_set: ExpressionFunctionVarSet; var: ExpressionFunctionVar; + theme: ExpressionFunctionTheme; } From 75b8a3cb710eb13c05b61c85bf345dd3e6d92cb3 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 11 Aug 2020 10:18:36 -0600 Subject: [PATCH 104/106] [Maps] add initial location option that fits to data bounds (#74583) * [Maps] add initial location option that fits to data bounds * update navigation_panel snapshot * add functional test to ensure sync is called when auto fit to bounds with no data * add functional test for auto fit to bounds on map load Co-authored-by: Elastic Machine --- x-pack/plugins/maps/common/constants.ts | 1 + .../public/actions/data_request_actions.ts | 34 +++++++++++++++- .../maps/public/actions/layer_actions.ts | 2 - .../maps/public/actions/map_actions.ts | 40 ++++++++----------- .../map/mb/get_initial_view.ts | 5 +++ .../navigation_panel.test.tsx.snap | 12 ++++++ .../map_settings_panel/navigation_panel.tsx | 11 ++++- .../apps/maps/auto_fit_to_bounds.js | 27 +++++++++++++ .../es_archives/maps/kibana/data.json | 29 ++++++++++++++ 9 files changed, 132 insertions(+), 29 deletions(-) diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index cf67ac4dd999f..eec23f95bb17b 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -234,6 +234,7 @@ export enum INITIAL_LOCATION { LAST_SAVED_LOCATION = 'LAST_SAVED_LOCATION', FIXED_LOCATION = 'FIXED_LOCATION', BROWSER_LOCATION = 'BROWSER_LOCATION', + AUTO_FIT_TO_BOUNDS = 'AUTO_FIT_TO_BOUNDS', } export enum LAYER_WIZARD_CATEGORY { diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index 4c829f8e75c20..a22e8d582bc5e 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -7,6 +7,7 @@ import { Dispatch } from 'redux'; import bbox from '@turf/bbox'; +import uuid from 'uuid/v4'; import { multiPoint } from '@turf/helpers'; import { FeatureCollection } from 'geojson'; import { MapStoreState } from '../reducers/store'; @@ -133,7 +134,7 @@ export function syncDataForAllLayers() { }; } -export function syncDataForAllJoinLayers() { +function syncDataForAllJoinLayers() { return async (dispatch: Dispatch, getState: () => MapStoreState) => { const syncPromises = getLayerList(getState()) .filter((layer) => { @@ -318,7 +319,7 @@ export function fitToLayerExtent(layerId: string) { }; } -export function fitToDataBounds() { +export function fitToDataBounds(onNoBounds?: () => void) { return async (dispatch: Dispatch, getState: () => MapStoreState) => { const layerList = getFittableLayers(getState()); @@ -365,6 +366,9 @@ export function fitToDataBounds() { } if (!corners.length) { + if (onNoBounds) { + onNoBounds(); + } return; } @@ -374,6 +378,32 @@ export function fitToDataBounds() { }; } +let lastSetQueryCallId: string = ''; +export function autoFitToBounds() { + return async (dispatch: Dispatch) => { + // Method can be triggered before async actions complete + // Use localSetQueryCallId to only continue execution path if method has not been re-triggered. + const localSetQueryCallId = uuid(); + lastSetQueryCallId = localSetQueryCallId; + + // Joins are performed on the client. + // As a result, bounds for join layers must also be performed on the client. + // Therefore join layers need to fetch data prior to auto fitting bounds. + await dispatch(syncDataForAllJoinLayers()); + + if (localSetQueryCallId === lastSetQueryCallId) { + // In cases where there are no bounds, such as no matching documents, fitToDataBounds does not trigger setGotoWithBounds. + // Ensure layer syncing occurs when setGotoWithBounds is not triggered. + function onNoBounds() { + if (localSetQueryCallId === lastSetQueryCallId) { + dispatch(syncDataForAllLayers()); + } + } + dispatch(fitToDataBounds(onNoBounds)); + } + }; +} + function setGotoWithBounds(bounds: MapExtent) { return { type: SET_GOTO, diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index 208f6dc6c6f85..472e42129816b 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -125,8 +125,6 @@ export function addLayer(layerDescriptor: LayerDescriptor) { }; } -// Do not use when rendering a map. Method exists to enable selectors for getLayerList when -// rendering is not needed. export function addLayerWithoutDataSync(layerDescriptor: LayerDescriptor) { return { type: ADD_LAYER, diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 7191fb312b211..08826276c12ad 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -6,7 +6,6 @@ import { Dispatch } from 'redux'; import turfBboxPolygon from '@turf/bbox-polygon'; import turfBooleanContains from '@turf/boolean-contains'; -import uuid from 'uuid/v4'; import { Filter, Query, TimeRange } from 'src/plugins/data/public'; import { MapStoreState } from '../reducers/store'; @@ -44,12 +43,8 @@ import { UPDATE_DRAW_STATE, UPDATE_MAP_SETTING, } from './map_action_constants'; -import { - fitToDataBounds, - syncDataForAllJoinLayers, - syncDataForAllLayers, -} from './data_request_actions'; -import { addLayer } from './layer_actions'; +import { autoFitToBounds, syncDataForAllLayers } from './data_request_actions'; +import { addLayer, addLayerWithoutDataSync } from './layer_actions'; import { MapSettings } from '../reducers/map'; import { DrawState, @@ -57,6 +52,7 @@ import { MapExtent, MapRefreshConfig, } from '../../common/descriptor_types'; +import { INITIAL_LOCATION } from '../../common/constants'; import { scaleBounds } from '../elasticsearch_geo_utils'; export function setMapInitError(errorMessage: string) { @@ -98,13 +94,21 @@ export function mapReady() { type: MAP_READY, }); - getWaitingForMapReadyLayerListRaw(getState()).forEach((layerDescriptor) => { - dispatch(addLayer(layerDescriptor)); - }); - + const waitingForMapReadyLayerList = getWaitingForMapReadyLayerListRaw(getState()); dispatch({ type: CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST, }); + + if (getMapSettings(getState()).initialLocation === INITIAL_LOCATION.AUTO_FIT_TO_BOUNDS) { + waitingForMapReadyLayerList.forEach((layerDescriptor) => { + dispatch(addLayerWithoutDataSync(layerDescriptor)); + }); + dispatch(autoFitToBounds()); + } else { + waitingForMapReadyLayerList.forEach((layerDescriptor) => { + dispatch(addLayer(layerDescriptor)); + }); + } }; } @@ -196,7 +200,6 @@ function generateQueryTimestamp() { return new Date().toISOString(); } -let lastSetQueryCallId: string = ''; export function setQuery({ query, timeFilters, @@ -227,18 +230,7 @@ export function setQuery({ }); if (getMapSettings(getState()).autoFitToDataBounds) { - // Joins are performed on the client. - // As a result, bounds for join layers must also be performed on the client. - // Therefore join layers need to fetch data prior to auto fitting bounds. - const localSetQueryCallId = uuid(); - lastSetQueryCallId = localSetQueryCallId; - await dispatch(syncDataForAllJoinLayers()); - - // setQuery can be triggered before async data fetching completes - // Only continue execution path if setQuery has not been re-triggered. - if (localSetQueryCallId === lastSetQueryCallId) { - dispatch(fitToDataBounds()); - } + dispatch(autoFitToBounds()); } else { await dispatch(syncDataForAllLayers()); } diff --git a/x-pack/plugins/maps/public/connected_components/map/mb/get_initial_view.ts b/x-pack/plugins/maps/public/connected_components/map/mb/get_initial_view.ts index b9d446d390ffb..20fb8186f9870 100644 --- a/x-pack/plugins/maps/public/connected_components/map/mb/get_initial_view.ts +++ b/x-pack/plugins/maps/public/connected_components/map/mb/get_initial_view.ts @@ -41,5 +41,10 @@ export async function getInitialView( }); } + if (settings.initialLocation === INITIAL_LOCATION.AUTO_FIT_TO_BOUNDS) { + // map bounds pulled from data sources. Just use default map location + return null; + } + return goto && goto.center ? goto.center : null; } diff --git a/x-pack/plugins/maps/public/connected_components/map_settings_panel/__snapshots__/navigation_panel.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/map_settings_panel/__snapshots__/navigation_panel.test.tsx.snap index 18e30d9446e05..1859c7d8177f8 100644 --- a/x-pack/plugins/maps/public/connected_components/map_settings_panel/__snapshots__/navigation_panel.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/map_settings_panel/__snapshots__/navigation_panel.test.tsx.snap @@ -75,6 +75,10 @@ exports[`should render 1`] = ` "id": "LAST_SAVED_LOCATION", "label": "Map location at save", }, + Object { + "id": "AUTO_FIT_TO_BOUNDS", + "label": "Auto fit map to data bounds", + }, Object { "id": "FIXED_LOCATION", "label": "Fixed location", @@ -165,6 +169,10 @@ exports[`should render browser location form when initialLocation is BROWSER_LOC "id": "LAST_SAVED_LOCATION", "label": "Map location at save", }, + Object { + "id": "AUTO_FIT_TO_BOUNDS", + "label": "Auto fit map to data bounds", + }, Object { "id": "FIXED_LOCATION", "label": "Fixed location", @@ -275,6 +283,10 @@ exports[`should render fixed location form when initialLocation is FIXED_LOCATIO "id": "LAST_SAVED_LOCATION", "label": "Map location at save", }, + Object { + "id": "AUTO_FIT_TO_BOUNDS", + "label": "Auto fit map to data bounds", + }, Object { "id": "FIXED_LOCATION", "label": "Fixed location", diff --git a/x-pack/plugins/maps/public/connected_components/map_settings_panel/navigation_panel.tsx b/x-pack/plugins/maps/public/connected_components/map_settings_panel/navigation_panel.tsx index 428a50e03515d..161c0c3576f8f 100644 --- a/x-pack/plugins/maps/public/connected_components/map_settings_panel/navigation_panel.tsx +++ b/x-pack/plugins/maps/public/connected_components/map_settings_panel/navigation_panel.tsx @@ -41,6 +41,12 @@ const initialLocationOptions = [ defaultMessage: 'Map location at save', }), }, + { + id: INITIAL_LOCATION.AUTO_FIT_TO_BOUNDS, + label: i18n.translate('xpack.maps.mapSettingsPanel.autoFitToBoundsLocationLabel', { + defaultMessage: 'Auto fit map to data bounds', + }), + }, { id: INITIAL_LOCATION.FIXED_LOCATION, label: i18n.translate('xpack.maps.mapSettingsPanel.fixedLocationLabel', { @@ -125,7 +131,10 @@ export function NavigationPanel({ center, settings, updateMapSetting, zoom }: Pr }; function renderInitialLocationInputs() { - if (settings.initialLocation === INITIAL_LOCATION.LAST_SAVED_LOCATION) { + if ( + settings.initialLocation === INITIAL_LOCATION.LAST_SAVED_LOCATION || + settings.initialLocation === INITIAL_LOCATION.AUTO_FIT_TO_BOUNDS + ) { return null; } diff --git a/x-pack/test/functional/apps/maps/auto_fit_to_bounds.js b/x-pack/test/functional/apps/maps/auto_fit_to_bounds.js index c8e8db84df96f..d3d4fe054ec34 100644 --- a/x-pack/test/functional/apps/maps/auto_fit_to_bounds.js +++ b/x-pack/test/functional/apps/maps/auto_fit_to_bounds.js @@ -10,6 +10,23 @@ export default function ({ getPageObjects }) { const PageObjects = getPageObjects(['maps']); describe('auto fit map to bounds', () => { + describe('initial location', () => { + before(async () => { + await PageObjects.maps.loadSavedMap( + 'document example - auto fit to bounds for initial location' + ); + }); + + it('should automatically fit to bounds on initial map load', async () => { + const hits = await PageObjects.maps.getHits(); + expect(hits).to.equal('6'); + + const { lat, lon } = await PageObjects.maps.getView(); + expect(Math.round(lat)).to.equal(41); + expect(Math.round(lon)).to.equal(-99); + }); + }); + describe('without joins', () => { before(async () => { await PageObjects.maps.loadSavedMap('document example'); @@ -25,10 +42,20 @@ export default function ({ getPageObjects }) { await PageObjects.maps.setAndSubmitQuery('machine.os.raw : "ios"'); await PageObjects.maps.waitForMapPanAndZoom(origView); + const hits = await PageObjects.maps.getHits(); + expect(hits).to.equal('2'); + const { lat, lon } = await PageObjects.maps.getView(); expect(Math.round(lat)).to.equal(43); expect(Math.round(lon)).to.equal(-102); }); + + it('should sync layers even when there is not data', async () => { + await PageObjects.maps.setAndSubmitQuery('machine.os.raw : "fake_os_with_no_matches"'); + + const hits = await PageObjects.maps.getHits(); + expect(hits).to.equal('0'); + }); }); describe('with joins', () => { diff --git a/x-pack/test/functional/es_archives/maps/kibana/data.json b/x-pack/test/functional/es_archives/maps/kibana/data.json index 7690c92589312..198174bccb286 100644 --- a/x-pack/test/functional/es_archives/maps/kibana/data.json +++ b/x-pack/test/functional/es_archives/maps/kibana/data.json @@ -979,6 +979,35 @@ } } +{ + "type": "doc", + "value": { + "id": "map:13776f20-db37-11ea-8fbb-3da39bb9bff2", + "index": ".kibana", + "source": { + "map" : { + "title" : "document example - auto fit to bounds for initial location", + "description" : "", + "mapStateJSON" : "{\"zoom\":5.2,\"center\":{\"lon\":-67.80052,\"lat\":-55.25331},\"timeFilters\":{\"from\":\"2015-09-20T00:00:00.000Z\",\"to\":\"2015-09-20T01:00:00.000Z\"},\"refreshConfig\":{\"isPaused\":true,\"interval\":1000},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[],\"settings\":{\"autoFitToDataBounds\":false,\"initialLocation\":\"AUTO_FIT_TO_BOUNDS\",\"fixedLocation\":{\"lat\":0,\"lon\":0,\"zoom\":2},\"browserLocation\":{\"zoom\":2},\"maxZoom\":24,\"minZoom\":0,\"showSpatialFilters\":true,\"spatialFiltersAlpa\":0.3,\"spatialFiltersFillColor\":\"#DA8B45\",\"spatialFiltersLineColor\":\"#DA8B45\"}}", + "layerListJSON" : "[{\"id\":\"0hmz5\",\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"id\":\"road_map\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"TILE\",\"properties\":{}},\"type\":\"VECTOR_TILE\",\"minZoom\":0,\"maxZoom\":24},{\"id\":\"z52lq\",\"label\":\"logstash\",\"minZoom\":0,\"maxZoom\":24,\"sourceDescriptor\":{\"id\":\"e1a5e1a6-676c-4a89-8ea9-0d91d64b73c6\",\"type\":\"ES_SEARCH\",\"geoField\":\"geo.coordinates\",\"limit\":2048,\"filterByMapBounds\":true,\"showTooltip\":true,\"tooltipProperties\":[],\"applyGlobalQuery\":true,\"scalingType\":\"LIMIT\",\"indexPatternRefName\":\"layer_1_source_index_pattern\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#e6194b\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}},\"previousStyle\":null},\"type\":\"VECTOR\"}]", + "uiStateJSON" : "{\"isLayerTOCOpen\":true,\"openTOCDetails\":[]}" + }, + "type" : "map", + "references" : [ + { + "name" : "layer_1_source_index_pattern", + "type" : "index-pattern", + "id" : "c698b940-e149-11e8-a35a-370a8516603a" + } + ], + "migrationVersion" : { + "map" : "7.9.0" + }, + "updated_at" : "2020-08-10T18:27:39.805Z" + } + } +} + { "type": "doc", "value": { From 0cfc7b464c329858effc6cef952c2d311c0aab52 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 11 Aug 2020 20:10:35 +0300 Subject: [PATCH 105/106] [Lens] Add styling options for x and y axes on the settings popover (#71829) * [Lens] Add styling options for x axis on the settings popover * ts related changes * Changes to the popover's design and y-axis implementatin * fix types and add unit tests * Add extra translations * Fix functional test and change the logic of the yTitle * fixes * fix showTitle settings bug * Fix ticklabels bug on y axes * fix some tests * Change the user flow on x and y titles on settings popover and enable the gridlines by default * disable linter warning * PR Comments * Add a comment to callback to explain the decision to listen only to open changes Co-authored-by: Elastic Machine --- .../__snapshots__/to_expression.test.ts.snap | 48 +++- .../__snapshots__/xy_expression.test.tsx.snap | 49 +++- .../lens/public/xy_visualization/index.ts | 4 +- .../xy_visualization/to_expression.test.ts | 77 +++++- .../public/xy_visualization/to_expression.ts | 63 +++-- .../lens/public/xy_visualization/types.ts | 85 ++++++ .../xy_visualization/xy_config_panel.test.tsx | 69 ++++- .../xy_visualization/xy_config_panel.tsx | 261 ++++++++++++++++-- .../xy_visualization/xy_expression.test.tsx | 173 +++++++++++- .../public/xy_visualization/xy_expression.tsx | 68 +++-- .../xy_visualization/xy_suggestions.test.ts | 20 ++ .../public/xy_visualization/xy_suggestions.ts | 12 + 12 files changed, 852 insertions(+), 77 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap index b5783803b803c..19ea75239ddb2 100644 --- a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap +++ b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap @@ -8,6 +8,25 @@ Object { "fittingFunction": Array [ "Carry", ], + "gridlinesVisibilitySettings": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "x": Array [ + false, + ], + "y": Array [ + true, + ], + }, + "function": "lens_xy_gridlinesConfig", + "type": "function", + }, + ], + "type": "expression", + }, + ], "layers": Array [ Object { "chain": Array [ @@ -73,11 +92,36 @@ Object { "type": "expression", }, ], + "showXAxisTitle": Array [ + true, + ], + "showYAxisTitle": Array [ + true, + ], + "tickLabelsVisibilitySettings": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "x": Array [ + false, + ], + "y": Array [ + true, + ], + }, + "function": "lens_xy_tickLabelsConfig", + "type": "function", + }, + ], + "type": "expression", + }, + ], "xTitle": Array [ - "col_a", + "", ], "yTitle": Array [ - "col_b", + "", ], }, "function": "lens_xy_chart", diff --git a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap index c7c173f87ad7c..f0c233b44a285 100644 --- a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap +++ b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap @@ -20,9 +20,14 @@ exports[`xy_expression XYChart component it renders area 1`] = ` } /> @@ -146,9 +151,14 @@ exports[`xy_expression XYChart component it renders bar 1`] = ` } /> @@ -262,9 +272,14 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = ` } /> @@ -378,9 +393,14 @@ exports[`xy_expression XYChart component it renders line 1`] = ` } /> @@ -504,9 +524,14 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = ` } /> @@ -628,9 +653,14 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = ` } /> @@ -752,9 +782,14 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] = } /> diff --git a/x-pack/plugins/lens/public/xy_visualization/index.ts b/x-pack/plugins/lens/public/xy_visualization/index.ts index 77cab1ee21344..fddcad7989b25 100644 --- a/x-pack/plugins/lens/public/xy_visualization/index.ts +++ b/x-pack/plugins/lens/public/xy_visualization/index.ts @@ -10,7 +10,7 @@ import { ExpressionsSetup } from '../../../../../src/plugins/expressions/public' import { UI_SETTINGS } from '../../../../../src/plugins/data/public'; import { xyVisualization } from './xy_visualization'; import { xyChart, getXyChartRenderer } from './xy_expression'; -import { legendConfig, layerConfig, yAxisConfig } from './types'; +import { legendConfig, layerConfig, yAxisConfig, tickLabelsConfig, gridlinesConfig } from './types'; import { EditorFrameSetup, FormatFactory } from '../types'; import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; @@ -39,6 +39,8 @@ export class XyVisualization { ) { expressions.registerFunction(() => legendConfig); expressions.registerFunction(() => yAxisConfig); + expressions.registerFunction(() => tickLabelsConfig); + expressions.registerFunction(() => gridlinesConfig); expressions.registerFunction(() => layerConfig); expressions.registerFunction(() => xyChart); diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts index 31b34e41e82db..876d1141740e1 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.test.ts @@ -41,6 +41,8 @@ describe('#toExpression', () => { legend: { position: Position.Bottom, isVisible: true }, preferredSeriesType: 'bar', fittingFunction: 'Carry', + tickLabelsVisibilitySettings: { x: false, y: true }, + gridlinesVisibilitySettings: { x: false, y: true }, layers: [ { layerId: 'first', @@ -77,6 +79,27 @@ describe('#toExpression', () => { ).toEqual('None'); }); + it('should default the showXAxisTitle and showYAxisTitle to true', () => { + const expression = xyVisualization.toExpression( + { + legend: { position: Position.Bottom, isVisible: true }, + preferredSeriesType: 'bar', + layers: [ + { + layerId: 'first', + seriesType: 'area', + splitAccessor: 'd', + xAccessor: 'a', + accessors: ['b', 'c'], + }, + ], + }, + frame + ) as Ast; + expect(expression.chain[0].arguments.showXAxisTitle[0]).toBe(true); + expect(expression.chain[0].arguments.showYAxisTitle[0]).toBe(true); + }); + it('should not generate an expression when missing x', () => { expect( xyVisualization.toExpression( @@ -140,8 +163,8 @@ describe('#toExpression', () => { expect(mockDatasource.publicAPIMock.getOperationForColumnId).toHaveBeenCalledWith('b'); expect(mockDatasource.publicAPIMock.getOperationForColumnId).toHaveBeenCalledWith('c'); expect(mockDatasource.publicAPIMock.getOperationForColumnId).toHaveBeenCalledWith('d'); - expect(expression.chain[0].arguments.xTitle).toEqual(['col_a']); - expect(expression.chain[0].arguments.yTitle).toEqual(['col_b']); + expect(expression.chain[0].arguments.xTitle).toEqual(['']); + expect(expression.chain[0].arguments.yTitle).toEqual(['']); expect( (expression.chain[0].arguments.layers[0] as Ast).chain[0].arguments.columnToLabel ).toEqual([ @@ -152,4 +175,54 @@ describe('#toExpression', () => { }), ]); }); + + it('should default the tick labels visibility settings to true', () => { + const expression = xyVisualization.toExpression( + { + legend: { position: Position.Bottom, isVisible: true }, + preferredSeriesType: 'bar', + layers: [ + { + layerId: 'first', + seriesType: 'area', + splitAccessor: 'd', + xAccessor: 'a', + accessors: ['b', 'c'], + }, + ], + }, + frame + ) as Ast; + expect( + (expression.chain[0].arguments.tickLabelsVisibilitySettings[0] as Ast).chain[0].arguments + ).toEqual({ + x: [true], + y: [true], + }); + }); + + it('should default the gridlines visibility settings to true', () => { + const expression = xyVisualization.toExpression( + { + legend: { position: Position.Bottom, isVisible: true }, + preferredSeriesType: 'bar', + layers: [ + { + layerId: 'first', + seriesType: 'area', + splitAccessor: 'd', + xAccessor: 'a', + accessors: ['b', 'c'], + }, + ], + }, + frame + ) as Ast; + expect( + (expression.chain[0].arguments.gridlinesVisibilitySettings[0] as Ast).chain[0].arguments + ).toEqual({ + x: [true], + y: [true], + }); + }); }); diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts index b17704b38cdec..9b9c159af265e 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts @@ -13,28 +13,6 @@ interface ValidLayer extends LayerConfig { xAccessor: NonNullable; } -function xyTitles(layer: LayerConfig, frame: FramePublicAPI) { - const defaults = { - xTitle: 'x', - yTitle: 'y', - }; - - if (!layer || !layer.accessors.length) { - return defaults; - } - const datasource = frame.datasourceLayers[layer.layerId]; - if (!datasource) { - return defaults; - } - const x = layer.xAccessor ? datasource.getOperationForColumnId(layer.xAccessor) : null; - const y = layer.accessors[0] ? datasource.getOperationForColumnId(layer.accessors[0]) : null; - - return { - xTitle: x ? x.label : defaults.xTitle, - yTitle: y ? y.label : defaults.yTitle, - }; -} - export const toExpression = (state: State, frame: FramePublicAPI): Ast | null => { if (!state || !state.layers.length) { return null; @@ -52,7 +30,7 @@ export const toExpression = (state: State, frame: FramePublicAPI): Ast | null => }); }); - return buildExpression(state, metadata, frame, xyTitles(state.layers[0], frame)); + return buildExpression(state, metadata, frame); }; export function toPreviewExpression(state: State, frame: FramePublicAPI) { @@ -99,8 +77,7 @@ export function getScaleType(metadata: OperationMetadata | null, defaultScale: S export const buildExpression = ( state: State, metadata: Record>, - frame?: FramePublicAPI, - { xTitle, yTitle }: { xTitle: string; yTitle: string } = { xTitle: '', yTitle: '' } + frame?: FramePublicAPI ): Ast | null => { const validLayers = state.layers.filter((layer): layer is ValidLayer => Boolean(layer.xAccessor && layer.accessors.length) @@ -116,8 +93,8 @@ export const buildExpression = ( type: 'function', function: 'lens_xy_chart', arguments: { - xTitle: [xTitle], - yTitle: [yTitle], + xTitle: [state.xTitle || ''], + yTitle: [state.yTitle || ''], legend: [ { type: 'expression', @@ -137,6 +114,38 @@ export const buildExpression = ( }, ], fittingFunction: [state.fittingFunction || 'None'], + showXAxisTitle: [state.showXAxisTitle ?? true], + showYAxisTitle: [state.showYAxisTitle ?? true], + tickLabelsVisibilitySettings: [ + { + type: 'expression', + chain: [ + { + type: 'function', + function: 'lens_xy_tickLabelsConfig', + arguments: { + x: [state?.tickLabelsVisibilitySettings?.x ?? true], + y: [state?.tickLabelsVisibilitySettings?.y ?? true], + }, + }, + ], + }, + ], + gridlinesVisibilitySettings: [ + { + type: 'expression', + chain: [ + { + type: 'function', + function: 'lens_xy_gridlinesConfig', + arguments: { + x: [state?.gridlinesVisibilitySettings?.x ?? true], + y: [state?.gridlinesVisibilitySettings?.y ?? true], + }, + }, + ], + }, + ], layers: validLayers.map((layer) => { const columnToLabel: Record = {}; diff --git a/x-pack/plugins/lens/public/xy_visualization/types.ts b/x-pack/plugins/lens/public/xy_visualization/types.ts index 605119535d1f0..ab689ceb183be 100644 --- a/x-pack/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/plugins/lens/public/xy_visualization/types.ts @@ -75,6 +75,81 @@ export const legendConfig: ExpressionFunctionDefinition< }, }; +export interface AxesSettingsConfig { + x: boolean; + y: boolean; +} + +type TickLabelsConfigResult = AxesSettingsConfig & { type: 'lens_xy_tickLabelsConfig' }; + +export const tickLabelsConfig: ExpressionFunctionDefinition< + 'lens_xy_tickLabelsConfig', + null, + AxesSettingsConfig, + TickLabelsConfigResult +> = { + name: 'lens_xy_tickLabelsConfig', + aliases: [], + type: 'lens_xy_tickLabelsConfig', + help: `Configure the xy chart's tick labels appearance`, + inputTypes: ['null'], + args: { + x: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.xAxisTickLabels.help', { + defaultMessage: 'Specifies whether or not the tick labels of the x-axis are visible.', + }), + }, + y: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.yAxisTickLabels.help', { + defaultMessage: 'Specifies whether or not the tick labels of the y-axis are visible.', + }), + }, + }, + fn: function fn(input: unknown, args: AxesSettingsConfig) { + return { + type: 'lens_xy_tickLabelsConfig', + ...args, + }; + }, +}; + +type GridlinesConfigResult = AxesSettingsConfig & { type: 'lens_xy_gridlinesConfig' }; + +export const gridlinesConfig: ExpressionFunctionDefinition< + 'lens_xy_gridlinesConfig', + null, + AxesSettingsConfig, + GridlinesConfigResult +> = { + name: 'lens_xy_gridlinesConfig', + aliases: [], + type: 'lens_xy_gridlinesConfig', + help: `Configure the xy chart's gridlines appearance`, + inputTypes: ['null'], + args: { + x: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.xAxisGridlines.help', { + defaultMessage: 'Specifies whether or not the gridlines of the x-axis are visible.', + }), + }, + y: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.yAxisgridlines.help', { + defaultMessage: 'Specifies whether or not the gridlines of the y-axis are visible.', + }), + }, + }, + fn: function fn(input: unknown, args: AxesSettingsConfig) { + return { + type: 'lens_xy_gridlinesConfig', + ...args, + }; + }, +}; + interface AxisConfig { title: string; hide?: boolean; @@ -243,6 +318,10 @@ export interface XYArgs { legend: LegendConfig & { type: 'lens_xy_legendConfig' }; layers: LayerArgs[]; fittingFunction?: FittingFunction; + showXAxisTitle?: boolean; + showYAxisTitle?: boolean; + tickLabelsVisibilitySettings?: AxesSettingsConfig & { type: 'lens_xy_tickLabelsConfig' }; + gridlinesVisibilitySettings?: AxesSettingsConfig & { type: 'lens_xy_gridlinesConfig' }; } // Persisted parts of the state @@ -251,6 +330,12 @@ export interface XYState { legend: LegendConfig; fittingFunction?: FittingFunction; layers: LayerConfig[]; + xTitle?: string; + yTitle?: string; + showXAxisTitle?: boolean; + showYAxisTitle?: boolean; + tickLabelsVisibilitySettings?: AxesSettingsConfig; + gridlinesVisibilitySettings?: AxesSettingsConfig; } export type State = XYState; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx index 375eaf736cc95..31ba1bc83d970 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx @@ -109,7 +109,6 @@ describe('XY Config panels', () => { it('should disable the select if there is no unstacked area or line series', () => { const state = testState(); - const component = shallow( { expect(component.find(EuiSuperSelect).prop('disabled')).toEqual(true); }); + + it('should show the values of the X and Y axes titles on the corresponding input text', () => { + const state = testState(); + const component = shallow( + + ); + + expect(component.find('[data-test-subj="lnsXAxisTitle"]').prop('value')).toBe( + 'My custom X axis title' + ); + expect(component.find('[data-test-subj="lnsYAxisTitle"]').prop('value')).toBe( + 'My custom Y axis title' + ); + }); + + it('should disable the input texts if the switch is off', () => { + const state = testState(); + const component = shallow( + + ); + + expect(component.find('[data-test-subj="lnsXAxisTitle"]').prop('disabled')).toBe(true); + expect(component.find('[data-test-subj="lnsYAxisTitle"]').prop('disabled')).toBe(true); + }); + + it('has the tick labels buttons enabled', () => { + const state = testState(); + const component = shallow(); + + const options = component + .find('[data-test-subj="lnsTickLabelsSettings"]') + .prop('options') as EuiButtonGroupProps['options']; + + expect(options!.map(({ label }) => label)).toEqual(['X-axis', 'Y-axis']); + + const selections = component + .find('[data-test-subj="lnsTickLabelsSettings"]') + .prop('idToSelectedMap'); + + expect(selections!).toEqual({ x: true, y: true }); + }); + + it('has the gridlines buttons enabled', () => { + const state = testState(); + const component = shallow(); + + const selections = component + .find('[data-test-subj="lnsGridlinesSettings"]') + .prop('idToSelectedMap'); + + expect(selections!).toEqual({ x: true, y: true }); + }); }); }); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index e4bc6de5cc68a..d64eb9451a50e 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -5,7 +5,7 @@ */ import './xy_config_panel.scss'; -import React, { useState } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import { Position } from '@elastic/charts'; import { debounce } from 'lodash'; @@ -24,14 +24,17 @@ import { EuiColorPickerProps, EuiToolTip, EuiIcon, + EuiFieldText, + EuiSwitch, EuiHorizontalRule, + EuiTitle, } from '@elastic/eui'; import { VisualizationLayerWidgetProps, VisualizationDimensionEditorProps, VisualizationToolbarProps, } from '../types'; -import { State, SeriesType, visualizationTypes, YAxisMode } from './types'; +import { State, SeriesType, visualizationTypes, YAxisMode, AxesSettingsConfig } from './types'; import { isHorizontalChart, isHorizontalSeries, getSeriesColor } from './state_helpers'; import { trackUiEvent } from '../lens_ui_telemetry'; import { fittingFunctionDefinitions } from './fitting_functions'; @@ -118,14 +121,117 @@ export function LayerContextMenu(props: VisualizationLayerWidgetProps) { } export function XyToolbar(props: VisualizationToolbarProps) { + const axes = [ + { + id: 'x', + label: 'X-axis', + }, + { + id: 'y', + label: 'Y-axis', + }, + ]; + + const { frame, state, setState } = props; + const [open, setOpen] = useState(false); - const hasNonBarSeries = props.state?.layers.some( + const hasNonBarSeries = state?.layers.some( (layer) => layer.seriesType === 'line' || layer.seriesType === 'area' ); + + const [xAxisTitle, setXAxisTitle] = useState(state?.xTitle); + const [yAxisTitle, setYAxisTitle] = useState(state?.yTitle); + + const xyTitles = useCallback(() => { + const defaults = { + xTitle: xAxisTitle, + yTitle: yAxisTitle, + }; + const layer = state?.layers[0]; + if (!layer || !layer.accessors.length) { + return defaults; + } + const datasource = frame.datasourceLayers[layer.layerId]; + if (!datasource) { + return defaults; + } + const x = layer.xAccessor ? datasource.getOperationForColumnId(layer.xAccessor) : null; + const y = layer.accessors[0] ? datasource.getOperationForColumnId(layer.accessors[0]) : null; + + return { + xTitle: defaults.xTitle || x?.label, + yTitle: defaults.yTitle || y?.label, + }; + /* We want this callback to run only if open changes its state. What we want to accomplish here is to give the user a better UX. + By default these input fields have the axis legends. If the user changes the input text, the axis legends should also change. + BUT if the user cleans up the input text, it should remain empty until the user closes and reopens the panel. + In that case, the default axes legend should appear. */ + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [open]); + + useEffect(() => { + const { + xTitle, + yTitle, + }: { xTitle: string | undefined; yTitle: string | undefined } = xyTitles(); + setXAxisTitle(xTitle); + setYAxisTitle(yTitle); + }, [xyTitles]); + + const onXTitleChange = (value: string): void => { + setXAxisTitle(value); + setState({ ...state, xTitle: value }); + }; + + const onYTitleChange = (value: string): void => { + setYAxisTitle(value); + setState({ ...state, yTitle: value }); + }; + + type AxesSettingsConfigKeys = keyof AxesSettingsConfig; + + const tickLabelsVisibilitySettings = { + x: state?.tickLabelsVisibilitySettings?.x ?? true, + y: state?.tickLabelsVisibilitySettings?.y ?? true, + }; + + const onTickLabelsVisibilitySettingsChange = (optionId: string): void => { + const id = optionId as AxesSettingsConfigKeys; + const newTickLabelsVisibilitySettings = { + ...tickLabelsVisibilitySettings, + ...{ + [id]: !tickLabelsVisibilitySettings[id], + }, + }; + setState({ + ...state, + tickLabelsVisibilitySettings: newTickLabelsVisibilitySettings, + }); + }; + + const gridlinesVisibilitySettings = { + x: state?.gridlinesVisibilitySettings?.x ?? true, + y: state?.gridlinesVisibilitySettings?.y ?? true, + }; + + const onGridlinesVisibilitySettingsChange = (optionId: string): void => { + const id = optionId as AxesSettingsConfigKeys; + const newGridlinesVisibilitySettings = { + ...gridlinesVisibilitySettings, + ...{ + [id]: !gridlinesVisibilitySettings[id], + }, + }; + setState({ + ...state, + gridlinesVisibilitySettings: newGridlinesVisibilitySettings, + }); + }; + const legendMode = - props.state?.legend.isVisible && !props.state?.legend.showSingleSeries + state?.legend.isVisible && !state?.legend.showSingleSeries ? 'auto' - : !props.state?.legend.isVisible + : !state?.legend.isVisible ? 'hide' : 'show'; return ( @@ -183,8 +289,8 @@ export function XyToolbar(props: VisualizationToolbarProps) { inputDisplay: title, }; })} - valueOfSelected={props.state?.fittingFunction || 'None'} - onChange={(value) => props.setState({ ...props.state, fittingFunction: value })} + valueOfSelected={state?.fittingFunction || 'None'} + onChange={(value) => setState({ ...state, fittingFunction: value })} itemLayoutAlign="top" hasDividers /> @@ -209,19 +315,19 @@ export function XyToolbar(props: VisualizationToolbarProps) { onChange={(optionId) => { const newMode = legendOptions.find(({ id }) => id === optionId)!.value; if (newMode === 'auto') { - props.setState({ - ...props.state, - legend: { ...props.state.legend, isVisible: true, showSingleSeries: false }, + setState({ + ...state, + legend: { ...state.legend, isVisible: true, showSingleSeries: false }, }); } else if (newMode === 'show') { - props.setState({ - ...props.state, - legend: { ...props.state.legend, isVisible: true, showSingleSeries: true }, + setState({ + ...state, + legend: { ...state.legend, isVisible: true, showSingleSeries: true }, }); } else if (newMode === 'hide') { - props.setState({ - ...props.state, - legend: { ...props.state.legend, isVisible: false, showSingleSeries: false }, + setState({ + ...state, + legend: { ...state.legend, isVisible: false, showSingleSeries: false }, }); } }} @@ -242,15 +348,130 @@ export function XyToolbar(props: VisualizationToolbarProps) { { value: Position.Right, text: 'Right' }, { value: Position.Bottom, text: 'Bottom' }, ]} - value={props.state?.legend.position} + value={state?.legend.position} onChange={(e) => { - props.setState({ - ...props.state, - legend: { ...props.state.legend, position: e.target.value as Position }, + setState({ + ...state, + legend: { ...state.legend, position: e.target.value as Position }, }); }} /> + + + onTickLabelsVisibilitySettingsChange(id)} + buttonSize="compressed" + isFullWidth + type="multi" + /> + + + onGridlinesVisibilitySettingsChange(id)} + buttonSize="compressed" + isFullWidth + type="multi" + /> + + + + + {i18n.translate('xpack.lens.xyChart.axisTitles', { defaultMessage: 'Axis titles' })} + + + + X-axis + + + setState({ ...state, showXAxisTitle: target.checked }) + } + checked={state?.showXAxisTitle ?? true} + /> + + + } + > + onXTitleChange(target.value)} + aria-label={i18n.translate('xpack.lens.xyChart.overwriteXaxis', { + defaultMessage: 'Overwrite X-axis title', + })} + /> + + + Y-axis + + + setState({ ...state, showYAxisTitle: target.checked }) + } + checked={state?.showYAxisTitle ?? true} + /> + + + } + > + onYTitleChange(target.value)} + aria-label={i18n.translate('xpack.lens.xyChart.overwriteYaxis', { + defaultMessage: 'Overwrite Y-axis title', + })} + /> + diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx index c880cbb641e5d..ba1ff6a1df030 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -22,7 +22,16 @@ import { LensMultiTable } from '../types'; import { KibanaDatatable, KibanaDatatableRow } from '../../../../../src/plugins/expressions/public'; import React from 'react'; import { shallow } from 'enzyme'; -import { XYArgs, LegendConfig, legendConfig, layerConfig, LayerArgs } from './types'; +import { + XYArgs, + LegendConfig, + legendConfig, + layerConfig, + LayerArgs, + AxesSettingsConfig, + tickLabelsConfig, + gridlinesConfig, +} from './types'; import { createMockExecutionContext } from '../../../../../src/plugins/expressions/common/mocks'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { chartPluginMock } from '../../../../../src/plugins/charts/public/mocks'; @@ -211,6 +220,18 @@ const createArgsWithLayers = (layers: LayerArgs[] = [sampleLayer]): XYArgs => ({ isVisible: false, position: Position.Top, }, + showXAxisTitle: true, + showYAxisTitle: true, + tickLabelsVisibilitySettings: { + type: 'lens_xy_tickLabelsConfig', + x: true, + y: false, + }, + gridlinesVisibilitySettings: { + type: 'lens_xy_gridlinesConfig', + x: true, + y: false, + }, layers, }); @@ -267,6 +288,34 @@ describe('xy_expression', () => { }); }); + test('tickLabelsConfig produces the correct arguments', () => { + const args: AxesSettingsConfig = { + x: true, + y: false, + }; + + const result = tickLabelsConfig.fn(null, args, createMockExecutionContext()); + + expect(result).toEqual({ + type: 'lens_xy_tickLabelsConfig', + ...args, + }); + }); + + test('gridlinesConfig produces the correct arguments', () => { + const args: AxesSettingsConfig = { + x: true, + y: false, + }; + + const result = gridlinesConfig.fn(null, args, createMockExecutionContext()); + + expect(result).toEqual({ + type: 'lens_xy_gridlinesConfig', + ...args, + }); + }); + describe('xyChart', () => { test('it renders with the specified data and args', () => { const { data, args } = sampleArgs(); @@ -1365,6 +1414,35 @@ describe('xy_expression', () => { expect(convertSpy).toHaveBeenCalledWith('I'); }); + test('it should not pass the formatter function to the x axis if the visibility of the tick labels is off', () => { + const { data, args } = sampleArgs(); + + args.tickLabelsVisibilitySettings = { x: false, y: true, type: 'lens_xy_tickLabelsConfig' }; + + const instance = shallow( + + ); + + const tickFormatter = instance.find(Axis).first().prop('tickFormat'); + + if (!tickFormatter) { + throw new Error('tickFormatter prop not found'); + } + + tickFormatter('I'); + + expect(convertSpy).toHaveBeenCalledTimes(0); + }); + test('it should remove invalid rows', () => { const data: LensMultiTable = { type: 'lens_multitable', @@ -1400,6 +1478,16 @@ describe('xy_expression', () => { xTitle: '', yTitle: '', legend: { type: 'lens_xy_legendConfig', isVisible: false, position: Position.Top }, + tickLabelsVisibilitySettings: { + type: 'lens_xy_tickLabelsConfig', + x: true, + y: true, + }, + gridlinesVisibilitySettings: { + type: 'lens_xy_gridlinesConfig', + x: true, + y: false, + }, layers: [ { layerId: 'first', @@ -1469,6 +1557,16 @@ describe('xy_expression', () => { xTitle: '', yTitle: '', legend: { type: 'lens_xy_legendConfig', isVisible: false, position: Position.Top }, + tickLabelsVisibilitySettings: { + type: 'lens_xy_tickLabelsConfig', + x: true, + y: false, + }, + gridlinesVisibilitySettings: { + type: 'lens_xy_gridlinesConfig', + x: true, + y: false, + }, layers: [ { layerId: 'first', @@ -1525,6 +1623,16 @@ describe('xy_expression', () => { xTitle: '', yTitle: '', legend: { type: 'lens_xy_legendConfig', isVisible: true, position: Position.Top }, + tickLabelsVisibilitySettings: { + type: 'lens_xy_tickLabelsConfig', + x: true, + y: false, + }, + gridlinesVisibilitySettings: { + type: 'lens_xy_gridlinesConfig', + x: true, + y: false, + }, layers: [ { layerId: 'first', @@ -1683,5 +1791,68 @@ describe('xy_expression', () => { expect(component.find(LineSeries).prop('fit')).toEqual({ type: Fit.None }); }); + + test('it should apply the xTitle if is specified', () => { + const { data, args } = sampleArgs(); + + args.xTitle = 'My custom x-axis title'; + + const component = shallow( + + ); + + expect(component.find(Axis).at(0).prop('title')).toEqual('My custom x-axis title'); + }); + + test('it should hide the X axis title if the corresponding switch is off', () => { + const { data, args } = sampleArgs(); + + args.showXAxisTitle = false; + + const component = shallow( + + ); + + expect(component.find(Axis).at(0).prop('title')).toEqual(undefined); + }); + + test('it should show the X axis gridlines if the setting is on', () => { + const { data, args } = sampleArgs(); + + args.gridlinesVisibilitySettings = { x: true, y: false, type: 'lens_xy_gridlinesConfig' }; + + const component = shallow( + + ); + + expect(component.find(Axis).at(0).prop('showGridLines')).toBeTruthy(); + }); }); }); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index a3468e109e75b..2037a3dbe6623 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -102,6 +102,30 @@ export const xyChart: ExpressionFunctionDefinition< defaultMessage: 'Define how missing values are treated', }), }, + tickLabelsVisibilitySettings: { + types: ['lens_xy_tickLabelsConfig'], + help: i18n.translate('xpack.lens.xyChart.tickLabelsSettings.help', { + defaultMessage: 'Show x and y axes tick labels', + }), + }, + gridlinesVisibilitySettings: { + types: ['lens_xy_gridlinesConfig'], + help: i18n.translate('xpack.lens.xyChart.gridlinesSettings.help', { + defaultMessage: 'Show x and y axes gridlines', + }), + }, + showXAxisTitle: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.showXAxisTitle.help', { + defaultMessage: 'Show x axis title', + }), + }, + showYAxisTitle: { + types: ['boolean'], + help: i18n.translate('xpack.lens.xyChart.showYAxisTitle.help', { + defaultMessage: 'Show y axis title', + }), + }, layers: { // eslint-disable-next-line @typescript-eslint/no-explicit-any types: ['lens_xy_layer'] as any, @@ -199,7 +223,7 @@ export function XYChart({ onClickValue, onSelectRange, }: XYChartRenderProps) { - const { legend, layers, fittingFunction } = args; + const { legend, layers, fittingFunction, gridlinesVisibilitySettings } = args; const chartTheme = chartsThemeService.useChartsTheme(); const chartBaseTheme = chartsThemeService.useChartsBaseTheme(); @@ -237,7 +261,10 @@ export function XYChart({ shouldRotate ); - const xTitle = (xAxisColumn && xAxisColumn.name) || args.xTitle; + const xTitle = args.xTitle || (xAxisColumn && xAxisColumn.name); + const showXAxisTitle = args.showXAxisTitle ?? true; + const showYAxisTitle = args.showYAxisTitle ?? true; + const tickLabelsVisibilitySettings = args.tickLabelsVisibilitySettings || { x: true, y: true }; function calculateMinInterval() { // check all the tables to see if all of the rows have the same timestamp @@ -279,6 +306,22 @@ export function XYChart({ } : undefined; + const getYAxesTitles = ( + axisSeries: Array<{ layer: string; accessor: string }>, + index: number + ) => { + if (index > 0 && args.yTitle) return; + return ( + args.yTitle || + axisSeries + .map( + (series) => + data.tables[series.layer].columns.find((column) => column.id === series.accessor)?.name + ) + .filter((name) => Boolean(name))[0] + ); + }; + return ( xAxisFormatter.convert(d)} + tickFormat={tickLabelsVisibilitySettings?.x ? (d) => xAxisFormatter.convert(d) : () => ''} /> {yAxesConfiguration.map((axis, index) => ( @@ -389,18 +433,10 @@ export function XYChart({ id={axis.groupId} groupId={axis.groupId} position={axis.position} - title={ - axis.series - .map( - (series) => - data.tables[series.layer].columns.find((column) => column.id === series.accessor) - ?.name - ) - .filter((name) => Boolean(name))[0] || args.yTitle - } - showGridLines={false} + title={showYAxisTitle ? getYAxesTitles(axis.series, index) : undefined} + showGridLines={gridlinesVisibilitySettings?.y} hide={filteredLayers[0].hide} - tickFormat={(d) => axis.formatter.convert(d)} + tickFormat={tickLabelsVisibilitySettings?.y ? (d) => axis.formatter.convert(d) : () => ''} /> ))} diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts index 7b3398658a500..632f6fc8861a4 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts @@ -445,6 +445,10 @@ describe('xy_suggestions', () => { const currentState: XYState = { legend: { isVisible: true, position: 'bottom' }, fittingFunction: 'None', + showXAxisTitle: true, + showYAxisTitle: true, + gridlinesVisibilitySettings: { x: true, y: true }, + tickLabelsVisibilitySettings: { x: true, y: false }, preferredSeriesType: 'bar', layers: [ { @@ -483,6 +487,10 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, preferredSeriesType: 'bar', fittingFunction: 'None', + showXAxisTitle: true, + showYAxisTitle: true, + gridlinesVisibilitySettings: { x: true, y: true }, + tickLabelsVisibilitySettings: { x: true, y: false }, layers: [ { accessors: ['price', 'quantity'], @@ -592,6 +600,10 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, preferredSeriesType: 'bar', fittingFunction: 'None', + showXAxisTitle: true, + showYAxisTitle: true, + gridlinesVisibilitySettings: { x: true, y: true }, + tickLabelsVisibilitySettings: { x: true, y: false }, layers: [ { accessors: ['price', 'quantity'], @@ -631,6 +643,10 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, preferredSeriesType: 'bar', fittingFunction: 'None', + showXAxisTitle: true, + showYAxisTitle: true, + gridlinesVisibilitySettings: { x: true, y: true }, + tickLabelsVisibilitySettings: { x: true, y: false }, layers: [ { accessors: ['price'], @@ -671,6 +687,10 @@ describe('xy_suggestions', () => { legend: { isVisible: true, position: 'bottom' }, preferredSeriesType: 'bar', fittingFunction: 'None', + showXAxisTitle: true, + showYAxisTitle: true, + gridlinesVisibilitySettings: { x: true, y: true }, + tickLabelsVisibilitySettings: { x: true, y: false }, layers: [ { accessors: ['price', 'quantity'], diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts index 1be8d566a8b64..387d56c03e31a 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts @@ -407,6 +407,18 @@ function buildSuggestion({ const state: State = { legend: currentState ? currentState.legend : { isVisible: true, position: Position.Right }, fittingFunction: currentState?.fittingFunction || 'None', + xTitle: currentState?.xTitle, + yTitle: currentState?.yTitle, + showXAxisTitle: currentState?.showXAxisTitle ?? true, + showYAxisTitle: currentState?.showYAxisTitle ?? true, + tickLabelsVisibilitySettings: currentState?.tickLabelsVisibilitySettings || { + x: true, + y: true, + }, + gridlinesVisibilitySettings: currentState?.gridlinesVisibilitySettings || { + x: true, + y: true, + }, preferredSeriesType: seriesType, layers: Object.keys(existingLayer).length ? keptLayers : [...keptLayers, newLayer], }; From 78689b7ecd3d1e50ebb1a9269c80f1eeb2e8ef1d Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 11 Aug 2020 20:17:08 +0300 Subject: [PATCH 106/106] [Functional Tests] Adds a wait time between setting the index pattern and the time field on TSVB (#74736) * Adds a wait time between setting the index pattern and the time field on tsvb * Char by char to set indexpattern to give more time to load the time field * Add more time * uncomment commented lines --- test/functional/apps/visualize/_tsvb_chart.ts | 9 ++++++++- test/functional/page_objects/visual_builder_page.ts | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/test/functional/apps/visualize/_tsvb_chart.ts b/test/functional/apps/visualize/_tsvb_chart.ts index ab76598ae2ea5..18d6e93090e8b 100644 --- a/test/functional/apps/visualize/_tsvb_chart.ts +++ b/test/functional/apps/visualize/_tsvb_chart.ts @@ -26,7 +26,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const inspector = getService('inspector'); const retry = getService('retry'); const security = getService('security'); - const PageObjects = getPageObjects(['visualize', 'visualBuilder', 'timePicker', 'visChart']); + const PageObjects = getPageObjects([ + 'visualize', + 'visualBuilder', + 'timePicker', + 'visChart', + 'common', + ]); describe('visual builder', function describeIndexTests() { this.tags('includeFirefox'); @@ -132,6 +138,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.tryForTime(20000, async () => { await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualBuilder.setIndexPatternValue('kibana_sample_data_flights'); + await PageObjects.common.sleep(3000); await PageObjects.visualBuilder.selectIndexPatternTimeField('timestamp'); }); const newValue = await PageObjects.visualBuilder.getMetricValue(); diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts index 2771982fecdea..f376c39ff67bb 100644 --- a/test/functional/page_objects/visual_builder_page.ts +++ b/test/functional/page_objects/visual_builder_page.ts @@ -420,7 +420,7 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro public async setIndexPatternValue(value: string) { const el = await testSubjects.find('metricsIndexPatternInput'); await el.clearValue(); - await el.type(value); + await el.type(value, { charByChar: true }); await PageObjects.header.waitUntilLoadingHasFinished(); }

    Made with NaturalEarth | Elastic Maps Service