diff --git a/.playground/index.html b/.playground/index.html
index 266524c14d..d28529866b 100644
--- a/.playground/index.html
+++ b/.playground/index.html
@@ -19,22 +19,15 @@
         position: absolute;
         top: 0px;
         left: 0px;
+        width: 100%;
       }
       .chart {
         background: white;
         display: inline-block;
         position: relative;
-        width: 900px;
-        height: 600px;
-        margin: 10px;
-        /* overflow: hidden; */
-      }
-      button {
-        padding: 10px !important;
-        background: black !important;
-        border: 1px solid white !important;
-        color: white !important;
-        margin: 4px !important;
+        width: 1000px;
+        height: 350px;
+        margin: 0px;
       }
     </style>
   </head>
diff --git a/.playground/playgroud.tsx b/.playground/playgroud.tsx
index 6288fb748e..778fbcb2af 100644
--- a/.playground/playgroud.tsx
+++ b/.playground/playgroud.tsx
@@ -6,10 +6,13 @@ import {
   getSpecId,
   Position,
   ScaleType,
-  HistogramBarSeries,
   Settings,
   LIGHT_THEME,
   niceTimeFormatter,
+  LineAnnotation,
+  AnnotationDomainTypes,
+  BarSeries,
+  RectAnnotation,
 } from '../src';
 import { KIBANA_METRICS } from '../src/utils/data_samples/test_dataset_kibana';
 export class Playground extends React.Component {
@@ -39,7 +42,7 @@ export class Playground extends React.Component {
     }
   };
   render() {
-    const data = KIBANA_METRICS.metrics.kibana_os_load[0].data.slice(0, 100);
+    const data = KIBANA_METRICS.metrics.kibana_os_load[0].data.slice(0, 7);
 
     return (
       <>
@@ -53,8 +56,29 @@ export class Playground extends React.Component {
               tickFormat={niceTimeFormatter([data[0][0], data[data.length - 1][0]])}
             />
             <Axis id={getAxisId('count')} position={Position.Left} />
-
-            <HistogramBarSeries
+            <LineAnnotation
+              id="line annotation"
+              dataValues={[
+                {
+                  dataValue: data[5][0],
+                  details: 'hello tooltip',
+                },
+              ]}
+              domainType={AnnotationDomainTypes.XDomain}
+              marker={<div style={{ width: 10, height: 10, background: 'red' }} />}
+            />
+            <RectAnnotation
+              id="rect annotation"
+              dataValues={[
+                {
+                  coordinates: {
+                    x1: data[3][0],
+                  },
+                  details: 'hello',
+                },
+              ]}
+            />
+            <BarSeries
               id={getSpecId('series bars chart')}
               xScaleType={ScaleType.Linear}
               yScaleType={ScaleType.Linear}
diff --git a/.playground/webpack.config.js b/.playground/webpack.config.js
index 3d24a4f4f9..4564fb6053 100644
--- a/.playground/webpack.config.js
+++ b/.playground/webpack.config.js
@@ -13,6 +13,7 @@ module.exports = {
         exclude: /node_modules/,
         options: {
           configFile: 'tsconfig.json',
+          transpileOnly: true,
         },
       },
       {
diff --git a/integration/page_objects/common.ts b/integration/page_objects/common.ts
index 2a0bd73307..abc72aea65 100644
--- a/integration/page_objects/common.ts
+++ b/integration/page_objects/common.ts
@@ -21,7 +21,7 @@ class CommonPage {
 
     return `${baseUrl}?${query}${query ? '&' : ''}knob-debug=false`;
   }
-  async getBoundingClientRect(selector = '.echChart[data-ech-render-complete=true]') {
+  async getBoundingClientRect(selector = '.echChart') {
     return await page.evaluate((selector) => {
       const element = document.querySelector(selector);
 
@@ -37,10 +37,7 @@ class CommonPage {
   /**
    * Capture screenshot or chart element only
    */
-  async screenshotDOMElement(
-    selector = '.echChart[data-ech-render-complete=true]',
-    opts?: ScreenshotDOMElementOptions,
-  ) {
+  async screenshotDOMElement(selector = '.echChart', opts?: ScreenshotDOMElementOptions) {
     const padding: number = opts && opts.padding ? opts.padding : 0;
     const path: string | undefined = opts && opts.path ? opts.path : undefined;
     const rect = await this.getBoundingClientRect(selector);
@@ -56,10 +53,7 @@ class CommonPage {
     });
   }
 
-  async moveMouseRelativeToDOMElement(
-    mousePosition: { x: number; y: number },
-    selector = '.echChart[data-ech-render-complete=true]',
-  ) {
+  async moveMouseRelativeToDOMElement(mousePosition: { x: number; y: number }, selector = '.echChart') {
     const chartContainer = await this.getBoundingClientRect(selector);
     await page.mouse.move(chartContainer.left + mousePosition.x, chartContainer.top + mousePosition.y);
   }
@@ -113,9 +107,14 @@ class CommonPage {
   async loadChartFromURL(url: string) {
     const cleanUrl = CommonPage.parseUrl(url);
     await page.goto(cleanUrl);
+    this.waitForElement();
   }
-
-  async waitForElement(selector = '.echChart[data-ech-render-complete=true]', timeout = 10000) {
+  /**
+   * Wait for an element to be on the DOM
+   * @param {string} [selector] the DOM selector to wait for, default to '.echChartStatus[data-ech-render-complete=true]'
+   * @param {number} [timeout] - the timeout for the operation, default to 10000ms
+   */
+  async waitForElement(selector = '.echChartStatus[data-ech-render-complete=true]', timeout = 10000) {
     await page.waitForSelector(selector, { timeout });
   }
 }
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-stacked-with-separated-specs-same-naming-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-stacked-with-separated-specs-same-naming-visually-looks-correct-1-snap.png
index ec4a40e69e..7656229b36 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-stacked-with-separated-specs-same-naming-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-stacked-with-separated-specs-same-naming-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-test-linear-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-test-linear-visually-looks-correct-1-snap.png
index b3edb0a61b..c85776c82f 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-test-linear-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-test-linear-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-test-time-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-test-time-visually-looks-correct-1-snap.png
index d7777d4019..22e96bafb3 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-test-time-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-test-time-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-w-axis-and-legend-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-w-axis-and-legend-visually-looks-correct-1-snap.png
index 627aa22fca..de6f227bd4 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-w-axis-and-legend-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-w-axis-and-legend-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-with-4-axes-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-with-4-axes-visually-looks-correct-1-snap.png
index 49f9e2ad60..923f01d36c 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-with-4-axes-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-area-chart-with-4-axes-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-4-axes-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-4-axes-visually-looks-correct-1-snap.png
index 1d35b1600b..c75c19bc5f 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-4-axes-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-4-axes-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-mixed-linear-chart-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-mixed-linear-chart-visually-looks-correct-1-snap.png
index 5724397a8a..e5d222a7cb 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-mixed-linear-chart-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-mixed-linear-chart-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-mixed-ordinal-linear-x-domain-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-mixed-ordinal-linear-x-domain-visually-looks-correct-1-snap.png
index 9bacef38a6..d9bf398224 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-mixed-ordinal-linear-x-domain-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-mixed-ordinal-linear-x-domain-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-only-one-bound-defined-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-only-one-bound-defined-visually-looks-correct-1-snap.png
index 5cccc53db0..f6922e4113 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-only-one-bound-defined-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-customizing-domain-limits-only-one-bound-defined-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-tick-label-rotation-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-tick-label-rotation-visually-looks-correct-1-snap.png
index 2e8c6b8e34..e9e6190f3c 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-tick-label-rotation-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-tick-label-rotation-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-with-multi-axis-bar-lines-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-with-multi-axis-bar-lines-visually-looks-correct-1-snap.png
index 895c56542d..9936ef26a5 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-with-multi-axis-bar-lines-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-axis-with-multi-axis-bar-lines-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-1-y-1-g-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-1-y-1-g-visually-looks-correct-1-snap.png
index cd96262897..170c01726d 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-1-y-1-g-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-1-y-1-g-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-1-y-2-g-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-1-y-2-g-visually-looks-correct-1-snap.png
index a80adea3a6..1928eb6866 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-1-y-2-g-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-1-y-2-g-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-2-y-1-g-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-2-y-1-g-visually-looks-correct-1-snap.png
index d0fbbd1df0..4e11f96bd0 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-2-y-1-g-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-2-y-1-g-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-clustered-multiple-series-specs-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-clustered-multiple-series-specs-visually-looks-correct-1-snap.png
index 133d5a50d2..baf6c86df0 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-clustered-multiple-series-specs-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-clustered-multiple-series-specs-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-clustered-with-axis-and-legend-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-clustered-with-axis-and-legend-visually-looks-correct-1-snap.png
index 4f3d9c873a..36faac9f74 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-clustered-with-axis-and-legend-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-clustered-with-axis-and-legend-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-min-height-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-min-height-visually-looks-correct-1-snap.png
index d31ba777c3..ef3bc95f1d 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-min-height-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-min-height-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-single-data-chart-ordinal-visually-looks-correct-2-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-single-data-chart-ordinal-visually-looks-correct-2-snap.png
new file mode 100644
index 0000000000..753b701224
Binary files /dev/null and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-single-data-chart-ordinal-visually-looks-correct-2-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-clustered-bar-chart-with-null-bars-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-clustered-bar-chart-with-null-bars-visually-looks-correct-1-snap.png
index 56393b1959..b1e9e661eb 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-clustered-bar-chart-with-null-bars-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-clustered-bar-chart-with-null-bars-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-linear-clustered-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-linear-clustered-visually-looks-correct-1-snap.png
index 09c4fb24a5..bb222cc068 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-linear-clustered-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-linear-clustered-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-switch-ordinal-linear-x-axis-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-switch-ordinal-linear-x-axis-visually-looks-correct-1-snap.png
index 72cc4a3d4e..cddb83dd77 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-switch-ordinal-linear-x-axis-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-switch-ordinal-linear-x-axis-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-time-clustered-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-time-clustered-visually-looks-correct-1-snap.png
index 2d872e6bee..5ae354e2aa 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-time-clustered-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-time-clustered-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-time-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-time-visually-looks-correct-1-snap.png
index 7e2f1d2d80..3fa958e7b6 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-time-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-test-time-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-axis-and-legend-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-axis-and-legend-visually-looks-correct-1-snap.png
index f9ef7508e0..b9e5b8746b 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-axis-and-legend-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-axis-and-legend-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-axis-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-axis-visually-looks-correct-1-snap.png
index 72cc4a3d4e..cddb83dd77 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-axis-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-axis-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-high-data-volume-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-high-data-volume-visually-looks-correct-1-snap.png
index c8ece4cf5f..7f8db335a8 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-high-data-volume-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-high-data-volume-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-linear-x-axis-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-linear-x-axis-visually-looks-correct-1-snap.png
index f4010a359a..751746c0c7 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-linear-x-axis-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-linear-x-axis-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-ordinal-x-axis-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-ordinal-x-axis-visually-looks-correct-1-snap.png
index 295fb3edff..df3b41a445 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-ordinal-x-axis-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-ordinal-x-axis-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-value-label-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-value-label-visually-looks-correct-1-snap.png
index 8ca3071d03..3b749d7a76 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-value-label-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-bar-chart-with-value-label-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-grids-basic-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-grids-basic-visually-looks-correct-1-snap.png
index 5bb21ebcd2..8452dab797 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-grids-basic-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-grids-basic-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-grids-multiple-axes-with-the-same-position-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-grids-multiple-axes-with-the-same-position-visually-looks-correct-1-snap.png
index 228c026a4a..a30017dede 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-grids-multiple-axes-with-the-same-position-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-grids-multiple-axes-with-the-same-position-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-area-point-clicks-and-hovers-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-area-point-clicks-and-hovers-visually-looks-correct-1-snap.png
index 678d99a66d..c58cc3588a 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-area-point-clicks-and-hovers-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-area-point-clicks-and-hovers-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-bar-clicks-and-hovers-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-bar-clicks-and-hovers-visually-looks-correct-1-snap.png
index 6292dd9a42..3fc7bd6117 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-bar-clicks-and-hovers-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-bar-clicks-and-hovers-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-bar-chart-linear-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-bar-chart-linear-visually-looks-correct-1-snap.png
index bdf2e92fb5..d73ed187ed 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-bar-chart-linear-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-bar-chart-linear-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-histogram-time-charts-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-histogram-time-charts-visually-looks-correct-1-snap.png
new file mode 100644
index 0000000000..0099161c11
Binary files /dev/null and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-histogram-time-charts-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-linear-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-linear-visually-looks-correct-1-snap.png
index 1d35b1600b..c75c19bc5f 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-linear-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-linear-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-time-charts-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-time-charts-visually-looks-correct-1-snap.png
index b4fd16e478..0f0e3426a0 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-time-charts-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-brush-selection-tool-on-time-charts-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-click-hovers-on-legend-items-line-chart-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-click-hovers-on-legend-items-line-chart-visually-looks-correct-1-snap.png
index 11fea9ecc2..2bae67388a 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-click-hovers-on-legend-items-line-chart-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-click-hovers-on-legend-items-line-chart-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-cursor-update-action-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-cursor-update-action-visually-looks-correct-1-snap.png
index 6292dd9a42..3fc7bd6117 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-cursor-update-action-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-cursor-update-action-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-line-area-bar-point-clicks-and-hovers-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-line-area-bar-point-clicks-and-hovers-visually-looks-correct-1-snap.png
index f6a069fc30..724c199905 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-line-area-bar-point-clicks-and-hovers-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-line-area-bar-point-clicks-and-hovers-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-line-point-clicks-and-hovers-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-line-point-clicks-and-hovers-visually-looks-correct-1-snap.png
index ea61fd21b1..e850a8819b 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-line-point-clicks-and-hovers-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-line-point-clicks-and-hovers-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-png-export-action-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-png-export-action-visually-looks-correct-1-snap.png
index d381a3b146..2ff8ed4ad9 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-png-export-action-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-png-export-action-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-render-change-action-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-render-change-action-visually-looks-correct-1-snap.png
index 6292dd9a42..3fc7bd6117 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-render-change-action-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-interactions-render-change-action-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-bottom-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-bottom-visually-looks-correct-1-snap.png
index 3f0eb59be0..859c4c54c1 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-bottom-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-bottom-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-display-values-in-legend-elements-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-display-values-in-legend-elements-visually-looks-correct-1-snap.png
index 5654907524..f9c91eea50 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-display-values-in-legend-elements-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-display-values-in-legend-elements-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-legend-spacing-buffer-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-legend-spacing-buffer-visually-looks-correct-1-snap.png
index 5c95cde5fd..cf8b08664c 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-legend-spacing-buffer-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-legend-legend-spacing-buffer-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-curved-w-axis-and-legend-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-curved-w-axis-and-legend-visually-looks-correct-1-snap.png
index ac13b8fdb6..9a86b8cf20 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-curved-w-axis-and-legend-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-curved-w-axis-and-legend-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multi-series-with-log-values-limit-0-or-negative-values-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multi-series-with-log-values-limit-0-or-negative-values-visually-looks-correct-1-snap.png
index 753c14736e..8b9569bb67 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multi-series-with-log-values-limit-0-or-negative-values-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multi-series-with-log-values-limit-0-or-negative-values-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multiple-w-axis-and-legend-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multiple-w-axis-and-legend-visually-looks-correct-1-snap.png
index 1121c9d238..181d63dafc 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multiple-w-axis-and-legend-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-multiple-w-axis-and-legend-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-stacked-w-axis-and-legend-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-stacked-w-axis-and-legend-visually-looks-correct-1-snap.png
index 0fb2fe6134..383a6f826e 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-stacked-w-axis-and-legend-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-stacked-w-axis-and-legend-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-w-axis-and-legend-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-w-axis-and-legend-visually-looks-correct-1-snap.png
index 6ebe43eb9c..bea9f66473 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-w-axis-and-legend-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-line-chart-w-axis-and-legend-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-areas-and-bars-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-areas-and-bars-visually-looks-correct-1-snap.png
index 698fcf17c2..dcaba5207d 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-areas-and-bars-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-areas-and-bars-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-lines-and-areas-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-lines-and-areas-visually-looks-correct-1-snap.png
index 0a3d66de5c..9a5b2bab57 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-lines-and-areas-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-lines-and-areas-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-test-bar-lines-linear-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-test-bar-lines-linear-visually-looks-correct-1-snap.png
index 54b298242f..1b4b2e339f 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-test-bar-lines-linear-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-test-bar-lines-linear-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-test-bar-lines-time-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-test-bar-lines-time-visually-looks-correct-1-snap.png
index 2c2d57dbc6..3b83c3ab19 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-test-bar-lines-time-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-mixed-charts-test-bar-lines-time-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-rotations-with-ordinal-axis-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-rotations-with-ordinal-axis-visually-looks-correct-1-snap.png
index 5b75cc1781..2644f58005 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-rotations-with-ordinal-axis-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-rotations-with-ordinal-axis-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-line-chart-with-different-timezones-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-line-chart-with-different-timezones-visually-looks-correct-1-snap.png
index d689e3d86c..53df6b37a3 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-line-chart-with-different-timezones-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-line-chart-with-different-timezones-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-remove-duplicate-scales-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-remove-duplicate-scales-visually-looks-correct-1-snap.png
index 99329bd201..eaad6f2e0e 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-remove-duplicate-scales-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-remove-duplicate-scales-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-utc-time-zone-local-tooltip-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-utc-time-zone-local-tooltip-visually-looks-correct-1-snap.png
index d689e3d86c..53df6b37a3 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-utc-time-zone-local-tooltip-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-utc-time-zone-local-tooltip-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-utc-time-zone-utc-tooltip-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-utc-time-zone-utc-tooltip-visually-looks-correct-1-snap.png
index d689e3d86c..53df6b37a3 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-utc-time-zone-utc-tooltip-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-utc-time-zone-utc-tooltip-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-year-scale-custom-timezone-same-zone-tooltip-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-year-scale-custom-timezone-same-zone-tooltip-visually-looks-correct-1-snap.png
index a7c33ba459..f335e70b8a 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-year-scale-custom-timezone-same-zone-tooltip-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-scales-x-scale-year-scale-custom-timezone-same-zone-tooltip-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-axis-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-axis-visually-looks-correct-1-snap.png
index ec86ac4d13..807c47161d 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-axis-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-axis-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-margins-and-paddings-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-margins-and-paddings-visually-looks-correct-1-snap.png
index 12f29cd34f..79b9563647 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-margins-and-paddings-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-margins-and-paddings-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-style-accessor-overrides-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-style-accessor-overrides-visually-looks-correct-1-snap.png
index 1917d368cc..4275dcc88c 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-style-accessor-overrides-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-style-accessor-overrides-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-theme-style-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-theme-style-visually-looks-correct-1-snap.png
index 0905daf933..09f1febeaa 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-theme-style-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-theme-style-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-tick-label-padding-both-prop-and-theme-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-tick-label-padding-both-prop-and-theme-visually-looks-correct-1-snap.png
index 8e19b41b86..8b9db30b91 100644
Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-tick-label-padding-both-prop-and-theme-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-stylings-tick-label-padding-both-prop-and-theme-visually-looks-correct-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-accessor-formats-should-show-custom-format-1-snap.png b/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-accessor-formats-should-show-custom-format-1-snap.png
index 0527889acd..5cfee5c36c 100644
Binary files a/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-accessor-formats-should-show-custom-format-1-snap.png and b/integration/tests/__image_snapshots__/area-stories-test-ts-area-series-stories-accessor-formats-should-show-custom-format-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-bottom-axis-1-snap.png b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-bottom-axis-1-snap.png
index 1261e797d2..f633f54844 100644
Binary files a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-bottom-axis-1-snap.png and b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-bottom-axis-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-left-axis-1-snap.png b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-left-axis-1-snap.png
index 57dcd868ce..9eda9241cf 100644
Binary files a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-left-axis-1-snap.png and b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-left-axis-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-right-axis-1-snap.png b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-right-axis-1-snap.png
index a9d01ed270..842bd72b6b 100644
Binary files a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-right-axis-1-snap.png and b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-right-axis-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-top-axis-1-snap.png b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-top-axis-1-snap.png
index f7dc5bace4..13f3ba54f9 100644
Binary files a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-top-axis-1-snap.png and b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-hide-top-axis-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-render-ticks-with-varied-rotations-1-snap.png b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-render-ticks-with-varied-rotations-1-snap.png
index 2d1341d46a..af6b3b5958 100644
Binary files a/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-render-ticks-with-varied-rotations-1-snap.png and b/integration/tests/__image_snapshots__/axis-stories-test-ts-axis-stories-should-render-ticks-with-varied-rotations-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/bar-stories-test-ts-bar-series-stories-test-switch-ordinal-linear-x-axis-using-ordinal-x-axis-1-snap.png b/integration/tests/__image_snapshots__/bar-stories-test-ts-bar-series-stories-test-switch-ordinal-linear-x-axis-using-ordinal-x-axis-1-snap.png
index 72cc4a3d4e..cddb83dd77 100644
Binary files a/integration/tests/__image_snapshots__/bar-stories-test-ts-bar-series-stories-test-switch-ordinal-linear-x-axis-using-ordinal-x-axis-1-snap.png and b/integration/tests/__image_snapshots__/bar-stories-test-ts-bar-series-stories-test-switch-ordinal-linear-x-axis-using-ordinal-x-axis-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-0-legend-buffer-1-snap.png b/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-0-legend-buffer-1-snap.png
index 9b9898945d..c140c9a2b4 100644
Binary files a/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-0-legend-buffer-1-snap.png and b/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-0-legend-buffer-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-hide-line-series-legend-item-1-snap.png b/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-hide-line-series-legend-item-1-snap.png
index 2e5b70b955..d6aeff8e70 100644
Binary files a/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-hide-line-series-legend-item-1-snap.png and b/integration/tests/__image_snapshots__/legend-stories-test-ts-legend-stories-should-hide-line-series-legend-item-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/line-stories-test-ts-line-series-stories-rotation-rotation-90-1-snap.png b/integration/tests/__image_snapshots__/line-stories-test-ts-line-series-stories-rotation-rotation-90-1-snap.png
index 26677d3bb2..7d26012345 100644
Binary files a/integration/tests/__image_snapshots__/line-stories-test-ts-line-series-stories-rotation-rotation-90-1-snap.png and b/integration/tests/__image_snapshots__/line-stories-test-ts-line-series-stories-rotation-rotation-90-1-snap.png differ
diff --git a/integration/tests/__image_snapshots__/line-stories-test-ts-line-series-stories-rotation-rotation-negative-90-1-snap.png b/integration/tests/__image_snapshots__/line-stories-test-ts-line-series-stories-rotation-rotation-negative-90-1-snap.png
index bb3e6dbb9d..4260f0f5cd 100644
Binary files a/integration/tests/__image_snapshots__/line-stories-test-ts-line-series-stories-rotation-rotation-negative-90-1-snap.png and b/integration/tests/__image_snapshots__/line-stories-test-ts-line-series-stories-rotation-rotation-negative-90-1-snap.png differ
diff --git a/package.json b/package.json
index 31bd2b20e2..18681e3d0e 100644
--- a/package.json
+++ b/package.json
@@ -83,10 +83,11 @@
     "@types/puppeteer": "^1.19.1",
     "@types/react": "^16.8.5",
     "@types/react-dom": "^16.8.2",
+    "@types/react-redux": "^7.1.1",
     "@types/seedrandom": "^2.4.28",
     "@types/storybook__addon-actions": "^3.4.3",
     "@types/storybook__addon-info": "^4.1.2",
-    "@types/storybook__addon-knobs": "^5.0.3",
+    "@types/storybook__addon-knobs": "5.0.4",
     "@types/storybook__react": "^4.0.2",
     "@types/url-parse": "^1.4.3",
     "@types/uuid": "^3.4.4",
@@ -126,6 +127,7 @@
     "puppeteer": "^1.20.0",
     "react-docgen-typescript-loader": "^3.0.1",
     "react-docgen-typescript-webpack-plugin": "^1.1.0",
+    "redux-devtools-extension": "^2.13.8",
     "sass-graph": "^3.0.4",
     "sass-loader": "^7.1.0",
     "seedrandom": "^3.0.5",
@@ -147,16 +149,17 @@
     "d3-collection": "^1.0.7",
     "d3-scale": "^1.0.7",
     "d3-shape": "^1.3.4",
-    "fp-ts": "^1.14.2",
     "konva": "^2.6.0",
-    "mobx": "^4.9.2",
-    "mobx-react": "^5.4.3",
     "newtype-ts": "^0.2.4",
     "prop-types": "^15.7.2",
+    "re-reselect": "^3.4.0",
     "react": "^16.8.3",
     "react-dom": "^16.8.3",
     "react-konva": "16.8.3",
+    "react-redux": "^7.1.0",
     "react-spring": "^8.0.8",
+    "redux": "^4.0.4",
+    "reselect": "^4.0.0",
     "resize-observer-polyfill": "^1.5.1",
     "ts-debounce": "^1.0.0",
     "uuid": "^3.3.2"
diff --git a/scripts/custom_matchers.ts b/scripts/custom_matchers.ts
index bf6d226a8e..0f6ebfe8db 100644
--- a/scripts/custom_matchers.ts
+++ b/scripts/custom_matchers.ts
@@ -15,7 +15,8 @@ type MatcherParameters<T extends (this: any, received: any, ...args: any[]) => a
   : never;
 
 declare global {
-  namespace jest { // eslint-disable-line
+  // eslint-disable-next-line
+  namespace jest {
     interface Matchers<R> {
       /**
        * Expect array to be filled with value, and optionally length
diff --git a/src/chart_types/index.ts b/src/chart_types/index.ts
new file mode 100644
index 0000000000..12f7dc46a2
--- /dev/null
+++ b/src/chart_types/index.ts
@@ -0,0 +1,9 @@
+import { $Values } from 'utility-types';
+
+export const ChartTypes = Object.freeze({
+  Global: 'global' as 'global',
+  Pie: 'pie' as 'pie',
+  XYAxis: 'xy_axis' as 'xy_axis',
+});
+
+export type ChartTypes = $Values<typeof ChartTypes>;
diff --git a/src/chart_types/specs.ts b/src/chart_types/specs.ts
new file mode 100644
index 0000000000..c969027460
--- /dev/null
+++ b/src/chart_types/specs.ts
@@ -0,0 +1,9 @@
+export {
+  AreaSeries,
+  BarSeries,
+  LineSeries,
+  Axis,
+  LineAnnotation,
+  RectAnnotation,
+  HistogramBarSeries,
+} from './xy_chart/specs';
diff --git a/src/chart_types/xy_chart/annotations/annotation_marker.test.tsx b/src/chart_types/xy_chart/annotations/annotation_marker.test.tsx
index dfa7e1c5de..46b9bc0b49 100644
--- a/src/chart_types/xy_chart/annotations/annotation_marker.test.tsx
+++ b/src/chart_types/xy_chart/annotations/annotation_marker.test.tsx
@@ -1,20 +1,16 @@
 import * as React from 'react';
 
-import { AnnotationDomainTypes, AnnotationSpec, Position, Rotation } from '../utils/specs';
+import { AnnotationDomainTypes, AnnotationSpec, Position, Rotation, SpecTypes, AnnotationTypes } from '../utils/specs';
 import { DEFAULT_ANNOTATION_LINE_STYLE } from '../../../utils/themes/theme';
 import { Dimensions } from '../../../utils/dimensions';
-import { getAnnotationId, getGroupId, GroupId } from '../../../utils/ids';
+import { GroupId } from '../../../utils/ids';
 import { ScaleContinuous } from '../../../utils/scales/scale_continuous';
 import { Scale, ScaleType } from '../../../utils/scales/scales';
-import {
-  computeLineAnnotationDimensions,
-  isWithinLineMarkerBounds,
-  AnnotationMarker,
-  AnnotationLineProps,
-} from './annotation_utils';
+import { computeLineAnnotationDimensions, AnnotationLineProps } from './line_annotation_tooltip';
+import { ChartTypes } from '../..';
 
 describe('annotation marker', () => {
-  const groupId = getGroupId('foo-group');
+  const groupId = 'foo-group';
 
   const minRange = 0;
   const maxRange = 100;
@@ -41,10 +37,12 @@ describe('annotation marker', () => {
   test('should compute line annotation dimensions with marker if defined (y domain)', () => {
     const chartRotation: Rotation = 0;
 
-    const annotationId = getAnnotationId('foo-line');
+    const id = 'foo-line';
     const lineAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -95,10 +93,11 @@ describe('annotation marker', () => {
   test('should compute line annotation dimensions with marker if defined (y domain: 180 deg rotation)', () => {
     const chartRotation: Rotation = 180;
 
-    const annotationId = getAnnotationId('foo-line');
     const lineAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: 'foo-line',
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -148,10 +147,11 @@ describe('annotation marker', () => {
   test('should compute line annotation dimensions with marker if defined (x domain)', () => {
     const chartRotation: Rotation = 0;
 
-    const annotationId = getAnnotationId('foo-line');
     const lineAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: 'foo-line',
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -197,26 +197,4 @@ describe('annotation marker', () => {
     ];
     expect(dimensions).toEqual(expectedDimensions);
   });
-
-  test('should compute if a point is within an annotation line marker bounds', () => {
-    const marker: AnnotationMarker = {
-      icon: <div />,
-      color: 'custom-color',
-      position: { top: 0, left: 0 },
-      dimension: { width: 10, height: 10 },
-    };
-    expect(isWithinLineMarkerBounds({ x: -1, y: 0 }, marker)).toBe(false);
-
-    expect(isWithinLineMarkerBounds({ x: 0, y: -1 }, marker)).toBe(false);
-
-    expect(isWithinLineMarkerBounds({ x: 0, y: 0 }, marker)).toBe(true);
-
-    expect(isWithinLineMarkerBounds({ x: 10, y: 10 }, marker)).toBe(true);
-
-    expect(isWithinLineMarkerBounds({ x: 11, y: 10 }, marker)).toBe(false);
-
-    expect(isWithinLineMarkerBounds({ x: 11, y: 10 }, { ...marker, position: { top: 0, left: 1 } })).toBe(true);
-
-    expect(isWithinLineMarkerBounds({ x: 15, y: 15 }, { ...marker, position: { top: 10, left: 10 } })).toBe(true);
-  });
 });
diff --git a/src/chart_types/xy_chart/annotations/annotation_utils.test.ts b/src/chart_types/xy_chart/annotations/annotation_utils.test.ts
index 4b2c2ebaa5..465bc59a4d 100644
--- a/src/chart_types/xy_chart/annotations/annotation_utils.test.ts
+++ b/src/chart_types/xy_chart/annotations/annotation_utils.test.ts
@@ -7,37 +7,41 @@ import {
   Position,
   RectAnnotationSpec,
   Rotation,
+  SpecTypes,
+  AnnotationTypes,
 } from '../utils/specs';
 import { DEFAULT_ANNOTATION_LINE_STYLE } from '../../../utils/themes/theme';
 import { Dimensions } from '../../../utils/dimensions';
-import { AnnotationId, AxisId, getAnnotationId, getAxisId, getGroupId, GroupId } from '../../../utils/ids';
+import { getAxisId, getGroupId, GroupId, AnnotationId } from '../../../utils/ids';
 import { ScaleBand } from '../../../utils/scales/scale_band';
 import { ScaleContinuous } from '../../../utils/scales/scale_continuous';
 import { Scale, ScaleType } from '../../../utils/scales/scales';
 import {
-  AnnotationLineProps,
   computeAnnotationDimensions,
   computeAnnotationTooltipState,
   computeClusterOffset,
-  computeLineAnnotationDimensions,
-  computeLineAnnotationTooltipState,
-  computeRectAnnotationDimensions,
-  computeRectAnnotationTooltipState,
-  computeRectTooltipLeft,
-  computeRectTooltipTop,
   getAnnotationAxis,
-  getAnnotationLineTooltipXOffset,
-  getAnnotationLineTooltipYOffset,
   getRotatedCursor,
-  isBottomRectTooltip,
-  isRightRectTooltip,
-  isVerticalAnnotationLine,
-  isWithinRectBounds,
   scaleAndValidateDatum,
-  AnnotationTooltipState,
   AnnotationDimensions,
+  AnnotationTooltipState,
+  Bounds,
 } from './annotation_utils';
-import { Point } from '../store/chart_state';
+import {
+  AnnotationLineProps,
+  computeLineAnnotationDimensions,
+  computeLineAnnotationTooltipState,
+  isVerticalAnnotationLine,
+  getAnnotationLineTooltipXOffset,
+  getAnnotationLineTooltipYOffset,
+} from './line_annotation_tooltip';
+import {
+  computeRectAnnotationDimensions,
+  isWithinRectBounds,
+  computeRectAnnotationTooltipState,
+} from './rect_annotation_tooltip';
+import { Point } from '../../../utils/point';
+import { ChartTypes } from '../..';
 
 describe('annotation utils', () => {
   const minRange = 0;
@@ -65,8 +69,10 @@ describe('annotation utils', () => {
 
   const groupId = getGroupId('foo-group');
 
-  const axesSpecs: Map<AxisId, AxisSpec> = new Map();
+  const axesSpecs: AxisSpec[] = [];
   const verticalAxisSpec: AxisSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Axis,
     id: getAxisId('vertical_axis'),
     groupId,
     hide: false,
@@ -79,6 +85,8 @@ describe('annotation utils', () => {
     showGridLines: true,
   };
   const horizontalAxisSpec: AxisSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Axis,
     id: getAxisId('horizontal_axis'),
     groupId,
     hide: false,
@@ -91,7 +99,7 @@ describe('annotation utils', () => {
     showGridLines: true,
   };
 
-  axesSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+  axesSpecs.push(verticalAxisSpec);
 
   test('should compute annotation dimensions', () => {
     const chartRotation: Rotation = 0;
@@ -100,27 +108,31 @@ describe('annotation utils', () => {
 
     const xScale: Scale = ordinalScale;
 
-    const annotations: Map<AnnotationId, AnnotationSpec> = new Map();
-    const annotationId = getAnnotationId('foo');
+    const annotations: AnnotationSpec[] = [];
+    const annotationId = 'foo';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
       style: DEFAULT_ANNOTATION_LINE_STYLE,
     };
 
-    const rectAnnotationId = getAnnotationId('rect');
+    const rectAnnotationId = 'rect';
     const rectAnnotation: AnnotationSpec = {
-      annotationId: rectAnnotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      id: rectAnnotationId,
       groupId,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       dataValues: [{ coordinates: { x0: 'a', x1: 'b', y0: 3, y1: 5 } }],
     };
 
-    annotations.set(annotationId, lineAnnotation);
-    annotations.set(rectAnnotationId, rectAnnotation);
+    annotations.push(lineAnnotation);
+    annotations.push(rectAnnotation);
 
     const dimensions = computeAnnotationDimensions(
       annotations,
@@ -159,18 +171,20 @@ describe('annotation utils', () => {
 
     const xScale: Scale = ordinalScale;
 
-    const annotations: Map<AnnotationId, AnnotationSpec> = new Map();
-    const annotationId = getAnnotationId('foo');
+    const annotations: AnnotationSpec[] = [];
+    const id = 'foo';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
       style: DEFAULT_ANNOTATION_LINE_STYLE,
     };
 
-    annotations.set(annotationId, lineAnnotation);
+    annotations.push(lineAnnotation);
 
     const dimensions = computeAnnotationDimensions(
       annotations,
@@ -178,7 +192,7 @@ describe('annotation utils', () => {
       chartRotation,
       yScales,
       xScale,
-      new Map(), // empty axesSpecs
+      [], // empty axesSpecs
       1,
       false,
     );
@@ -193,10 +207,12 @@ describe('annotation utils', () => {
 
     const xScale: Scale = ordinalScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const id = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -237,10 +253,12 @@ describe('annotation utils', () => {
 
     const xScale: Scale = ordinalScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -281,10 +299,12 @@ describe('annotation utils', () => {
 
     const xScale: Scale = ordinalScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -324,10 +344,12 @@ describe('annotation utils', () => {
     const yScales: Map<GroupId, Scale> = new Map();
     const xScale: Scale = ordinalScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [],
       groupId,
@@ -352,10 +374,12 @@ describe('annotation utils', () => {
     const yScales: Map<GroupId, Scale> = new Map();
     const xScale: Scale = ordinalScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 'a', details: 'foo' }],
       groupId,
@@ -394,10 +418,12 @@ describe('annotation utils', () => {
     const yScales: Map<GroupId, Scale> = new Map();
     const xScale: Scale = continuousScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -437,10 +463,12 @@ describe('annotation utils', () => {
     const yScales: Map<GroupId, Scale> = new Map();
     const xScale: Scale = continuousScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -480,10 +508,12 @@ describe('annotation utils', () => {
     const yScales: Map<GroupId, Scale> = new Map();
     const xScale: Scale = continuousScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 10.5, details: 'foo' }],
       groupId,
@@ -524,10 +554,12 @@ describe('annotation utils', () => {
 
     const xScale: Scale = ordinalScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 'a', details: 'foo' }],
       groupId,
@@ -568,10 +600,12 @@ describe('annotation utils', () => {
 
     const xScale: Scale = continuousScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -612,10 +646,12 @@ describe('annotation utils', () => {
 
     const xScale: Scale = continuousScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -656,10 +692,12 @@ describe('annotation utils', () => {
 
     const xScale: Scale = continuousScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -699,10 +737,12 @@ describe('annotation utils', () => {
     const yScales: Map<GroupId, Scale> = new Map();
     const xScale: Scale = continuousScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -744,10 +784,12 @@ describe('annotation utils', () => {
 
     const xScale: Scale = ordinalScale;
 
-    const annotationId = getAnnotationId('foo-line');
+    const annotationId = 'foo-line';
     const invalidXLineAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 'e', details: 'foo' }],
       groupId,
@@ -768,8 +810,10 @@ describe('annotation utils', () => {
     expect(emptyXDimensions).toEqual([]);
 
     const invalidStringXLineAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: '', details: 'foo' }],
       groupId,
@@ -790,8 +834,10 @@ describe('annotation utils', () => {
     expect(invalidStringXDimensions).toEqual([]);
 
     const outOfBoundsXLineAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: -999, details: 'foo' }],
       groupId,
@@ -812,8 +858,10 @@ describe('annotation utils', () => {
     expect(emptyOutOfBoundsXDimensions).toEqual([]);
 
     const invalidYLineAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: 'e', details: 'foo' }],
       groupId,
@@ -834,8 +882,10 @@ describe('annotation utils', () => {
     expect(emptyYDimensions).toEqual([]);
 
     const outOfBoundsYLineAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: -999, details: 'foo' }],
       groupId,
@@ -856,8 +906,10 @@ describe('annotation utils', () => {
     expect(emptyOutOfBoundsYDimensions).toEqual([]);
 
     const invalidStringYLineAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: '', details: 'foo' }],
       groupId,
@@ -878,8 +930,10 @@ describe('annotation utils', () => {
     expect(invalidStringYDimensions).toEqual([]);
 
     const validHiddenAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.XDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -1007,7 +1061,8 @@ describe('annotation utils', () => {
         },
       },
     ];
-    const localAxesSpecs = new Map();
+
+    const localAxesSpecs: AxisSpec[] = [];
 
     // missing annotation axis (xDomain)
     const missingTooltipState = computeLineAnnotationTooltipState(
@@ -1021,7 +1076,7 @@ describe('annotation utils', () => {
     expect(missingTooltipState).toEqual({ isVisible: false });
 
     // add axis for xDomain annotation
-    localAxesSpecs.set(horizontalAxisSpec.id, horizontalAxisSpec);
+    localAxesSpecs.push(horizontalAxisSpec);
 
     const xDomainTooltipState = computeLineAnnotationTooltipState(
       cursorPosition,
@@ -1032,7 +1087,7 @@ describe('annotation utils', () => {
     );
     const expectedXDomainTooltipState = {
       isVisible: true,
-      annotationType: 'line',
+      annotationType: AnnotationTypes.Line,
       anchor: {
         position: Position.Left,
         top: 0,
@@ -1057,13 +1112,13 @@ describe('annotation utils', () => {
         top: 0,
         left: 0,
       },
-      annotationType: 'line',
+      annotationType: AnnotationTypes.Line,
     };
 
     expect(xDomainRotatedTooltipState).toEqual(expectedXDomainRotatedTooltipState);
 
     // add axis for yDomain annotation
-    localAxesSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+    localAxesSpecs.push(verticalAxisSpec);
 
     const yDomainTooltipState = computeLineAnnotationTooltipState(
       cursorPosition,
@@ -1079,7 +1134,7 @@ describe('annotation utils', () => {
         top: 0,
         left: 0,
       },
-      annotationType: 'line',
+      annotationType: AnnotationTypes.Line,
     };
 
     expect(yDomainTooltipState).toEqual(expectedYDomainTooltipState);
@@ -1098,7 +1153,7 @@ describe('annotation utils', () => {
         top: 0,
         left: 0,
       },
-      annotationType: 'line',
+      annotationType: AnnotationTypes.Line,
     };
 
     expect(flippedYDomainTooltipState).toEqual(expectedFlippedYDomainTooltipState);
@@ -1117,18 +1172,20 @@ describe('annotation utils', () => {
         top: 0,
         left: 0,
       },
-      annotationType: 'line',
+      annotationType: AnnotationTypes.Line,
     };
 
     expect(rotatedYDomainTooltipState).toEqual(expectedRotatedYDomainTooltipState);
   });
 
   test('should compute the tooltip state for an annotation', () => {
-    const annotations: Map<AnnotationId, AnnotationSpec> = new Map();
-    const annotationId = getAnnotationId('foo');
+    const annotations: AnnotationSpec[] = [];
+    const annotationId = 'foo';
     const lineAnnotation: LineAnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -1155,7 +1212,7 @@ describe('annotation utils', () => {
       },
     ];
     const chartRotation: Rotation = 0;
-    const localAxesSpecs: Map<AxisId, AxisSpec> = new Map();
+    const localAxesSpecs: AxisSpec[] = [];
 
     const annotationDimensions = new Map();
     annotationDimensions.set(annotationId, annotationLines);
@@ -1173,8 +1230,8 @@ describe('annotation utils', () => {
     expect(missingSpecTooltipState).toBe(null);
 
     // add valid annotation axis
-    annotations.set(annotationId, lineAnnotation);
-    localAxesSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+    annotations.push(lineAnnotation);
+    localAxesSpecs.push(verticalAxisSpec);
 
     // hide tooltipState
     lineAnnotation.hideTooltips = true;
@@ -1220,7 +1277,7 @@ describe('annotation utils', () => {
 
     const expectedTooltipState = {
       isVisible: true,
-      annotationType: 'line',
+      annotationType: AnnotationTypes.Line,
       anchor: {
         top: 0,
         left: 0,
@@ -1232,17 +1289,19 @@ describe('annotation utils', () => {
 
     // rect annotation tooltip
     const annotationRectangle: RectAnnotationSpec = {
-      annotationId: getAnnotationId('rect'),
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      id: 'rect',
       groupId,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       dataValues: [{ coordinates: { x0: 1, x1: 2, y0: 3, y1: 5 } }],
     };
 
-    const rectAnnotations = new Map();
-    rectAnnotations.set(annotationRectangle.annotationId, annotationRectangle);
+    const rectAnnotations: RectAnnotationSpec[] = [];
+    rectAnnotations.push(annotationRectangle);
 
     const rectAnnotationDimensions = [{ rect: { x: 2, y: 3, width: 3, height: 5 } }];
-    annotationDimensions.set(annotationRectangle.annotationId, rectAnnotationDimensions);
+    annotationDimensions.set(annotationRectangle.id, rectAnnotationDimensions);
 
     const rectTooltipState = computeAnnotationTooltipState(
       { x: 3, y: 4 },
@@ -1255,7 +1314,7 @@ describe('annotation utils', () => {
 
     expect(rectTooltipState).toEqual({
       isVisible: true,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       anchor: {
         top: 4,
         left: 3,
@@ -1276,13 +1335,13 @@ describe('annotation utils', () => {
   });
 
   test('should get associated axis for an annotation', () => {
-    const localAxesSpecs = new Map();
+    const localAxesSpecs: AxisSpec[] = [];
 
     const noAxis = getAnnotationAxis(localAxesSpecs, groupId, AnnotationDomainTypes.XDomain, 0);
     expect(noAxis).toBe(null);
 
-    localAxesSpecs.set(horizontalAxisSpec.id, horizontalAxisSpec);
-    localAxesSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+    localAxesSpecs.push(horizontalAxisSpec);
+    localAxesSpecs.push(verticalAxisSpec);
 
     const xAnnotationAxisPosition = getAnnotationAxis(localAxesSpecs, groupId, AnnotationDomainTypes.XDomain, 0);
     expect(xAnnotationAxisPosition).toEqual(Position.Bottom);
@@ -1297,9 +1356,11 @@ describe('annotation utils', () => {
     const xScale: Scale = continuousScale;
 
     const annotationRectangle: RectAnnotationSpec = {
-      annotationId: getAnnotationId('rect'),
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      id: 'rect',
       groupId: getGroupId('foo'),
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       dataValues: [{ coordinates: { x0: 1, x1: 2, y0: 3, y1: 5 } }],
     };
 
@@ -1314,9 +1375,11 @@ describe('annotation utils', () => {
     const xScale: Scale = continuousScale;
 
     const annotationRectangle: RectAnnotationSpec = {
-      annotationId: getAnnotationId('rect'),
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      id: 'rect',
       groupId,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       dataValues: [
         { coordinates: { x0: 1, x1: 2, y0: -10, y1: 5 } },
         { coordinates: { x0: null, x1: null, y0: null, y1: null } },
@@ -1337,9 +1400,11 @@ describe('annotation utils', () => {
     );
 
     const annotationRectangle: RectAnnotationSpec = {
-      annotationId: getAnnotationId('rect'),
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      id: 'rect',
       groupId,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       dataValues: [
         { coordinates: { x0: 1, x1: null, y0: null, y1: null } },
         { coordinates: { x0: null, x1: 1, y0: null, y1: null } },
@@ -1378,9 +1443,11 @@ describe('annotation utils', () => {
     const xScale: Scale = continuousScale;
 
     const annotationRectangle: RectAnnotationSpec = {
-      annotationId: getAnnotationId('rect'),
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      id: 'rect',
       groupId,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       dataValues: [
         { coordinates: { x0: 1, x1: null, y0: null, y1: null } },
         { coordinates: { x0: null, x1: 1, y0: null, y1: null } },
@@ -1407,9 +1474,11 @@ describe('annotation utils', () => {
     const xScale: Scale = continuousScale;
 
     const annotationRectangle: RectAnnotationSpec = {
-      annotationId: getAnnotationId('rect'),
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      id: 'rect',
       groupId,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       dataValues: [{ coordinates: { x0: 1, x1: 2, y0: 3, y1: 5 } }],
     };
 
@@ -1424,9 +1493,11 @@ describe('annotation utils', () => {
     const xScale: Scale = ordinalScale;
 
     const annotationRectangle: RectAnnotationSpec = {
-      annotationId: getAnnotationId('rect'),
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      id: 'rect',
       groupId,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       dataValues: [{ coordinates: { x0: 'a', x1: 'b', y0: 0, y1: 2 } }],
     };
 
@@ -1454,11 +1525,11 @@ describe('annotation utils', () => {
   test('should determine if a point is within a rectangle annotation', () => {
     const cursorPosition = { x: 3, y: 4 };
 
-    const outOfXBounds = { startX: 4, endX: 5, startY: 3, endY: 5 };
-    const outOfYBounds = { startX: 2, endX: 4, startY: 5, endY: 6 };
-    const withinBounds = { startX: 2, endX: 4, startY: 3, endY: 5 };
-    const withinBoundsReverseXScale = { startX: 4, endX: 2, startY: 3, endY: 5 };
-    const withinBoundsReverseYScale = { startX: 2, endX: 4, startY: 5, endY: 3 };
+    const outOfXBounds: Bounds = { startX: 4, endX: 5, startY: 3, endY: 5 };
+    const outOfYBounds: Bounds = { startX: 2, endX: 4, startY: 5, endY: 6 };
+    const withinBounds: Bounds = { startX: 2, endX: 4, startY: 3, endY: 5 };
+    const withinBoundsReverseXScale: Bounds = { startX: 4, endX: 2, startY: 3, endY: 5 };
+    const withinBoundsReverseYScale: Bounds = { startX: 2, endX: 4, startY: 5, endY: 3 };
 
     // chart rotation 0
     expect(isWithinRectBounds(cursorPosition, outOfXBounds)).toBe(false);
@@ -1488,66 +1559,6 @@ describe('annotation utils', () => {
     expect(isWithinRectBounds(cursorPosition, withinBoundsReverseXScale)).toBe(false);
     expect(isWithinRectBounds(cursorPosition, withinBoundsReverseYScale)).toBe(false);
   });
-  test('should determine if an annotation has a rightward tooltip based on cursor position', () => {
-    const cursor1 = { x: 8, y: 0 };
-    const cursor2 = { x: 0, y: 8 };
-
-    // chart rotation 0
-    expect(isRightRectTooltip(0, cursor1, 10)).toBe(false);
-    expect(isRightRectTooltip(0, cursor2, 10)).toBe(true);
-
-    // chart rotation 180
-    expect(isRightRectTooltip(180, cursor1, 10)).toBe(false);
-    expect(isRightRectTooltip(180, cursor2, 10)).toBe(true);
-
-    // chart rotation 90
-    expect(isRightRectTooltip(90, cursor1, 10)).toBe(true);
-    expect(isRightRectTooltip(90, cursor2, 10)).toBe(false);
-
-    // chart rotation -90
-    expect(isRightRectTooltip(-90, cursor1, 10)).toBe(false);
-    expect(isRightRectTooltip(-90, cursor2, 10)).toBe(true);
-  });
-  test('should determine if an annotation has a bottomward tooltip based on cursor position', () => {
-    const cursor1 = { x: 8, y: 0 };
-    const cursor2 = { x: 0, y: 8 };
-
-    // chart rotation 0
-    expect(isBottomRectTooltip(0, cursor1, 10)).toBe(true);
-    expect(isBottomRectTooltip(0, cursor2, 10)).toBe(false);
-
-    // chart rotation 180
-    expect(isBottomRectTooltip(180, cursor1, 10)).toBe(false);
-    expect(isBottomRectTooltip(180, cursor2, 10)).toBe(true);
-
-    // chart rotation 90
-    expect(isBottomRectTooltip(90, cursor1, 10)).toBe(false);
-    expect(isBottomRectTooltip(90, cursor2, 10)).toBe(true);
-
-    // chart rotation -90
-    expect(isBottomRectTooltip(-90, cursor1, 10)).toBe(false);
-    expect(isBottomRectTooltip(-90, cursor2, 10)).toBe(true);
-  });
-  test('should compute rect annotation tooltip left', () => {
-    const isRightTooltip = true;
-    const xPosition = { startX: 2, endX: 4 };
-    const cursorX = 3;
-    const chartWidth = 10;
-
-    expect(computeRectTooltipLeft(0, isRightTooltip, xPosition, cursorX, chartWidth)).toBe(4);
-    expect(computeRectTooltipLeft(180, !isRightTooltip, xPosition, cursorX, chartWidth)).toBe(8);
-    expect(computeRectTooltipLeft(90, isRightTooltip, xPosition, cursorX, chartWidth)).toBe(3);
-  });
-  test('should compute rect annotation tooltip top', () => {
-    const isBottomTooltip = true;
-    const xPosition = { startX: 2, endX: 4 };
-    const cursorY = 3;
-    const chartHeight = 10;
-
-    expect(computeRectTooltipTop(0, isBottomTooltip, xPosition, cursorY, chartHeight)).toBe(3);
-    expect(computeRectTooltipTop(90, isBottomTooltip, xPosition, cursorY, chartHeight)).toBe(4);
-    expect(computeRectTooltipTop(-90, !isBottomTooltip, xPosition, cursorY, chartHeight)).toBe(8);
-  });
   test('should compute tooltip state for rect annotation', () => {
     const cursorPosition = { x: 3, y: 4 };
     const annotationRects = [{ rect: { x: 2, y: 3, width: 3, height: 5 } }];
@@ -1555,7 +1566,7 @@ describe('annotation utils', () => {
     const visibleTooltip = computeRectAnnotationTooltipState(cursorPosition, annotationRects, 0, chartDimensions);
     const expectedVisibleTooltipState: AnnotationTooltipState = {
       isVisible: true,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       anchor: {
         top: 4,
         left: 3,
diff --git a/src/chart_types/xy_chart/annotations/annotation_utils.ts b/src/chart_types/xy_chart/annotations/annotation_utils.ts
index e0cdc4e110..a278287ebf 100644
--- a/src/chart_types/xy_chart/annotations/annotation_utils.ts
+++ b/src/chart_types/xy_chart/annotations/annotation_utils.ts
@@ -3,25 +3,28 @@ import {
   AnnotationDomainTypes,
   AnnotationSpec,
   AnnotationType,
-  AnnotationTypes,
   AxisSpec,
   HistogramModeAlignments,
   isLineAnnotation,
   isRectAnnotation,
-  LineAnnotationDatum,
-  LineAnnotationSpec,
   Position,
-  RectAnnotationDatum,
-  RectAnnotationSpec,
   Rotation,
 } from '../utils/specs';
-import { isHorizontalAxis } from '../utils/axis_utils';
-import { LineAnnotationStyle } from '../../../utils/themes/theme';
 import { Dimensions } from '../../../utils/dimensions';
-import { AnnotationId, AxisId, GroupId } from '../../../utils/ids';
+import { AnnotationId, GroupId } from '../../../utils/ids';
 import { Scale, ScaleType } from '../../../utils/scales/scales';
-import { Point } from '../store/chart_state';
-import { computeXScaleOffset, getAxesSpecForSpecId, isHorizontalRotation } from '../store/utils';
+import { computeXScaleOffset, getAxesSpecForSpecId, isHorizontalRotation, getSpecsById } from '../state/utils';
+import { Point } from '../../../utils/point';
+import {
+  computeLineAnnotationTooltipState,
+  AnnotationLineProps,
+  computeLineAnnotationDimensions,
+} from './line_annotation_tooltip';
+import {
+  computeRectAnnotationTooltipState,
+  AnnotationRectProps,
+  computeRectAnnotationDimensions,
+} from './rect_annotation_tooltip';
 
 export type AnnotationTooltipFormatter = (details?: string) => JSX.Element | null;
 
@@ -37,11 +40,17 @@ export interface AnnotationTooltipVisibleState {
 export interface AnnotationTooltipHiddenState {
   isVisible: false;
 }
+/**
+ * The header and description strings for an Annotation
+ */
 export interface AnnotationDetails {
   headerText?: string;
   detailsText?: string;
 }
 
+/**
+ * The marker for an Annotation. Usually a JSX element
+ */
 export interface AnnotationMarker {
   icon: JSX.Element;
   position: { top: number; left: number };
@@ -49,344 +58,9 @@ export interface AnnotationMarker {
   color: string;
 }
 
-/**
- * The path points of a line annotation.
- */
-export type AnnotationLinePathPoints = {
-  /** x1,y1 the start point anchored to the linked axis */
-  start: {
-    x1: number;
-    y1: number;
-  };
-  /** x2,y2 the end point */
-  end: {
-    x2: number;
-    y2: number;
-  };
-};
-
-export interface AnnotationLineProps {
-  /** the position of the start point relative to the Chart */
-  anchor: {
-    position: Position;
-    top: number;
-    left: number;
-  };
-  /**
-   * The path points of a line annotation
-   */
-  linePathPoints: AnnotationLinePathPoints;
-  details: AnnotationDetails;
-  marker?: AnnotationMarker;
-}
-
-export interface AnnotationRectProps {
-  rect: {
-    x: number;
-    y: number;
-    width: number;
-    height: number;
-  };
-  details?: string;
-}
-
-// TODO: add AnnotationTextProps
 export type AnnotationDimensions = AnnotationLineProps[] | AnnotationRectProps[];
 
-export function computeYDomainLineAnnotationDimensions(
-  dataValues: LineAnnotationDatum[],
-  yScale: Scale,
-  chartRotation: Rotation,
-  axisPosition: Position,
-  chartDimensions: Dimensions,
-  lineColor: string,
-  marker?: JSX.Element,
-  markerDimension = { width: 0, height: 0 },
-): AnnotationLineProps[] {
-  const chartHeight = chartDimensions.height;
-  const chartWidth = chartDimensions.width;
-  const isHorizontalChartRotation = isHorizontalRotation(chartRotation);
-
-  const lineProps: AnnotationLineProps[] = [];
-
-  dataValues.forEach((datum: LineAnnotationDatum) => {
-    const { dataValue } = datum;
-
-    // avoid rendering invalid annotation value
-    if (dataValue === null || dataValue === undefined || dataValue === '') {
-      return;
-    }
-
-    const annotationValueYposition = yScale.scale(dataValue);
-    // avoid rendering non scalable annotation values
-    if (isNaN(annotationValueYposition)) {
-      return;
-    }
-
-    const [domainStart, domainEnd] = yScale.domain;
-    // avoid rendering annotation with values outside the scale domain
-    if (domainStart > dataValue || domainEnd < dataValue) {
-      return;
-    }
-    const anchor = {
-      position: axisPosition,
-      top: 0,
-      left: 0,
-    };
-    const markerPosition = { top: 0, left: 0 };
-    const linePathPoints: AnnotationLinePathPoints = {
-      start: { x1: 0, y1: 0 },
-      end: { x2: 0, y2: 0 },
-    };
-    // the Y axis is vertical, X axis is horizontal  y|--x--|y
-    if (isHorizontalChartRotation) {
-      // y|__x__
-      if (axisPosition === Position.Left) {
-        anchor.left = 0;
-        markerPosition.left = -markerDimension.width;
-        linePathPoints.start.x1 = 0;
-        linePathPoints.end.x2 = chartWidth;
-        // __x__|y
-      } else {
-        anchor.left = chartWidth;
-        markerPosition.left = chartWidth;
-        linePathPoints.start.x1 = chartWidth;
-        linePathPoints.end.x2 = 0;
-      }
-      // __x__
-      if (chartRotation === 0) {
-        anchor.top = annotationValueYposition;
-        markerPosition.top = annotationValueYposition - markerDimension.height / 2;
-        // ¯¯x¯¯
-      } else {
-        anchor.top = chartHeight - annotationValueYposition;
-        markerPosition.top = chartHeight - annotationValueYposition - markerDimension.height / 2;
-      }
-      linePathPoints.start.y1 = annotationValueYposition;
-      linePathPoints.end.y2 = annotationValueYposition;
-      // the Y axis is horizontal, X axis is vertical x|--y--|x
-    } else {
-      // ¯¯y¯¯
-      if (axisPosition === Position.Top) {
-        anchor.top = 0;
-        markerPosition.top = -markerDimension.height;
-        linePathPoints.start.x1 = 0;
-        linePathPoints.end.x2 = chartHeight;
-        // __y__
-      } else {
-        anchor.top = chartHeight;
-        markerPosition.top = chartHeight;
-        linePathPoints.start.x1 = chartHeight;
-        linePathPoints.end.x2 = 0;
-      }
-      // __y__|x
-      if (chartRotation === -90) {
-        anchor.left = annotationValueYposition;
-        markerPosition.left = annotationValueYposition - markerDimension.width / 2;
-        // x|__y__
-      } else {
-        anchor.left = chartWidth - annotationValueYposition;
-        markerPosition.left = chartWidth - annotationValueYposition - markerDimension.width / 2;
-      }
-      linePathPoints.start.y1 = annotationValueYposition;
-      linePathPoints.end.y2 = annotationValueYposition;
-    }
-
-    const annotationMarker: AnnotationMarker | undefined = marker
-      ? {
-          icon: marker,
-          color: lineColor,
-          dimension: markerDimension,
-          position: markerPosition,
-        }
-      : undefined;
-    const lineProp: AnnotationLineProps = {
-      anchor,
-      linePathPoints,
-      marker: annotationMarker,
-      details: {
-        detailsText: datum.details,
-        headerText: datum.header || dataValue.toString(),
-      },
-    };
-
-    lineProps.push(lineProp);
-  });
-
-  return lineProps;
-}
-
-export function computeXDomainLineAnnotationDimensions(
-  dataValues: LineAnnotationDatum[],
-  xScale: Scale,
-  chartRotation: Rotation,
-  axisPosition: Position,
-  chartDimensions: Dimensions,
-  lineColor: string,
-  xScaleOffset: number,
-  enableHistogramMode: boolean,
-  marker?: JSX.Element,
-  markerDimension = { width: 0, height: 0 },
-): AnnotationLineProps[] {
-  const chartHeight = chartDimensions.height;
-  const chartWidth = chartDimensions.width;
-  const lineProps: AnnotationLineProps[] = [];
-  const isHorizontalChartRotation = isHorizontalRotation(chartRotation);
-
-  const alignWithTick = xScale.bandwidth > 0 && !enableHistogramMode;
-  dataValues.forEach((datum: LineAnnotationDatum) => {
-    const { dataValue } = datum;
-
-    const scaledXValue = scaleAndValidateDatum(dataValue, xScale, alignWithTick);
-
-    if (scaledXValue == null) {
-      return;
-    }
-
-    const offset = xScale.bandwidth / 2 - xScaleOffset;
-    const annotationValueXposition = scaledXValue + offset;
-
-    const markerPosition = { top: 0, left: 0 };
-    const linePathPoints: AnnotationLinePathPoints = {
-      start: { x1: 0, y1: 0 },
-      end: { x2: 0, y2: 0 },
-    };
-    const anchor = {
-      position: axisPosition,
-      top: 0,
-      left: 0,
-    };
-    // the Y axis is vertical, X axis is horizontal  y|--x--|y
-    if (isHorizontalChartRotation) {
-      // __x__
-      if (axisPosition === Position.Bottom) {
-        linePathPoints.start.y1 = chartHeight;
-        linePathPoints.end.y2 = 0;
-        anchor.top = chartHeight;
-        markerPosition.top = chartHeight;
-        // ¯¯x¯¯
-      } else {
-        linePathPoints.start.y1 = 0;
-        linePathPoints.end.y2 = chartHeight;
-        anchor.top = 0;
-        markerPosition.top = 0 - markerDimension.height;
-      }
-      // __x__
-      if (chartRotation === 0) {
-        anchor.left = annotationValueXposition;
-        markerPosition.left = annotationValueXposition - markerDimension.width / 2;
-        // ¯¯x¯¯
-      } else {
-        anchor.left = chartWidth - annotationValueXposition;
-        markerPosition.left = chartWidth - annotationValueXposition - markerDimension.width / 2;
-      }
-      linePathPoints.start.x1 = annotationValueXposition;
-      linePathPoints.end.x2 = annotationValueXposition;
-      // the Y axis is horizontal, X axis is vertical x|--y--|x
-    } else {
-      // x|--y--
-      if (axisPosition === Position.Left) {
-        anchor.left = 0;
-        markerPosition.left = -markerDimension.width;
-        linePathPoints.start.x1 = annotationValueXposition;
-        linePathPoints.end.x2 = annotationValueXposition;
-        // --y--|x
-      } else {
-        anchor.left = chartWidth;
-        markerPosition.left = chartWidth;
-        linePathPoints.start.x1 = annotationValueXposition;
-        linePathPoints.end.x2 = annotationValueXposition;
-      }
-      // __y__|x
-      if (chartRotation === -90) {
-        anchor.top = chartHeight - annotationValueXposition;
-        markerPosition.top = chartHeight - annotationValueXposition - markerDimension.height / 2;
-        linePathPoints.start.y1 = 0;
-        linePathPoints.end.y2 = chartWidth;
-        // x|__y__
-      } else {
-        anchor.top = annotationValueXposition;
-        markerPosition.top = annotationValueXposition - markerDimension.height / 2;
-        linePathPoints.start.y1 = 0;
-        linePathPoints.end.y2 = chartWidth;
-      }
-    }
-
-    const annotationMarker: AnnotationMarker | undefined = marker
-      ? {
-          icon: marker,
-          color: lineColor,
-          dimension: markerDimension,
-          position: markerPosition,
-        }
-      : undefined;
-    const lineProp: AnnotationLineProps = {
-      anchor,
-      linePathPoints,
-      details: {
-        detailsText: datum.details,
-        headerText: datum.header || dataValue.toString(),
-      },
-      marker: annotationMarker,
-    };
-    lineProps.push(lineProp);
-  });
-
-  return lineProps;
-}
-
-export function computeLineAnnotationDimensions(
-  annotationSpec: LineAnnotationSpec,
-  chartDimensions: Dimensions,
-  chartRotation: Rotation,
-  yScales: Map<GroupId, Scale>,
-  xScale: Scale,
-  axisPosition: Position,
-  xScaleOffset: number,
-  enableHistogramMode: boolean,
-): AnnotationLineProps[] | null {
-  const { domainType, dataValues, marker, markerDimensions, hideLines } = annotationSpec;
-
-  if (hideLines) {
-    return null;
-  }
-
-  // this type is guaranteed as this has been merged with default
-  const lineStyle = annotationSpec.style as LineAnnotationStyle;
-  const lineColor = lineStyle.line.stroke;
-
-  if (domainType === AnnotationDomainTypes.XDomain) {
-    return computeXDomainLineAnnotationDimensions(
-      dataValues,
-      xScale,
-      chartRotation,
-      axisPosition,
-      chartDimensions,
-      lineColor,
-      xScaleOffset,
-      enableHistogramMode,
-      marker,
-      markerDimensions,
-    );
-  }
-
-  const groupId = annotationSpec.groupId;
-  const yScale = yScales.get(groupId);
-  if (!yScale) {
-    return null;
-  }
-
-  return computeYDomainLineAnnotationDimensions(
-    dataValues,
-    yScale,
-    chartRotation,
-    axisPosition,
-    chartDimensions,
-    lineColor,
-    marker,
-    markerDimensions,
-  );
-}
+export type Bounds = { startX: number; endX: number; startY: number; endY: number };
 
 export function scaleAndValidateDatum(dataValue: any, scale: Scale, alignWithTick: boolean): number | null {
   const isContinuous = scale.type !== ScaleType.Ordinal;
@@ -410,107 +84,8 @@ export function scaleAndValidateDatum(dataValue: any, scale: Scale, alignWithTic
   return scaledValue;
 }
 
-export function computeRectAnnotationDimensions(
-  annotationSpec: RectAnnotationSpec,
-  yScales: Map<GroupId, Scale>,
-  xScale: Scale,
-  enableHistogramMode: boolean,
-  barsPadding: number,
-): AnnotationRectProps[] | null {
-  const { dataValues } = annotationSpec;
-
-  const groupId = annotationSpec.groupId;
-  const yScale = yScales.get(groupId);
-  if (!yScale) {
-    return null;
-  }
-
-  const xDomain = xScale.domain;
-  const yDomain = yScale.domain;
-  const lastX = xDomain[xDomain.length - 1];
-  const xMinInterval = xScale.minInterval;
-  const rectsProps: AnnotationRectProps[] = [];
-
-  dataValues.forEach((dataValue: RectAnnotationDatum) => {
-    let { x0, x1, y0, y1 } = dataValue.coordinates;
-
-    // if everything is null, return; otherwise we coerce the other coordinates
-    if (x0 == null && x1 == null && y0 == null && y1 == null) {
-      return;
-    }
-
-    if (x1 == null) {
-      // if x1 is defined, we want the rect to draw to the end of the scale
-      // if we're in histogram mode, extend domain end by min interval
-      x1 = enableHistogramMode && !xScale.isSingleValue() ? lastX + xMinInterval : lastX;
-    }
-
-    if (x0 == null) {
-      // if x0 is defined, we want the rect to draw to the start of the scale
-      x0 = xDomain[0];
-    }
-
-    if (y0 == null) {
-      // if y0 is defined, we want the rect to draw to the end of the scale
-      y0 = yDomain[yDomain.length - 1];
-    }
-
-    if (y1 == null) {
-      // if y1 is defined, we want the rect to draw to the start of the scale
-      y1 = yDomain[0];
-    }
-
-    const alignWithTick = xScale.bandwidth > 0 && !enableHistogramMode;
-
-    let x0Scaled = scaleAndValidateDatum(x0, xScale, alignWithTick);
-    let x1Scaled = scaleAndValidateDatum(x1, xScale, alignWithTick);
-    const y0Scaled = scaleAndValidateDatum(y0, yScale, false);
-    const y1Scaled = scaleAndValidateDatum(y1, yScale, false);
-
-    // TODO: surface this as a warning
-    if (x0Scaled === null || x1Scaled === null || y0Scaled === null || y1Scaled === null) {
-      return;
-    }
-
-    let xOffset = 0;
-    if (xScale.bandwidth > 0) {
-      const xBand = xScale.bandwidth / (1 - xScale.barsPadding);
-      xOffset = enableHistogramMode ? (xBand - xScale.bandwidth) / 2 : barsPadding;
-    }
-
-    x0Scaled = x0Scaled - xOffset;
-    x1Scaled = x1Scaled - xOffset;
-
-    const minX = Math.min(x0Scaled, x1Scaled);
-    const minY = Math.min(y0Scaled, y1Scaled);
-
-    const deltaX = Math.abs(x0Scaled - x1Scaled);
-    const deltaY = Math.abs(y0Scaled - y1Scaled);
-
-    const xOrigin = minX;
-    const yOrigin = minY;
-
-    const width = deltaX;
-    const height = deltaY;
-
-    const rectDimensions = {
-      x: xOrigin,
-      y: yOrigin,
-      width,
-      height,
-    };
-
-    rectsProps.push({
-      rect: rectDimensions,
-      details: dataValue.details,
-    });
-  });
-
-  return rectsProps;
-}
-
 export function getAnnotationAxis(
-  axesSpecs: Map<AxisId, AxisSpec>,
+  axesSpecs: AxisSpec[],
   groupId: GroupId,
   domainType: AnnotationDomainType,
   chartRotation: Rotation,
@@ -531,13 +106,37 @@ export function computeClusterOffset(totalBarsInCluster: number, barsShift: numb
   return 0;
 }
 
+export function isXDomain(domainType: AnnotationDomainType): boolean {
+  return domainType === AnnotationDomainTypes.XDomain;
+}
+
+export function getRotatedCursor(
+  /** the cursor position relative to the projection area */
+  cursorPosition: Point,
+  chartDimensions: Dimensions,
+  chartRotation: Rotation,
+): Point {
+  const { x, y } = cursorPosition;
+  const { height, width } = chartDimensions;
+  switch (chartRotation) {
+    case 0:
+      return { x, y };
+    case 90:
+      return { x: y, y: width - x };
+    case -90:
+      return { x: height - y, y: x };
+    case 180:
+      return { x: width - x, y: height - y };
+  }
+}
+
 export function computeAnnotationDimensions(
-  annotations: Map<AnnotationId, AnnotationSpec>,
+  annotations: AnnotationSpec[],
   chartDimensions: Dimensions,
   chartRotation: Rotation,
   yScales: Map<GroupId, Scale>,
   xScale: Scale,
-  axesSpecs: Map<AxisId, AxisSpec>,
+  axesSpecs: AxisSpec[],
   totalBarsInCluster: number,
   enableHistogramMode: boolean,
 ): Map<AnnotationId, AnnotationDimensions> {
@@ -553,7 +152,8 @@ export function computeAnnotationDimensions(
   // Annotations should always align with the axis line in histogram mode
   const xScaleOffset = computeXScaleOffset(xScale, enableHistogramMode, HistogramModeAlignments.Start);
 
-  annotations.forEach((annotationSpec: AnnotationSpec, annotationId: AnnotationId) => {
+  annotations.forEach((annotationSpec) => {
+    const { id } = annotationSpec;
     if (isLineAnnotation(annotationSpec)) {
       const { groupId, domainType } = annotationSpec;
       const annotationAxisPosition = getAnnotationAxis(axesSpecs, groupId, domainType, chartRotation);
@@ -573,7 +173,7 @@ export function computeAnnotationDimensions(
       );
 
       if (dimensions) {
-        annotationDimensions.set(annotationId, dimensions);
+        annotationDimensions.set(id, dimensions);
       }
     } else if (isRectAnnotation(annotationSpec)) {
       const dimensions = computeRectAnnotationDimensions(
@@ -585,7 +185,7 @@ export function computeAnnotationDimensions(
       );
 
       if (dimensions) {
-        annotationDimensions.set(annotationId, dimensions);
+        annotationDimensions.set(id, dimensions);
       }
     }
   });
@@ -593,210 +193,16 @@ export function computeAnnotationDimensions(
   return annotationDimensions;
 }
 
-/**
- * Checks if the cursorPosition is within the line annotation marker
- * @param cursorPosition the cursor position relative to the projected area
- * @param marker the line annotation marker
- */
-export function isWithinLineMarkerBounds(cursorPosition: Point, marker: AnnotationMarker): boolean {
-  const { top, left } = marker.position;
-  const { width, height } = marker.dimension;
-  const markerRect = { startX: left, startY: top, endX: left + width, endY: top + height };
-  return isWithinRectBounds(cursorPosition, markerRect);
-}
-
-export function isVerticalAnnotationLine(isXDomainAnnotation: boolean, isHorizontalChartRotation: boolean): boolean {
-  if (isXDomainAnnotation) {
-    return isHorizontalChartRotation;
-  }
-
-  return !isHorizontalChartRotation;
-}
-
-export function getAnnotationLineTooltipXOffset(chartRotation: Rotation, axisPosition: Position): number {
-  let xOffset = 0;
-  const isChartHorizontalRotation = isHorizontalRotation(chartRotation);
-
-  if (isHorizontalAxis(axisPosition)) {
-    xOffset = isChartHorizontalRotation ? 50 : 0;
-  } else {
-    xOffset = isChartHorizontalRotation ? (axisPosition === Position.Right ? 100 : 0) : 50;
-  }
-
-  return xOffset;
-}
-
-export function getAnnotationLineTooltipYOffset(chartRotation: Rotation, axisPosition: Position): number {
-  let yOffset = 0;
-  const isChartHorizontalRotation = isHorizontalRotation(chartRotation);
-
-  if (isHorizontalAxis(axisPosition)) {
-    yOffset = isChartHorizontalRotation ? (axisPosition === Position.Top ? 0 : 100) : 50;
-  } else {
-    yOffset = isChartHorizontalRotation ? 50 : 100;
-  }
-
-  return yOffset;
-}
-
-export function isXDomain(domainType: AnnotationDomainType): boolean {
-  return domainType === AnnotationDomainTypes.XDomain;
-}
-
-export function computeLineAnnotationTooltipState(
-  cursorPosition: Point,
-  annotationLines: AnnotationLineProps[],
-  groupId: GroupId,
-  domainType: AnnotationDomainType,
-  axesSpecs: Map<AxisId, AxisSpec>,
-): AnnotationTooltipState {
-  const { xAxis, yAxis } = getAxesSpecForSpecId(axesSpecs, groupId);
-  const isXDomainAnnotation = isXDomain(domainType);
-  const annotationAxis = isXDomainAnnotation ? xAxis : yAxis;
-
-  if (!annotationAxis) {
-    return {
-      isVisible: false,
-    };
-  }
-
-  const totalAnnotationLines = annotationLines.length;
-  for (let i = 0; i < totalAnnotationLines; i++) {
-    const line = annotationLines[i];
-    const isWithinBounds = line.marker && isWithinLineMarkerBounds(cursorPosition, line.marker);
-
-    if (isWithinBounds) {
-      return {
-        annotationType: AnnotationTypes.Line,
-        isVisible: true,
-        anchor: {
-          ...line.anchor,
-        },
-        ...(line.details && { header: line.details.headerText }),
-        ...(line.details && { details: line.details.detailsText }),
-      };
-    }
-  }
-  return {
-    isVisible: false,
-  };
-}
-
-export function isWithinRectBounds(
-  cursorPosition: Point,
-  { startX, endX, startY, endY }: { startX: number; endX: number; startY: number; endY: number },
-): boolean {
-  const withinXBounds = cursorPosition.x >= startX && cursorPosition.x <= endX;
-  const withinYBounds = cursorPosition.y >= startY && cursorPosition.y <= endY;
-
-  return withinXBounds && withinYBounds;
-}
-
-export function isRightRectTooltip(chartRotation: Rotation, cursorPosition: Point, chartWidth: number) {
-  const xPosition = isHorizontalRotation(chartRotation) ? cursorPosition.x : cursorPosition.y;
-
-  return chartRotation === -90 ? xPosition > chartWidth / 2 : xPosition < chartWidth / 2;
-}
-
-export function isBottomRectTooltip(chartRotation: Rotation, cursorPosition: Point, chartHeight: number) {
-  const yPosition = isHorizontalRotation(chartRotation) ? cursorPosition.y : cursorPosition.x;
-  return chartRotation === 180 ? yPosition > chartHeight / 2 : yPosition < chartHeight / 2;
-}
-
-export function computeRectTooltipLeft(
-  chartRotation: Rotation,
-  isRightTooltip: boolean,
-  { startX, endX }: { startX: number; endX: number },
-  cursorX: number,
-  chartWidth: number,
-): number {
-  const isHorizontalChartRotation = isHorizontalRotation(chartRotation);
-  const horizontalLeft = isRightTooltip ? endX : startX;
-  return isHorizontalChartRotation ? (chartRotation === 180 ? chartWidth - horizontalLeft : horizontalLeft) : cursorX;
-}
-
-export function computeRectTooltipTop(
-  chartRotation: Rotation,
-  isBottomTooltip: boolean,
-  { startX, endX }: { startX: number; endX: number },
-  cursorY: number,
-  chartHeight: number,
-): number {
-  const isHorizontalChartRotation = isHorizontalRotation(chartRotation);
-  const verticalTop = isBottomTooltip ? endX : startX;
-
-  return isHorizontalChartRotation ? cursorY : chartRotation === -90 ? chartHeight - verticalTop : verticalTop;
-}
-
-export function getRotatedCursor(
-  /** the cursor position relative to the projection area */
-  cursorPosition: Point,
-  chartDimensions: Dimensions,
-  chartRotation: Rotation,
-): Point {
-  const { x, y } = cursorPosition;
-  const { height, width } = chartDimensions;
-  switch (chartRotation) {
-    case 0:
-      return { x, y };
-    case 90:
-      return { x: y, y: width - x };
-    case -90:
-      return { x: height - y, y: x };
-    case 180:
-      return { x: width - x, y: height - y };
-  }
-}
-
-export function computeRectAnnotationTooltipState(
-  /** the cursor position relative to the projection area */
-  cursorPosition: Point,
-  annotationRects: AnnotationRectProps[],
-  chartRotation: Rotation,
-  chartDimensions: Dimensions,
-  renderTooltip?: AnnotationTooltipFormatter,
-): AnnotationTooltipState {
-  const rotatedCursorPosition = getRotatedCursor(cursorPosition, chartDimensions, chartRotation);
-
-  const totalAnnotationRect = annotationRects.length;
-  for (let i = 0; i < totalAnnotationRect; i++) {
-    const rectProps = annotationRects[i];
-    const { rect, details } = rectProps;
-    const startX = rect.x;
-    const endX = startX + rect.width;
-
-    const startY = rect.y;
-    const endY = startY + rect.height;
-
-    const isWithinBounds = isWithinRectBounds(rotatedCursorPosition, { startX, endX, startY, endY });
-    if (isWithinBounds) {
-      return {
-        isVisible: true,
-        annotationType: AnnotationTypes.Rectangle,
-        anchor: {
-          left: rotatedCursorPosition.x,
-          top: rotatedCursorPosition.y,
-        },
-        ...(details && { details }),
-        ...(renderTooltip && { renderTooltip }),
-      };
-    }
-  }
-  return {
-    isVisible: false,
-  };
-}
-
 export function computeAnnotationTooltipState(
   cursorPosition: Point,
   annotationDimensions: Map<AnnotationId, any>,
-  annotationSpecs: Map<AnnotationId, AnnotationSpec>,
+  annotationSpecs: AnnotationSpec[],
   chartRotation: Rotation,
-  axesSpecs: Map<AxisId, AxisSpec>,
+  axesSpecs: AxisSpec[],
   chartDimensions: Dimensions,
 ): AnnotationTooltipState | null {
   for (const [annotationId, annotationDimension] of annotationDimensions) {
-    const spec = annotationSpecs.get(annotationId);
+    const spec = getSpecsById<AnnotationSpec>(annotationSpecs, annotationId);
 
     if (!spec || spec.hideTooltips) {
       continue;
diff --git a/src/chart_types/xy_chart/annotations/line_annotation_tooltip.ts b/src/chart_types/xy_chart/annotations/line_annotation_tooltip.ts
new file mode 100644
index 0000000000..6b681b98cc
--- /dev/null
+++ b/src/chart_types/xy_chart/annotations/line_annotation_tooltip.ts
@@ -0,0 +1,447 @@
+import {
+  AnnotationDomainType,
+  AnnotationDomainTypes,
+  AnnotationTypes,
+  Position,
+  Rotation,
+  LineAnnotationSpec,
+  LineAnnotationDatum,
+  AxisSpec,
+} from '../utils/specs';
+import {
+  AnnotationTooltipState,
+  AnnotationDetails,
+  AnnotationMarker,
+  scaleAndValidateDatum,
+  isXDomain,
+  Bounds,
+} from './annotation_utils';
+import { isHorizontalRotation, getAxesSpecForSpecId } from '../state/utils';
+import { isHorizontalAxis } from '../utils/axis_utils';
+import { Dimensions } from '../../../utils/dimensions';
+import { Scale } from '../../../utils/scales/scales';
+import { GroupId } from '../../../utils/ids';
+import { LineAnnotationStyle } from '../../../utils/themes/theme';
+import { Point } from '../../../utils/point';
+import { isWithinRectBounds } from './rect_annotation_tooltip';
+
+export type AnnotationLinePosition = [number, number, number, number];
+
+/** Start and end points of a line annotation  */
+export interface AnnotationLinePathPoints {
+  /** x1,y1 the start point anchored to the linked axis */
+  start: {
+    x1: number;
+    y1: number;
+  };
+  /** x2,y2 the end point */
+  end: {
+    x2: number;
+    y2: number;
+  };
+}
+
+export interface AnnotationLineProps {
+  /** the position of the start point relative to the Chart */
+  anchor: {
+    position: Position;
+    top: number;
+    left: number;
+  };
+  /**
+   * The path points of a line annotation
+   */
+  linePathPoints: AnnotationLinePathPoints;
+  details: AnnotationDetails;
+  marker?: AnnotationMarker;
+}
+
+export const DEFAULT_LINE_OVERFLOW = 0;
+
+export function computeYDomainLineAnnotationDimensions(
+  dataValues: LineAnnotationDatum[],
+  yScale: Scale,
+  chartRotation: Rotation,
+  axisPosition: Position,
+  chartDimensions: Dimensions,
+  lineColor: string,
+  marker?: JSX.Element,
+  markerDimension = { width: 0, height: 0 },
+): AnnotationLineProps[] {
+  const chartHeight = chartDimensions.height;
+  const chartWidth = chartDimensions.width;
+  const isHorizontalChartRotation = isHorizontalRotation(chartRotation);
+
+  const lineProps: AnnotationLineProps[] = [];
+
+  dataValues.forEach((datum: LineAnnotationDatum) => {
+    const { dataValue } = datum;
+
+    // avoid rendering invalid annotation value
+    if (dataValue === null || dataValue === undefined || dataValue === '') {
+      return;
+    }
+
+    const annotationValueYposition = yScale.scale(dataValue);
+    // avoid rendering non scalable annotation values
+    if (isNaN(annotationValueYposition)) {
+      return;
+    }
+
+    const [domainStart, domainEnd] = yScale.domain;
+    // avoid rendering annotation with values outside the scale domain
+    if (domainStart > dataValue || domainEnd < dataValue) {
+      return;
+    }
+    const anchor = {
+      position: axisPosition,
+      top: 0,
+      left: 0,
+    };
+    const markerPosition = { top: 0, left: 0 };
+    const linePathPoints: AnnotationLinePathPoints = {
+      start: { x1: 0, y1: 0 },
+      end: { x2: 0, y2: 0 },
+    };
+    // the Y axis is vertical, X axis is horizontal  y|--x--|y
+    if (isHorizontalChartRotation) {
+      // y|__x__
+      if (axisPosition === Position.Left) {
+        anchor.left = 0;
+        markerPosition.left = -markerDimension.width;
+        linePathPoints.start.x1 = 0;
+        linePathPoints.end.x2 = chartWidth;
+        // __x__|y
+      } else {
+        anchor.left = chartWidth;
+        markerPosition.left = chartWidth;
+        linePathPoints.start.x1 = chartWidth;
+        linePathPoints.end.x2 = 0;
+      }
+      // __x__
+      if (chartRotation === 0) {
+        anchor.top = annotationValueYposition;
+        markerPosition.top = annotationValueYposition - markerDimension.height / 2;
+        // ¯¯x¯¯
+      } else {
+        anchor.top = chartHeight - annotationValueYposition;
+        markerPosition.top = chartHeight - annotationValueYposition - markerDimension.height / 2;
+      }
+      linePathPoints.start.y1 = annotationValueYposition;
+      linePathPoints.end.y2 = annotationValueYposition;
+      // the Y axis is horizontal, X axis is vertical x|--y--|x
+    } else {
+      // ¯¯y¯¯
+      if (axisPosition === Position.Top) {
+        anchor.top = 0;
+        markerPosition.top = -markerDimension.height;
+        linePathPoints.start.x1 = 0;
+        linePathPoints.end.x2 = chartHeight;
+        // __y__
+      } else {
+        anchor.top = chartHeight;
+        markerPosition.top = chartHeight;
+        linePathPoints.start.x1 = chartHeight;
+        linePathPoints.end.x2 = 0;
+      }
+      // __y__|x
+      if (chartRotation === -90) {
+        anchor.left = annotationValueYposition;
+        markerPosition.left = annotationValueYposition - markerDimension.width / 2;
+        // x|__y__
+      } else {
+        anchor.left = chartWidth - annotationValueYposition;
+        markerPosition.left = chartWidth - annotationValueYposition - markerDimension.width / 2;
+      }
+      linePathPoints.start.y1 = annotationValueYposition;
+      linePathPoints.end.y2 = annotationValueYposition;
+    }
+
+    const annotationMarker: AnnotationMarker | undefined = marker
+      ? {
+          icon: marker,
+          color: lineColor,
+          dimension: markerDimension,
+          position: markerPosition,
+        }
+      : undefined;
+    const lineProp: AnnotationLineProps = {
+      anchor,
+      linePathPoints,
+      marker: annotationMarker,
+      details: {
+        detailsText: datum.details,
+        headerText: datum.header || dataValue.toString(),
+      },
+    };
+
+    lineProps.push(lineProp);
+  });
+
+  return lineProps;
+}
+
+export function computeXDomainLineAnnotationDimensions(
+  dataValues: LineAnnotationDatum[],
+  xScale: Scale,
+  chartRotation: Rotation,
+  axisPosition: Position,
+  chartDimensions: Dimensions,
+  lineColor: string,
+  xScaleOffset: number,
+  enableHistogramMode: boolean,
+  marker?: JSX.Element,
+  markerDimension = { width: 0, height: 0 },
+): AnnotationLineProps[] {
+  const chartHeight = chartDimensions.height;
+  const chartWidth = chartDimensions.width;
+  const lineProps: AnnotationLineProps[] = [];
+  const isHorizontalChartRotation = isHorizontalRotation(chartRotation);
+
+  const alignWithTick = xScale.bandwidth > 0 && !enableHistogramMode;
+  dataValues.forEach((datum: LineAnnotationDatum) => {
+    const { dataValue } = datum;
+
+    const scaledXValue = scaleAndValidateDatum(dataValue, xScale, alignWithTick);
+
+    if (scaledXValue == null) {
+      return;
+    }
+
+    const offset = xScale.bandwidth / 2 - xScaleOffset;
+    const annotationValueXposition = scaledXValue + offset;
+
+    const markerPosition = { top: 0, left: 0 };
+    const linePathPoints: AnnotationLinePathPoints = {
+      start: { x1: 0, y1: 0 },
+      end: { x2: 0, y2: 0 },
+    };
+    const anchor = {
+      position: axisPosition,
+      top: 0,
+      left: 0,
+    };
+    // the Y axis is vertical, X axis is horizontal  y|--x--|y
+    if (isHorizontalChartRotation) {
+      // __x__
+      if (axisPosition === Position.Bottom) {
+        linePathPoints.start.y1 = chartHeight;
+        linePathPoints.end.y2 = 0;
+        anchor.top = chartHeight;
+        markerPosition.top = chartHeight;
+        // ¯¯x¯¯
+      } else {
+        linePathPoints.start.y1 = 0;
+        linePathPoints.end.y2 = chartHeight;
+        anchor.top = 0;
+        markerPosition.top = 0 - markerDimension.height;
+      }
+      // __x__
+      if (chartRotation === 0) {
+        anchor.left = annotationValueXposition;
+        markerPosition.left = annotationValueXposition - markerDimension.width / 2;
+        // ¯¯x¯¯
+      } else {
+        anchor.left = chartWidth - annotationValueXposition;
+        markerPosition.left = chartWidth - annotationValueXposition - markerDimension.width / 2;
+      }
+      linePathPoints.start.x1 = annotationValueXposition;
+      linePathPoints.end.x2 = annotationValueXposition;
+      // the Y axis is horizontal, X axis is vertical x|--y--|x
+    } else {
+      // x|--y--
+      if (axisPosition === Position.Left) {
+        anchor.left = 0;
+        markerPosition.left = -markerDimension.width;
+        linePathPoints.start.x1 = annotationValueXposition;
+        linePathPoints.end.x2 = annotationValueXposition;
+        // --y--|x
+      } else {
+        anchor.left = chartWidth;
+        markerPosition.left = chartWidth;
+        linePathPoints.start.x1 = annotationValueXposition;
+        linePathPoints.end.x2 = annotationValueXposition;
+      }
+      // __y__|x
+      if (chartRotation === -90) {
+        anchor.top = chartHeight - annotationValueXposition;
+        markerPosition.top = chartHeight - annotationValueXposition - markerDimension.height / 2;
+        linePathPoints.start.y1 = 0;
+        linePathPoints.end.y2 = chartWidth;
+        // x|__y__
+      } else {
+        anchor.top = annotationValueXposition;
+        markerPosition.top = annotationValueXposition - markerDimension.height / 2;
+        linePathPoints.start.y1 = 0;
+        linePathPoints.end.y2 = chartWidth;
+      }
+    }
+
+    const annotationMarker: AnnotationMarker | undefined = marker
+      ? {
+          icon: marker,
+          color: lineColor,
+          dimension: markerDimension,
+          position: markerPosition,
+        }
+      : undefined;
+    const lineProp: AnnotationLineProps = {
+      anchor,
+      linePathPoints,
+      details: {
+        detailsText: datum.details,
+        headerText: datum.header || dataValue.toString(),
+      },
+      marker: annotationMarker,
+    };
+    lineProps.push(lineProp);
+  });
+
+  return lineProps;
+}
+
+export function computeLineAnnotationDimensions(
+  annotationSpec: LineAnnotationSpec,
+  chartDimensions: Dimensions,
+  chartRotation: Rotation,
+  yScales: Map<GroupId, Scale>,
+  xScale: Scale,
+  axisPosition: Position,
+  xScaleOffset: number,
+  enableHistogramMode: boolean,
+): AnnotationLineProps[] | null {
+  const { domainType, dataValues, marker, markerDimensions, hideLines } = annotationSpec;
+
+  if (hideLines) {
+    return null;
+  }
+
+  // this type is guaranteed as this has been merged with default
+  const lineStyle = annotationSpec.style as LineAnnotationStyle;
+  const lineColor = lineStyle.line.stroke;
+
+  if (domainType === AnnotationDomainTypes.XDomain) {
+    return computeXDomainLineAnnotationDimensions(
+      dataValues,
+      xScale,
+      chartRotation,
+      axisPosition,
+      chartDimensions,
+      lineColor,
+      xScaleOffset,
+      enableHistogramMode,
+      marker,
+      markerDimensions,
+    );
+  }
+
+  const groupId = annotationSpec.groupId;
+  const yScale = yScales.get(groupId);
+  if (!yScale) {
+    return null;
+  }
+
+  return computeYDomainLineAnnotationDimensions(
+    dataValues,
+    yScale,
+    chartRotation,
+    axisPosition,
+    chartDimensions,
+    lineColor,
+    marker,
+    markerDimensions,
+  );
+}
+
+export function getAnnotationLineTooltipXOffset(chartRotation: Rotation, axisPosition: Position): number {
+  let xOffset = 0;
+  const isChartHorizontalRotation = isHorizontalRotation(chartRotation);
+
+  if (isHorizontalAxis(axisPosition)) {
+    xOffset = isChartHorizontalRotation ? 50 : 0;
+  } else {
+    if (isChartHorizontalRotation) {
+      xOffset = axisPosition === Position.Right ? 100 : 0;
+    } else {
+      xOffset = 50;
+    }
+  }
+
+  return xOffset;
+}
+
+export function getAnnotationLineTooltipYOffset(chartRotation: Rotation, axisPosition: Position): number {
+  let yOffset = 0;
+  const isChartHorizontalRotation = isHorizontalRotation(chartRotation);
+
+  if (isHorizontalAxis(axisPosition)) {
+    if (isChartHorizontalRotation) {
+      yOffset = axisPosition === Position.Top ? 0 : 100;
+    } else {
+      yOffset = 50;
+    }
+  } else {
+    yOffset = isChartHorizontalRotation ? 50 : 100;
+  }
+
+  return yOffset;
+}
+
+export function isVerticalAnnotationLine(isXDomainAnnotation: boolean, isHorizontalChartRotation: boolean): boolean {
+  if (isXDomainAnnotation) {
+    return isHorizontalChartRotation;
+  }
+
+  return !isHorizontalChartRotation;
+}
+
+/**
+ * Checks if the cursorPosition is within the line annotation marker
+ * @param cursorPosition the cursor position relative to the projected area
+ * @param marker the line annotation marker
+ */
+export function isWithinLineMarkerBounds(cursorPosition: Point, marker: AnnotationMarker): boolean {
+  const { top, left } = marker.position;
+  const { width, height } = marker.dimension;
+  const markerRect: Bounds = { startX: left, startY: top, endX: left + width, endY: top + height };
+  return isWithinRectBounds(cursorPosition, markerRect);
+}
+
+export function computeLineAnnotationTooltipState(
+  cursorPosition: Point,
+  annotationLines: AnnotationLineProps[],
+  groupId: GroupId,
+  domainType: AnnotationDomainType,
+  axesSpecs: AxisSpec[],
+): AnnotationTooltipState {
+  const { xAxis, yAxis } = getAxesSpecForSpecId(axesSpecs, groupId);
+  const isXDomainAnnotation = isXDomain(domainType);
+  const annotationAxis = isXDomainAnnotation ? xAxis : yAxis;
+
+  if (!annotationAxis) {
+    return {
+      isVisible: false,
+    };
+  }
+
+  const totalAnnotationLines = annotationLines.length;
+  for (let i = 0; i < totalAnnotationLines; i++) {
+    const line = annotationLines[i];
+    const isWithinBounds = line.marker && isWithinLineMarkerBounds(cursorPosition, line.marker);
+
+    if (isWithinBounds) {
+      return {
+        annotationType: AnnotationTypes.Line,
+        isVisible: true,
+        anchor: {
+          ...line.anchor,
+        },
+        ...(line.details && { header: line.details.headerText }),
+        ...(line.details && { details: line.details.detailsText }),
+      };
+    }
+  }
+  return {
+    isVisible: false,
+  };
+}
diff --git a/src/chart_types/xy_chart/annotations/rect_annotation_tooltip.ts b/src/chart_types/xy_chart/annotations/rect_annotation_tooltip.ts
new file mode 100644
index 0000000000..1794af0fa9
--- /dev/null
+++ b/src/chart_types/xy_chart/annotations/rect_annotation_tooltip.ts
@@ -0,0 +1,169 @@
+import { AnnotationTypes, RectAnnotationDatum, RectAnnotationSpec, Rotation } from '../utils/specs';
+import { Dimensions } from '../../../utils/dimensions';
+import { GroupId } from '../../../utils/ids';
+import { Scale } from '../../../utils/scales/scales';
+import { Point } from '../../../utils/point';
+import {
+  AnnotationTooltipFormatter,
+  AnnotationTooltipState,
+  getRotatedCursor,
+  scaleAndValidateDatum,
+  Bounds,
+} from './annotation_utils';
+
+export interface AnnotationRectProps {
+  rect: {
+    x: number;
+    y: number;
+    width: number;
+    height: number;
+  };
+  details?: string;
+}
+
+export function computeRectAnnotationTooltipState(
+  /** the cursor position relative to the projection area */
+  cursorPosition: Point,
+  annotationRects: AnnotationRectProps[],
+  chartRotation: Rotation,
+  chartDimensions: Dimensions,
+  renderTooltip?: AnnotationTooltipFormatter,
+): AnnotationTooltipState {
+  const rotatedCursorPosition = getRotatedCursor(cursorPosition, chartDimensions, chartRotation);
+
+  const totalAnnotationRect = annotationRects.length;
+  for (let i = 0; i < totalAnnotationRect; i++) {
+    const rectProps = annotationRects[i];
+    const { rect, details } = rectProps;
+    const startX = rect.x;
+    const endX = startX + rect.width;
+
+    const startY = rect.y;
+    const endY = startY + rect.height;
+
+    const bounds: Bounds = { startX, endX, startY, endY };
+
+    const isWithinBounds = isWithinRectBounds(rotatedCursorPosition, bounds);
+    if (isWithinBounds) {
+      return {
+        isVisible: true,
+        annotationType: AnnotationTypes.Rectangle,
+        anchor: {
+          left: rotatedCursorPosition.x,
+          top: rotatedCursorPosition.y,
+        },
+        ...(details && { details }),
+        ...(renderTooltip && { renderTooltip }),
+      };
+    }
+  }
+  return {
+    isVisible: false,
+  };
+}
+
+export function isWithinRectBounds({ x, y }: Point, { startX, endX, startY, endY }: Bounds): boolean {
+  const withinXBounds = x >= startX && x <= endX;
+  const withinYBounds = y >= startY && y <= endY;
+
+  return withinXBounds && withinYBounds;
+}
+
+export function computeRectAnnotationDimensions(
+  annotationSpec: RectAnnotationSpec,
+  yScales: Map<GroupId, Scale>,
+  xScale: Scale,
+  enableHistogramMode: boolean,
+  barsPadding: number,
+): AnnotationRectProps[] | null {
+  const { dataValues } = annotationSpec;
+
+  const groupId = annotationSpec.groupId;
+  const yScale = yScales.get(groupId);
+  if (!yScale) {
+    return null;
+  }
+
+  const xDomain = xScale.domain;
+  const yDomain = yScale.domain;
+  const lastX = xDomain[xDomain.length - 1];
+  const xMinInterval = xScale.minInterval;
+  const rectsProps: AnnotationRectProps[] = [];
+
+  dataValues.forEach((dataValue: RectAnnotationDatum) => {
+    let { x0, x1, y0, y1 } = dataValue.coordinates;
+
+    // if everything is null, return; otherwise we coerce the other coordinates
+    if (x0 == null && x1 == null && y0 == null && y1 == null) {
+      return;
+    }
+
+    if (x1 == null) {
+      // if x1 is defined, we want the rect to draw to the end of the scale
+      // if we're in histogram mode, extend domain end by min interval
+      x1 = enableHistogramMode && !xScale.isSingleValue() ? lastX + xMinInterval : lastX;
+    }
+
+    if (x0 == null) {
+      // if x0 is defined, we want the rect to draw to the start of the scale
+      x0 = xDomain[0];
+    }
+
+    if (y0 == null) {
+      // if y0 is defined, we want the rect to draw to the end of the scale
+      y0 = yDomain[yDomain.length - 1];
+    }
+
+    if (y1 == null) {
+      // if y1 is defined, we want the rect to draw to the start of the scale
+      y1 = yDomain[0];
+    }
+
+    const alignWithTick = xScale.bandwidth > 0 && !enableHistogramMode;
+
+    let x0Scaled = scaleAndValidateDatum(x0, xScale, alignWithTick);
+    let x1Scaled = scaleAndValidateDatum(x1, xScale, alignWithTick);
+    const y0Scaled = scaleAndValidateDatum(y0, yScale, false);
+    const y1Scaled = scaleAndValidateDatum(y1, yScale, false);
+
+    // TODO: surface this as a warning
+    if (x0Scaled === null || x1Scaled === null || y0Scaled === null || y1Scaled === null) {
+      return;
+    }
+
+    let xOffset = 0;
+    if (xScale.bandwidth > 0) {
+      const xBand = xScale.bandwidth / (1 - xScale.barsPadding);
+      xOffset = enableHistogramMode ? (xBand - xScale.bandwidth) / 2 : barsPadding;
+    }
+
+    x0Scaled = x0Scaled - xOffset;
+    x1Scaled = x1Scaled - xOffset;
+
+    const minX = Math.min(x0Scaled, x1Scaled);
+    const minY = Math.min(y0Scaled, y1Scaled);
+
+    const deltaX = Math.abs(x0Scaled - x1Scaled);
+    const deltaY = Math.abs(y0Scaled - y1Scaled);
+
+    const xOrigin = minX;
+    const yOrigin = minY;
+
+    const width = deltaX;
+    const height = deltaY;
+
+    const rectDimensions = {
+      x: xOrigin,
+      y: yOrigin,
+      width,
+      height,
+    };
+
+    rectsProps.push({
+      rect: rectDimensions,
+      details: dataValue.details,
+    });
+  });
+
+  return rectsProps;
+}
diff --git a/src/chart_types/xy_chart/crosshair/crosshair_utils.linear_snap.test.ts b/src/chart_types/xy_chart/crosshair/crosshair_utils.linear_snap.test.ts
index ad5f31a77e..9617ebe45f 100644
--- a/src/chart_types/xy_chart/crosshair/crosshair_utils.linear_snap.test.ts
+++ b/src/chart_types/xy_chart/crosshair/crosshair_utils.linear_snap.test.ts
@@ -1,10 +1,11 @@
 import { computeXScale } from '../utils/scales';
-import { BasicSeriesSpec } from '../utils/specs';
+import { BasicSeriesSpec, SpecTypes, SeriesTypes } from '../utils/specs';
 import { Dimensions } from '../../../utils/dimensions';
 import { getGroupId, getSpecId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
 import { getCursorBandPosition, getSnapPosition } from './crosshair_utils';
-import { computeSeriesDomains } from '../store/utils';
+import { computeSeriesDomains } from '../state/utils';
+import { ChartTypes } from '../..';
 
 describe('Crosshair utils linear scale', () => {
   const barSeries1SpecId = getSpecId('barSeries1');
@@ -13,9 +14,11 @@ describe('Crosshair utils linear scale', () => {
   const lineSeries2SpecId = getSpecId('lineSeries2');
 
   const barSeries1: BasicSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: barSeries1SpecId,
     groupId: getGroupId('group1'),
-    seriesType: 'bar',
+    seriesType: SeriesTypes.Bar,
     data: [[0, 0], [1, 0], [2, 0]],
     xAccessor: 0,
     yAccessors: [1],
@@ -24,9 +27,11 @@ describe('Crosshair utils linear scale', () => {
     yScaleToDataExtent: true,
   };
   const barSeries2: BasicSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: barSeries2SpecId,
     groupId: getGroupId('group1'),
-    seriesType: 'bar',
+    seriesType: SeriesTypes.Bar,
     data: [[0, 2], [1, 2], [2, 2]],
     xAccessor: 0,
     yAccessors: [1],
@@ -35,9 +40,11 @@ describe('Crosshair utils linear scale', () => {
     yScaleToDataExtent: true,
   };
   const lineSeries1: BasicSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: lineSeries1SpecId,
     groupId: getGroupId('group1'),
-    seriesType: 'line',
+    seriesType: SeriesTypes.Line,
     data: [[0, 0], [1, 0], [2, 0]],
     xAccessor: 0,
     yAccessors: [1],
@@ -46,9 +53,11 @@ describe('Crosshair utils linear scale', () => {
     yScaleToDataExtent: true,
   };
   const lineSeries2: BasicSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: lineSeries2SpecId,
     groupId: getGroupId('group1'),
-    seriesType: 'line',
+    seriesType: SeriesTypes.Line,
     data: [[0, 2], [1, 2], [2, 2]],
     xAccessor: 0,
     yAccessors: [1],
@@ -57,54 +66,44 @@ describe('Crosshair utils linear scale', () => {
     yScaleToDataExtent: true,
   };
 
-  const barSeriesMap = new Map();
-  barSeriesMap.set(barSeries1SpecId, barSeries1);
-  const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map());
+  const barSeries = [barSeries1];
+  const barSeriesDomains = computeSeriesDomains(barSeries);
 
-  const multiBarSeriesMap = new Map();
-  multiBarSeriesMap.set(barSeries1SpecId, barSeries1);
-  multiBarSeriesMap.set(barSeries2SpecId, barSeries2);
-  const multiBarSeriesDomains = computeSeriesDomains(multiBarSeriesMap, new Map());
+  const multiBarSeries = [barSeries1, barSeries2];
+  const multiBarSeriesDomains = computeSeriesDomains(multiBarSeries);
 
-  const lineSeriesMap = new Map();
-  lineSeriesMap.set(lineSeries1SpecId, lineSeries1);
-  const lineSeriesDomains = computeSeriesDomains(lineSeriesMap, new Map());
+  const lineSeries = [lineSeries1];
+  const lineSeriesDomains = computeSeriesDomains(lineSeries);
 
-  const multiLineSeriesMap = new Map();
-  multiLineSeriesMap.set(lineSeries1SpecId, lineSeries1);
-  multiLineSeriesMap.set(lineSeries2SpecId, lineSeries2);
-  const multiLineSeriesDomains = computeSeriesDomains(multiLineSeriesMap, new Map());
+  const multiLineSeries = [lineSeries1, lineSeries2];
+  const multiLineSeriesDomains = computeSeriesDomains(multiLineSeries);
 
-  const mixedLinesBarsMap = new Map();
-  mixedLinesBarsMap.set(lineSeries1SpecId, lineSeries1);
-  mixedLinesBarsMap.set(lineSeries2SpecId, lineSeries2);
-  mixedLinesBarsMap.set(barSeries1SpecId, barSeries1);
-  mixedLinesBarsMap.set(barSeries2SpecId, barSeries2);
-  const mixedLinesBarsSeriesDomains = computeSeriesDomains(mixedLinesBarsMap, new Map());
+  const mixedLinesBars = [lineSeries1, lineSeries2, barSeries1, barSeries2];
+  const mixedLinesBarsSeriesDomains = computeSeriesDomains(mixedLinesBars);
 
   const barSeriesScale = computeXScale({
     xDomain: barSeriesDomains.xDomain,
-    totalBarsInCluster: barSeriesMap.size,
+    totalBarsInCluster: barSeries.length,
     range: [0, 120],
   });
   const multiBarSeriesScale = computeXScale({
     xDomain: multiBarSeriesDomains.xDomain,
-    totalBarsInCluster: multiBarSeriesMap.size,
+    totalBarsInCluster: multiBarSeries.length,
     range: [0, 120],
   });
   const lineSeriesScale = computeXScale({
     xDomain: lineSeriesDomains.xDomain,
-    totalBarsInCluster: lineSeriesMap.size,
+    totalBarsInCluster: lineSeries.length,
     range: [0, 120],
   });
   const multiLineSeriesScale = computeXScale({
     xDomain: multiLineSeriesDomains.xDomain,
-    totalBarsInCluster: multiLineSeriesMap.size,
+    totalBarsInCluster: multiLineSeries.length,
     range: [0, 120],
   });
   const mixedLinesBarsSeriesScale = computeXScale({
     xDomain: mixedLinesBarsSeriesDomains.xDomain,
-    totalBarsInCluster: mixedLinesBarsMap.size,
+    totalBarsInCluster: mixedLinesBars.length,
     range: [0, 120],
   });
 
@@ -205,7 +204,7 @@ describe('Crosshair utils linear scale', () => {
       chartRotation,
       chartDimensions,
       { x: 200, y: 0 },
-      lineSeriesScale.invertWithStep(200, [0, 1, 2]),
+      lineSeriesScale.invertWithStep(200, [0, 1, 2])!,
       snapPosition,
       lineSeriesScale,
       1,
@@ -216,7 +215,7 @@ describe('Crosshair utils linear scale', () => {
       chartRotation,
       chartDimensions,
       { x: 0, y: 200 },
-      lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+      lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
       snapPosition,
       lineSeriesScale,
       1,
@@ -227,7 +226,7 @@ describe('Crosshair utils linear scale', () => {
       chartRotation,
       chartDimensions,
       { x: -1, y: 0 },
-      lineSeriesScale.invertWithStep(-1, [0, 1, 2]),
+      lineSeriesScale.invertWithStep(-1, [0, 1, 2])!,
       snapPosition,
       lineSeriesScale,
       1,
@@ -238,7 +237,7 @@ describe('Crosshair utils linear scale', () => {
       chartRotation,
       chartDimensions,
       { x: 0, y: -1 },
-      lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+      lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
       snapPosition,
       lineSeriesScale,
       1,
@@ -258,7 +257,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -277,7 +276,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 45 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -296,7 +295,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 40, y: 0 },
-          lineSeriesScale.invertWithStep(40, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(40, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -315,7 +314,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 90, y: 0 },
-          lineSeriesScale.invertWithStep(90, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(90, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -334,7 +333,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 200, y: 0 },
-          lineSeriesScale.invertWithStep(200, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(200, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -351,7 +350,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -370,7 +369,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 45 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -389,7 +388,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 20, y: 0 },
-          lineSeriesScale.invertWithStep(20, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(20, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -408,7 +407,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 40, y: 0 },
-          lineSeriesScale.invertWithStep(40, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(40, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -427,7 +426,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 95, y: 0 },
-          lineSeriesScale.invertWithStep(95, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(95, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -446,7 +445,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 200, y: 0 },
-          lineSeriesScale.invertWithStep(200, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(200, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -464,7 +463,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -484,7 +483,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 45 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -503,7 +502,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 40, y: 0 },
-          lineSeriesScale.invertWithStep(40, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(40, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -522,7 +521,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 90, y: 0 },
-          lineSeriesScale.invertWithStep(90, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(90, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -541,7 +540,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 200, y: 0 },
-          lineSeriesScale.invertWithStep(200, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(200, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -559,7 +558,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -578,7 +577,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 45 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -597,7 +596,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 20, y: 0 },
-          lineSeriesScale.invertWithStep(20, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(20, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -616,7 +615,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 40, y: 0 },
-          lineSeriesScale.invertWithStep(40, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(40, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -635,7 +634,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 95, y: 0 },
-          lineSeriesScale.invertWithStep(95, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(95, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -654,7 +653,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 200, y: 0 },
-          lineSeriesScale.invertWithStep(200, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(200, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -672,7 +671,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -691,7 +690,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 45, y: 0 },
-          lineSeriesScale.invertWithStep(45, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(45, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -710,7 +709,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 40 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -729,7 +728,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 90 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -748,7 +747,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 200 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -766,7 +765,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -785,7 +784,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 45, y: 0 },
-          lineSeriesScale.invertWithStep(45, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(45, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -804,7 +803,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 20 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -823,7 +822,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 40 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -842,7 +841,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 95 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -861,7 +860,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 200 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -879,7 +878,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -898,7 +897,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 45, y: 0 },
-          lineSeriesScale.invertWithStep(45, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(45, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -917,7 +916,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 40 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -936,7 +935,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 90 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -955,7 +954,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 200 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -973,7 +972,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -992,7 +991,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 45, y: 0 },
-          lineSeriesScale.invertWithStep(45, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(45, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -1011,7 +1010,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 20 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -1030,7 +1029,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 40 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -1049,7 +1048,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 95 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -1068,7 +1067,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 200 },
-          lineSeriesScale.invertWithStep(0, [0, 1, 2]),
+          lineSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           lineSeriesScale,
           1,
@@ -1089,7 +1088,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1108,7 +1107,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 45 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1127,7 +1126,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 40, y: 0 },
-          barSeriesScale.invertWithStep(40, [0, 1, 2]),
+          barSeriesScale.invertWithStep(40, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1143,7 +1142,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 41, y: 0 },
-          barSeriesScale.invertWithStep(41, [0, 1, 2]),
+          barSeriesScale.invertWithStep(41, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1162,7 +1161,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 90, y: 0 },
-          barSeriesScale.invertWithStep(90, [0, 1, 2]),
+          barSeriesScale.invertWithStep(90, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1181,7 +1180,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 200, y: 0 },
-          barSeriesScale.invertWithStep(200, [0, 1, 2]),
+          barSeriesScale.invertWithStep(200, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1199,7 +1198,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1218,7 +1217,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 45 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1237,7 +1236,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 41, y: 0 },
-          barSeriesScale.invertWithStep(41, [0, 1, 2]),
+          barSeriesScale.invertWithStep(41, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1256,7 +1255,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 90, y: 0 },
-          barSeriesScale.invertWithStep(90, [0, 1, 2]),
+          barSeriesScale.invertWithStep(90, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1275,7 +1274,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 200, y: 0 },
-          barSeriesScale.invertWithStep(200, [0, 1, 2]),
+          barSeriesScale.invertWithStep(200, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1293,7 +1292,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1312,7 +1311,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 45, y: 0 },
-          barSeriesScale.invertWithStep(45, [0, 1, 2]),
+          barSeriesScale.invertWithStep(45, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1331,7 +1330,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 40 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1350,7 +1349,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 90 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1369,7 +1368,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 200 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1387,7 +1386,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 0 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1406,7 +1405,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 45, y: 0 },
-          barSeriesScale.invertWithStep(45, [0, 1, 2]),
+          barSeriesScale.invertWithStep(45, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1425,7 +1424,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 40 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1444,7 +1443,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 90 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1463,7 +1462,7 @@ describe('Crosshair utils linear scale', () => {
           chartRotation,
           chartDimensions,
           { x: 0, y: 200 },
-          barSeriesScale.invertWithStep(0, [0, 1, 2]),
+          barSeriesScale.invertWithStep(0, [0, 1, 2])!,
           snapPosition,
           barSeriesScale,
           1,
@@ -1516,7 +1515,7 @@ describe('Crosshair utils linear scale', () => {
           scaleType: ScaleType.Linear,
           type: 'xDomain',
         },
-        totalBarsInCluster: barSeriesMap.size,
+        totalBarsInCluster: barSeries.length,
         range: [0, 120],
       });
       const bandPosition = getCursorBandPosition(
@@ -1580,7 +1579,7 @@ describe('Crosshair utils linear scale', () => {
           scaleType: ScaleType.Linear,
           type: 'xDomain',
         },
-        totalBarsInCluster: barSeriesMap.size,
+        totalBarsInCluster: barSeries.length,
         range: [0, 120],
       });
       const bandPosition = getCursorBandPosition(
diff --git a/src/chart_types/xy_chart/crosshair/crosshair_utils.ordinal_snap.test.ts b/src/chart_types/xy_chart/crosshair/crosshair_utils.ordinal_snap.test.ts
index 74edfdeb1f..d0480af837 100644
--- a/src/chart_types/xy_chart/crosshair/crosshair_utils.ordinal_snap.test.ts
+++ b/src/chart_types/xy_chart/crosshair/crosshair_utils.ordinal_snap.test.ts
@@ -1,9 +1,10 @@
 import { computeXScale } from '../utils/scales';
-import { BasicSeriesSpec } from '../utils/specs';
+import { BasicSeriesSpec, SpecTypes, SeriesTypes } from '../utils/specs';
 import { getGroupId, getSpecId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
 import { getSnapPosition } from './crosshair_utils';
-import { computeSeriesDomains } from '../store/utils';
+import { computeSeriesDomains } from '../state/utils';
+import { ChartTypes } from '../..';
 
 describe('Crosshair utils ordinal scales', () => {
   const barSeries1SpecId = getSpecId('barSeries1');
@@ -12,9 +13,11 @@ describe('Crosshair utils ordinal scales', () => {
   const lineSeries2SpecId = getSpecId('lineSeries2');
 
   const barSeries1: BasicSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: barSeries1SpecId,
     groupId: getGroupId('group1'),
-    seriesType: 'bar',
+    seriesType: SeriesTypes.Bar,
     data: [['a', 0], ['b', 0], ['c', 0]],
     xAccessor: 0,
     yAccessors: [1],
@@ -23,9 +26,11 @@ describe('Crosshair utils ordinal scales', () => {
     yScaleToDataExtent: true,
   };
   const barSeries2: BasicSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: barSeries2SpecId,
     groupId: getGroupId('group1'),
-    seriesType: 'bar',
+    seriesType: SeriesTypes.Bar,
     data: [['a', 2], ['b', 2], ['c', 2]],
     xAccessor: 0,
     yAccessors: [1],
@@ -34,9 +39,11 @@ describe('Crosshair utils ordinal scales', () => {
     yScaleToDataExtent: true,
   };
   const lineSeries1: BasicSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: lineSeries1SpecId,
     groupId: getGroupId('group1'),
-    seriesType: 'line',
+    seriesType: SeriesTypes.Line,
     data: [['a', 0], ['b', 0], ['c', 0]],
     xAccessor: 0,
     yAccessors: [1],
@@ -45,9 +52,11 @@ describe('Crosshair utils ordinal scales', () => {
     yScaleToDataExtent: true,
   };
   const lineSeries2: BasicSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: lineSeries2SpecId,
     groupId: getGroupId('group1'),
-    seriesType: 'line',
+    seriesType: SeriesTypes.Line,
     data: [['a', 2], ['b', 2], ['c', 2]],
     xAccessor: 0,
     yAccessors: [1],
@@ -56,54 +65,44 @@ describe('Crosshair utils ordinal scales', () => {
     yScaleToDataExtent: true,
   };
 
-  const barSeriesMap = new Map();
-  barSeriesMap.set(barSeries1SpecId, barSeries1);
-  const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map());
+  const barSeries = [barSeries1];
+  const barSeriesDomains = computeSeriesDomains(barSeries);
 
-  const multiBarSeriesMap = new Map();
-  multiBarSeriesMap.set(barSeries1SpecId, barSeries1);
-  multiBarSeriesMap.set(barSeries2SpecId, barSeries2);
-  const multiBarSeriesDomains = computeSeriesDomains(multiBarSeriesMap, new Map());
+  const multiBarSeries = [barSeries1, barSeries2];
+  const multiBarSeriesDomains = computeSeriesDomains(multiBarSeries);
 
-  const lineSeriesMap = new Map();
-  lineSeriesMap.set(lineSeries1SpecId, lineSeries1);
-  const lineSeriesDomains = computeSeriesDomains(lineSeriesMap, new Map());
+  const lineSeries = [lineSeries1];
+  const lineSeriesDomains = computeSeriesDomains(lineSeries);
 
-  const multiLineSeriesMap = new Map();
-  multiLineSeriesMap.set(lineSeries1SpecId, lineSeries1);
-  multiLineSeriesMap.set(lineSeries2SpecId, lineSeries2);
-  const multiLineSeriesDomains = computeSeriesDomains(multiLineSeriesMap, new Map());
+  const multiLineSeries = [lineSeries1, lineSeries2];
+  const multiLineSeriesDomains = computeSeriesDomains(multiLineSeries);
 
-  const mixedLinesBarsMap = new Map();
-  mixedLinesBarsMap.set(lineSeries1SpecId, lineSeries1);
-  mixedLinesBarsMap.set(lineSeries2SpecId, lineSeries2);
-  mixedLinesBarsMap.set(barSeries1SpecId, barSeries1);
-  mixedLinesBarsMap.set(barSeries2SpecId, barSeries2);
-  const mixedLinesBarsSeriesDomains = computeSeriesDomains(mixedLinesBarsMap, new Map());
+  const mixedLinesBars = [lineSeries1, lineSeries2, barSeries1, barSeries2];
+  const mixedLinesBarsSeriesDomains = computeSeriesDomains(mixedLinesBars);
 
   const barSeriesScale = computeXScale({
     xDomain: barSeriesDomains.xDomain,
-    totalBarsInCluster: barSeriesMap.size,
+    totalBarsInCluster: barSeries.length,
     range: [0, 120],
   });
   const multiBarSeriesScale = computeXScale({
     xDomain: multiBarSeriesDomains.xDomain,
-    totalBarsInCluster: multiBarSeriesMap.size,
+    totalBarsInCluster: multiBarSeries.length,
     range: [0, 120],
   });
   const lineSeriesScale = computeXScale({
     xDomain: lineSeriesDomains.xDomain,
-    totalBarsInCluster: lineSeriesMap.size,
+    totalBarsInCluster: lineSeries.length,
     range: [0, 120],
   });
   const multiLineSeriesScale = computeXScale({
     xDomain: multiLineSeriesDomains.xDomain,
-    totalBarsInCluster: multiLineSeriesMap.size,
+    totalBarsInCluster: multiLineSeries.length,
     range: [0, 120],
   });
   const mixedLinesBarsSeriesScale = computeXScale({
     xDomain: mixedLinesBarsSeriesDomains.xDomain,
-    totalBarsInCluster: mixedLinesBarsMap.size,
+    totalBarsInCluster: mixedLinesBars.length,
     range: [0, 120],
   });
 
diff --git a/src/chart_types/xy_chart/crosshair/crosshair_utils.ts b/src/chart_types/xy_chart/crosshair/crosshair_utils.ts
index 7b72cb6c0e..1231469ef9 100644
--- a/src/chart_types/xy_chart/crosshair/crosshair_utils.ts
+++ b/src/chart_types/xy_chart/crosshair/crosshair_utils.ts
@@ -1,8 +1,8 @@
 import { Rotation } from '../utils/specs';
 import { Dimensions } from '../../../utils/dimensions';
 import { Scale } from '../../../utils/scales/scales';
-import { isHorizontalRotation } from '../store/utils';
-import { Point } from '../store/chart_state';
+import { isHorizontalRotation } from '../state/utils';
+import { Point } from '../../../utils/point';
 
 export interface SnappedPosition {
   position: number;
@@ -56,12 +56,12 @@ export function getSnapPosition(
 export function getCursorLinePosition(
   chartRotation: Rotation,
   chartDimensions: Dimensions,
-  cursorPosition: { x: number; y: number },
+  projectedPointerPosition: { x: number; y: number },
 ): Dimensions {
   const { left, top, width, height } = chartDimensions;
   const isHorizontalRotated = isHorizontalRotation(chartRotation);
   if (isHorizontalRotated) {
-    const crosshairTop = cursorPosition.y + top;
+    const crosshairTop = projectedPointerPosition.y + top;
     return {
       left,
       width,
@@ -69,7 +69,7 @@ export function getCursorLinePosition(
       height: 0,
     };
   } else {
-    const crosshairLeft = cursorPosition.x + left;
+    const crosshairLeft = projectedPointerPosition.x + left;
 
     return {
       top,
@@ -187,7 +187,7 @@ export function getTooltipPosition(
   };
 }
 
-export function getHorizontalTooltipPosition(
+function getHorizontalTooltipPosition(
   cursorXPosition: number,
   cursorBandPosition: Dimensions,
   chartDimensions: Dimensions,
@@ -207,7 +207,7 @@ export function getHorizontalTooltipPosition(
   }
 }
 
-export function getVerticalTooltipPosition(
+function getVerticalTooltipPosition(
   cursorYPosition: number,
   cursorBandPosition: Dimensions,
   chartDimensions: Dimensions,
diff --git a/src/chart_types/xy_chart/domains/x_domain.test.ts b/src/chart_types/xy_chart/domains/x_domain.test.ts
index f3142e5dad..f63ddc0a61 100644
--- a/src/chart_types/xy_chart/domains/x_domain.test.ts
+++ b/src/chart_types/xy_chart/domains/x_domain.test.ts
@@ -1,8 +1,8 @@
-import { getGroupId, getSpecId, SpecId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
 import { getSplittedSeries } from '../utils/series';
-import { BasicSeriesSpec } from '../utils/specs';
+import { BasicSeriesSpec, SpecTypes, SeriesTypes } from '../utils/specs';
 import { convertXScaleTypes, findMinInterval, mergeXDomain } from './x_domain';
+import { ChartTypes } from '../..';
 
 describe('X Domain', () => {
   test('Should return null when missing specs or specs types', () => {
@@ -20,7 +20,7 @@ describe('X Domain', () => {
   test('Should return correct scale type with single bar', () => {
     const seriesSpecs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType'>[] = [
       {
-        seriesType: 'bar',
+        seriesType: SeriesTypes.Bar,
         xScaleType: ScaleType.Linear,
       },
     ];
@@ -34,7 +34,7 @@ describe('X Domain', () => {
   test('Should return correct scale type with single bar with Ordinal', () => {
     const seriesSpecs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType'>[] = [
       {
-        seriesType: 'bar',
+        seriesType: SeriesTypes.Bar,
         xScaleType: ScaleType.Ordinal,
       },
     ];
@@ -48,7 +48,7 @@ describe('X Domain', () => {
   test('Should return correct scale type with single area', () => {
     const seriesSpecs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType'>[] = [
       {
-        seriesType: 'area',
+        seriesType: SeriesTypes.Area,
         xScaleType: ScaleType.Linear,
       },
     ];
@@ -61,7 +61,7 @@ describe('X Domain', () => {
   test('Should return correct scale type with single line (time)', () => {
     const seriesSpecs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType' | 'timeZone'>[] = [
       {
-        seriesType: 'line',
+        seriesType: SeriesTypes.Line,
         xScaleType: ScaleType.Time,
         timeZone: 'utc-3',
       },
@@ -76,12 +76,12 @@ describe('X Domain', () => {
   test('Should return correct scale type with multi line with same scale types (time) same tz', () => {
     const seriesSpecs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType' | 'timeZone'>[] = [
       {
-        seriesType: 'line',
+        seriesType: SeriesTypes.Line,
         xScaleType: ScaleType.Time,
         timeZone: 'UTC-3',
       },
       {
-        seriesType: 'line',
+        seriesType: SeriesTypes.Line,
         xScaleType: ScaleType.Time,
         timeZone: 'utc-3',
       },
@@ -96,12 +96,12 @@ describe('X Domain', () => {
   test('Should return correct scale type with multi line with same scale types (time) coerce to UTC', () => {
     const seriesSpecs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType' | 'timeZone'>[] = [
       {
-        seriesType: 'line',
+        seriesType: SeriesTypes.Line,
         xScaleType: ScaleType.Time,
         timeZone: 'utc-3',
       },
       {
-        seriesType: 'line',
+        seriesType: SeriesTypes.Line,
         xScaleType: ScaleType.Time,
         timeZone: 'utc+3',
       },
@@ -117,11 +117,11 @@ describe('X Domain', () => {
   test('Should return correct scale type with multi line with different scale types (linear, ordinal)', () => {
     const seriesSpecs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType'>[] = [
       {
-        seriesType: 'line',
+        seriesType: SeriesTypes.Line,
         xScaleType: ScaleType.Linear,
       },
       {
-        seriesType: 'line',
+        seriesType: SeriesTypes.Line,
         xScaleType: ScaleType.Ordinal,
       },
     ];
@@ -134,11 +134,11 @@ describe('X Domain', () => {
   test('Should return correct scale type with multi bar, area with different scale types (linear, ordinal)', () => {
     const seriesSpecs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType'>[] = [
       {
-        seriesType: 'bar',
+        seriesType: SeriesTypes.Bar,
         xScaleType: ScaleType.Linear,
       },
       {
-        seriesType: 'area',
+        seriesType: SeriesTypes.Area,
         xScaleType: ScaleType.Ordinal,
       },
     ];
@@ -151,11 +151,11 @@ describe('X Domain', () => {
   test('Should return correct scale type with multi bar, area with same scale types (linear, linear)', () => {
     const seriesSpecs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType' | 'timeZone'>[] = [
       {
-        seriesType: 'bar',
+        seriesType: SeriesTypes.Bar,
         xScaleType: ScaleType.Linear,
       },
       {
-        seriesType: 'area',
+        seriesType: SeriesTypes.Area,
         xScaleType: ScaleType.Time,
         timeZone: 'utc+3',
       },
@@ -169,9 +169,11 @@ describe('X Domain', () => {
 
   test('Should merge line series correctly', () => {
     const ds1: BasicSeriesSpec = {
-      id: getSpecId('ds1'),
-      groupId: getGroupId('g1'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds1',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Line,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -180,9 +182,11 @@ describe('X Domain', () => {
       data: [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }, { x: 5, y: 0 }],
     };
     const ds2: BasicSeriesSpec = {
-      id: getSpecId('ds2'),
-      groupId: getGroupId('g1'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds2',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Line,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -190,14 +194,12 @@ describe('X Domain', () => {
       yScaleToDataExtent: false,
       data: [{ x: 0, y: 0 }, { x: 7, y: 0 }],
     };
-    const specDataSeries = new Map<SpecId, BasicSeriesSpec>();
-    specDataSeries.set(ds1.id, ds1);
-    specDataSeries.set(ds2.id, ds2);
+    const specDataSeries: BasicSeriesSpec[] = [ds1, ds2];
     const { xValues } = getSplittedSeries(specDataSeries);
     const mergedDomain = mergeXDomain(
       [
         {
-          seriesType: 'line',
+          seriesType: SeriesTypes.Line,
           xScaleType: ScaleType.Linear,
         },
       ],
@@ -207,9 +209,11 @@ describe('X Domain', () => {
   });
   test('Should merge bar series correctly', () => {
     const ds1: BasicSeriesSpec = {
-      id: getSpecId('ds1'),
-      groupId: getGroupId('g1'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds1',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Bar,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -218,9 +222,11 @@ describe('X Domain', () => {
       data: [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }, { x: 5, y: 0 }],
     };
     const ds2: BasicSeriesSpec = {
-      id: getSpecId('ds2'),
-      groupId: getGroupId('g1'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds2',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Bar,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -228,14 +234,13 @@ describe('X Domain', () => {
       yScaleToDataExtent: false,
       data: [{ x: 0, y: 0 }, { x: 7, y: 0 }],
     };
-    const specDataSeries = new Map<SpecId, BasicSeriesSpec>();
-    specDataSeries.set(ds1.id, ds1);
-    specDataSeries.set(ds2.id, ds2);
+    const specDataSeries = [ds1, ds2];
+
     const { xValues } = getSplittedSeries(specDataSeries);
     const mergedDomain = mergeXDomain(
       [
         {
-          seriesType: 'bar',
+          seriesType: SeriesTypes.Bar,
           xScaleType: ScaleType.Linear,
         },
       ],
@@ -245,9 +250,11 @@ describe('X Domain', () => {
   });
   test('Should merge multi bar series correctly', () => {
     const ds1: BasicSeriesSpec = {
-      id: getSpecId('ds1'),
-      groupId: getGroupId('g1'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds1',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Bar,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -256,9 +263,11 @@ describe('X Domain', () => {
       data: [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }, { x: 5, y: 0 }],
     };
     const ds2: BasicSeriesSpec = {
-      id: getSpecId('ds2'),
-      groupId: getGroupId('g2'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds2',
+      groupId: 'g2',
+      seriesType: SeriesTypes.Bar,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -266,18 +275,17 @@ describe('X Domain', () => {
       yScaleToDataExtent: false,
       data: [{ x: 0, y: 0 }, { x: 7, y: 0 }],
     };
-    const specDataSeries = new Map<SpecId, BasicSeriesSpec>();
-    specDataSeries.set(ds1.id, ds1);
-    specDataSeries.set(ds2.id, ds2);
+    const specDataSeries = [ds1, ds2];
+
     const { xValues } = getSplittedSeries(specDataSeries);
     const mergedDomain = mergeXDomain(
       [
         {
-          seriesType: 'bar',
+          seriesType: SeriesTypes.Bar,
           xScaleType: ScaleType.Linear,
         },
         {
-          seriesType: 'bar',
+          seriesType: SeriesTypes.Bar,
           xScaleType: ScaleType.Linear,
         },
       ],
@@ -287,9 +295,11 @@ describe('X Domain', () => {
   });
   test('Should merge multi bar series correctly', () => {
     const ds1: BasicSeriesSpec = {
-      id: getSpecId('ds1'),
-      groupId: getGroupId('g1'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds1',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Bar,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -298,9 +308,11 @@ describe('X Domain', () => {
       data: [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }, { x: 5, y: 0 }],
     };
     const ds2: BasicSeriesSpec = {
-      id: getSpecId('ds2'),
-      groupId: getGroupId('g2'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds2',
+      groupId: 'g2',
+      seriesType: SeriesTypes.Bar,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -308,18 +320,17 @@ describe('X Domain', () => {
       yScaleToDataExtent: false,
       data: [{ x: 0, y: 0 }, { x: 7, y: 0 }],
     };
-    const specDataSeries = new Map<SpecId, BasicSeriesSpec>();
-    specDataSeries.set(ds1.id, ds1);
-    specDataSeries.set(ds2.id, ds2);
+    const specDataSeries = [ds1, ds2];
+
     const { xValues } = getSplittedSeries(specDataSeries);
     const mergedDomain = mergeXDomain(
       [
         {
-          seriesType: 'bar',
+          seriesType: SeriesTypes.Bar,
           xScaleType: ScaleType.Linear,
         },
         {
-          seriesType: 'bar',
+          seriesType: SeriesTypes.Bar,
           xScaleType: ScaleType.Linear,
         },
       ],
@@ -329,9 +340,11 @@ describe('X Domain', () => {
   });
   test('Should merge multi bar linear/bar ordinal series correctly', () => {
     const ds1: BasicSeriesSpec = {
-      id: getSpecId('ds1'),
-      groupId: getGroupId('g1'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds1',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Bar,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -340,9 +353,11 @@ describe('X Domain', () => {
       data: [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }, { x: 5, y: 0 }],
     };
     const ds2: BasicSeriesSpec = {
-      id: getSpecId('ds2'),
-      groupId: getGroupId('g2'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds2',
+      groupId: 'g2',
+      seriesType: SeriesTypes.Bar,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Ordinal,
@@ -350,18 +365,17 @@ describe('X Domain', () => {
       yScaleToDataExtent: false,
       data: [{ x: 0, y: 0 }, { x: 7, y: 0 }],
     };
-    const specDataSeries = new Map<SpecId, BasicSeriesSpec>();
-    specDataSeries.set(ds1.id, ds1);
-    specDataSeries.set(ds2.id, ds2);
+    const specDataSeries = [ds1, ds2];
+
     const { xValues } = getSplittedSeries(specDataSeries);
     const mergedDomain = mergeXDomain(
       [
         {
-          seriesType: 'bar',
+          seriesType: SeriesTypes.Bar,
           xScaleType: ScaleType.Linear,
         },
         {
-          seriesType: 'bar',
+          seriesType: SeriesTypes.Bar,
           xScaleType: ScaleType.Ordinal,
         },
       ],
@@ -371,9 +385,11 @@ describe('X Domain', () => {
   });
   test('Should merge multi bar/line ordinal series correctly', () => {
     const ds1: BasicSeriesSpec = {
-      id: getSpecId('ds1'),
-      groupId: getGroupId('g1'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds1',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Bar,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -382,9 +398,11 @@ describe('X Domain', () => {
       data: [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }, { x: 5, y: 0 }],
     };
     const ds2: BasicSeriesSpec = {
-      id: getSpecId('ds2'),
-      groupId: getGroupId('g2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds2',
+      groupId: 'g2',
+      seriesType: SeriesTypes.Line,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Ordinal,
@@ -392,18 +410,17 @@ describe('X Domain', () => {
       yScaleToDataExtent: false,
       data: [{ x: 0, y: 0 }, { x: 7, y: 0 }],
     };
-    const specDataSeries = new Map<SpecId, BasicSeriesSpec>();
-    specDataSeries.set(ds1.id, ds1);
-    specDataSeries.set(ds2.id, ds2);
+    const specDataSeries = [ds1, ds2];
+
     const { xValues } = getSplittedSeries(specDataSeries);
     const mergedDomain = mergeXDomain(
       [
         {
-          seriesType: 'bar',
+          seriesType: SeriesTypes.Bar,
           xScaleType: ScaleType.Linear,
         },
         {
-          seriesType: 'line',
+          seriesType: SeriesTypes.Line,
           xScaleType: ScaleType.Ordinal,
         },
       ],
@@ -413,9 +430,11 @@ describe('X Domain', () => {
   });
   test('Should merge multi bar/line time series correctly', () => {
     const ds1: BasicSeriesSpec = {
-      id: getSpecId('ds1'),
-      groupId: getGroupId('g1'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds1',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Bar,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Ordinal,
@@ -424,9 +443,11 @@ describe('X Domain', () => {
       data: [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }, { x: 5, y: 0 }],
     };
     const ds2: BasicSeriesSpec = {
-      id: getSpecId('ds2'),
-      groupId: getGroupId('g2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds2',
+      groupId: 'g2',
+      seriesType: SeriesTypes.Line,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Time,
@@ -434,18 +455,17 @@ describe('X Domain', () => {
       yScaleToDataExtent: false,
       data: [{ x: 0, y: 0 }, { x: 7, y: 0 }],
     };
-    const specDataSeries = new Map<SpecId, BasicSeriesSpec>();
-    specDataSeries.set(ds1.id, ds1);
-    specDataSeries.set(ds2.id, ds2);
+    const specDataSeries = [ds1, ds2];
+
     const { xValues } = getSplittedSeries(specDataSeries);
     const mergedDomain = mergeXDomain(
       [
         {
-          seriesType: 'bar',
+          seriesType: SeriesTypes.Bar,
           xScaleType: ScaleType.Ordinal,
         },
         {
-          seriesType: 'line',
+          seriesType: SeriesTypes.Line,
           xScaleType: ScaleType.Time,
         },
       ],
@@ -455,9 +475,11 @@ describe('X Domain', () => {
   });
   test('Should merge multi lines series correctly', () => {
     const ds1: BasicSeriesSpec = {
-      id: getSpecId('ds1'),
-      groupId: getGroupId('g1'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds1',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Line,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Ordinal,
@@ -466,9 +488,11 @@ describe('X Domain', () => {
       data: [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }, { x: 5, y: 0 }],
     };
     const ds2: BasicSeriesSpec = {
-      id: getSpecId('ds2'),
-      groupId: getGroupId('g2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds2',
+      groupId: 'g2',
+      seriesType: SeriesTypes.Line,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -476,18 +500,17 @@ describe('X Domain', () => {
       yScaleToDataExtent: false,
       data: [{ x: 0, y: 0 }, { x: 7, y: 0 }],
     };
-    const specDataSeries = new Map<SpecId, BasicSeriesSpec>();
-    specDataSeries.set(ds1.id, ds1);
-    specDataSeries.set(ds2.id, ds2);
+    const specDataSeries = [ds1, ds2];
+
     const { xValues } = getSplittedSeries(specDataSeries);
     const mergedDomain = mergeXDomain(
       [
         {
-          seriesType: 'line',
+          seriesType: SeriesTypes.Line,
           xScaleType: ScaleType.Ordinal,
         },
         {
-          seriesType: 'line',
+          seriesType: SeriesTypes.Line,
           xScaleType: ScaleType.Linear,
         },
       ],
@@ -499,9 +522,11 @@ describe('X Domain', () => {
   test('Should merge X multi high volume of data', () => {
     const maxValues = 10000;
     const ds1: BasicSeriesSpec = {
-      id: getSpecId('ds1'),
-      groupId: getGroupId('g1'),
-      seriesType: 'area',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds1',
+      groupId: 'g1',
+      seriesType: SeriesTypes.Area,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Linear,
@@ -510,9 +535,11 @@ describe('X Domain', () => {
       data: new Array(maxValues).fill(0).map((d, i) => ({ x: i, y: i })),
     };
     const ds2: BasicSeriesSpec = {
-      id: getSpecId('ds2'),
-      groupId: getGroupId('g2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'ds2',
+      groupId: 'g2',
+      seriesType: SeriesTypes.Line,
       xAccessor: 'x',
       yAccessors: ['y'],
       xScaleType: ScaleType.Ordinal,
@@ -520,19 +547,18 @@ describe('X Domain', () => {
       yScaleToDataExtent: false,
       data: new Array(maxValues).fill(0).map((d, i) => ({ x: i, y: i })),
     };
-    const specDataSeries = new Map<SpecId, BasicSeriesSpec>();
-    specDataSeries.set(ds1.id, ds1);
-    specDataSeries.set(ds2.id, ds2);
+    const specDataSeries = [ds1, ds2];
+
     const { xValues } = getSplittedSeries(specDataSeries);
 
     const mergedDomain = mergeXDomain(
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           xScaleType: ScaleType.Linear,
         },
         {
-          seriesType: 'line',
+          seriesType: SeriesTypes.Line,
           xScaleType: ScaleType.Ordinal,
         },
       ],
@@ -572,7 +598,7 @@ describe('X Domain', () => {
     const xValues = new Set([1, 2, 3, 4, 5]);
     const xDomain = { min: 0, max: 3 };
     const specs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType'>[] = [
-      { seriesType: 'line', xScaleType: ScaleType.Linear },
+      { seriesType: SeriesTypes.Line, xScaleType: ScaleType.Linear },
     ];
 
     const basicMergedDomain = mergeXDomain(specs, xValues, xDomain);
@@ -596,7 +622,7 @@ describe('X Domain', () => {
     const xValues = new Set([1, 2, 3, 4, 5]);
     const xDomain = { min: 0 };
     const specs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType'>[] = [
-      { seriesType: 'line', xScaleType: ScaleType.Linear },
+      { seriesType: SeriesTypes.Line, xScaleType: ScaleType.Linear },
     ];
 
     const mergedDomain = mergeXDomain(specs, xValues, xDomain);
@@ -613,7 +639,7 @@ describe('X Domain', () => {
     const xValues = new Set([1, 2, 3, 4, 5]);
     const xDomain = { max: 3 };
     const specs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType'>[] = [
-      { seriesType: 'line', xScaleType: ScaleType.Linear },
+      { seriesType: SeriesTypes.Line, xScaleType: ScaleType.Linear },
     ];
 
     const mergedDomain = mergeXDomain(specs, xValues, xDomain);
@@ -630,7 +656,7 @@ describe('X Domain', () => {
     const xValues = new Set(['a', 'b', 'c', 'd']);
     const xDomain = ['a', 'b', 'c'];
     const specs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType'>[] = [
-      { seriesType: 'bar', xScaleType: ScaleType.Ordinal },
+      { seriesType: SeriesTypes.Bar, xScaleType: ScaleType.Ordinal },
     ];
     const basicMergedDomain = mergeXDomain(specs, xValues, xDomain);
     expect(basicMergedDomain.domain).toEqual(['a', 'b', 'c']);
@@ -646,7 +672,7 @@ describe('X Domain', () => {
   describe('should account for custom minInterval', () => {
     const xValues = new Set([1, 2, 3, 4, 5]);
     const specs: Pick<BasicSeriesSpec, 'seriesType' | 'xScaleType'>[] = [
-      { seriesType: 'bar', xScaleType: ScaleType.Linear },
+      { seriesType: SeriesTypes.Bar, xScaleType: ScaleType.Linear },
     ];
 
     test('with valid minInterval', () => {
diff --git a/src/chart_types/xy_chart/domains/x_domain.ts b/src/chart_types/xy_chart/domains/x_domain.ts
index 280d527787..f2aef2bd2f 100644
--- a/src/chart_types/xy_chart/domains/x_domain.ts
+++ b/src/chart_types/xy_chart/domains/x_domain.ts
@@ -2,7 +2,7 @@ import { isCompleteBound, isLowerBound, isUpperBound } from '../utils/axis_utils
 import { compareByValueAsc, identity, isNumberArray } from '../../../utils/commons';
 import { computeContinuousDataDomain, computeOrdinalDataDomain, Domain } from '../../../utils/domain';
 import { ScaleType } from '../../../utils/scales/scales';
-import { BasicSeriesSpec, DomainRange } from '../utils/specs';
+import { BasicSeriesSpec, DomainRange, SeriesTypes } from '../utils/specs';
 import { BaseDomain } from './domain';
 
 export type XDomain = BaseDomain & {
@@ -155,7 +155,7 @@ export function convertXScaleTypes(
   if (specs.length === 0 || seriesTypes.size === 0 || scaleTypes.size === 0) {
     return null;
   }
-  const isBandScale = seriesTypes.has('bar');
+  const isBandScale = seriesTypes.has(SeriesTypes.Bar);
   if (scaleTypes.size === 1) {
     const scaleType = scaleTypes.values().next().value;
     let timeZone: string | undefined;
diff --git a/src/chart_types/xy_chart/domains/y_domain.test.ts b/src/chart_types/xy_chart/domains/y_domain.test.ts
index 1b10b48127..8e2a3d3303 100644
--- a/src/chart_types/xy_chart/domains/y_domain.test.ts
+++ b/src/chart_types/xy_chart/domains/y_domain.test.ts
@@ -1,7 +1,6 @@
-import { getGroupId, getSpecId, GroupId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
 import { RawDataSeries } from '../utils/series';
-import { BasicSeriesSpec, DomainRange } from '../utils/specs';
+import { BasicSeriesSpec, DomainRange, SpecTypes, SeriesTypes } from '../utils/specs';
 import { BARCHART_1Y0G } from '../../../utils/data_samples/test_dataset';
 import {
   coerceYScaleTypes,
@@ -10,33 +9,35 @@ import {
   splitSpecsByGroupId,
   YBasicSeriesSpec,
 } from './y_domain';
+import { GroupId } from '../../../utils/ids';
+import { ChartTypes } from '../..';
 
 describe('Y Domain', () => {
   test('Should merge Y domain', () => {
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries);
+    specDataSeries.set('a', dataSeries);
     const mergedDomain = mergeYDomain(
       specDataSeries,
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Linear,
-          groupId: getGroupId('a'),
-          id: getSpecId('a'),
+          groupId: 'a',
+          id: 'a',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
         },
@@ -56,13 +57,13 @@ describe('Y Domain', () => {
   test('Should merge Y domain different group', () => {
     const dataSeries1: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
@@ -70,31 +71,31 @@ describe('Y Domain', () => {
     ];
     const dataSeries2: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 10 }, { x: 2, y1: 10 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries1);
-    specDataSeries.set(getSpecId('b'), dataSeries2);
+    specDataSeries.set('a', dataSeries1);
+    specDataSeries.set('b', dataSeries2);
     const mergedDomain = mergeYDomain(
       specDataSeries,
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Linear,
-          groupId: getGroupId('a'),
-          id: getSpecId('a'),
+          groupId: 'a',
+          id: 'a',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
         },
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Log,
-          groupId: getGroupId('b'),
-          id: getSpecId('b'),
+          groupId: 'b',
+          id: 'b',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
         },
@@ -121,13 +122,13 @@ describe('Y Domain', () => {
   test('Should merge Y domain same group all stacked', () => {
     const dataSeries1: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
@@ -135,31 +136,31 @@ describe('Y Domain', () => {
     ];
     const dataSeries2: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 10 }, { x: 2, y1: 10 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries1);
-    specDataSeries.set(getSpecId('b'), dataSeries2);
+    specDataSeries.set('a', dataSeries1);
+    specDataSeries.set('b', dataSeries2);
     const mergedDomain = mergeYDomain(
       specDataSeries,
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Linear,
-          groupId: getGroupId('a'),
-          id: getSpecId('a'),
+          groupId: 'a',
+          id: 'a',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
         },
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Log,
-          groupId: getGroupId('a'),
-          id: getSpecId('b'),
+          groupId: 'a',
+          id: 'b',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
         },
@@ -179,13 +180,13 @@ describe('Y Domain', () => {
   test('Should merge Y domain same group partially stacked', () => {
     const dataSeries1: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
@@ -193,31 +194,31 @@ describe('Y Domain', () => {
     ];
     const dataSeries2: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 10 }, { x: 2, y1: 10 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries1);
-    specDataSeries.set(getSpecId('b'), dataSeries2);
+    specDataSeries.set('a', dataSeries1);
+    specDataSeries.set('b', dataSeries2);
     const mergedDomain = mergeYDomain(
       specDataSeries,
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Linear,
-          groupId: getGroupId('a'),
-          id: getSpecId('a'),
+          groupId: 'a',
+          id: 'a',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
         },
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Log,
-          groupId: getGroupId('a'),
-          id: getSpecId('b'),
+          groupId: 'a',
+          id: 'b',
           yScaleToDataExtent: true,
         },
       ],
@@ -237,13 +238,13 @@ describe('Y Domain', () => {
     const maxValues = 10000;
     const dataSeries1: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: new Array(maxValues).fill(0).map((d, i) => ({ x: i, y1: i })),
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: new Array(maxValues).fill(0).map((d, i) => ({ x: i, y1: i })),
@@ -251,31 +252,31 @@ describe('Y Domain', () => {
     ];
     const dataSeries2: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: new Array(maxValues).fill(0).map((d, i) => ({ x: i, y1: i })),
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries1);
-    specDataSeries.set(getSpecId('b'), dataSeries2);
+    specDataSeries.set('a', dataSeries1);
+    specDataSeries.set('b', dataSeries2);
     const mergedDomain = mergeYDomain(
       specDataSeries,
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Linear,
-          groupId: getGroupId('a'),
-          id: getSpecId('a'),
+          groupId: 'a',
+          id: 'a',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
         },
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Log,
-          groupId: getGroupId('a'),
-          id: getSpecId('b'),
+          groupId: 'a',
+          id: 'b',
           yScaleToDataExtent: true,
         },
       ],
@@ -285,9 +286,11 @@ describe('Y Domain', () => {
   });
   test('Should split specs by groupId, two groups, non stacked', () => {
     const spec1: BasicSeriesSpec = {
-      id: getSpecId('spec1'),
-      groupId: getGroupId('group1'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec1',
+      groupId: 'group1',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -296,9 +299,11 @@ describe('Y Domain', () => {
       data: BARCHART_1Y0G,
     };
     const spec2: BasicSeriesSpec = {
-      id: getSpecId('spec2'),
-      groupId: getGroupId('group2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec2',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -318,9 +323,11 @@ describe('Y Domain', () => {
   });
   test('Should split specs by groupId, two groups, stacked', () => {
     const spec1: BasicSeriesSpec = {
-      id: getSpecId('spec1'),
-      groupId: getGroupId('group1'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec1',
+      groupId: 'group1',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -330,9 +337,11 @@ describe('Y Domain', () => {
       data: BARCHART_1Y0G,
     };
     const spec2: BasicSeriesSpec = {
-      id: getSpecId('spec2'),
-      groupId: getGroupId('group2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec2',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -353,9 +362,11 @@ describe('Y Domain', () => {
   });
   test('Should split specs by groupId, 1 group, stacked', () => {
     const spec1: BasicSeriesSpec = {
-      id: getSpecId('spec1'),
-      groupId: getGroupId('group'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec1',
+      groupId: 'group',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -365,9 +376,11 @@ describe('Y Domain', () => {
       data: BARCHART_1Y0G,
     };
     const spec2: BasicSeriesSpec = {
-      id: getSpecId('spec2'),
-      groupId: getGroupId('group'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec2',
+      groupId: 'group',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -386,9 +399,11 @@ describe('Y Domain', () => {
   });
   test('Should 3 split specs by groupId, 2 group, semi/stacked', () => {
     const spec1: BasicSeriesSpec = {
-      id: getSpecId('spec1'),
-      groupId: getGroupId('group1'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec1',
+      groupId: 'group1',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -398,9 +413,11 @@ describe('Y Domain', () => {
       data: BARCHART_1Y0G,
     };
     const spec2: BasicSeriesSpec = {
-      id: getSpecId('spec2'),
-      groupId: getGroupId('group1'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec2',
+      groupId: 'group1',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -410,9 +427,11 @@ describe('Y Domain', () => {
       data: BARCHART_1Y0G,
     };
     const spec3: BasicSeriesSpec = {
-      id: getSpecId('spec3'),
-      groupId: getGroupId('group2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec3',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -440,27 +459,27 @@ describe('Y Domain', () => {
   test('Should getDataSeriesOnGroup for matching specs', () => {
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('b'), dataSeries);
+    specDataSeries.set('b', dataSeries);
 
     const specs: YBasicSeriesSpec[] = [
       {
-        seriesType: 'area',
+        seriesType: SeriesTypes.Area,
         yScaleType: ScaleType.Linear,
-        groupId: getGroupId('a'),
-        id: getSpecId('a'),
+        groupId: 'a',
+        id: 'a',
         stackAccessors: ['a'],
         yScaleToDataExtent: true,
       },
@@ -470,24 +489,24 @@ describe('Y Domain', () => {
     expect(rawDataSeries).toEqual([]);
   });
   test('Should merge Y domain accounting for custom domain limits: complete bounded domain', () => {
-    const groupId = getGroupId('a');
+    const groupId = 'a';
 
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries);
+    specDataSeries.set('a', dataSeries);
     const domainsByGroupId = new Map<GroupId, DomainRange>();
     domainsByGroupId.set(groupId, { min: 0, max: 20 });
 
@@ -495,10 +514,10 @@ describe('Y Domain', () => {
       specDataSeries,
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Linear,
           groupId,
-          id: getSpecId('a'),
+          id: 'a',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
         },
@@ -516,24 +535,24 @@ describe('Y Domain', () => {
     ]);
   });
   test('Should merge Y domain accounting for custom domain limits: partial lower bounded domain', () => {
-    const groupId = getGroupId('a');
+    const groupId = 'a';
 
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries);
+    specDataSeries.set('a', dataSeries);
     const domainsByGroupId = new Map<GroupId, DomainRange>();
     domainsByGroupId.set(groupId, { min: 0 });
 
@@ -541,10 +560,10 @@ describe('Y Domain', () => {
       specDataSeries,
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Linear,
           groupId,
-          id: getSpecId('a'),
+          id: 'a',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
         },
@@ -562,24 +581,24 @@ describe('Y Domain', () => {
     ]);
   });
   test('Should not merge Y domain with invalid custom domain limits: partial lower bounded domain', () => {
-    const groupId = getGroupId('a');
+    const groupId = 'a';
 
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries);
+    specDataSeries.set('a', dataSeries);
     const domainsByGroupId = new Map<GroupId, DomainRange>();
     domainsByGroupId.set(groupId, { min: 20 });
 
@@ -588,10 +607,10 @@ describe('Y Domain', () => {
         specDataSeries,
         [
           {
-            seriesType: 'area',
+            seriesType: SeriesTypes.Area,
             yScaleType: ScaleType.Linear,
             groupId,
-            id: getSpecId('a'),
+            id: 'a',
             stackAccessors: ['a'],
             yScaleToDataExtent: true,
           },
@@ -604,24 +623,24 @@ describe('Y Domain', () => {
     expect(attemptToMerge).toThrowError(errorMessage);
   });
   test('Should merge Y domain accounting for custom domain limits: partial upper bounded domain', () => {
-    const groupId = getGroupId('a');
+    const groupId = 'a';
 
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries);
+    specDataSeries.set('a', dataSeries);
     const domainsByGroupId = new Map<GroupId, DomainRange>();
     domainsByGroupId.set(groupId, { max: 20 });
 
@@ -629,10 +648,10 @@ describe('Y Domain', () => {
       specDataSeries,
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Linear,
           groupId,
-          id: getSpecId('a'),
+          id: 'a',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
         },
@@ -650,24 +669,24 @@ describe('Y Domain', () => {
     ]);
   });
   test('Should not merge Y domain with invalid custom domain limits: partial upper bounded domain', () => {
-    const groupId = getGroupId('a');
+    const groupId = 'a';
 
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries);
+    specDataSeries.set('a', dataSeries);
     const domainsByGroupId = new Map<GroupId, DomainRange>();
     domainsByGroupId.set(groupId, { max: -1 });
 
@@ -676,10 +695,10 @@ describe('Y Domain', () => {
         specDataSeries,
         [
           {
-            seriesType: 'area',
+            seriesType: SeriesTypes.Area,
             yScaleType: ScaleType.Linear,
             groupId,
-            id: getSpecId('a'),
+            id: 'a',
             stackAccessors: ['a'],
             yScaleToDataExtent: true,
           },
@@ -694,13 +713,13 @@ describe('Y Domain', () => {
   test('Should merge Y domain with stacked as percentage', () => {
     const dataSeries1: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
@@ -708,32 +727,32 @@ describe('Y Domain', () => {
     ];
     const dataSeries2: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 10 }, { x: 2, y1: 10 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries1);
-    specDataSeries.set(getSpecId('b'), dataSeries2);
+    specDataSeries.set('a', dataSeries1);
+    specDataSeries.set('b', dataSeries2);
     const mergedDomain = mergeYDomain(
       specDataSeries,
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Linear,
-          groupId: getGroupId('a'),
-          id: getSpecId('a'),
+          groupId: 'a',
+          id: 'a',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
           stackAsPercentage: true,
         },
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Log,
-          groupId: getGroupId('a'),
-          id: getSpecId('b'),
+          groupId: 'a',
+          id: 'b',
           yScaleToDataExtent: true,
         },
       ],
@@ -750,24 +769,24 @@ describe('Y Domain', () => {
     ]);
   });
   test('Should merge Y domain with as percentage regadless of custom domains', () => {
-    const groupId = getGroupId('a');
+    const groupId = 'a';
 
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 2, y1: 2 }, { x: 3, y1: 2 }, { x: 4, y1: 5 }],
       },
       {
-        specId: getSpecId('a'),
+        specId: 'a',
         key: [''],
         seriesColorKey: '',
         data: [{ x: 1, y1: 2 }, { x: 4, y1: 7 }],
       },
     ];
     const specDataSeries = new Map();
-    specDataSeries.set(getSpecId('a'), dataSeries);
+    specDataSeries.set('a', dataSeries);
     const domainsByGroupId = new Map<GroupId, DomainRange>();
     domainsByGroupId.set(groupId, { min: 2, max: 20 });
 
@@ -775,10 +794,10 @@ describe('Y Domain', () => {
       specDataSeries,
       [
         {
-          seriesType: 'area',
+          seriesType: SeriesTypes.Area,
           yScaleType: ScaleType.Linear,
           groupId,
-          id: getSpecId('a'),
+          id: 'a',
           stackAccessors: ['a'],
           yScaleToDataExtent: true,
           stackAsPercentage: true,
diff --git a/src/chart_types/xy_chart/domains/y_domain.ts b/src/chart_types/xy_chart/domains/y_domain.ts
index 945bfce29a..5e0fd2a232 100644
--- a/src/chart_types/xy_chart/domains/y_domain.ts
+++ b/src/chart_types/xy_chart/domains/y_domain.ts
@@ -1,4 +1,4 @@
-import { BasicSeriesSpec, DomainRange, DEFAULT_GLOBAL_ID } from '../utils/specs';
+import { BasicSeriesSpec, DomainRange, DEFAULT_GLOBAL_ID, SeriesTypes } from '../utils/specs';
 import { GroupId, SpecId, getGroupId } from '../../../utils/ids';
 import { ScaleContinuousType, ScaleType } from '../../../utils/scales/scales';
 import { isCompleteBound, isLowerBound, isUpperBound } from '../utils/axis_utils';
@@ -17,7 +17,7 @@ export type YDomain = BaseDomain & {
 export type YBasicSeriesSpec = Pick<
   BasicSeriesSpec,
   'id' | 'seriesType' | 'yScaleType' | 'groupId' | 'stackAccessors' | 'yScaleToDataExtent' | 'useDefaultGroupDomain'
-> & { stackAsPercentage?: boolean };
+> & { stackAsPercentage?: boolean; enableHistogramMode?: boolean };
 
 interface GroupSpecs {
   isPercentageStack: boolean;
@@ -160,6 +160,7 @@ function computeYStackedDomain(dataseries: RawDataSeries[], scaleToExtent: boole
   }
   return computeContinuousDataDomain(dataValues, identity, scaleToExtent);
 }
+
 function computeYNonStackedDomain(dataseries: RawDataSeries[], scaleToExtent: boolean) {
   const yValues = new Set<any>();
   dataseries.forEach((ds) => {
@@ -175,11 +176,18 @@ function computeYNonStackedDomain(dataseries: RawDataSeries[], scaleToExtent: bo
   }
   return computeContinuousDataDomain([...yValues.values()], identity, scaleToExtent);
 }
+
 export function splitSpecsByGroupId(specs: YBasicSeriesSpec[]) {
   const specsByGroupIds = new Map<
     GroupId,
     { isPercentageStack: boolean; stacked: YBasicSeriesSpec[]; nonStacked: YBasicSeriesSpec[] }
   >();
+  // After mobx->redux https://github.com/elastic/elastic-charts/pull/281 we keep the specs untouched on mount
+  // in MobX version, the stackAccessors was programmatically added to every histogram specs
+  // in ReduX version, we left untouched the specs, so we have to manually check that
+  const isHistogramEnabled = specs.some(({ seriesType, enableHistogramMode }) => {
+    return seriesType === SeriesTypes.Bar && enableHistogramMode;
+  });
   // split each specs by groupId and by stacked or not
   specs.forEach((spec) => {
     const group = specsByGroupIds.get(spec.groupId) || {
@@ -187,7 +195,12 @@ export function splitSpecsByGroupId(specs: YBasicSeriesSpec[]) {
       stacked: [],
       nonStacked: [],
     };
-    if (spec.stackAccessors && spec.stackAccessors.length > 0) {
+    // stack every bars if using histogram mode
+    // independenyly from lines and areas
+    if (
+      (spec.seriesType === SeriesTypes.Bar && isHistogramEnabled) ||
+      (spec.stackAccessors && spec.stackAccessors.length > 0)
+    ) {
       group.stacked.push(spec);
     } else {
       group.nonStacked.push(spec);
diff --git a/src/chart_types/xy_chart/legend/legend.test.ts b/src/chart_types/xy_chart/legend/legend.test.ts
index d8369f8d87..e931947703 100644
--- a/src/chart_types/xy_chart/legend/legend.test.ts
+++ b/src/chart_types/xy_chart/legend/legend.test.ts
@@ -1,8 +1,9 @@
-import { AxisId, getAxisId, getGroupId, getSpecId, SpecId } from '../../../utils/ids';
+import { getAxisId, getGroupId, getSpecId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
 import { computeLegend, getSeriesColorLabel } from './legend';
 import { DataSeriesColorsValues } from '../utils/series';
-import { AxisSpec, BasicSeriesSpec, Position } from '../utils/specs';
+import { AxisSpec, BasicSeriesSpec, Position, SpecTypes, SeriesTypes } from '../utils/specs';
+import { ChartTypes } from '../..';
 
 const nullDisplayValue = {
   formatted: {
@@ -31,10 +32,12 @@ const colorValues2b = {
   colorValues: ['c', 'd'],
 };
 const spec1: BasicSeriesSpec = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Series,
   id: getSpecId('spec1'),
   name: 'Spec 1 title',
   groupId: getGroupId('group'),
-  seriesType: 'line',
+  seriesType: SeriesTypes.Line,
   yScaleType: ScaleType.Log,
   xScaleType: ScaleType.Linear,
   xAccessor: 'x',
@@ -44,9 +47,11 @@ const spec1: BasicSeriesSpec = {
   hideInLegend: false,
 };
 const spec2: BasicSeriesSpec = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Series,
   id: getSpecId('spec2'),
   groupId: getGroupId('group'),
-  seriesType: 'line',
+  seriesType: SeriesTypes.Line,
   yScaleType: ScaleType.Log,
   xScaleType: ScaleType.Linear,
   xAccessor: 'x',
@@ -56,8 +61,10 @@ const spec2: BasicSeriesSpec = {
   hideInLegend: false,
 };
 
-const axesSpecs = new Map<AxisId, AxisSpec>();
+const axesSpecs: AxisSpec[] = [];
 const axisSpec: AxisSpec = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Axis,
   id: getAxisId('axis1'),
   groupId: getGroupId('group1'),
   hide: false,
@@ -70,14 +77,12 @@ const axisSpec: AxisSpec = {
     return `${value}`;
   },
 };
-axesSpecs.set(axisSpec.id, axisSpec);
+axesSpecs.push(axisSpec);
 
 describe('Legends', () => {
   const seriesColor = new Map<string, DataSeriesColorsValues>();
   const seriesColorMap = new Map<string, string>();
-  const specs = new Map<SpecId, BasicSeriesSpec>();
-  specs.set(spec1.id, spec1);
-  specs.set(spec2.id, spec2);
+  const specs = [spec1, spec2];
   seriesColorMap.set('colorSeries1a', 'red');
   seriesColorMap.set('colorSeries1b', 'blue');
   seriesColorMap.set('colorSeries2a', 'green');
@@ -182,9 +187,8 @@ describe('Legends', () => {
     seriesColor.set('colorSeries2b', colorValues2b);
 
     const emptyColorMap = new Map<string, string>();
-    const deselectedDataSeries = null;
 
-    const legend = computeLegend(seriesColor, emptyColorMap, specs, 'violet', axesSpecs, deselectedDataSeries);
+    const legend = computeLegend(seriesColor, emptyColorMap, specs, 'violet', axesSpecs);
 
     const visibility = [...legend.values()].map((item) => item.isSeriesVisible);
 
diff --git a/src/chart_types/xy_chart/legend/legend.ts b/src/chart_types/xy_chart/legend/legend.ts
index d1153ff89b..48ede4e62c 100644
--- a/src/chart_types/xy_chart/legend/legend.ts
+++ b/src/chart_types/xy_chart/legend/legend.ts
@@ -1,15 +1,15 @@
-import { getAxesSpecForSpecId, LastValues } from '../store/utils';
+import { getAxesSpecForSpecId, LastValues, getSpecsById } from '../state/utils';
 import { identity } from '../../../utils/commons';
-import { AxisId, SpecId } from '../../../utils/ids';
 import {
   DataSeriesColorsValues,
-  findDataSeriesByColorValues,
   getSortedDataSeriesColorsValuesMap,
+  findDataSeriesByColorValues,
 } from '../utils/series';
 import { AxisSpec, BasicSeriesSpec, Postfixes, isAreaSeriesSpec, isBarSeriesSpec } from '../utils/specs';
 import { Y0_ACCESSOR_POSTFIX, Y1_ACCESSOR_POSTFIX } from '../tooltip/tooltip';
+import { AccessorType } from '../../../utils/geometry';
 
-export interface FormatedLastValues {
+interface FormattedLastValues {
   y0: number | string | null;
   y1: number | string | null;
 }
@@ -24,11 +24,11 @@ export type LegendItem = Postfixes & {
   isLegendItemVisible?: boolean;
   displayValue: {
     raw: LastValues;
-    formatted: FormatedLastValues;
+    formatted: FormattedLastValues;
   };
 };
 
-export function getPostfix(spec: BasicSeriesSpec): Postfixes {
+function getPostfix(spec: BasicSeriesSpec): Postfixes {
   if (isAreaSeriesSpec(spec) || isBarSeriesSpec(spec)) {
     const { y0AccessorFormat = Y0_ACCESSOR_POSTFIX, y1AccessorFormat = Y1_ACCESSOR_POSTFIX } = spec;
     return {
@@ -40,20 +40,31 @@ export function getPostfix(spec: BasicSeriesSpec): Postfixes {
   return {};
 }
 
+export function getItemLabel(
+  { banded, label, y1AccessorFormat, y0AccessorFormat }: LegendItem,
+  yAccessor: AccessorType,
+) {
+  if (!banded) {
+    return label;
+  }
+
+  return yAccessor === AccessorType.Y1 ? `${label}${y1AccessorFormat}` : `${label}${y0AccessorFormat}`;
+}
+
 export function computeLegend(
   seriesColor: Map<string, DataSeriesColorsValues>,
   seriesColorMap: Map<string, string>,
-  specs: Map<SpecId, BasicSeriesSpec>,
+  specs: BasicSeriesSpec[],
   defaultColor: string,
-  axesSpecs: Map<AxisId, AxisSpec>,
-  deselectedDataSeries?: DataSeriesColorsValues[] | null,
+  axesSpecs: AxisSpec[],
+  deselectedDataSeries: DataSeriesColorsValues[] = [],
 ): Map<string, LegendItem> {
   const legendItems: Map<string, LegendItem> = new Map();
   const sortedSeriesColors = getSortedDataSeriesColorsValuesMap(seriesColor);
 
   sortedSeriesColors.forEach((series, key) => {
     const { banded, specId, lastValue, colorValues } = series;
-    const spec = specs.get(specId);
+    const spec = getSpecsById<BasicSeriesSpec>(specs, specId);
     const color = seriesColorMap.get(key) || defaultColor;
     const hasSingleSeries = seriesColor.size === 1;
     const label = getSeriesColorLabel(colorValues, hasSingleSeries, spec);
@@ -82,8 +93,8 @@ export function computeLegend(
           y1: lastValue && lastValue.y1 !== null ? lastValue.y1 : null,
         },
         formatted: {
-          y0: isSeriesVisible && lastValue && lastValue.y0 !== null ? formatter(lastValue.y0) : null,
-          y1: isSeriesVisible && lastValue && lastValue.y1 !== null ? formatter(lastValue.y1) : null,
+          y0: lastValue && lastValue.y0 !== null ? formatter(lastValue.y0) : null,
+          y1: lastValue && lastValue.y1 !== null ? formatter(lastValue.y1) : null,
         },
       },
       ...getPostfix(spec),
diff --git a/src/chart_types/xy_chart/renderer/_index.scss b/src/chart_types/xy_chart/renderer/_index.scss
new file mode 100644
index 0000000000..57d9fadc19
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/_index.scss
@@ -0,0 +1 @@
+@import 'dom/index';
diff --git a/src/components/react_canvas/area_geometries.tsx b/src/chart_types/xy_chart/renderer/canvas/area_geometries.tsx
similarity index 92%
rename from src/components/react_canvas/area_geometries.tsx
rename to src/chart_types/xy_chart/renderer/canvas/area_geometries.tsx
index 0ae752443c..e5d0f0bb24 100644
--- a/src/components/react_canvas/area_geometries.tsx
+++ b/src/chart_types/xy_chart/renderer/canvas/area_geometries.tsx
@@ -1,26 +1,19 @@
 import React from 'react';
 import { Group as KonvaGroup, PathConfig } from 'konva';
 import { Circle, Group, Path } from 'react-konva';
-
-import { LegendItem } from '../../chart_types/xy_chart/legend/legend';
-import {
-  AreaGeometry,
-  getGeometryStateStyle,
-  PointGeometry,
-  getGeometryIdKey,
-  GeometryId,
-} from '../../chart_types/xy_chart/rendering/rendering';
-import { SharedGeometryStateStyle, PointStyle } from '../../utils/themes/theme';
 import {
   buildAreaRenderProps,
   buildPointStyleProps,
   buildPointRenderProps,
   PointStyleProps,
   buildLineRenderProps,
-  Clippings,
-  clipRanges,
 } from './utils/rendering_props_utils';
-import { mergePartial } from '../../utils/commons';
+import { getGeometryIdKey, getGeometryStateStyle } from '../../rendering/rendering';
+import { mergePartial } from '../../../../utils/commons';
+import { AreaGeometry, PointGeometry, GeometryId } from '../../../../utils/geometry';
+import { PointStyle, SharedGeometryStateStyle } from '../../../../utils/themes/theme';
+import { LegendItem } from '../../legend/legend';
+import { Clippings, clipRanges } from './bar_values_utils';
 
 interface AreaGeometriesDataProps {
   animated?: boolean;
diff --git a/src/components/react_canvas/axis.tsx b/src/chart_types/xy_chart/renderer/canvas/axis.tsx
similarity index 63%
rename from src/components/react_canvas/axis.tsx
rename to src/chart_types/xy_chart/renderer/canvas/axis.tsx
index 54af603190..47d21d14c8 100644
--- a/src/components/react_canvas/axis.tsx
+++ b/src/chart_types/xy_chart/renderer/canvas/axis.tsx
@@ -9,13 +9,24 @@ import {
   getVerticalAxisTickLineProps,
   isHorizontalAxis,
   isVerticalAxis,
-} from '../../chart_types/xy_chart/utils/axis_utils';
-import { AxisSpec, Position } from '../../chart_types/xy_chart/utils/specs';
-import { Theme } from '../../utils/themes/theme';
-import { Dimensions } from '../../utils/dimensions';
+} from '../../utils/axis_utils';
+import { AxisSpec, Position } from '../../utils/specs';
+import { Theme } from '../../../../utils/themes/theme';
+import { Dimensions } from '../../../../utils/dimensions';
+import { connect } from 'react-redux';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { computeAxisVisibleTicksSelector } from '../../state/selectors/compute_axis_visible_ticks';
+import { getAxisSpecsSelector } from '../../state/selectors/get_specs';
+import { AxisId } from '../../../../utils/ids';
+import { computeAxisTicksDimensionsSelector } from '../../state/selectors/compute_axis_ticks_dimensions';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { computeChartDimensionsSelector } from '../../state/selectors/compute_chart_dimensions';
+import { LIGHT_THEME } from '../../../../utils/themes/light_theme';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getSpecsById } from '../../state/utils';
 
 interface AxisProps {
-  chartTheme: Theme;
+  theme: Theme;
   axisSpec: AxisSpec;
   axisTicksDimensions: AxisTicksDimensions;
   axisPosition: Dimensions;
@@ -25,70 +36,6 @@ interface AxisProps {
 }
 
 export class Axis extends React.PureComponent<AxisProps> {
-  render() {
-    return this.renderAxis();
-  }
-
-  private renderAxis = () => {
-    const { ticks, axisPosition, debug } = this.props;
-    return (
-      <Group x={axisPosition.left} y={axisPosition.top}>
-        {debug && (
-          <Rect
-            x={0}
-            y={0}
-            width={axisPosition.width}
-            height={axisPosition.height}
-            stroke="black"
-            strokeWidth={1}
-            fill="violet"
-            opacity={0.2}
-          />
-        )}
-        <Group key="lines">{this.renderAxisLine()}</Group>
-        <Group key="tick-lines">{ticks.map(this.renderTickLine)}</Group>
-        <Group key="ticks">{ticks.filter((tick) => tick.label !== null).map(this.renderTickLabel)}</Group>
-        {this.renderAxisTitle()}
-      </Group>
-    );
-  };
-  private renderAxisLine = () => {
-    const {
-      axisSpec: { position },
-      axisPosition,
-      chartTheme: {
-        axes: { axisLineStyle },
-      },
-    } = this.props;
-    const lineProps: number[] = [];
-    if (isVerticalAxis(position)) {
-      lineProps[0] = position === Position.Left ? axisPosition.width : 0;
-      lineProps[2] = position === Position.Left ? axisPosition.width : 0;
-      lineProps[1] = 0;
-      lineProps[3] = axisPosition.height;
-    } else {
-      lineProps[0] = 0;
-      lineProps[2] = axisPosition.width;
-      lineProps[1] = position === Position.Top ? axisPosition.height : 0;
-      lineProps[3] = position === Position.Top ? axisPosition.height : 0;
-    }
-    return <Line points={lineProps} {...axisLineStyle} />;
-  };
-  private renderTickLine = (tick: AxisTick, i: number) => {
-    const {
-      axisSpec: { tickSize, position },
-      axisPosition,
-      chartTheme: {
-        axes: { tickLineStyle },
-      },
-    } = this.props;
-
-    const lineProps = isVerticalAxis(position)
-      ? getVerticalAxisTickLineProps(position, axisPosition.width, tickSize, tick.position)
-      : getHorizontalAxisTickLineProps(position, axisPosition.height, tickSize, tick.position);
-
-    return <Line {...tickLineStyle} key={`tick-${i}`} points={lineProps} />;
-  };
   private renderTickLabel = (tick: AxisTick, i: number) => {
     /**
      * padding is already computed through width
@@ -96,7 +43,7 @@ export class Axis extends React.PureComponent<AxisProps> {
      * set padding to 0 to avoid conflict
      */
     const labelStyle = {
-      ...this.props.chartTheme.axes.tickLabelStyle,
+      ...this.props.theme.axes.tickLabelStyle,
       padding: 0,
     };
 
@@ -141,6 +88,46 @@ export class Axis extends React.PureComponent<AxisProps> {
       </Group>
     );
   };
+
+  private renderTickLine = (tick: AxisTick, i: number) => {
+    const {
+      axisSpec: { tickSize, position },
+      axisPosition,
+      theme: {
+        axes: { tickLineStyle },
+      },
+    } = this.props;
+
+    const lineProps = isVerticalAxis(position)
+      ? getVerticalAxisTickLineProps(position, axisPosition.width, tickSize, tick.position)
+      : getHorizontalAxisTickLineProps(position, axisPosition.height, tickSize, tick.position);
+
+    return <Line {...tickLineStyle} key={`tick-${i}`} points={lineProps} />;
+  };
+
+  private renderAxisLine = () => {
+    const {
+      axisSpec: { position },
+      axisPosition,
+      theme: {
+        axes: { axisLineStyle },
+      },
+    } = this.props;
+    const lineProps: number[] = [];
+    if (isVerticalAxis(position)) {
+      lineProps[0] = position === Position.Left ? axisPosition.width : 0;
+      lineProps[2] = position === Position.Left ? axisPosition.width : 0;
+      lineProps[1] = 0;
+      lineProps[3] = axisPosition.height;
+    } else {
+      lineProps[0] = 0;
+      lineProps[2] = axisPosition.width;
+      lineProps[1] = position === Position.Top ? axisPosition.height : 0;
+      lineProps[3] = position === Position.Top ? axisPosition.height : 0;
+    }
+    return <Line points={lineProps} {...axisLineStyle} />;
+  };
+
   private renderAxisTitle() {
     const {
       axisSpec: { title, position },
@@ -158,7 +145,7 @@ export class Axis extends React.PureComponent<AxisProps> {
       axisPosition: { height },
       axisSpec: { title, position, tickSize, tickPadding },
       axisTicksDimensions: { maxLabelBboxWidth },
-      chartTheme: {
+      theme: {
         axes: { axisTitleStyle },
       },
       debug,
@@ -194,7 +181,7 @@ export class Axis extends React.PureComponent<AxisProps> {
       axisPosition: { width, height },
       axisSpec: { title, position, tickSize, tickPadding },
       axisTicksDimensions: { maxLabelBboxHeight },
-      chartTheme: {
+      theme: {
         axes: {
           axisTitleStyle: { padding, ...titleStyle },
         },
@@ -227,4 +214,104 @@ export class Axis extends React.PureComponent<AxisProps> {
       </Group>
     );
   }
+  render() {
+    const { ticks, axisPosition, debug } = this.props;
+    return (
+      <Group x={axisPosition.left} y={axisPosition.top}>
+        {debug && (
+          <Rect
+            x={0}
+            y={0}
+            width={axisPosition.width}
+            height={axisPosition.height}
+            stroke="black"
+            strokeWidth={1}
+            fill="violet"
+            opacity={0.2}
+          />
+        )}
+        <Group key="lines">{this.renderAxisLine()}</Group>
+        <Group key="tick-lines">{ticks.map(this.renderTickLine)}</Group>
+        <Group key="ticks">{ticks.filter((tick) => tick.label !== null).map(this.renderTickLabel)}</Group>
+        {this.renderAxisTitle()}
+      </Group>
+    );
+  }
 }
+
+interface AxesProps {
+  axesVisibleTicks: Map<AxisId, AxisTick[]>;
+  axesSpecs: AxisSpec[];
+  axesTicksDimensions: Map<AxisId, AxisTicksDimensions>;
+  axesPositions: Map<string, Dimensions>;
+  theme: Theme;
+  debug: boolean;
+  chartDimensions: Dimensions;
+}
+class AxesComponent extends React.PureComponent<AxesProps> {
+  render() {
+    const {
+      axesVisibleTicks,
+      axesSpecs,
+      axesTicksDimensions,
+      axesPositions,
+      theme,
+      debug,
+      chartDimensions,
+    } = this.props;
+    const axesComponents: JSX.Element[] = [];
+    axesVisibleTicks.forEach((axisTicks, axisId) => {
+      const axisSpec = getSpecsById<AxisSpec>(axesSpecs, axisId);
+      const axisTicksDimensions = axesTicksDimensions.get(axisId);
+      const axisPosition = axesPositions.get(axisId);
+      const ticks = axesVisibleTicks.get(axisId);
+      if (!ticks || !axisSpec || !axisTicksDimensions || !axisPosition) {
+        return;
+      }
+      axesComponents.push(
+        <Axis
+          key={`axis-${axisId}`}
+          axisSpec={axisSpec}
+          axisTicksDimensions={axisTicksDimensions}
+          axisPosition={axisPosition}
+          ticks={ticks}
+          theme={theme}
+          debug={debug}
+          chartDimensions={chartDimensions}
+        />,
+      );
+    });
+    return axesComponents;
+  }
+}
+
+const mapStateToProps = (state: GlobalChartState): AxesProps => {
+  if (!state.specsInitialized) {
+    return {
+      theme: LIGHT_THEME,
+      chartDimensions: {
+        width: 0,
+        left: 0,
+        top: 0,
+        height: 0,
+      },
+      debug: false,
+      axesSpecs: [],
+      axesPositions: new Map(),
+      axesTicksDimensions: new Map(),
+      axesVisibleTicks: new Map(),
+    };
+  }
+  const axisTickPositions = computeAxisVisibleTicksSelector(state);
+  return {
+    theme: getChartThemeSelector(state),
+    chartDimensions: computeChartDimensionsSelector(state).chartDimensions,
+    debug: getSettingsSpecSelector(state).debug,
+    axesPositions: axisTickPositions.axisPositions,
+    axesSpecs: getAxisSpecsSelector(state),
+    axesTicksDimensions: computeAxisTicksDimensionsSelector(state),
+    axesVisibleTicks: axisTickPositions.axisVisibleTicks,
+  };
+};
+
+export const Axes = connect(mapStateToProps)(AxesComponent);
diff --git a/src/components/react_canvas/bar_geometries.tsx b/src/chart_types/xy_chart/renderer/canvas/bar_geometries.tsx
similarity index 89%
rename from src/components/react_canvas/bar_geometries.tsx
rename to src/chart_types/xy_chart/renderer/canvas/bar_geometries.tsx
index 646decef6b..4fa7cd11c7 100644
--- a/src/components/react_canvas/bar_geometries.tsx
+++ b/src/chart_types/xy_chart/renderer/canvas/bar_geometries.tsx
@@ -2,10 +2,12 @@ import { Group as KonvaGroup } from 'konva';
 import React from 'react';
 import { Group, Rect } from 'react-konva';
 import { animated, Spring } from 'react-spring/renderprops-konva.cjs';
-import { LegendItem } from '../../chart_types/xy_chart/legend/legend';
-import { BarGeometry, getGeometryStateStyle } from '../../chart_types/xy_chart/rendering/rendering';
-import { SharedGeometryStateStyle } from '../../utils/themes/theme';
-import { buildBarRenderProps, buildBarBorderRenderProps, Clippings } from './utils/rendering_props_utils';
+import { buildBarRenderProps, buildBarBorderRenderProps } from './utils/rendering_props_utils';
+import { BarGeometry } from '../../../../utils/geometry';
+import { LegendItem } from '../../../../chart_types/xy_chart/legend/legend';
+import { SharedGeometryStateStyle } from '../../../../utils/themes/theme';
+import { getGeometryStateStyle } from '../../rendering/rendering';
+import { Clippings } from './bar_values_utils';
 
 interface BarGeometriesDataProps {
   animated?: boolean;
diff --git a/src/chart_types/xy_chart/renderer/canvas/bar_values.tsx b/src/chart_types/xy_chart/renderer/canvas/bar_values.tsx
new file mode 100644
index 0000000000..e515cf0ef3
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/canvas/bar_values.tsx
@@ -0,0 +1,103 @@
+import React from 'react';
+import { Group, Rect, Text } from 'react-konva';
+import { Rotation } from '../../utils/specs';
+import { Theme } from '../../../../utils/themes/theme';
+import { Dimensions } from '../../../../utils/dimensions';
+import { BarGeometry } from '../../../../utils/geometry';
+import { buildBarValueProps } from './bar_values_utils';
+import { connect } from 'react-redux';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { computeChartDimensionsSelector } from '../../state/selectors/compute_chart_dimensions';
+import { getChartRotationSelector } from '../../../../state/selectors/get_chart_rotation';
+import { computeSeriesGeometriesSelector } from '../../state/selectors/compute_series_geometries';
+import { LIGHT_THEME } from '../../../../utils/themes/light_theme';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+
+interface BarValuesProps {
+  theme: Theme;
+  chartDimensions: Dimensions;
+  chartRotation: Rotation;
+  debug: boolean;
+  bars: BarGeometry[];
+}
+
+export class BarValuesComponent extends React.PureComponent<BarValuesProps> {
+  render() {
+    const { chartDimensions, bars } = this.props;
+    if (!bars) {
+      return;
+    }
+
+    return (
+      <Group x={chartDimensions.left} y={chartDimensions.top}>
+        {this.renderBarValues()}
+      </Group>
+    );
+  }
+
+  private renderBarValues = () => {
+    const { bars, debug, chartRotation, chartDimensions, theme } = this.props;
+    const displayValueStyle = theme.barSeriesStyle.displayValue;
+
+    return bars.map((bar, index) => {
+      const { displayValue, x, y, height, width } = bar;
+      if (!displayValue) {
+        return;
+      }
+
+      const key = `bar-value-${index}`;
+      const displayValueProps = buildBarValueProps({
+        x,
+        y,
+        barHeight: height,
+        barWidth: width,
+        displayValueStyle,
+        displayValue,
+        chartRotation,
+        chartDimensions,
+      });
+
+      const debugProps = {
+        ...displayValueProps,
+        stroke: 'violet',
+        strokeWidth: 1,
+        fill: 'transparent',
+      };
+
+      return (
+        <Group key={key}>
+          {debug && <Rect {...debugProps} />}
+          {displayValue && <Text {...displayValueProps} />}
+        </Group>
+      );
+    });
+  };
+}
+
+const mapStateToProps = (state: GlobalChartState): BarValuesProps => {
+  if (!state.specsInitialized) {
+    return {
+      theme: LIGHT_THEME,
+      chartDimensions: {
+        width: 0,
+        left: 0,
+        top: 0,
+        height: 0,
+      },
+      chartRotation: 0,
+      debug: false,
+      bars: [],
+    };
+  }
+  const geometries = computeSeriesGeometriesSelector(state);
+  return {
+    theme: getChartThemeSelector(state),
+    chartDimensions: computeChartDimensionsSelector(state).chartDimensions,
+    chartRotation: getChartRotationSelector(state),
+    debug: getSettingsSpecSelector(state).debug,
+    bars: geometries.geometries.bars,
+  };
+};
+
+export const BarValues = connect(mapStateToProps)(BarValuesComponent);
diff --git a/src/components/react_canvas/utils/rendering_props_utils.ts b/src/chart_types/xy_chart/renderer/canvas/bar_values_utils.ts
similarity index 56%
rename from src/components/react_canvas/utils/rendering_props_utils.ts
rename to src/chart_types/xy_chart/renderer/canvas/bar_values_utils.ts
index 0c320da9d2..7672b1da39 100644
--- a/src/components/react_canvas/utils/rendering_props_utils.ts
+++ b/src/chart_types/xy_chart/renderer/canvas/bar_values_utils.ts
@@ -1,19 +1,9 @@
-import { RectConfig, PathConfig, CircleConfig, ContainerConfig } from 'konva';
 import { Required } from 'utility-types';
-
-import { ClippedRanges } from '../../../chart_types/xy_chart/rendering/rendering';
-import { Rotation } from '../../../chart_types/xy_chart/utils/specs';
-import {
-  AreaStyle,
-  DisplayValueStyle,
-  LineStyle,
-  PointStyle,
-  RectBorderStyle,
-  RectStyle,
-  GeometryStateStyle,
-} from '../../../utils/themes/theme';
-import { Dimensions } from '../../../utils/dimensions';
-import { GlobalKonvaElementProps } from '../globals';
+import { Rotation } from '../../utils/specs';
+import { Dimensions } from '../../../../utils/dimensions';
+import { DisplayValueStyle } from '../../../../utils/themes/theme';
+import { ContainerConfig } from 'konva';
+import { ClippedRanges } from '../../../../utils/geometry';
 
 export interface PointStyleProps {
   radius: number;
@@ -107,40 +97,6 @@ export function rotateBarValueProps(
   return props;
 }
 
-export function getBarValueClipDimensions(
-  displayValue: { width: number; height: number; isValueContainedInElement?: boolean },
-  computedDimensions: { width: number; height: number },
-  barHeight: number,
-  chartRotation: Rotation,
-): { width: number; height: number; offsetX: number; offsetY: number } {
-  const height = displayValue.isValueContainedInElement ? displayValue.height : computedDimensions.height;
-  const width = displayValue.isValueContainedInElement ? displayValue.width : computedDimensions.width;
-
-  const offsetY = chartRotation === 180 ? barHeight - displayValue.height : 0;
-  const offsetX = chartRotation === 90 ? barHeight - displayValue.width : 0;
-
-  return { height, width, offsetX, offsetY };
-}
-
-export function isBarValueOverflow(
-  chartDimensions: Dimensions,
-  clip: { width: number; height: number; offsetX: number; offsetY: number },
-  valuePosition: { x: number; y: number; offsetX: number; offsetY: number },
-  hideClippedValue?: boolean,
-): boolean {
-  const chartHeight = chartDimensions.height;
-  const chartWidth = chartDimensions.width;
-
-  const isOverflowX =
-    valuePosition.x + clip.width - valuePosition.offsetX > chartWidth ||
-    valuePosition.x + clip.offsetX - valuePosition.offsetX < 0;
-  const isOverflowY =
-    valuePosition.y + clip.height - valuePosition.offsetY > chartHeight ||
-    valuePosition.y + clip.offsetY - valuePosition.offsetY < 0;
-
-  return !!hideClippedValue && (isOverflowX || isOverflowY);
-}
-
 export function buildBarValueProps({
   x,
   y,
@@ -240,186 +196,38 @@ export function buildBarValueProps({
   return props;
 }
 
-/**
- * Return the style of a point.
- * The color value is used for stroke or fill if they are undefind in the PointStyle
- * @param color the series color
- * @param pointStyle the merged point style
- */
-export function buildPointStyleProps(
-  color: string,
-  pointStyle: PointStyle,
-  geometryStateStyle: GeometryStateStyle,
-): PointStyleProps {
-  const { strokeWidth, opacity } = pointStyle;
-  const stroke = pointStyle.stroke || color;
-  const fill = pointStyle.fill || color;
-  return {
-    radius: pointStyle.radius,
-    stroke,
-    strokeWidth,
-    strokeEnabled: strokeWidth !== 0,
-    fill: fill,
-    ...geometryStateStyle,
-    opacity: opacity * geometryStateStyle.opacity,
-  };
-}
-
-/**
- * Return the rendering props for a point
- * @param x the x position of the point
- * @param y the y position of the point
- * @param pointStyleProps the style props of the point
- */
-export function buildPointRenderProps(x: number, y: number, pointStyleProps: PointStyleProps): CircleConfig {
-  return {
-    x,
-    y,
-    ...pointStyleProps,
-    ...GlobalKonvaElementProps,
-  };
-}
+export function getBarValueClipDimensions(
+  displayValue: { width: number; height: number; isValueContainedInElement?: boolean },
+  computedDimensions: { width: number; height: number },
+  barHeight: number,
+  chartRotation: Rotation,
+): { width: number; height: number; offsetX: number; offsetY: number } {
+  const height = displayValue.isValueContainedInElement ? displayValue.height : computedDimensions.height;
+  const width = displayValue.isValueContainedInElement ? displayValue.width : computedDimensions.width;
 
-/**
- * Return the rendering props for a line. The color of the line will be overwritten
- * by the stroke color of the lineStyle parameter if present
- * @param x the horizontal offset to place the line
- * @param linePath the SVG line path
- * @param color the computed color of the line for this series
- * @param lineStyle the line style
- * @param geometryStateStyle the highlight geometry style
- */
-export function buildLineRenderProps(
-  x: number,
-  linePath: string,
-  color: string,
-  lineStyle: LineStyle,
-  geometryStateStyle: GeometryStateStyle,
-): PathConfig {
-  const opacity = lineStyle.opacity * geometryStateStyle.opacity;
-
-  return {
-    x,
-    data: linePath,
-    stroke: lineStyle.stroke || color,
-    strokeWidth: lineStyle.strokeWidth,
-    lineCap: 'round',
-    lineJoin: 'round',
-    ...geometryStateStyle,
-    opacity, // want to override opactiy of geometryStateStyle
-    ...GlobalKonvaElementProps,
-  };
-}
+  const offsetY = chartRotation === 180 ? barHeight - displayValue.height : 0;
+  const offsetX = chartRotation === 90 ? barHeight - displayValue.width : 0;
 
-/**
- * Return the rendering props for an area. The color of the area will be overwritten
- * by the fill color of the areaStyle parameter if present
- * @param areaPath the SVG area path
- * @param x the horizontal offset to place the area
- * @param color the computed color of the line for this series
- * @param areaStyle the area style
- * @param geometryStateStyle the highlight geometry style
- */
-export function buildAreaRenderProps(
-  xTransform: number,
-  areaPath: string,
-  color: string,
-  areaStyle: AreaStyle,
-  geometryStateStyle: GeometryStateStyle,
-): PathConfig {
-  const opacity = areaStyle.opacity * geometryStateStyle.opacity;
-
-  return {
-    x: xTransform,
-    data: areaPath,
-    fill: areaStyle.fill || color,
-    lineCap: 'round',
-    lineJoin: 'round',
-    ...geometryStateStyle,
-    opacity, // want to override opactiy of geometryStateStyle
-    ...GlobalKonvaElementProps,
-  };
+  return { height, width, offsetX, offsetY };
 }
 
-/**
- * Return the rendering props for a bar. The color of the bar will be overwritten
- * by the fill color of the rectStyle parameter if present
- * @param x the x position of the rect
- * @param y the y position of the rect
- * @param width the width of the rect
- * @param height the height of the rect
- * @param color the computed color of the rect for this series
- * @param rectStyle the rect style
- * @param geometryStateStyle the highlight geometry style
- */
-export function buildBarRenderProps(
-  x: number,
-  y: number,
-  width: number,
-  height: number,
-  color: string,
-  rectStyle: RectStyle,
-  borderStyle: RectBorderStyle,
-  geometryStateStyle: GeometryStateStyle,
-): RectConfig {
-  const opacity = rectStyle.opacity * geometryStateStyle.opacity;
-  const { stroke, visible, strokeWidth, strokeOpacity = 0 } = borderStyle;
-  const offset = !visible || strokeWidth <= 0 || !stroke || strokeOpacity <= 0 || opacity <= 0 ? 0 : strokeWidth;
-
-  return {
-    x: x + offset,
-    y: y + offset,
-    width: width - 2 * offset,
-    height: height - 2 * offset,
-    fill: rectStyle.fill || color,
-    strokeEnabled: false,
-    ...geometryStateStyle,
-    opacity, // want to override opactiy of geometryStateStyle
-    ...GlobalKonvaElementProps,
-  };
-}
+export function isBarValueOverflow(
+  chartDimensions: Dimensions,
+  clip: { width: number; height: number; offsetX: number; offsetY: number },
+  valuePosition: { x: number; y: number; offsetX: number; offsetY: number },
+  hideClippedValue?: boolean,
+): boolean {
+  const chartHeight = chartDimensions.height;
+  const chartWidth = chartDimensions.width;
 
-/**
- * Return the rendering props for a bar. The color of the bar will be overwritten
- * by the fill color of the rectStyle parameter if present
- * @param x the x position of the rect
- * @param y the y position of the rect
- * @param width the width of the rect
- * @param height the height of the rect
- * @param color the computed color of the rect for this series
- * @param rectStyle the rect style
- * @param borderStyle the border rect style
- * @param geometryStateStyle the highlight geometry style
- */
-export function buildBarBorderRenderProps(
-  x: number,
-  y: number,
-  width: number,
-  height: number,
-  rectStyle: RectStyle,
-  borderStyle: RectBorderStyle,
-  geometryStateStyle: GeometryStateStyle,
-): RectConfig | null {
-  const { stroke, visible, strokeWidth, strokeOpacity = rectStyle.opacity } = borderStyle;
-  const opacity = strokeOpacity * geometryStateStyle.opacity;
-
-  if (!visible || strokeWidth <= 0 || !stroke || opacity <= 0) {
-    return null;
-  }
+  const isOverflowX =
+    valuePosition.x + clip.width - valuePosition.offsetX > chartWidth ||
+    valuePosition.x + clip.offsetX - valuePosition.offsetX < 0;
+  const isOverflowY =
+    valuePosition.y + clip.height - valuePosition.offsetY > chartHeight ||
+    valuePosition.y + clip.offsetY - valuePosition.offsetY < 0;
 
-  return {
-    x: x + strokeWidth / 2,
-    y: y + strokeWidth / 2,
-    width: width - strokeWidth,
-    height: height - strokeWidth,
-    fillEnabled: false,
-    strokeEnabled: true,
-    strokeWidth,
-    stroke,
-    ...geometryStateStyle,
-    opacity, // want to override opactiy of geometryStateStyle
-    ...GlobalKonvaElementProps,
-  };
+  return !!hideClippedValue && (isOverflowX || isOverflowY);
 }
 
 /**
diff --git a/src/chart_types/xy_chart/renderer/canvas/grid.tsx b/src/chart_types/xy_chart/renderer/canvas/grid.tsx
new file mode 100644
index 0000000000..5b4976fc86
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/canvas/grid.tsx
@@ -0,0 +1,78 @@
+import React from 'react';
+import { Group, Line } from 'react-konva';
+import { connect } from 'react-redux';
+import { AxisLinePosition, isVerticalGrid } from '../../utils/axis_utils';
+import { GridLineConfig, mergeGridLineConfigs, Theme } from '../../../../utils/themes/theme';
+import { Dimensions } from '../../../../utils/dimensions';
+import { AxisId } from '../../../../utils/ids';
+import { AxisSpec } from '../../../../chart_types/xy_chart/utils/specs';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { computeChartDimensionsSelector } from '../../state/selectors/compute_chart_dimensions';
+import { getAxisSpecsSelector } from '../../state/selectors/get_specs';
+import { computeAxisVisibleTicksSelector } from '../../state/selectors/compute_axis_visible_ticks';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { LIGHT_THEME } from '../../../../utils/themes/light_theme';
+import { getSpecsById } from '../../state/utils';
+
+interface GridProps {
+  chartTheme: Theme;
+  axesGridLinesPositions: Map<AxisId, AxisLinePosition[]>;
+  axesSpecs: AxisSpec[];
+  chartDimensions: Dimensions;
+}
+
+class GridComponent extends React.PureComponent<GridProps> {
+  render() {
+    const { axesGridLinesPositions, axesSpecs, chartDimensions, chartTheme } = this.props;
+    const gridComponents: JSX.Element[] = [];
+    axesGridLinesPositions.forEach((axisGridLinesPositions, axisId) => {
+      const axisSpec = getSpecsById<AxisSpec>(axesSpecs, axisId);
+      if (axisSpec && axisGridLinesPositions.length > 0) {
+        const themeConfig = isVerticalGrid(axisSpec.position)
+          ? chartTheme.axes.gridLineStyle.vertical
+          : chartTheme.axes.gridLineStyle.horizontal;
+
+        const axisSpecConfig = axisSpec.gridLineStyle;
+        const gridLineStyle = axisSpecConfig ? mergeGridLineConfigs(axisSpecConfig, themeConfig) : themeConfig;
+        gridComponents.push(
+          <Group key={`axis-grid-${axisId}`} x={chartDimensions.left} y={chartDimensions.top}>
+            <Group key="grid-lines">
+              {axisGridLinesPositions.map((linePosition, index) => {
+                return this.renderGridLine(linePosition, index, gridLineStyle);
+              })}
+            </Group>
+          </Group>,
+        );
+      }
+    });
+
+    return gridComponents;
+  }
+  private renderGridLine = (linePosition: AxisLinePosition, i: number, gridLineStyle?: GridLineConfig) => {
+    return <Line {...gridLineStyle} key={`tick-${i}`} points={linePosition} />;
+  };
+}
+
+const mapStateToProps = (state: GlobalChartState): GridProps => {
+  if (!state.specsInitialized) {
+    return {
+      chartTheme: LIGHT_THEME,
+      chartDimensions: {
+        width: 0,
+        left: 0,
+        top: 0,
+        height: 0,
+      },
+      axesSpecs: [],
+      axesGridLinesPositions: new Map(),
+    };
+  }
+  return {
+    chartTheme: getChartThemeSelector(state),
+    chartDimensions: computeChartDimensionsSelector(state).chartDimensions,
+    axesSpecs: getAxisSpecsSelector(state),
+    axesGridLinesPositions: computeAxisVisibleTicksSelector(state).axisGridLinesPositions,
+  };
+};
+
+export const Grid = connect(mapStateToProps)(GridComponent);
diff --git a/src/components/react_canvas/line_annotation.tsx b/src/chart_types/xy_chart/renderer/canvas/line_annotation.tsx
similarity index 61%
rename from src/components/react_canvas/line_annotation.tsx
rename to src/chart_types/xy_chart/renderer/canvas/line_annotation.tsx
index 92540a68fa..1853e197bf 100644
--- a/src/components/react_canvas/line_annotation.tsx
+++ b/src/chart_types/xy_chart/renderer/canvas/line_annotation.tsx
@@ -1,21 +1,20 @@
 import React from 'react';
 import { Group, Line } from 'react-konva';
-import { LineAnnotationStyle } from '../../utils/themes/theme';
-import { Dimensions } from '../../utils/dimensions';
-import { AnnotationLineProps } from '../../chart_types/xy_chart/annotations/annotation_utils';
+import { LineAnnotationStyle } from '../../../../utils/themes/theme';
+import { AnnotationLineProps } from '../../annotations/line_annotation_tooltip';
 
 interface LineAnnotationProps {
-  chartDimensions: Dimensions;
-  debug: boolean;
   lines: AnnotationLineProps[];
   lineStyle: LineAnnotationStyle;
 }
 
 export class LineAnnotation extends React.PureComponent<LineAnnotationProps> {
   render() {
-    return this.renderAnnotation();
+    const { lines } = this.props;
+
+    return <Group>{lines.map(this.renderAnnotationLine)}</Group>;
   }
-  private renderAnnotationLine = (lineConfig: AnnotationLineProps, i: number) => {
+  private renderAnnotationLine = (lineConfig: AnnotationLineProps, index: number) => {
     const { line } = this.props.lineStyle;
     const {
       start: { x1, y1 },
@@ -25,13 +24,6 @@ export class LineAnnotation extends React.PureComponent<LineAnnotationProps> {
       points: [x1, y1, x2, y2],
       ...line,
     };
-
-    return <Line {...lineProps} key={`tick-${i}`} />;
-  };
-
-  private renderAnnotation = () => {
-    const { lines } = this.props;
-
-    return <Group>{lines.map(this.renderAnnotationLine)}</Group>;
+    return <Line {...lineProps} key={`annotation-line-${index}`} />;
   };
 }
diff --git a/src/components/react_canvas/line_geometries.tsx b/src/chart_types/xy_chart/renderer/canvas/line_geometries.tsx
similarity index 89%
rename from src/components/react_canvas/line_geometries.tsx
rename to src/chart_types/xy_chart/renderer/canvas/line_geometries.tsx
index 20799e5207..f17e7c65d5 100644
--- a/src/components/react_canvas/line_geometries.tsx
+++ b/src/chart_types/xy_chart/renderer/canvas/line_geometries.tsx
@@ -1,23 +1,18 @@
-import { Group as KonvaGroup } from 'konva';
 import React from 'react';
+import { Group as KonvaGroup } from 'konva';
 import { Circle, Group, Path } from 'react-konva';
-import { LegendItem } from '../../chart_types/xy_chart/legend/legend';
-import {
-  getGeometryStateStyle,
-  LineGeometry,
-  PointGeometry,
-  getGeometryIdKey,
-} from '../../chart_types/xy_chart/rendering/rendering';
-import { SharedGeometryStateStyle, PointStyle } from '../../utils/themes/theme';
 import {
   buildLineRenderProps,
   buildPointStyleProps,
   PointStyleProps,
   buildPointRenderProps,
-  Clippings,
-  clipRanges,
 } from './utils/rendering_props_utils';
-import { mergePartial } from '../../utils/commons';
+import { getGeometryIdKey, getGeometryStateStyle } from '../../rendering/rendering';
+import { mergePartial } from '../../../../utils/commons';
+import { LineGeometry, PointGeometry } from '../../../../utils/geometry';
+import { PointStyle, SharedGeometryStateStyle } from '../../../../utils/themes/theme';
+import { LegendItem } from '../../../../chart_types/xy_chart/legend/legend';
+import { Clippings, clipRanges } from './bar_values_utils';
 
 interface LineGeometriesDataProps {
   animated?: boolean;
diff --git a/src/chart_types/xy_chart/renderer/canvas/reactive_chart.tsx b/src/chart_types/xy_chart/renderer/canvas/reactive_chart.tsx
new file mode 100644
index 0000000000..c790d5b838
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/canvas/reactive_chart.tsx
@@ -0,0 +1,359 @@
+import React, { RefObject } from 'react';
+import { bindActionCreators, Dispatch } from 'redux';
+import { connect, ReactReduxContext, Provider } from 'react-redux';
+import { Layer, Rect, Stage } from 'react-konva';
+import { AreaGeometries } from './area_geometries';
+import { BarGeometries } from './bar_geometries';
+import { LineGeometries } from './line_geometries';
+import { LineAnnotation } from './line_annotation';
+import { RectAnnotation } from './rect_annotation';
+import { Grid } from './grid';
+import { Axes } from './axis';
+import { BarValues } from './bar_values';
+import { AnnotationDimensions } from '../../annotations/annotation_utils';
+import { AnnotationLineProps } from '../../annotations/line_annotation_tooltip';
+import { AnnotationRectProps } from '../../annotations/rect_annotation_tooltip';
+import { computeAnnotationDimensionsSelector } from '../../state/selectors/compute_annotations';
+import { computeChartTransformSelector } from '../../state/selectors/compute_chart_transform';
+import { getAnnotationSpecsSelector } from '../../state/selectors/get_specs';
+import { getHighlightedSeriesSelector } from '../../state/selectors/get_highlighted_series';
+import { isChartEmptySelector } from '../../state/selectors/is_chart_empty';
+import { isChartAnimatableSelector } from '../../state/selectors/is_chart_animatable';
+import { isBrushAvailableSelector } from '../../state/selectors/is_brush_available';
+import { Transform, getSpecsById, Geometries } from '../../state/utils';
+import { Rotation, AnnotationSpec, isLineAnnotation, isRectAnnotation } from '../../utils/specs';
+import { onChartRendered } from '../../../../state/actions/chart';
+import { isInitialized } from '../../../../state/selectors/is_initialized';
+import { getChartRotationSelector } from '../../../../state/selectors/get_chart_rotation';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { Dimensions } from '../../../../utils/dimensions';
+import { AnnotationId } from '../../../../utils/ids';
+import { Theme, mergeWithDefaultAnnotationLine, mergeWithDefaultAnnotationRect } from '../../../../utils/themes/theme';
+import { LIGHT_THEME } from '../../../../utils/themes/light_theme';
+import { computeSeriesGeometriesSelector } from '../../state/selectors/compute_series_geometries';
+import { LegendItem } from '../../../../chart_types/xy_chart/legend/legend';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { computeChartDimensionsSelector } from '../../state/selectors/compute_chart_dimensions';
+import { getChartContainerDimensionsSelector } from '../../../../state/selectors/get_chart_container_dimensions';
+import { Clippings } from './bar_values_utils';
+
+interface ReactiveChartStateProps {
+  initialized: boolean;
+  geometries: Geometries;
+  debug: boolean;
+  chartContainerDimensions: Dimensions;
+  chartRotation: Rotation;
+  chartDimensions: Dimensions;
+  chartTransform: Transform;
+  theme: Theme;
+  isChartAnimatable: boolean;
+  isChartEmpty: boolean;
+  annotationDimensions: Map<AnnotationId, AnnotationDimensions>;
+  annotationSpecs: AnnotationSpec[];
+  isBrushAvailable: boolean;
+  highlightedLegendItem?: LegendItem;
+}
+interface ReactiveChartDispatchProps {
+  onChartRendered: typeof onChartRendered;
+}
+interface ReactiveChartOwnProps {
+  forwardStageRef: RefObject<Stage>;
+}
+interface ReactiveChartElementIndex {
+  element: JSX.Element;
+  zIndex: number;
+}
+
+type ReactiveChartProps = ReactiveChartOwnProps & ReactiveChartStateProps & ReactiveChartDispatchProps;
+class Chart extends React.Component<ReactiveChartProps> {
+  static displayName = 'ReactiveChart';
+  firstRender = true;
+
+  componentDidUpdate() {
+    if (this.props.initialized) {
+      this.props.onChartRendered();
+    }
+  }
+  renderBarSeries = (clippings: Clippings): ReactiveChartElementIndex[] => {
+    const { geometries, theme, isChartAnimatable, highlightedLegendItem } = this.props;
+    if (geometries.bars.length === 0) {
+      return [];
+    }
+
+    const element = (
+      <BarGeometries
+        key={'bar-geometries'}
+        animated={isChartAnimatable}
+        bars={geometries.bars}
+        sharedStyle={theme.sharedStyle}
+        highlightedLegendItem={highlightedLegendItem}
+        clippings={clippings}
+      />
+    );
+
+    return [
+      {
+        element,
+        zIndex: 0,
+      },
+    ];
+  };
+
+  renderLineSeries = (clippings: Clippings): ReactiveChartElementIndex[] => {
+    const { geometries, theme, isChartAnimatable, highlightedLegendItem } = this.props;
+    if (geometries.lines.length === 0) {
+      return [];
+    }
+
+    const element = (
+      <LineGeometries
+        key={'line-geometries'}
+        animated={isChartAnimatable}
+        lines={geometries.lines}
+        sharedStyle={theme.sharedStyle}
+        highlightedLegendItem={highlightedLegendItem}
+        clippings={clippings}
+      />
+    );
+
+    return [
+      {
+        element,
+        zIndex: 0,
+      },
+    ];
+  };
+
+  renderAreaSeries = (clippings: Clippings): ReactiveChartElementIndex[] => {
+    const { geometries, theme, isChartAnimatable, highlightedLegendItem } = this.props;
+    if (geometries.areas.length === 0) {
+      return [];
+    }
+    const element = (
+      <AreaGeometries
+        key={'area-geometries'}
+        animated={isChartAnimatable}
+        areas={geometries.areas}
+        sharedStyle={theme.sharedStyle}
+        highlightedLegendItem={highlightedLegendItem}
+        clippings={clippings}
+      />
+    );
+
+    return [
+      {
+        element,
+        zIndex: 0,
+      },
+    ];
+  };
+
+  renderAnnotations = (): ReactiveChartElementIndex[] => {
+    const { annotationDimensions, annotationSpecs } = this.props;
+    const annotationElements: ReactiveChartElementIndex[] = [];
+
+    annotationDimensions.forEach((annotation: AnnotationDimensions, id: AnnotationId) => {
+      const spec = getSpecsById<AnnotationSpec>(annotationSpecs, id);
+
+      if (!spec) {
+        return;
+      }
+
+      if (isLineAnnotation(spec)) {
+        const lineStyle = mergeWithDefaultAnnotationLine(spec.style);
+        const element = (
+          <LineAnnotation
+            key={`line-annotation-group-${id}`}
+            lines={annotation as AnnotationLineProps[]}
+            lineStyle={lineStyle}
+          />
+        );
+        annotationElements.push({
+          element,
+          zIndex: spec.zIndex || 0,
+        });
+      } else if (isRectAnnotation(spec)) {
+        const rectStyle = mergeWithDefaultAnnotationRect(spec.style);
+        const element = (
+          <RectAnnotation
+            key={`rect-annotation-group-${id}`}
+            rects={annotation as AnnotationRectProps[]}
+            rectStyle={rectStyle}
+          />
+        );
+        annotationElements.push({
+          element,
+          zIndex: spec.zIndex || 0,
+        });
+      }
+    });
+    return annotationElements;
+  };
+
+  sortAndRenderElements() {
+    const { chartDimensions, chartRotation } = this.props;
+    const clippings = {
+      clipX: 0,
+      clipY: 0,
+      clipWidth: [90, -90].includes(chartRotation) ? chartDimensions.height : chartDimensions.width,
+      clipHeight: [90, -90].includes(chartRotation) ? chartDimensions.width : chartDimensions.height,
+    };
+
+    const bars = this.renderBarSeries(clippings);
+    const areas = this.renderAreaSeries(clippings);
+    const lines = this.renderLineSeries(clippings);
+    const annotations: ReactiveChartElementIndex[] = this.renderAnnotations();
+    return [...bars, ...areas, ...lines, ...annotations]
+      .sort((elemIdxA, elemIdxB) => elemIdxA.zIndex - elemIdxB.zIndex)
+      .map((elemIdx) => elemIdx.element);
+  }
+
+  render() {
+    const { initialized, chartRotation, chartDimensions, isChartEmpty, debug, chartContainerDimensions } = this.props;
+    if (!initialized || chartDimensions.width === 0 || chartDimensions.height === 0) {
+      return null;
+    }
+    const { chartTransform } = this.props;
+
+    if (isChartEmpty) {
+      return (
+        <div className="echReactiveChart_unavailable">
+          <p>No data to display</p>
+        </div>
+      );
+    }
+    const brushProps = {};
+    return (
+      <ReactReduxContext.Consumer>
+        {({ store }) => {
+          return (
+            <Stage
+              width={chartContainerDimensions.width}
+              height={chartContainerDimensions.height}
+              ref={this.props.forwardStageRef}
+              style={{
+                width: '100%',
+                height: '100%',
+              }}
+              {...brushProps}
+            >
+              <Provider store={store}>
+                <Layer hitGraphEnabled={false} listening={false}>
+                  <Grid />
+                  <Axes />
+                </Layer>
+              </Provider>
+              <Layer
+                x={chartDimensions.left + chartTransform.x}
+                y={chartDimensions.top + chartTransform.y}
+                rotation={chartRotation}
+                hitGraphEnabled={false}
+                listening={false}
+              >
+                {this.sortAndRenderElements()}
+              </Layer>
+              <Provider store={store}>
+                <Layer hitGraphEnabled={false} listening={false}>
+                  <BarValues />
+                </Layer>
+              </Provider>
+              {debug && (
+                <Layer hitGraphEnabled={false} listening={false}>
+                  {this.renderDebugChartBorders()}
+                </Layer>
+              )}
+            </Stage>
+          );
+        }}
+      </ReactReduxContext.Consumer>
+    );
+  }
+
+  private renderDebugChartBorders = () => {
+    const { chartDimensions } = this.props;
+    return (
+      <Rect
+        x={chartDimensions.left}
+        y={chartDimensions.top}
+        width={chartDimensions.width}
+        height={chartDimensions.height}
+        stroke="red"
+        strokeWidth={4}
+        listening={false}
+        dash={[4, 4]}
+      />
+    );
+  };
+}
+
+const mapDispatchToProps = (dispatch: Dispatch): ReactiveChartDispatchProps =>
+  bindActionCreators(
+    {
+      onChartRendered,
+    },
+    dispatch,
+  );
+
+const DEFAULT_PROPS: ReactiveChartStateProps = {
+  initialized: false,
+  theme: LIGHT_THEME,
+  geometries: {
+    areas: [],
+    bars: [],
+    lines: [],
+    points: [],
+  },
+  debug: false,
+  chartContainerDimensions: {
+    width: 0,
+    height: 0,
+    left: 0,
+    top: 0,
+  },
+  chartRotation: 0 as 0,
+  chartDimensions: {
+    width: 0,
+    height: 0,
+    left: 0,
+    top: 0,
+  },
+  chartTransform: {
+    x: 0,
+    y: 0,
+    rotate: 0,
+  },
+  isChartAnimatable: false,
+  isChartEmpty: true,
+  annotationDimensions: new Map(),
+  annotationSpecs: [],
+  isBrushAvailable: false,
+  highlightedLegendItem: undefined,
+};
+
+const mapStateToProps = (state: GlobalChartState): ReactiveChartStateProps => {
+  if (!isInitialized(state)) {
+    return DEFAULT_PROPS;
+  }
+  return {
+    initialized: true,
+    theme: getChartThemeSelector(state),
+    geometries: computeSeriesGeometriesSelector(state).geometries,
+    chartContainerDimensions: getChartContainerDimensionsSelector(state),
+    debug: getSettingsSpecSelector(state).debug,
+    chartRotation: getChartRotationSelector(state),
+    chartDimensions: computeChartDimensionsSelector(state).chartDimensions,
+    chartTransform: computeChartTransformSelector(state),
+    isChartAnimatable: isChartAnimatableSelector(state),
+    isChartEmpty: isChartEmptySelector(state),
+    annotationDimensions: computeAnnotationDimensionsSelector(state),
+    annotationSpecs: getAnnotationSpecsSelector(state),
+    isBrushAvailable: isBrushAvailableSelector(state),
+    highlightedLegendItem: getHighlightedSeriesSelector(state),
+  };
+};
+
+export const ReactiveChart = connect(
+  mapStateToProps,
+  mapDispatchToProps,
+)(Chart);
diff --git a/src/chart_types/xy_chart/renderer/canvas/rect_annotation.tsx b/src/chart_types/xy_chart/renderer/canvas/rect_annotation.tsx
new file mode 100644
index 0000000000..ff7753afa8
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/canvas/rect_annotation.tsx
@@ -0,0 +1,29 @@
+import React from 'react';
+import { Group, Rect } from 'react-konva';
+import { RectAnnotationStyle } from '../../../../utils/themes/theme';
+import { AnnotationRectProps } from '../../annotations/rect_annotation_tooltip';
+
+interface Props {
+  rects: AnnotationRectProps[];
+  rectStyle: RectAnnotationStyle;
+}
+
+export class RectAnnotation extends React.PureComponent<Props> {
+  render() {
+    const { rects } = this.props;
+    return <Group>{rects.map(this.renderAnnotationRect)}</Group>;
+  }
+  private renderAnnotationRect = ({ rect }: AnnotationRectProps, index: number) => {
+    const { x, y, width, height } = rect;
+
+    const rectProps = {
+      ...this.props.rectStyle,
+      x,
+      y,
+      width,
+      height,
+    };
+
+    return <Rect {...rectProps} key={`rect-annotation-${index}`} />;
+  };
+}
diff --git a/src/components/react_canvas/utils/rendering_props_utils.test.ts b/src/chart_types/xy_chart/renderer/canvas/utils/rendering_props_utils.test.ts
similarity index 98%
rename from src/components/react_canvas/utils/rendering_props_utils.test.ts
rename to src/chart_types/xy_chart/renderer/canvas/utils/rendering_props_utils.test.ts
index 581fab3cd7..5bf10a1a52 100644
--- a/src/components/react_canvas/utils/rendering_props_utils.test.ts
+++ b/src/chart_types/xy_chart/renderer/canvas/utils/rendering_props_utils.test.ts
@@ -1,21 +1,23 @@
-import { Rotation } from '../../../chart_types/xy_chart/utils/specs';
+import { Rotation } from '../../../utils/specs';
 import {
   buildAreaRenderProps,
   buildBarRenderProps,
-  buildBarValueProps,
   buildLineRenderProps,
   buildPointRenderProps,
-  getBarValueClipDimensions,
-  isBarValueOverflow,
-  rotateBarValueProps,
   buildPointStyleProps,
   buildBarBorderRenderProps,
+} from './rendering_props_utils';
+import { RectBorderStyle, RectStyle } from '../../../../../utils/themes/theme';
+import {
+  buildBarValueProps,
+  isBarValueOverflow,
+  getBarValueClipDimensions,
+  rotateBarValueProps,
   Clippings,
   clipRanges,
-} from './rendering_props_utils';
-import { RectBorderStyle, RectStyle } from '../../../utils/themes/theme';
-import { forcedType } from '../../../mocks/utils';
-import { ClippedRanges } from '../../../chart_types/xy_chart/rendering/rendering';
+} from '../bar_values_utils';
+import { ClippedRanges } from '../../../../../utils/geometry';
+import { forcedType } from '../../../../../mocks/utils';
 
 describe('[canvas] Area Geometries props', () => {
   test('can build area point props', () => {
diff --git a/src/chart_types/xy_chart/renderer/canvas/utils/rendering_props_utils.ts b/src/chart_types/xy_chart/renderer/canvas/utils/rendering_props_utils.ts
new file mode 100644
index 0000000000..99b34e0e75
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/canvas/utils/rendering_props_utils.ts
@@ -0,0 +1,201 @@
+import { RectConfig, PathConfig, CircleConfig } from 'konva';
+import {
+  AreaStyle,
+  LineStyle,
+  PointStyle,
+  RectBorderStyle,
+  RectStyle,
+  GeometryStateStyle,
+} from '../../../../../utils/themes/theme';
+import { GlobalKonvaElementProps } from '../../../../../components/react_canvas/globals';
+
+export interface PointStyleProps {
+  radius: number;
+  stroke: string;
+  strokeWidth: number;
+  strokeEnabled: boolean;
+  fill: string;
+  opacity: number;
+}
+
+/**
+ * Return the style of a point.
+ * The color value is used for stroke or fill if they are undefind in the PointStyle
+ * @param color the series color
+ * @param pointStyle the merged point style
+ */
+export function buildPointStyleProps(
+  color: string,
+  pointStyle: PointStyle,
+  geometryStateStyle: GeometryStateStyle,
+): PointStyleProps {
+  const { strokeWidth, opacity } = pointStyle;
+  const stroke = pointStyle.stroke || color;
+  const fill = pointStyle.fill || color;
+  return {
+    radius: pointStyle.radius,
+    stroke,
+    strokeWidth,
+    strokeEnabled: strokeWidth !== 0,
+    fill: fill,
+    ...geometryStateStyle,
+    opacity: opacity * geometryStateStyle.opacity,
+  };
+}
+
+/**
+ * Return the rendering props for a point
+ * @param x the x position of the point
+ * @param y the y position of the point
+ * @param pointStyleProps the style props of the point
+ */
+export function buildPointRenderProps(x: number, y: number, pointStyleProps: PointStyleProps): CircleConfig {
+  return {
+    x,
+    y,
+    ...pointStyleProps,
+    ...GlobalKonvaElementProps,
+  };
+}
+
+/**
+ * Return the rendering props for a line. The color of the line will be overwritten
+ * by the stroke color of the lineStyle parameter if present
+ * @param x the horizontal offset to place the line
+ * @param linePath the SVG line path
+ * @param color the computed color of the line for this series
+ * @param lineStyle the line style
+ * @param geometryStateStyle the highlight geometry style
+ */
+export function buildLineRenderProps(
+  x: number,
+  linePath: string,
+  color: string,
+  lineStyle: LineStyle,
+  geometryStateStyle: GeometryStateStyle,
+): PathConfig {
+  const opacity = lineStyle.opacity * geometryStateStyle.opacity;
+
+  return {
+    x,
+    data: linePath,
+    stroke: lineStyle.stroke || color,
+    strokeWidth: lineStyle.strokeWidth,
+    lineCap: 'round',
+    lineJoin: 'round',
+    ...geometryStateStyle,
+    opacity, // want to override opactiy of geometryStateStyle
+    ...GlobalKonvaElementProps,
+  };
+}
+
+/**
+ * Return the rendering props for an area. The color of the area will be overwritten
+ * by the fill color of the areaStyle parameter if present
+ * @param areaPath the SVG area path
+ * @param x the horizontal offset to place the area
+ * @param color the computed color of the line for this series
+ * @param areaStyle the area style
+ * @param geometryStateStyle the highlight geometry style
+ */
+export function buildAreaRenderProps(
+  xTransform: number,
+  areaPath: string,
+  color: string,
+  areaStyle: AreaStyle,
+  geometryStateStyle: GeometryStateStyle,
+): PathConfig {
+  const opacity = areaStyle.opacity * geometryStateStyle.opacity;
+
+  return {
+    x: xTransform,
+    data: areaPath,
+    fill: areaStyle.fill || color,
+    lineCap: 'round',
+    lineJoin: 'round',
+    ...geometryStateStyle,
+    opacity, // want to override opactiy of geometryStateStyle
+    ...GlobalKonvaElementProps,
+  };
+}
+
+/**
+ * Return the rendering props for a bar. The color of the bar will be overwritten
+ * by the fill color of the rectStyle parameter if present
+ * @param x the x position of the rect
+ * @param y the y position of the rect
+ * @param width the width of the rect
+ * @param height the height of the rect
+ * @param color the computed color of the rect for this series
+ * @param rectStyle the rect style
+ * @param geometryStateStyle the highlight geometry style
+ */
+export function buildBarRenderProps(
+  x: number,
+  y: number,
+  width: number,
+  height: number,
+  color: string,
+  rectStyle: RectStyle,
+  borderStyle: RectBorderStyle,
+  geometryStateStyle: GeometryStateStyle,
+): RectConfig {
+  const opacity = rectStyle.opacity * geometryStateStyle.opacity;
+  const { stroke, visible, strokeWidth, strokeOpacity = 0 } = borderStyle;
+  const offset = !visible || strokeWidth <= 0 || !stroke || strokeOpacity <= 0 || opacity <= 0 ? 0 : strokeWidth;
+
+  return {
+    x: x + offset,
+    y: y + offset,
+    width: width - 2 * offset,
+    height: height - 2 * offset,
+    fill: rectStyle.fill || color,
+    strokeEnabled: false,
+    ...geometryStateStyle,
+    opacity, // want to override opactiy of geometryStateStyle
+    ...GlobalKonvaElementProps,
+  };
+}
+
+/**
+ * Return the rendering props for a bar. The color of the bar will be overwritten
+ * by the fill color of the rectStyle parameter if present
+ * @param x the x position of the rect
+ * @param y the y position of the rect
+ * @param width the width of the rect
+ * @param height the height of the rect
+ * @param color the computed color of the rect for this series
+ * @param rectStyle the rect style
+ * @param borderStyle the border rect style
+ * @param geometryStyle the highlight geometry style
+ */
+export function buildBarBorderRenderProps(
+  x: number,
+  y: number,
+  width: number,
+  height: number,
+  rectStyle: RectStyle,
+  borderStyle: RectBorderStyle,
+  geometryStateStyle: GeometryStateStyle,
+): RectConfig | null {
+  const { stroke, visible, strokeWidth, strokeOpacity = rectStyle.opacity } = borderStyle;
+  const opacity = strokeOpacity * geometryStateStyle.opacity;
+
+  if (!visible || strokeWidth <= 0 || !stroke || opacity <= 0) {
+    return null;
+  }
+
+  return {
+    x: x + strokeWidth / 2,
+    y: y + strokeWidth / 2,
+    width: width - strokeWidth,
+    height: height - strokeWidth,
+    fillEnabled: false,
+    strokeEnabled: true,
+    strokeWidth,
+    stroke,
+    ...geometryStateStyle,
+    opacity, // want to override opactiy of geometryStateStyle
+    ...GlobalKonvaElementProps,
+  };
+}
diff --git a/src/chart_types/xy_chart/renderer/dom/_brush.scss b/src/chart_types/xy_chart/renderer/dom/_brush.scss
new file mode 100644
index 0000000000..f6f6f8fc20
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/dom/_brush.scss
@@ -0,0 +1,6 @@
+.echBrushTool {
+  position: absolute;
+  box-sizing: border-box;
+  overflow: hidden;
+  pointer-events: none;
+}
diff --git a/src/components/_crosshair.scss b/src/chart_types/xy_chart/renderer/dom/_crosshair.scss
similarity index 100%
rename from src/components/_crosshair.scss
rename to src/chart_types/xy_chart/renderer/dom/_crosshair.scss
diff --git a/src/components/_highlighter.scss b/src/chart_types/xy_chart/renderer/dom/_highlighter.scss
similarity index 100%
rename from src/components/_highlighter.scss
rename to src/chart_types/xy_chart/renderer/dom/_highlighter.scss
diff --git a/src/chart_types/xy_chart/renderer/dom/_index.scss b/src/chart_types/xy_chart/renderer/dom/_index.scss
new file mode 100644
index 0000000000..7b4cbb2616
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/dom/_index.scss
@@ -0,0 +1,3 @@
+@import 'highlighter';
+@import 'crosshair';
+@import 'brush';
diff --git a/src/components/annotation_tooltips.tsx b/src/chart_types/xy_chart/renderer/dom/annotation_tooltips.tsx
similarity index 65%
rename from src/components/annotation_tooltips.tsx
rename to src/chart_types/xy_chart/renderer/dom/annotation_tooltips.tsx
index fb7a758cd2..8efce018dc 100644
--- a/src/components/annotation_tooltips.tsx
+++ b/src/chart_types/xy_chart/renderer/dom/annotation_tooltips.tsx
@@ -1,20 +1,39 @@
-import { inject, observer } from 'mobx-react';
 import React from 'react';
-import { isLineAnnotation } from '../chart_types/xy_chart/utils/specs';
-import { AnnotationId } from '../utils/ids';
+import { isLineAnnotation, AnnotationSpec, AnnotationTypes } from '../../utils/specs';
+import { AnnotationId } from '../../../../utils/ids';
 import {
   AnnotationDimensions,
-  AnnotationLineProps,
+  AnnotationTooltipState,
   AnnotationTooltipFormatter,
-} from '../chart_types/xy_chart/annotations/annotation_utils';
-import { ChartStore } from '../chart_types/xy_chart/store/chart_state';
+} from '../../annotations/annotation_utils';
+import { connect } from 'react-redux';
+import { Dimensions } from '../../../../utils/dimensions';
+import { GlobalChartState, BackwardRef } from '../../../../state/chart_state';
+import { isInitialized } from '../../../../state/selectors/is_initialized';
+import { computeAnnotationDimensionsSelector } from '../../state/selectors/compute_annotations';
+import { getAnnotationSpecsSelector } from '../../state/selectors/get_specs';
+import { getAnnotationTooltipStateSelector } from '../../state/selectors/get_annotation_tooltip_state';
+import { isChartEmptySelector } from '../../state/selectors/is_chart_empty';
+import { AnnotationLineProps } from '../../annotations/line_annotation_tooltip';
+import { computeChartDimensionsSelector } from '../../state/selectors/compute_chart_dimensions';
 import { createPortal } from 'react-dom';
-import { getFinalAnnotationTooltipPosition } from '../chart_types/xy_chart/annotations/annotation_tooltip';
+import { getFinalAnnotationTooltipPosition } from '../../annotations/annotation_tooltip';
+import { getSpecsById } from '../../state/utils';
+
+interface AnnotationTooltipStateProps {
+  isChartEmpty: boolean;
+  tooltipState: AnnotationTooltipState | null;
+  chartDimensions: Dimensions;
+  annotationDimensions: Map<AnnotationId, AnnotationDimensions>;
+  annotationSpecs: AnnotationSpec[];
+}
 
-interface AnnotationTooltipProps {
-  chartStore?: ChartStore;
-  getChartContainerRef: () => React.RefObject<HTMLDivElement>;
+interface AnnotationTooltipOwnProps {
+  getChartContainerRef: BackwardRef;
 }
+
+type AnnotationTooltipProps = AnnotationTooltipStateProps & AnnotationTooltipOwnProps;
+
 const ANNOTATION_CONTAINER_ID = 'echAnnotationContainerPortal';
 
 class AnnotationTooltipComponent extends React.Component<AnnotationTooltipProps> {
@@ -52,8 +71,8 @@ class AnnotationTooltipComponent extends React.Component<AnnotationTooltipProps>
     if (!chartContainerRef.current) {
       return;
     }
-    const { annotationTooltipState, chartDimensions } = this.props.chartStore!;
-    const tooltipState = annotationTooltipState.get();
+
+    const { tooltipState, chartDimensions } = this.props;
     if (!tooltipState || !tooltipState.isVisible || !this.portalNode) {
       return null;
     }
@@ -67,8 +86,12 @@ class AnnotationTooltipComponent extends React.Component<AnnotationTooltipProps>
       tooltipState.anchor,
     );
 
-    this.portalNode.style.left = tooltipStyle.left;
-    this.portalNode.style.top = tooltipStyle.top;
+    if (tooltipStyle.left) {
+      this.portalNode.style.left = tooltipStyle.left;
+    }
+    if (tooltipStyle.top) {
+      this.portalNode.style.top = tooltipStyle.top;
+    }
   }
 
   componentWillUnmount() {
@@ -78,8 +101,7 @@ class AnnotationTooltipComponent extends React.Component<AnnotationTooltipProps>
   }
 
   renderTooltip = () => {
-    const { annotationTooltipState } = this.props.chartStore!;
-    const tooltipState = annotationTooltipState.get();
+    const { tooltipState } = this.props;
     if (!this.portalNode) {
       return null;
     }
@@ -90,11 +112,11 @@ class AnnotationTooltipComponent extends React.Component<AnnotationTooltipProps>
     const { details, header } = tooltipState;
 
     switch (tooltipState.annotationType) {
-      case 'line': {
+      case AnnotationTypes.Line: {
         const props = { details, header };
         return createPortal(<LineAnnotationTooltip {...props} ref={this.tooltipRef} />, this.portalNode);
       }
-      case 'rectangle': {
+      case AnnotationTypes.Rectangle: {
         const props = { details, customTooltip: tooltipState.renderTooltip };
         return createPortal(<RectAnnotationTooltip {...props} ref={this.tooltipRef} />, this.portalNode);
       }
@@ -104,7 +126,7 @@ class AnnotationTooltipComponent extends React.Component<AnnotationTooltipProps>
   };
 
   renderAnnotationLineMarkers(annotationLines: AnnotationLineProps[], id: AnnotationId): JSX.Element[] {
-    const { chartDimensions } = this.props.chartStore!;
+    const { chartDimensions } = this.props;
 
     const markers: JSX.Element[] = [];
 
@@ -134,11 +156,11 @@ class AnnotationTooltipComponent extends React.Component<AnnotationTooltipProps>
   }
 
   renderAnnotationMarkers(): JSX.Element[] {
-    const { annotationDimensions, annotationSpecs } = this.props.chartStore!;
+    const { annotationDimensions, annotationSpecs } = this.props;
     const markers: JSX.Element[] = [];
 
     annotationDimensions.forEach((dimensions: AnnotationDimensions, id: AnnotationId) => {
-      const annotationSpec = annotationSpecs.get(id);
+      const annotationSpec = getSpecsById<AnnotationSpec>(annotationSpecs, id);
       if (!annotationSpec) {
         return;
       }
@@ -154,9 +176,9 @@ class AnnotationTooltipComponent extends React.Component<AnnotationTooltipProps>
   }
 
   render() {
-    const { chartStore } = this.props;
+    const { isChartEmpty } = this.props;
 
-    if (chartStore!.isChartEmpty.get()) {
+    if (isChartEmpty) {
       return null;
     }
 
@@ -169,8 +191,6 @@ class AnnotationTooltipComponent extends React.Component<AnnotationTooltipProps>
   }
 }
 
-export const AnnotationTooltip = inject('chartStore')(observer(AnnotationTooltipComponent));
-
 interface RectAnnotationTooltipProps {
   details?: string;
   customTooltip?: AnnotationTooltipFormatter;
@@ -208,3 +228,24 @@ function LineAnnotationTooltipRender(props: LineAnnotationTooltipProps, ref: Rea
   );
 }
 const LineAnnotationTooltip = React.forwardRef(LineAnnotationTooltipRender);
+
+const mapStateToProps = (state: GlobalChartState): AnnotationTooltipStateProps => {
+  if (!isInitialized(state)) {
+    return {
+      isChartEmpty: true,
+      chartDimensions: { top: 0, left: 0, width: 0, height: 0 },
+      annotationDimensions: new Map(),
+      annotationSpecs: [],
+      tooltipState: null,
+    };
+  }
+  return {
+    isChartEmpty: isChartEmptySelector(state),
+    chartDimensions: computeChartDimensionsSelector(state).chartDimensions,
+    annotationDimensions: computeAnnotationDimensionsSelector(state),
+    annotationSpecs: getAnnotationSpecsSelector(state),
+    tooltipState: getAnnotationTooltipStateSelector(state),
+  };
+};
+
+export const AnnotationTooltip = connect(mapStateToProps)(AnnotationTooltipComponent);
diff --git a/src/chart_types/xy_chart/renderer/dom/brush.tsx b/src/chart_types/xy_chart/renderer/dom/brush.tsx
new file mode 100644
index 0000000000..e2a01a47bf
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/dom/brush.tsx
@@ -0,0 +1,90 @@
+import React from 'react';
+import { Layer, Rect, Stage } from 'react-konva';
+import { connect } from 'react-redux';
+import { Dimensions } from '../../../../utils/dimensions';
+import { isInitialized } from '../../../../state/selectors/is_initialized';
+import { computeChartTransformSelector } from '../../state/selectors/compute_chart_transform';
+import { Transform } from '../../state/utils';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { getBrushAreaSelector } from '../../state/selectors/get_brush_area';
+import { isBrushAvailableSelector } from '../../state/selectors/is_brush_available';
+import { computeChartDimensionsSelector } from '../../state/selectors/compute_chart_dimensions';
+import { isBrushingSelector } from '../../state/selectors/is_brushing';
+
+interface Props {
+  initialized: boolean;
+  chartDimensions: Dimensions;
+  chartTransform: Transform;
+  isBrushing: boolean | undefined;
+  isBrushAvailable: boolean | undefined;
+  brushArea: Dimensions | null;
+}
+
+class BrushToolComponent extends React.Component<Props> {
+  static displayName = 'BrushToolComponent';
+
+  renderBrushTool = (brushArea: Dimensions | null) => {
+    if (!brushArea) {
+      return null;
+    }
+    const { top, left, width, height } = brushArea;
+    return <Rect x={left} y={top} width={width} height={height} fill="gray" opacity={0.6} />;
+  };
+
+  render() {
+    const { initialized, isBrushAvailable, isBrushing, chartDimensions, chartTransform, brushArea } = this.props;
+    if (!initialized || !isBrushAvailable || !isBrushing) {
+      return null;
+    }
+
+    return (
+      <Stage
+        width={chartDimensions.width}
+        height={chartDimensions.height}
+        className="echBrushTool"
+        style={{
+          top: chartDimensions.top + chartTransform.x,
+          left: chartDimensions.left + chartTransform.y,
+          width: chartDimensions.width,
+          height: chartDimensions.height,
+        }}
+      >
+        <Layer hitGraphEnabled={false} listening={false}>
+          {this.renderBrushTool(brushArea)}
+        </Layer>
+      </Stage>
+    );
+  }
+}
+
+const mapStateToProps = (state: GlobalChartState): Props => {
+  if (!isInitialized(state)) {
+    return {
+      initialized: false,
+      isBrushing: false,
+      isBrushAvailable: false,
+      brushArea: null,
+      chartDimensions: {
+        top: 0,
+        left: 0,
+        width: 0,
+        height: 0,
+      },
+      chartTransform: {
+        x: 0,
+        y: 0,
+        rotate: 0,
+      },
+    };
+  }
+  return {
+    initialized: state.specsInitialized,
+    brushArea: getBrushAreaSelector(state),
+    isBrushAvailable: isBrushAvailableSelector(state),
+    chartDimensions: computeChartDimensionsSelector(state).chartDimensions,
+    chartTransform: computeChartTransformSelector(state),
+    isBrushing: isBrushingSelector(state),
+  };
+};
+
+export const BrushTool = connect(mapStateToProps)(BrushToolComponent);
diff --git a/src/chart_types/xy_chart/renderer/dom/crosshair.tsx b/src/chart_types/xy_chart/renderer/dom/crosshair.tsx
new file mode 100644
index 0000000000..fc70dac82f
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/dom/crosshair.tsx
@@ -0,0 +1,117 @@
+import React, { CSSProperties } from 'react';
+import { connect } from 'react-redux';
+import { TooltipType } from '../../utils/interactions';
+import { isHorizontalRotation } from '../../state/utils';
+import { Dimensions } from '../../../../utils/dimensions';
+import { Theme } from '../../../../utils/themes/theme';
+import { Rotation } from '../../../../chart_types/xy_chart/utils/specs';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { isInitialized } from '../../../../state/selectors/is_initialized';
+import { getChartRotationSelector } from '../../../../state/selectors/get_chart_rotation';
+import { getCursorBandPositionSelector } from '../../state/selectors/get_cursor_band';
+import { getCursorLinePositionSelector } from '../../state/selectors/get_cursor_line';
+import { getTooltipTypeSelector } from '../../state/selectors/get_tooltip_type';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { LIGHT_THEME } from '../../../../utils/themes/light_theme';
+
+interface CrosshairProps {
+  theme: Theme;
+  chartRotation: Rotation;
+  cursorBandPosition?: Dimensions;
+  cursorLinePosition: Dimensions;
+  tooltipType: TooltipType;
+}
+
+function canRenderBand(type: TooltipType, visible: boolean) {
+  return visible && (type === TooltipType.Crosshairs || type === TooltipType.VerticalCursor);
+}
+function canRenderHelpLine(type: TooltipType, visible: boolean) {
+  return visible && type === TooltipType.Crosshairs;
+}
+
+class CrosshairComponent extends React.Component<CrosshairProps> {
+  static displayName = 'Crosshair';
+
+  render() {
+    return (
+      <div className="echCrosshair">
+        {this.renderBand()}
+        {this.renderLine()}
+      </div>
+    );
+  }
+
+  renderBand() {
+    const {
+      theme: {
+        crosshair: { band },
+      },
+      cursorBandPosition,
+      tooltipType,
+    } = this.props;
+
+    if (!cursorBandPosition || !canRenderBand(tooltipType, band.visible)) {
+      return null;
+    }
+    const style: CSSProperties = {
+      ...cursorBandPosition,
+      background: band.fill,
+    };
+
+    return <div className="echCrosshair__band" style={style} />;
+  }
+
+  renderLine() {
+    const {
+      theme: {
+        crosshair: { line },
+      },
+      cursorLinePosition,
+      tooltipType,
+      chartRotation,
+    } = this.props;
+
+    if (!cursorLinePosition || !canRenderHelpLine(tooltipType, line.visible)) {
+      return null;
+    }
+    const isHorizontalRotated = isHorizontalRotation(chartRotation);
+    let style: CSSProperties;
+    if (isHorizontalRotated) {
+      style = {
+        ...cursorLinePosition,
+        borderTopWidth: line.strokeWidth,
+        borderTopColor: line.stroke,
+        borderTopStyle: line.dash ? 'dashed' : 'solid',
+      };
+    } else {
+      style = {
+        ...cursorLinePosition,
+        borderLeftWidth: line.strokeWidth,
+        borderLeftColor: line.stroke,
+        borderLeftStyle: line.dash ? 'dashed' : 'solid',
+      };
+    }
+    return <div className="echCrosshair__line" style={style} />;
+  }
+}
+
+const mapStateToProps = (state: GlobalChartState): CrosshairProps => {
+  if (!isInitialized(state)) {
+    return {
+      theme: LIGHT_THEME,
+      chartRotation: 0,
+      cursorBandPosition: { top: 0, left: 0, width: 0, height: 0 },
+      cursorLinePosition: { top: 0, left: 0, width: 0, height: 0 },
+      tooltipType: TooltipType.None,
+    };
+  }
+  return {
+    theme: getChartThemeSelector(state),
+    chartRotation: getChartRotationSelector(state),
+    cursorBandPosition: getCursorBandPositionSelector(state),
+    cursorLinePosition: getCursorLinePositionSelector(state),
+    tooltipType: getTooltipTypeSelector(state),
+  };
+};
+
+export const Crosshair = connect(mapStateToProps)(CrosshairComponent);
diff --git a/src/chart_types/xy_chart/renderer/dom/highlighter.tsx b/src/chart_types/xy_chart/renderer/dom/highlighter.tsx
new file mode 100644
index 0000000000..bff9fe9d1e
--- /dev/null
+++ b/src/chart_types/xy_chart/renderer/dom/highlighter.tsx
@@ -0,0 +1,95 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { isPointGeometry, IndexedGeometry } from '../../../../utils/geometry';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { isInitialized } from '../../../../state/selectors/is_initialized';
+import { computeChartTransformSelector } from '../../state/selectors/compute_chart_transform';
+import { getHighlightedGeomsSelector } from '../../state/selectors/get_tooltip_values_highlighted_geoms';
+import { Dimensions } from '../../../../utils/dimensions';
+import { Rotation } from '../../../../chart_types/xy_chart/utils/specs';
+import { Transform } from '../../state/utils';
+import { getChartRotationSelector } from '../../../../state/selectors/get_chart_rotation';
+import { computeChartDimensionsSelector } from '../../state/selectors/compute_chart_dimensions';
+
+interface HighlighterProps {
+  highlightedGeometries: IndexedGeometry[];
+  initialized: boolean;
+  chartTransform: Transform;
+  chartDimensions: Dimensions;
+  chartRotation: Rotation;
+}
+
+class HighlighterComponent extends React.Component<HighlighterProps> {
+  static displayName = 'Highlighter';
+
+  render() {
+    const { highlightedGeometries, chartTransform, chartDimensions, chartRotation } = this.props;
+    const left = chartDimensions.left + chartTransform.x;
+    const top = chartDimensions.top + chartTransform.y;
+    const clipWidth = [90, -90].includes(chartRotation) ? chartDimensions.height : chartDimensions.width;
+    const clipHeight = [90, -90].includes(chartRotation) ? chartDimensions.width : chartDimensions.height;
+    return (
+      <svg className="echHighlighter">
+        <defs>
+          <clipPath id="echHighlighterClipPath">
+            <rect x="0" y="0" width={clipWidth} height={clipHeight} />
+          </clipPath>
+        </defs>
+        <g transform={`translate(${left}, ${top}) rotate(${chartRotation})`}>
+          {highlightedGeometries.map((geom, i) => {
+            const { color, x, y } = geom;
+            if (isPointGeometry(geom)) {
+              return (
+                <circle
+                  key={i}
+                  cx={x + geom.transform.x}
+                  cy={y}
+                  r={geom.radius}
+                  stroke={color}
+                  strokeWidth={4}
+                  fill="transparent"
+                />
+              );
+            }
+            return (
+              <rect
+                key={i}
+                x={x}
+                y={y}
+                width={geom.width}
+                height={geom.height}
+                className="echHighlighter__rect"
+                clipPath="url(#echHighlighterClipPath)"
+              />
+            );
+          })}
+        </g>
+      </svg>
+    );
+  }
+}
+
+const mapStateToProps = (state: GlobalChartState): HighlighterProps => {
+  if (!isInitialized(state)) {
+    return {
+      initialized: false,
+      highlightedGeometries: [],
+      chartTransform: {
+        x: 0,
+        y: 0,
+        rotate: 0,
+      },
+      chartDimensions: { top: 0, left: 0, width: 0, height: 0 },
+      chartRotation: 0,
+    };
+  }
+  return {
+    initialized: true,
+    highlightedGeometries: getHighlightedGeomsSelector(state),
+    chartTransform: computeChartTransformSelector(state),
+    chartDimensions: computeChartDimensionsSelector(state).chartDimensions,
+    chartRotation: getChartRotationSelector(state),
+  };
+};
+
+export const Highlighter = connect(mapStateToProps)(HighlighterComponent);
diff --git a/src/components/tooltips.tsx b/src/chart_types/xy_chart/renderer/dom/tooltips.tsx
similarity index 52%
rename from src/components/tooltips.tsx
rename to src/chart_types/xy_chart/renderer/dom/tooltips.tsx
index cfc7addacb..e0a2799b12 100644
--- a/src/components/tooltips.tsx
+++ b/src/chart_types/xy_chart/renderer/dom/tooltips.tsx
@@ -1,15 +1,28 @@
 import classNames from 'classnames';
-import { inject, observer } from 'mobx-react';
 import React from 'react';
+import { connect } from 'react-redux';
+import { TooltipValue, TooltipValueFormatter } from '../../utils/interactions';
+import { GlobalChartState, BackwardRef } from '../../../../state/chart_state';
+import { isTooltipVisibleSelector } from '../../state/selectors/is_tooltip_visible';
+import { getTooltipHeaderFormatterSelector } from '../../state/selectors/get_tooltip_header_formatter';
+import { getTooltipPositionSelector } from '../../state/selectors/get_tooltip_position';
+import { getTooltipValuesSelector } from '../../state/selectors/get_tooltip_values_highlighted_geoms';
+import { isInitialized } from '../../../../state/selectors/is_initialized';
 import { createPortal } from 'react-dom';
-import { TooltipValue, TooltipValueFormatter } from '../chart_types/xy_chart/utils/interactions';
-import { ChartStore } from '../chart_types/xy_chart/store/chart_state';
-import { getFinalTooltipPosition } from '../chart_types/xy_chart/crosshair/crosshair_utils';
+import { getFinalTooltipPosition, TooltipPosition } from '../../crosshair/crosshair_utils';
+import { isAnnotationTooltipVisibleSelector } from '../../state/selectors/is_annotation_tooltip_visible';
 
-interface TooltipProps {
-  chartStore?: ChartStore;
-  getChartContainerRef: () => React.RefObject<HTMLDivElement>;
+interface TooltipStateProps {
+  isTooltipVisible: boolean;
+  isAnnotationTooltipVisible: boolean;
+  tooltipValues: TooltipValue[];
+  tooltipPosition: TooltipPosition | null;
+  tooltipHeaderFormatter?: TooltipValueFormatter;
 }
+interface TooltipOwnProps {
+  getChartContainerRef: BackwardRef;
+}
+type TooltipProps = TooltipStateProps & TooltipOwnProps;
 
 class TooltipsComponent extends React.Component<TooltipProps> {
   static displayName = 'Tooltips';
@@ -36,11 +49,10 @@ class TooltipsComponent extends React.Component<TooltipProps> {
 
   componentDidUpdate() {
     this.createPortalNode();
-    const { getChartContainerRef } = this.props;
-    const { tooltipPosition } = this.props.chartStore!;
+    const { getChartContainerRef, tooltipPosition } = this.props;
     const chartContainerRef = getChartContainerRef();
 
-    if (!this.tooltipRef.current || !chartContainerRef.current || !this.portalNode) {
+    if (!this.tooltipRef.current || !chartContainerRef.current || !this.portalNode || !tooltipPosition) {
       return;
     }
 
@@ -48,8 +60,12 @@ class TooltipsComponent extends React.Component<TooltipProps> {
     const tooltipBBox = this.tooltipRef.current.getBoundingClientRect();
     const tooltipStyle = getFinalTooltipPosition(chartContainerBBox, tooltipBBox, tooltipPosition);
 
-    this.portalNode.style.left = tooltipStyle.left;
-    this.portalNode.style.top = tooltipStyle.top;
+    if (tooltipStyle.left) {
+      this.portalNode.style.left = tooltipStyle.left;
+    }
+    if (tooltipStyle.top) {
+      this.portalNode.style.top = tooltipStyle.top;
+    }
   }
 
   componentWillUnmount() {
@@ -67,22 +83,21 @@ class TooltipsComponent extends React.Component<TooltipProps> {
   }
 
   render() {
-    const { isTooltipVisible, tooltipData, tooltipHeaderFormatter } = this.props.chartStore!;
-    const isVisible = isTooltipVisible.get();
-    let tooltip;
+    const { isTooltipVisible, tooltipValues, tooltipHeaderFormatter, isAnnotationTooltipVisible } = this.props;
     if (!this.portalNode) {
       return null;
     }
     const { getChartContainerRef } = this.props;
     const chartContainerRef = getChartContainerRef();
-    if (chartContainerRef.current === null || !isVisible) {
+    let tooltip;
+    if (chartContainerRef.current === null || !isTooltipVisible || isAnnotationTooltipVisible) {
       return null;
     } else {
       tooltip = (
         <div className="echTooltip" ref={this.tooltipRef}>
-          <div className="echTooltip__header">{this.renderHeader(tooltipData[0], tooltipHeaderFormatter)}</div>
+          <div className="echTooltip__header">{this.renderHeader(tooltipValues[0], tooltipHeaderFormatter)}</div>
           <div className="echTooltip__list">
-            {tooltipData.slice(1).map(({ name, value, color, isHighlighted, seriesKey, yAccessor }) => {
+            {tooltipValues.slice(1).map(({ name, value, color, isHighlighted, seriesKey, yAccessor }) => {
               const classes = classNames('echTooltip__item', {
                 /* eslint @typescript-eslint/camelcase:0 */
                 echTooltip__rowHighlighted: isHighlighted,
@@ -108,4 +123,23 @@ class TooltipsComponent extends React.Component<TooltipProps> {
   }
 }
 
-export const Tooltips = inject('chartStore')(observer(TooltipsComponent));
+const mapStateToProps = (state: GlobalChartState): TooltipStateProps => {
+  if (!isInitialized(state)) {
+    return {
+      isTooltipVisible: false,
+      isAnnotationTooltipVisible: false,
+      tooltipValues: [],
+      tooltipPosition: null,
+      tooltipHeaderFormatter: undefined,
+    };
+  }
+  return {
+    isTooltipVisible: isTooltipVisibleSelector(state),
+    isAnnotationTooltipVisible: isAnnotationTooltipVisibleSelector(state),
+    tooltipValues: getTooltipValuesSelector(state),
+    tooltipPosition: getTooltipPositionSelector(state),
+    tooltipHeaderFormatter: getTooltipHeaderFormatterSelector(state),
+  };
+};
+
+export const Tooltips = connect(mapStateToProps)(TooltipsComponent);
diff --git a/src/chart_types/xy_chart/rendering/rendering.areas.test.ts b/src/chart_types/xy_chart/rendering/rendering.areas.test.ts
index d3b8f12407..367266ec8b 100644
--- a/src/chart_types/xy_chart/rendering/rendering.areas.test.ts
+++ b/src/chart_types/xy_chart/rendering/rendering.areas.test.ts
@@ -1,22 +1,24 @@
-/* eslint @typescript-eslint/no-object-literal-type-assertion: off */
-import { computeSeriesDomains } from '../store/utils';
-import { getGroupId, getSpecId, SpecId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
 import { CurveType } from '../../../utils/curves';
-import { AreaGeometry, IndexedGeometry, PointGeometry, renderArea } from './rendering';
-import { computeXScale, computeYScales } from '../utils/scales';
-import { AreaSeriesSpec } from '../utils/specs';
+import { IndexedGeometry, PointGeometry, AreaGeometry } from '../../../utils/geometry';
 import { LIGHT_THEME } from '../../../utils/themes/light_theme';
+import { computeXScale, computeYScales } from '../utils/scales';
+import { AreaSeriesSpec, SpecTypes, SeriesTypes } from '../utils/specs';
+import { computeSeriesDomains } from '../state/utils';
+import { renderArea } from './rendering';
+import { ChartTypes } from '../..';
 
-const SPEC_ID = getSpecId('spec_1');
-const GROUP_ID = getGroupId('group_1');
+const SPEC_ID = 'spec_1';
+const GROUP_ID = 'group_1';
 
 describe('Rendering points - areas', () => {
   describe('Empty line for missing data', () => {
     const pointSeriesSpec: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -24,12 +26,11 @@ describe('Rendering points - areas', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({
@@ -70,9 +71,11 @@ describe('Rendering points - areas', () => {
   });
   describe('Single series area chart - ordinal', () => {
     const pointSeriesSpec: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -80,12 +83,11 @@ describe('Rendering points - areas', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -170,12 +172,14 @@ describe('Rendering points - areas', () => {
     });
   });
   describe('Multi series area chart - ordinal', () => {
-    const spec1Id = getSpecId('point1');
-    const spec2Id = getSpecId('point2');
+    const spec1Id = 'point1';
+    const spec2Id = 'point2';
     const pointSeriesSpec1: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec1Id,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -184,9 +188,11 @@ describe('Rendering points - areas', () => {
       yScaleType: ScaleType.Linear,
     };
     const pointSeriesSpec2: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec2Id,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 20], [1, 10]],
       xAccessor: 0,
@@ -194,13 +200,11 @@ describe('Rendering points - areas', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(spec1Id, pointSeriesSpec1);
-    pointSeriesMap.set(spec2Id, pointSeriesSpec2);
+    const pointSeriesMap = [pointSeriesSpec1, pointSeriesSpec2];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -353,9 +357,11 @@ describe('Rendering points - areas', () => {
   });
   describe('Single series area chart - linear', () => {
     const pointSeriesSpec: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -363,12 +369,11 @@ describe('Rendering points - areas', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -448,12 +453,14 @@ describe('Rendering points - areas', () => {
     });
   });
   describe('Multi series area chart - linear', () => {
-    const spec1Id = getSpecId('point1');
-    const spec2Id = getSpecId('point2');
+    const spec1Id = 'point1';
+    const spec2Id = 'point2';
     const pointSeriesSpec1: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec1Id,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -462,9 +469,11 @@ describe('Rendering points - areas', () => {
       yScaleType: ScaleType.Linear,
     };
     const pointSeriesSpec2: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec2Id,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 20], [1, 10]],
       xAccessor: 0,
@@ -472,13 +481,11 @@ describe('Rendering points - areas', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(spec1Id, pointSeriesSpec1);
-    pointSeriesMap.set(spec2Id, pointSeriesSpec2);
+    const pointSeriesMap = [pointSeriesSpec1, pointSeriesSpec2];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -630,9 +637,11 @@ describe('Rendering points - areas', () => {
   });
   describe('Single series area chart - time', () => {
     const pointSeriesSpec: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[1546300800000, 10], [1546387200000, 5]],
       xAccessor: 0,
@@ -640,12 +649,11 @@ describe('Rendering points - areas', () => {
       xScaleType: ScaleType.Time,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -725,12 +733,14 @@ describe('Rendering points - areas', () => {
     });
   });
   describe('Multi series area chart - time', () => {
-    const spec1Id = getSpecId('point1');
-    const spec2Id = getSpecId('point2');
+    const spec1Id = 'point1';
+    const spec2Id = 'point2';
     const pointSeriesSpec1: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec1Id,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[1546300800000, 10], [1546387200000, 5]],
       xAccessor: 0,
@@ -739,9 +749,11 @@ describe('Rendering points - areas', () => {
       yScaleType: ScaleType.Linear,
     };
     const pointSeriesSpec2: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec2Id,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[1546300800000, 20], [1546387200000, 10]],
       xAccessor: 0,
@@ -749,13 +761,11 @@ describe('Rendering points - areas', () => {
       xScaleType: ScaleType.Time,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(spec1Id, pointSeriesSpec1);
-    pointSeriesMap.set(spec2Id, pointSeriesSpec2);
+    const pointSeriesMap = [pointSeriesSpec1, pointSeriesSpec2];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -892,9 +902,11 @@ describe('Rendering points - areas', () => {
   });
   describe('Single series area chart - y log', () => {
     const pointSeriesSpec: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5], [2, null], [3, 5], [4, 5], [5, 0], [6, 10], [7, 10], [8, 10]],
       xAccessor: 0,
@@ -902,12 +914,11 @@ describe('Rendering points - areas', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Log,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 90],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
diff --git a/src/chart_types/xy_chart/rendering/rendering.bands.test.ts b/src/chart_types/xy_chart/rendering/rendering.bands.test.ts
index 3bbeca0b78..42a19c4441 100644
--- a/src/chart_types/xy_chart/rendering/rendering.bands.test.ts
+++ b/src/chart_types/xy_chart/rendering/rendering.bands.test.ts
@@ -1,22 +1,24 @@
-/* eslint @typescript-eslint/no-object-literal-type-assertion: off */
-import { computeSeriesDomains } from '../store/utils';
-import { getGroupId, getSpecId, SpecId } from '../../../utils/ids';
+import { computeSeriesDomains } from '../state/utils';
 import { ScaleType } from '../../../utils/scales/scales';
 import { CurveType } from '../../../utils/curves';
-import { AreaGeometry, IndexedGeometry, PointGeometry, renderArea, renderBars } from './rendering';
+import { renderArea, renderBars } from './rendering';
 import { computeXScale, computeYScales } from '../utils/scales';
-import { AreaSeriesSpec, BarSeriesSpec } from '../utils/specs';
+import { AreaSeriesSpec, BarSeriesSpec, SpecTypes, SeriesTypes } from '../utils/specs';
 import { LIGHT_THEME } from '../../../utils/themes/light_theme';
+import { AreaGeometry, IndexedGeometry, PointGeometry } from '../../../utils/geometry';
+import { ChartTypes } from '../..';
 
-const SPEC_ID = getSpecId('spec_1');
-const GROUP_ID = getGroupId('group_1');
+const SPEC_ID = 'spec_1';
+const GROUP_ID = 'group_1';
 
 describe('Rendering bands - areas', () => {
   describe('Empty line for missing data', () => {
     const pointSeriesSpec: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 2, 10], [1, 3, 5]],
       xAccessor: 0,
@@ -25,12 +27,11 @@ describe('Rendering bands - areas', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -68,9 +69,11 @@ describe('Rendering bands - areas', () => {
   });
   describe('Single band area chart', () => {
     const pointSeriesSpec: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 2, 10], [1, 3, 5]],
       xAccessor: 0,
@@ -79,12 +82,11 @@ describe('Rendering bands - areas', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -210,9 +212,11 @@ describe('Rendering bands - areas', () => {
   });
   describe('Single band area chart with null values', () => {
     const pointSeriesSpec: AreaSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'area',
+      seriesType: SeriesTypes.Area,
       yScaleToDataExtent: false,
       data: [[0, 2, 10], [1, 2, null], [2, 3, 5], [3, 3, 5]],
       xAccessor: 0,
@@ -221,12 +225,11 @@ describe('Rendering bands - areas', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, AreaSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -391,9 +394,11 @@ describe('Rendering bands - areas', () => {
   });
   describe('Single series band bar chart - ordinal', () => {
     const barSeriesSpec: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[0, 2, 10], [1, 3, null], [2, 3, 5], [3, 4, 8]],
       xAccessor: 0,
@@ -402,12 +407,11 @@ describe('Rendering bands - areas', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const barSeriesMap = new Map<SpecId, BarSeriesSpec>();
-    barSeriesMap.set(SPEC_ID, barSeriesSpec);
+    const barSeriesMap = [barSeriesSpec];
     const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: barSeriesDomains.xDomain,
-      totalBarsInCluster: barSeriesMap.size,
+      totalBarsInCluster: barSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: barSeriesDomains.yDomain, range: [100, 0] });
diff --git a/src/chart_types/xy_chart/rendering/rendering.bars.test.ts b/src/chart_types/xy_chart/rendering/rendering.bars.test.ts
index 2c950cbe79..ed3d915f75 100644
--- a/src/chart_types/xy_chart/rendering/rendering.bars.test.ts
+++ b/src/chart_types/xy_chart/rendering/rendering.bars.test.ts
@@ -1,21 +1,24 @@
-import { computeSeriesDomains } from '../store/utils';
+import { computeSeriesDomains } from '../state/utils';
 import { identity } from '../../../utils/commons';
-import { getGroupId, getSpecId, SpecId, GroupId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
 import { renderBars } from './rendering';
 import { computeXScale, computeYScales } from '../utils/scales';
-import { BarSeriesSpec, DomainRange } from '../utils/specs';
+import { BarSeriesSpec, DomainRange, SpecTypes, SeriesTypes } from '../utils/specs';
 import { LIGHT_THEME } from '../../../utils/themes/light_theme';
+import { GroupId } from '../../../utils/ids';
+import { ChartTypes } from '../..';
 
-const SPEC_ID = getSpecId('spec_1');
-const GROUP_ID = getGroupId('group_1');
+const SPEC_ID = 'spec_1';
+const GROUP_ID = 'group_1';
 
 describe('Rendering bars', () => {
   describe('Single series bar chart - ordinal', () => {
     const barSeriesSpec: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[-200, 0], [0, 10], [1, 5]], // first datum should be skipped as it's out of domain
       xAccessor: 0,
@@ -23,13 +26,12 @@ describe('Rendering bars', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const barSeriesMap = new Map<SpecId, BarSeriesSpec>();
-    barSeriesMap.set(SPEC_ID, barSeriesSpec);
+    const barSeriesMap = [barSeriesSpec];
     const customDomain = [0, 1];
-    const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map(), customDomain);
+    const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map(), [], customDomain);
     const xScale = computeXScale({
       xDomain: barSeriesDomains.xDomain,
-      totalBarsInCluster: barSeriesMap.size,
+      totalBarsInCluster: barSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: barSeriesDomains.yDomain, range: [100, 0] });
@@ -183,12 +185,14 @@ describe('Rendering bars', () => {
     });
   });
   describe('Multi series bar chart - ordinal', () => {
-    const spec1Id = getSpecId('bar1');
-    const spec2Id = getSpecId('bar2');
+    const spec1Id = 'bar1';
+    const spec2Id = 'bar2';
     const barSeriesSpec1: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec1Id,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -197,9 +201,11 @@ describe('Rendering bars', () => {
       yScaleType: ScaleType.Linear,
     };
     const barSeriesSpec2: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec2Id,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[0, 20], [1, 10]],
       xAccessor: 0,
@@ -207,13 +213,11 @@ describe('Rendering bars', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const barSeriesMap = new Map<SpecId, BarSeriesSpec>();
-    barSeriesMap.set(spec1Id, barSeriesSpec1);
-    barSeriesMap.set(spec2Id, barSeriesSpec2);
+    const barSeriesMap = [barSeriesSpec1, barSeriesSpec2];
     const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: barSeriesDomains.xDomain,
-      totalBarsInCluster: barSeriesMap.size,
+      totalBarsInCluster: barSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: barSeriesDomains.yDomain, range: [100, 0] });
@@ -387,9 +391,11 @@ describe('Rendering bars', () => {
   });
   describe('Single series bar chart - linear', () => {
     const barSeriesSpec: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -397,12 +403,11 @@ describe('Rendering bars', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Linear,
     };
-    const barSeriesMap = new Map<SpecId, BarSeriesSpec>();
-    barSeriesMap.set(SPEC_ID, barSeriesSpec);
+    const barSeriesMap = [barSeriesSpec];
     const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: barSeriesDomains.xDomain,
-      totalBarsInCluster: barSeriesMap.size,
+      totalBarsInCluster: barSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: barSeriesDomains.yDomain, range: [100, 0] });
@@ -492,9 +497,11 @@ describe('Rendering bars', () => {
   });
   describe('Single series bar chart - log', () => {
     const barSeriesSpec: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[1, 0], [2, 1], [3, 2], [4, 3], [5, 4], [6, 5]],
       xAccessor: 0,
@@ -502,12 +509,10 @@ describe('Rendering bars', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Log,
     };
-    const barSeriesMap = new Map<SpecId, BarSeriesSpec>();
-    barSeriesMap.set(SPEC_ID, barSeriesSpec);
-    const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map());
+    const barSeriesDomains = computeSeriesDomains([barSeriesSpec], new Map());
     const xScale = computeXScale({
       xDomain: barSeriesDomains.xDomain,
-      totalBarsInCluster: barSeriesMap.size,
+      totalBarsInCluster: 1,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: barSeriesDomains.yDomain, range: [100, 0] });
@@ -531,12 +536,14 @@ describe('Rendering bars', () => {
     });
   });
   describe('Multi series bar chart - linear', () => {
-    const spec1Id = getSpecId('bar1');
-    const spec2Id = getSpecId('bar2');
+    const spec1Id = 'bar1';
+    const spec2Id = 'bar2';
     const barSeriesSpec1: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec1Id,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -545,9 +552,11 @@ describe('Rendering bars', () => {
       yScaleType: ScaleType.Linear,
     };
     const barSeriesSpec2: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec2Id,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[0, 20], [1, 10]],
       xAccessor: 0,
@@ -555,13 +564,11 @@ describe('Rendering bars', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Linear,
     };
-    const barSeriesMap = new Map<SpecId, BarSeriesSpec>();
-    barSeriesMap.set(spec1Id, barSeriesSpec1);
-    barSeriesMap.set(spec2Id, barSeriesSpec2);
+    const barSeriesMap = [barSeriesSpec1, barSeriesSpec2];
     const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: barSeriesDomains.xDomain,
-      totalBarsInCluster: barSeriesMap.size,
+      totalBarsInCluster: barSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: barSeriesDomains.yDomain, range: [100, 0] });
@@ -734,12 +741,14 @@ describe('Rendering bars', () => {
     });
   });
   describe('Multi series bar chart - time', () => {
-    const spec1Id = getSpecId('bar1');
-    const spec2Id = getSpecId('bar2');
+    const spec1Id = 'bar1';
+    const spec2Id = 'bar2';
     const barSeriesSpec1: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec1Id,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[1546300800000, 10], [1546387200000, 5]],
       xAccessor: 0,
@@ -748,9 +757,11 @@ describe('Rendering bars', () => {
       yScaleType: ScaleType.Linear,
     };
     const barSeriesSpec2: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec2Id,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[1546300800000, 20], [1546387200000, 10]],
       xAccessor: 0,
@@ -758,13 +769,11 @@ describe('Rendering bars', () => {
       xScaleType: ScaleType.Time,
       yScaleType: ScaleType.Linear,
     };
-    const barSeriesMap = new Map<SpecId, BarSeriesSpec>();
-    barSeriesMap.set(spec1Id, barSeriesSpec1);
-    barSeriesMap.set(spec2Id, barSeriesSpec2);
+    const barSeriesMap = [barSeriesSpec1, barSeriesSpec2];
     const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: barSeriesDomains.xDomain,
-      totalBarsInCluster: barSeriesMap.size,
+      totalBarsInCluster: barSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: barSeriesDomains.yDomain, range: [100, 0] });
@@ -938,9 +947,11 @@ describe('Rendering bars', () => {
   });
   describe('Remove points datum is not in domain', () => {
     const barSeriesSpec: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [[0, 0], [1, 1], [2, 10], [3, 3]],
       xAccessor: 0,
@@ -948,18 +959,16 @@ describe('Rendering bars', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Linear,
     };
-    const barSeriesMap = new Map<SpecId, BarSeriesSpec>();
-    barSeriesMap.set(SPEC_ID, barSeriesSpec);
     const customYDomain = new Map<GroupId, DomainRange>();
     customYDomain.set(GROUP_ID, {
       max: 1,
     });
-    const barSeriesDomains = computeSeriesDomains(barSeriesMap, customYDomain, {
+    const barSeriesDomains = computeSeriesDomains([barSeriesSpec], customYDomain, [], {
       max: 2,
     });
     const xScale = computeXScale({
       xDomain: barSeriesDomains.xDomain,
-      totalBarsInCluster: barSeriesMap.size,
+      totalBarsInCluster: 1,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: barSeriesDomains.yDomain, range: [100, 0] });
@@ -1004,9 +1013,11 @@ describe('Rendering bars', () => {
       [18, 100000],
     ];
     const barSeriesSpec: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data,
       xAccessor: 0,
@@ -1015,13 +1026,12 @@ describe('Rendering bars', () => {
       yScaleType: ScaleType.Linear,
       minBarHeight,
     };
-    const barSeriesMap = new Map<SpecId, BarSeriesSpec>();
-    barSeriesMap.set(SPEC_ID, barSeriesSpec);
+
     const customYDomain = new Map<GroupId, DomainRange>();
-    const barSeriesDomains = computeSeriesDomains(barSeriesMap, customYDomain);
+    const barSeriesDomains = computeSeriesDomains([barSeriesSpec], customYDomain);
     const xScale = computeXScale({
       xDomain: barSeriesDomains.xDomain,
-      totalBarsInCluster: barSeriesMap.size,
+      totalBarsInCluster: 1,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: barSeriesDomains.yDomain, range: [100, 0] });
diff --git a/src/chart_types/xy_chart/rendering/rendering.lines.test.ts b/src/chart_types/xy_chart/rendering/rendering.lines.test.ts
index 2de21b9e8e..8eb35367fd 100644
--- a/src/chart_types/xy_chart/rendering/rendering.lines.test.ts
+++ b/src/chart_types/xy_chart/rendering/rendering.lines.test.ts
@@ -1,23 +1,25 @@
-/* eslint @typescript-eslint/no-object-literal-type-assertion: off */
-
-import { computeSeriesDomains } from '../store/utils';
-import { getGroupId, getSpecId, SpecId, GroupId } from '../../../utils/ids';
+import { computeSeriesDomains } from '../state/utils';
 import { ScaleType } from '../../../utils/scales/scales';
 import { CurveType } from '../../../utils/curves';
-import { IndexedGeometry, LineGeometry, PointGeometry, renderLine } from './rendering';
+import { renderLine } from './rendering';
 import { computeXScale, computeYScales } from '../utils/scales';
-import { LineSeriesSpec, DomainRange } from '../utils/specs';
+import { LineSeriesSpec, DomainRange, SpecTypes, SeriesTypes } from '../utils/specs';
 import { LIGHT_THEME } from '../../../utils/themes/light_theme';
+import { LineGeometry, IndexedGeometry, PointGeometry } from '../../../utils/geometry';
+import { GroupId } from '../../../utils/ids';
+import { ChartTypes } from '../..';
 
-const SPEC_ID = getSpecId('spec_1');
-const GROUP_ID = getGroupId('group_1');
+const SPEC_ID = 'spec_1';
+const GROUP_ID = 'group_1';
 
 describe('Rendering points - line', () => {
   describe('Empty line for missing data', () => {
     const pointSeriesSpec: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -25,12 +27,11 @@ describe('Rendering points - line', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, LineSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -65,9 +66,11 @@ describe('Rendering points - line', () => {
   });
   describe('Single series line chart - ordinal', () => {
     const pointSeriesSpec: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -75,12 +78,11 @@ describe('Rendering points - line', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, LineSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -160,12 +162,14 @@ describe('Rendering points - line', () => {
     });
   });
   describe('Multi series line chart - ordinal', () => {
-    const spec1Id = getSpecId('point1');
-    const spec2Id = getSpecId('point2');
+    const spec1Id = 'point1';
+    const spec2Id = 'point2';
     const pointSeriesSpec1: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec1Id,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -174,9 +178,11 @@ describe('Rendering points - line', () => {
       yScaleType: ScaleType.Linear,
     };
     const pointSeriesSpec2: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec2Id,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[0, 20], [1, 10]],
       xAccessor: 0,
@@ -184,13 +190,11 @@ describe('Rendering points - line', () => {
       xScaleType: ScaleType.Ordinal,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, LineSeriesSpec>();
-    pointSeriesMap.set(spec1Id, pointSeriesSpec1);
-    pointSeriesMap.set(spec2Id, pointSeriesSpec2);
+    const pointSeriesMap = [pointSeriesSpec1, pointSeriesSpec2];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -341,9 +345,11 @@ describe('Rendering points - line', () => {
   });
   describe('Single series line chart - linear', () => {
     const pointSeriesSpec: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -351,12 +357,11 @@ describe('Rendering points - line', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, LineSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -435,12 +440,14 @@ describe('Rendering points - line', () => {
     });
   });
   describe('Multi series line chart - linear', () => {
-    const spec1Id = getSpecId('point1');
-    const spec2Id = getSpecId('point2');
+    const spec1Id = 'point1';
+    const spec2Id = 'point2';
     const pointSeriesSpec1: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec1Id,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5]],
       xAccessor: 0,
@@ -449,9 +456,11 @@ describe('Rendering points - line', () => {
       yScaleType: ScaleType.Linear,
     };
     const pointSeriesSpec2: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec2Id,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[0, 20], [1, 10]],
       xAccessor: 0,
@@ -459,13 +468,11 @@ describe('Rendering points - line', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, LineSeriesSpec>();
-    pointSeriesMap.set(spec1Id, pointSeriesSpec1);
-    pointSeriesMap.set(spec2Id, pointSeriesSpec2);
+    const pointSeriesMap = [pointSeriesSpec1, pointSeriesSpec2];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -615,9 +622,11 @@ describe('Rendering points - line', () => {
   });
   describe('Single series line chart - time', () => {
     const pointSeriesSpec: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[1546300800000, 10], [1546387200000, 5]],
       xAccessor: 0,
@@ -625,12 +634,11 @@ describe('Rendering points - line', () => {
       xScaleType: ScaleType.Time,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, LineSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -709,12 +717,14 @@ describe('Rendering points - line', () => {
     });
   });
   describe('Multi series line chart - time', () => {
-    const spec1Id = getSpecId('point1');
-    const spec2Id = getSpecId('point2');
+    const spec1Id = 'point1';
+    const spec2Id = 'point2';
     const pointSeriesSpec1: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec1Id,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[1546300800000, 10], [1546387200000, 5]],
       xAccessor: 0,
@@ -723,9 +733,11 @@ describe('Rendering points - line', () => {
       yScaleType: ScaleType.Linear,
     };
     const pointSeriesSpec2: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: spec2Id,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[1546300800000, 20], [1546387200000, 10]],
       xAccessor: 0,
@@ -733,13 +745,11 @@ describe('Rendering points - line', () => {
       xScaleType: ScaleType.Time,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, LineSeriesSpec>();
-    pointSeriesMap.set(spec1Id, pointSeriesSpec1);
-    pointSeriesMap.set(spec2Id, pointSeriesSpec2);
+    const pointSeriesMap = [pointSeriesSpec1, pointSeriesSpec2];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -876,9 +886,11 @@ describe('Rendering points - line', () => {
   });
   describe('Single series line chart - y log', () => {
     const pointSeriesSpec: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[0, 10], [1, 5], [2, null], [3, 5], [4, 5], [5, 0], [6, 10], [7, 10], [8, 10]],
       xAccessor: 0,
@@ -886,12 +898,11 @@ describe('Rendering points - line', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Log,
     };
-    const pointSeriesMap = new Map<SpecId, LineSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
+    const pointSeriesMap = [pointSeriesSpec];
     const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, new Map());
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: pointSeriesMap.length,
       range: [0, 90],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
@@ -947,9 +958,11 @@ describe('Rendering points - line', () => {
   });
   describe('Remove points datum is not in domain', () => {
     const pointSeriesSpec: LineSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'line',
+      seriesType: SeriesTypes.Line,
       yScaleToDataExtent: false,
       data: [[0, 0], [1, 1], [2, 10], [3, 3]],
       xAccessor: 0,
@@ -957,18 +970,16 @@ describe('Rendering points - line', () => {
       xScaleType: ScaleType.Linear,
       yScaleType: ScaleType.Linear,
     };
-    const pointSeriesMap = new Map<SpecId, LineSeriesSpec>();
-    pointSeriesMap.set(SPEC_ID, pointSeriesSpec);
     const customYDomain = new Map<GroupId, DomainRange>();
     customYDomain.set(GROUP_ID, {
       max: 1,
     });
-    const pointSeriesDomains = computeSeriesDomains(pointSeriesMap, customYDomain, {
+    const pointSeriesDomains = computeSeriesDomains([pointSeriesSpec], customYDomain, [], {
       max: 2,
     });
     const xScale = computeXScale({
       xDomain: pointSeriesDomains.xDomain,
-      totalBarsInCluster: pointSeriesMap.size,
+      totalBarsInCluster: 1,
       range: [0, 100],
     });
     const yScales = computeYScales({ yDomains: pointSeriesDomains.yDomain, range: [100, 0] });
diff --git a/src/chart_types/xy_chart/rendering/rendering.test.ts b/src/chart_types/xy_chart/rendering/rendering.test.ts
index 45b0997b5e..0c5f9c7a0e 100644
--- a/src/chart_types/xy_chart/rendering/rendering.test.ts
+++ b/src/chart_types/xy_chart/rendering/rendering.test.ts
@@ -1,17 +1,14 @@
-import { getSpecId } from '../../../utils/ids';
 import {
-  BarGeometry,
   getGeometryStateStyle,
   isPointOnGeometry,
-  PointGeometry,
   getBarStyleOverrides,
-  GeometryId,
   getPointStyleOverrides,
   getClippedRanges,
 } from './rendering';
 import { BarSeriesStyle, SharedGeometryStateStyle, PointStyle } from '../../../utils/themes/theme';
 import { DataSeriesDatum } from '../utils/series';
-import { RecursivePartial, mergePartial } from '../../../utils/commons';
+import { mergePartial, RecursivePartial } from '../../../utils/commons';
+import { BarGeometry, PointGeometry, GeometryId } from '../../../utils/geometry';
 import { MockDataSeries } from '../../../mocks';
 import { MockScale } from '../../../mocks/scale';
 
@@ -39,7 +36,7 @@ describe('Rendering utils', () => {
       color: 'red',
       geometryId: {
         seriesKey: [],
-        specId: getSpecId('id'),
+        specId: 'id',
       },
       value: {
         accessor: 'y1',
@@ -65,7 +62,7 @@ describe('Rendering utils', () => {
       color: 'red',
       geometryId: {
         seriesKey: [],
-        specId: getSpecId('id'),
+        specId: 'id',
       },
       value: {
         accessor: 'y1',
@@ -93,7 +90,7 @@ describe('Rendering utils', () => {
   test('should get common geometry style dependent on legend item highlight state', () => {
     const geometryId = {
       seriesKey: [],
-      specId: getSpecId('id'),
+      specId: 'id',
     };
     const highlightedLegendItem = {
       key: '',
@@ -101,7 +98,7 @@ describe('Rendering utils', () => {
       label: '',
       value: {
         colorValues: [],
-        specId: getSpecId('id'),
+        specId: 'id',
       },
       isSeriesVisible: true,
       isLegendItemVisible: true,
@@ -121,7 +118,7 @@ describe('Rendering utils', () => {
       ...highlightedLegendItem,
       value: {
         colorValues: [],
-        specId: getSpecId('foo'),
+        specId: 'foo',
       },
     };
 
@@ -207,7 +204,7 @@ describe('Rendering utils', () => {
       initialY0: 5,
     };
     const geometryId: GeometryId = {
-      specId: getSpecId('test'),
+      specId: 'test',
       seriesKey: ['test'],
     };
 
@@ -296,7 +293,7 @@ describe('Rendering utils', () => {
       initialY0: 5,
     };
     const geometryId: GeometryId = {
-      specId: getSpecId('test'),
+      specId: 'test',
       seriesKey: ['test'],
     };
 
diff --git a/src/chart_types/xy_chart/rendering/rendering.ts b/src/chart_types/xy_chart/rendering/rendering.ts
index 7565f5b6c3..27e81945d7 100644
--- a/src/chart_types/xy_chart/rendering/rendering.ts
+++ b/src/chart_types/xy_chart/rendering/rendering.ts
@@ -1,12 +1,8 @@
 import { area, line } from 'd3-shape';
-import { $Values } from 'utility-types';
-
 import { CanvasTextBBoxCalculator } from '../../../utils/bbox/canvas_text_bbox_calculator';
 import {
   AreaSeriesStyle,
-  AreaStyle,
   LineSeriesStyle,
-  LineStyle,
   PointStyle,
   SharedGeometryStateStyle,
   BarSeriesStyle,
@@ -16,114 +12,22 @@ import { SpecId } from '../../../utils/ids';
 import { isLogarithmicScale } from '../../../utils/scales/scale_continuous';
 import { Scale, ScaleType } from '../../../utils/scales/scales';
 import { CurveType, getCurveFactory } from '../../../utils/curves';
-import { LegendItem } from '../legend/legend';
 import { DataSeriesDatum } from '../utils/series';
 import { belongsToDataSeries } from '../utils/series_utils';
-import { DisplayValueSpec, BarStyleAccessor, PointStyleAccessor } from '../utils/specs';
+import { DisplayValueSpec, PointStyleAccessor, BarStyleAccessor } from '../utils/specs';
+import {
+  IndexedGeometry,
+  PointGeometry,
+  BarGeometry,
+  AreaGeometry,
+  LineGeometry,
+  GeometryId,
+  isPointGeometry,
+  AccessorType,
+  ClippedRanges,
+} from '../../../utils/geometry';
 import { mergePartial } from '../../../utils/commons';
-
-export interface GeometryId {
-  specId: SpecId;
-  seriesKey: any[];
-}
-
-/**
- * The accessor type
- */
-export const AccessorType = Object.freeze({
-  Y0: 'y0' as 'y0',
-  Y1: 'y1' as 'y1',
-});
-
-export type AccessorType = $Values<typeof AccessorType>;
-
-export interface GeometryValue {
-  y: any;
-  x: any;
-  accessor: AccessorType;
-}
-
-export type IndexedGeometry = PointGeometry | BarGeometry;
-
-/**
- * Array of **range** clippings [x1, x2] to be excluded during rendering
- *
- * Note: Must be scaled **range** values (i.e. pixel coordinates) **NOT** domain values
- */
-export type ClippedRanges = [number, number][];
-
-export interface PointGeometry {
-  x: number;
-  y: number;
-  radius: number;
-  color: string;
-  transform: {
-    x: number;
-    y: number;
-  };
-  geometryId: GeometryId;
-  value: GeometryValue;
-  styleOverrides?: Partial<PointStyle>;
-}
-export interface BarGeometry {
-  x: number;
-  y: number;
-  width: number;
-  height: number;
-  color: string;
-  displayValue?: {
-    text: any;
-    width: number;
-    height: number;
-    hideClippedValue?: boolean;
-    isValueContainedInElement?: boolean;
-  };
-  geometryId: GeometryId;
-  value: GeometryValue;
-  seriesStyle: BarSeriesStyle;
-}
-export interface LineGeometry {
-  line: string;
-  points: PointGeometry[];
-  color: string;
-  transform: {
-    x: number;
-    y: number;
-  };
-  geometryId: GeometryId;
-  seriesLineStyle: LineStyle;
-  seriesPointStyle: PointStyle;
-  /**
-   * Ranges of `[x0, x1]` pairs to clip from series
-   */
-  clippedRanges: ClippedRanges;
-}
-export interface AreaGeometry {
-  area: string;
-  lines: string[];
-  points: PointGeometry[];
-  color: string;
-  transform: {
-    x: number;
-    y: number;
-  };
-  geometryId: GeometryId;
-  seriesAreaStyle: AreaStyle;
-  seriesAreaLineStyle: LineStyle;
-  seriesPointStyle: PointStyle;
-  isStacked: boolean;
-  /**
-   * Ranges of `[x0, x1]` pairs to clip from series
-   */
-  clippedRanges: ClippedRanges;
-}
-
-export function isPointGeometry(ig: IndexedGeometry): ig is PointGeometry {
-  return ig.hasOwnProperty('radius');
-}
-export function isBarGeometry(ig: IndexedGeometry): ig is BarGeometry {
-  return ig.hasOwnProperty('width') && ig.hasOwnProperty('height');
-}
+import { LegendItem } from '../legend/legend';
 
 export function mutableIndexedGeometryMapUpsert(
   mutableGeometriesIndex: Map<any, IndexedGeometry[]>,
@@ -186,7 +90,7 @@ export function getBarStyleOverrides(
   });
 }
 
-export function renderPoints(
+function renderPoints(
   shift: number,
   dataset: DataSeriesDatum[],
   xScale: Scale,
@@ -354,12 +258,8 @@ export function renderBars(
           : undefined
         : formattedDisplayValue;
 
-    const computedDisplayValueWidth = bboxCalculator
-      .compute(displayValueText || '', padding, fontSize, fontFamily)
-      .getOrElse({
-        width: 0,
-        height: 0,
-      }).width;
+    const computedDisplayValueWidth = bboxCalculator.compute(displayValueText || '', padding, fontSize, fontFamily)
+      .width;
     const displayValueWidth =
       displayValueSettings && displayValueSettings.isValueContainedInElement ? width : computedDisplayValueWidth;
 
diff --git a/src/chart_types/xy_chart/specs/area_series.tsx b/src/chart_types/xy_chart/specs/area_series.tsx
index 5151a27917..5f16d672e0 100644
--- a/src/chart_types/xy_chart/specs/area_series.tsx
+++ b/src/chart_types/xy_chart/specs/area_series.tsx
@@ -1,42 +1,36 @@
-import { inject } from 'mobx-react';
-import { PureComponent } from 'react';
-import { AreaSeriesSpec, HistogramModeAlignments, DEFAULT_GLOBAL_ID } from '../utils/specs';
-import { getGroupId } from '../../../utils/ids';
+import { AreaSeriesSpec, HistogramModeAlignments, DEFAULT_GLOBAL_ID, SpecTypes, SeriesTypes } from '../utils/specs';
 import { ScaleType } from '../../../utils/scales/scales';
-import { SpecProps } from '../../../specs/specs_parser';
+import { specComponentFactory, getConnect } from '../../../state/spec_factory';
+import { ChartTypes } from '../../../chart_types';
 
-type AreaSpecProps = SpecProps & AreaSeriesSpec;
+const defaultProps = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Series,
+  seriesType: SeriesTypes.Area,
+  groupId: DEFAULT_GLOBAL_ID,
+  xScaleType: ScaleType.Ordinal,
+  yScaleType: ScaleType.Linear,
+  xAccessor: 'x',
+  yAccessors: ['y'],
+  yScaleToDataExtent: false,
+  hideInLegend: false,
+  histogramModeAlignment: HistogramModeAlignments.Center,
+};
 
-export class AreaSeriesSpecComponent extends PureComponent<AreaSpecProps> {
-  static defaultProps: Partial<AreaSpecProps> = {
-    seriesType: 'area',
-    groupId: getGroupId(DEFAULT_GLOBAL_ID),
-    xScaleType: ScaleType.Ordinal,
-    yScaleType: ScaleType.Linear,
-    xAccessor: 'x',
-    yAccessors: ['y'],
-    yScaleToDataExtent: false,
-    hideInLegend: false,
-    histogramModeAlignment: HistogramModeAlignments.Center,
-  };
-  componentDidMount() {
-    const { chartStore, children, ...config } = this.props;
-    chartStore!.addSeriesSpec({ ...config });
-  }
-  componentDidUpdate(prevProps: AreaSpecProps) {
-    const { chartStore, children, ...config } = this.props;
-    chartStore!.addSeriesSpec({ ...config });
-    if (prevProps.id !== this.props.id) {
-      chartStore!.removeSeriesSpec(prevProps.id);
-    }
-  }
-  componentWillUnmount() {
-    const { chartStore, id } = this.props;
-    chartStore!.removeSeriesSpec(id);
-  }
-  render() {
-    return null;
-  }
-}
+type SpecRequiredProps = Pick<AreaSeriesSpec, 'id' | 'data'>;
+type SpecOptionalProps = Partial<Omit<AreaSeriesSpec, 'chartType' | 'specType' | 'seriesType' | 'id' | 'data'>>;
 
-export const AreaSeries = inject('chartStore')(AreaSeriesSpecComponent);
+export const AreaSeries: React.FunctionComponent<SpecRequiredProps & SpecOptionalProps> = getConnect()(
+  specComponentFactory<
+    AreaSeriesSpec,
+    | 'seriesType'
+    | 'groupId'
+    | 'xScaleType'
+    | 'yScaleType'
+    | 'xAccessor'
+    | 'yAccessors'
+    | 'yScaleToDataExtent'
+    | 'hideInLegend'
+    | 'histogramModeAlignment'
+  >(defaultProps),
+);
diff --git a/src/chart_types/xy_chart/specs/axis.tsx b/src/chart_types/xy_chart/specs/axis.tsx
index d195bb0e7a..ca6ad98409 100644
--- a/src/chart_types/xy_chart/specs/axis.tsx
+++ b/src/chart_types/xy_chart/specs/axis.tsx
@@ -1,38 +1,35 @@
-import { inject } from 'mobx-react';
-import { PureComponent } from 'react';
-import { AxisSpec as AxisSpecType, Position, DEFAULT_GLOBAL_ID } from '../utils/specs';
-import { getGroupId } from '../../../utils/ids';
-import { SpecProps } from '../../../specs/specs_parser';
+import { AxisSpec, Position, DEFAULT_GLOBAL_ID, SpecTypes } from '../utils/specs';
+import { ChartTypes } from '../../../chart_types';
+import { specComponentFactory, getConnect } from '../../../state/spec_factory';
 
-type AxisSpecProps = SpecProps & AxisSpecType;
+const defaultProps = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Axis,
+  groupId: DEFAULT_GLOBAL_ID,
+  hide: false,
+  showOverlappingTicks: false,
+  showOverlappingLabels: false,
+  position: Position.Left,
+  tickSize: 10,
+  tickPadding: 10,
+  tickFormat: (tick: any) => `${tick}`,
+  tickLabelRotation: 0,
+};
 
-class AxisSpec extends PureComponent<AxisSpecProps> {
-  static defaultProps: Partial<AxisSpecProps> = {
-    groupId: getGroupId(DEFAULT_GLOBAL_ID),
-    hide: false,
-    showOverlappingTicks: false,
-    showOverlappingLabels: false,
-    position: Position.Left,
-    tickSize: 10,
-    tickPadding: 10,
-    tickFormat: (tick: any) => `${tick}`,
-    tickLabelRotation: 0,
-  };
-  componentDidMount() {
-    const { chartStore, children, ...spec } = this.props;
-    chartStore!.addAxisSpec({ ...spec });
-  }
-  componentDidUpdate() {
-    const { chartStore, children, ...spec } = this.props;
-    chartStore!.addAxisSpec({ ...spec });
-  }
-  componentWillUnmount() {
-    const { id } = this.props;
-    this.props.chartStore!.removeAxisSpec(id);
-  }
-  render() {
-    return null;
-  }
-}
+type SpecRequired = Pick<AxisSpec, 'id'>;
+type SpecOptionals = Partial<Omit<AxisSpec, 'chartType' | 'specType' | 'seriesType' | 'id'>>;
 
-export const Axis = inject('chartStore')(AxisSpec);
+export const Axis: React.FunctionComponent<SpecRequired & SpecOptionals> = getConnect()(
+  specComponentFactory<
+    AxisSpec,
+    | 'groupId'
+    | 'hide'
+    | 'showOverlappingTicks'
+    | 'showOverlappingLabels'
+    | 'position'
+    | 'tickSize'
+    | 'tickPadding'
+    | 'tickFormat'
+    | 'tickLabelRotation'
+  >(defaultProps),
+);
diff --git a/src/chart_types/xy_chart/specs/bar_series.tsx b/src/chart_types/xy_chart/specs/bar_series.tsx
index 91c81ad013..d7f5e5d4a0 100644
--- a/src/chart_types/xy_chart/specs/bar_series.tsx
+++ b/src/chart_types/xy_chart/specs/bar_series.tsx
@@ -1,43 +1,38 @@
-import { inject } from 'mobx-react';
-import { PureComponent } from 'react';
-import { BarSeriesSpec, DEFAULT_GLOBAL_ID } from '../utils/specs';
-import { getGroupId } from '../../../utils/ids';
+import { BarSeriesSpec, DEFAULT_GLOBAL_ID, SpecTypes, SeriesTypes } from '../utils/specs';
 import { ScaleType } from '../../../utils/scales/scales';
-import { SpecProps } from '../../../specs/specs_parser';
+import { ChartTypes } from '../../../chart_types';
+import { specComponentFactory, getConnect } from '../../../state/spec_factory';
 
-type BarSpecProps = SpecProps & BarSeriesSpec;
+const defaultProps = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Series,
+  seriesType: SeriesTypes.Bar,
+  groupId: DEFAULT_GLOBAL_ID,
+  xScaleType: ScaleType.Ordinal,
+  yScaleType: ScaleType.Linear,
+  xAccessor: 'x',
+  yAccessors: ['y'],
+  yScaleToDataExtent: false,
+  hideInLegend: false,
+  enableHistogramMode: false,
+  stackAsPercentage: false,
+};
 
-export class BarSeriesSpecComponent extends PureComponent<BarSpecProps> {
-  static defaultProps: Partial<BarSpecProps> = {
-    seriesType: 'bar',
-    groupId: getGroupId(DEFAULT_GLOBAL_ID),
-    xScaleType: ScaleType.Ordinal,
-    yScaleType: ScaleType.Linear,
-    xAccessor: 'x',
-    yAccessors: ['y'],
-    yScaleToDataExtent: false,
-    hideInLegend: false,
-    enableHistogramMode: false,
-    stackAsPercentage: false,
-  };
-  componentDidMount() {
-    const { chartStore, children, ...config } = this.props;
-    chartStore!.addSeriesSpec({ ...config });
-  }
-  componentDidUpdate(prevProps: BarSpecProps) {
-    const { chartStore, children, ...config } = this.props;
-    chartStore!.addSeriesSpec({ ...config });
-    if (prevProps.id !== this.props.id) {
-      chartStore!.removeSeriesSpec(prevProps.id);
-    }
-  }
-  componentWillUnmount() {
-    const { chartStore, id } = this.props;
-    chartStore!.removeSeriesSpec(id);
-  }
-  render() {
-    return null;
-  }
-}
+type SpecRequiredProps = Pick<BarSeriesSpec, 'id' | 'data'>;
+type SpecOptionalProps = Partial<Omit<BarSeriesSpec, 'chartType' | 'specType' | 'seriesType' | 'id' | 'data'>>;
 
-export const BarSeries = inject('chartStore')(BarSeriesSpecComponent);
+export const BarSeries: React.FunctionComponent<SpecRequiredProps & SpecOptionalProps> = getConnect()(
+  specComponentFactory<
+    BarSeriesSpec,
+    | 'seriesType'
+    | 'groupId'
+    | 'xScaleType'
+    | 'yScaleType'
+    | 'xAccessor'
+    | 'yAccessors'
+    | 'yScaleToDataExtent'
+    | 'hideInLegend'
+    | 'enableHistogramMode'
+    | 'stackAsPercentage'
+  >(defaultProps),
+);
diff --git a/src/chart_types/xy_chart/specs/histogram_bar_series.tsx b/src/chart_types/xy_chart/specs/histogram_bar_series.tsx
index 70f5621a6c..733226d822 100644
--- a/src/chart_types/xy_chart/specs/histogram_bar_series.tsx
+++ b/src/chart_types/xy_chart/specs/histogram_bar_series.tsx
@@ -1,42 +1,36 @@
-import { inject } from 'mobx-react';
-import { PureComponent } from 'react';
-import { HistogramBarSeriesSpec, DEFAULT_GLOBAL_ID } from '../utils/specs';
-import { getGroupId } from '../../../utils/ids';
+import { HistogramBarSeriesSpec, DEFAULT_GLOBAL_ID, SpecTypes, SeriesTypes } from '../utils/specs';
 import { ScaleType } from '../../../utils/scales/scales';
-import { SpecProps } from '../../../specs/specs_parser';
+import { specComponentFactory, getConnect } from '../../../state/spec_factory';
+import { ChartTypes } from '../../../chart_types';
 
-type HistogramBarSpecProps = SpecProps & HistogramBarSeriesSpec;
+const defaultProps = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Series,
+  seriesType: SeriesTypes.Bar,
+  groupId: DEFAULT_GLOBAL_ID,
+  xScaleType: ScaleType.Linear,
+  yScaleType: ScaleType.Linear,
+  xAccessor: 'x',
+  yAccessors: ['y'],
+  yScaleToDataExtent: false,
+  hideInLegend: false,
+  enableHistogramMode: true as true,
+};
 
-export class HistogramBarSeriesSpecComponent extends PureComponent<HistogramBarSpecProps> {
-  static defaultProps: Partial<HistogramBarSpecProps> = {
-    seriesType: 'bar',
-    groupId: getGroupId(DEFAULT_GLOBAL_ID),
-    xScaleType: ScaleType.Ordinal,
-    yScaleType: ScaleType.Linear,
-    xAccessor: 'x',
-    yAccessors: ['y'],
-    yScaleToDataExtent: false,
-    hideInLegend: false,
-    enableHistogramMode: true,
-  };
-  componentDidMount() {
-    const { chartStore, children, ...config } = this.props;
-    chartStore!.addSeriesSpec({ ...config });
-  }
-  componentDidUpdate(prevProps: HistogramBarSpecProps) {
-    const { chartStore, children, ...config } = this.props;
-    chartStore!.addSeriesSpec({ ...config });
-    if (prevProps.id !== this.props.id) {
-      chartStore!.removeSeriesSpec(prevProps.id);
-    }
-  }
-  componentWillUnmount() {
-    const { chartStore, id } = this.props;
-    chartStore!.removeSeriesSpec(id);
-  }
-  render() {
-    return null;
-  }
-}
+type SpecRequiredProps = Pick<HistogramBarSeriesSpec, 'id' | 'data'>;
+type SpecOptionalProps = Partial<Omit<HistogramBarSeriesSpec, 'chartType' | 'specType' | 'seriesType' | 'id' | 'data'>>;
 
-export const HistogramBarSeries = inject('chartStore')(HistogramBarSeriesSpecComponent);
+export const HistogramBarSeries: React.FunctionComponent<SpecRequiredProps & SpecOptionalProps> = getConnect()(
+  specComponentFactory<
+    HistogramBarSeriesSpec,
+    | 'seriesType'
+    | 'groupId'
+    | 'xScaleType'
+    | 'yScaleType'
+    | 'xAccessor'
+    | 'yAccessors'
+    | 'yScaleToDataExtent'
+    | 'hideInLegend'
+    | 'enableHistogramMode'
+  >(defaultProps),
+);
diff --git a/src/chart_types/xy_chart/specs/line_annotation.tsx b/src/chart_types/xy_chart/specs/line_annotation.tsx
index 7ad35481c7..96c965aabf 100644
--- a/src/chart_types/xy_chart/specs/line_annotation.tsx
+++ b/src/chart_types/xy_chart/specs/line_annotation.tsx
@@ -1,16 +1,23 @@
-import { inject } from 'mobx-react';
 import React, { createRef, CSSProperties, PureComponent } from 'react';
-import { LineAnnotationSpec, DEFAULT_GLOBAL_ID } from '../utils/specs';
+import { LineAnnotationSpec, DEFAULT_GLOBAL_ID, SpecTypes, AnnotationTypes } from '../utils/specs';
 import { DEFAULT_ANNOTATION_LINE_STYLE } from '../../../utils/themes/theme';
-import { getGroupId } from '../../../utils/ids';
-import { SpecProps } from '../../../specs/specs_parser';
+import { bindActionCreators, Dispatch } from 'redux';
+import { connect } from 'react-redux';
+import { upsertSpec, removeSpec } from '../../../state/actions/specs';
+import { Spec } from '../../../specs';
+import { ChartTypes } from '../..';
 
-type LineAnnotationProps = SpecProps & LineAnnotationSpec;
-
-export class LineAnnotationSpecComponent extends PureComponent<LineAnnotationProps> {
-  static defaultProps: Partial<LineAnnotationProps> = {
-    groupId: getGroupId(DEFAULT_GLOBAL_ID),
-    annotationType: 'line',
+type InjectedProps = LineAnnotationSpec &
+  DispatchProps &
+  Readonly<{
+    children?: React.ReactNode;
+  }>;
+export class LineAnnotationSpecComponent extends PureComponent<LineAnnotationSpec> {
+  static defaultProps: Partial<LineAnnotationSpec> = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Annotation,
+    groupId: DEFAULT_GLOBAL_ID,
+    annotationType: AnnotationTypes.Line,
     style: DEFAULT_ANNOTATION_LINE_STYLE,
     hideLines: false,
     hideTooltips: false,
@@ -21,7 +28,7 @@ export class LineAnnotationSpecComponent extends PureComponent<LineAnnotationPro
   private markerRef = createRef<HTMLDivElement>();
 
   componentDidMount() {
-    const { chartStore, children, ...config } = this.props;
+    const { children, upsertSpec, removeSpec, ...config } = this.props as InjectedProps;
     if (this.markerRef.current) {
       const { offsetWidth, offsetHeight } = this.markerRef.current;
       config.markerDimensions = {
@@ -29,10 +36,10 @@ export class LineAnnotationSpecComponent extends PureComponent<LineAnnotationPro
         height: offsetHeight,
       };
     }
-    chartStore!.addAnnotationSpec({ ...config });
+    upsertSpec({ ...config });
   }
   componentDidUpdate() {
-    const { chartStore, children, ...config } = this.props;
+    const { upsertSpec, removeSpec, children, ...config } = this.props as InjectedProps;
     if (this.markerRef.current) {
       const { offsetWidth, offsetHeight } = this.markerRef.current;
       config.markerDimensions = {
@@ -40,11 +47,11 @@ export class LineAnnotationSpecComponent extends PureComponent<LineAnnotationPro
         height: offsetHeight,
       };
     }
-    chartStore!.addAnnotationSpec({ ...config });
+    upsertSpec({ ...config });
   }
   componentWillUnmount() {
-    const { chartStore, annotationId } = this.props;
-    chartStore!.removeAnnotationSpec(annotationId);
+    const { removeSpec, id } = this.props as InjectedProps;
+    removeSpec(id);
   }
   render() {
     if (!this.props.marker) {
@@ -68,4 +75,32 @@ export class LineAnnotationSpecComponent extends PureComponent<LineAnnotationPro
   }
 }
 
-export const LineAnnotation = inject('chartStore')(LineAnnotationSpecComponent);
+interface DispatchProps {
+  upsertSpec: (spec: Spec) => void;
+  removeSpec: (id: string) => void;
+}
+const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
+  bindActionCreators(
+    {
+      upsertSpec,
+      removeSpec,
+    },
+    dispatch,
+  );
+
+type SpecRequiredProps = Pick<LineAnnotationSpec, 'id' | 'dataValues' | 'domainType'>;
+type SpecOptionalProps = Partial<
+  Omit<
+    LineAnnotationSpec,
+    'chartType' | 'specType' | 'seriesType' | 'id' | 'dataValues' | 'domainType' | 'annotationType'
+  >
+>;
+
+export const LineAnnotation: React.FunctionComponent<SpecRequiredProps & SpecOptionalProps> = connect<
+  {},
+  DispatchProps,
+  LineAnnotationSpec
+>(
+  null,
+  mapDispatchToProps,
+)(LineAnnotationSpecComponent);
diff --git a/src/chart_types/xy_chart/specs/line_series.tsx b/src/chart_types/xy_chart/specs/line_series.tsx
index acf5023080..86b48265c8 100644
--- a/src/chart_types/xy_chart/specs/line_series.tsx
+++ b/src/chart_types/xy_chart/specs/line_series.tsx
@@ -1,42 +1,35 @@
-import { inject } from 'mobx-react';
-import { PureComponent } from 'react';
-import { HistogramModeAlignments, LineSeriesSpec, DEFAULT_GLOBAL_ID } from '../utils/specs';
-import { getGroupId } from '../../../utils/ids';
+import { LineSeriesSpec, DEFAULT_GLOBAL_ID, HistogramModeAlignments, SpecTypes, SeriesTypes } from '../utils/specs';
 import { ScaleType } from '../../../utils/scales/scales';
-import { SpecProps } from '../../../specs/specs_parser';
+import { ChartTypes } from '../../../chart_types';
+import { specComponentFactory, getConnect } from '../../../state/spec_factory';
 
-type LineSpecProps = SpecProps & LineSeriesSpec;
+const defaultProps = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Series,
+  seriesType: SeriesTypes.Line,
+  groupId: DEFAULT_GLOBAL_ID,
+  xScaleType: ScaleType.Ordinal,
+  yScaleType: ScaleType.Linear,
+  xAccessor: 'x',
+  yAccessors: ['y'],
+  yScaleToDataExtent: false,
+  hideInLegend: false,
+  histogramModeAlignment: HistogramModeAlignments.Center,
+};
+type SpecRequiredProps = Pick<LineSeriesSpec, 'id' | 'data'>;
+type SpecOptionalProps = Partial<Omit<LineSeriesSpec, 'chartType' | 'specType' | 'seriesType' | 'id' | 'data'>>;
 
-export class LineSeriesSpecComponent extends PureComponent<LineSpecProps> {
-  static defaultProps: Partial<LineSpecProps> = {
-    seriesType: 'line',
-    groupId: getGroupId(DEFAULT_GLOBAL_ID),
-    xScaleType: ScaleType.Ordinal,
-    yScaleType: ScaleType.Linear,
-    xAccessor: 'x',
-    yAccessors: ['y'],
-    yScaleToDataExtent: false,
-    hideInLegend: false,
-    histogramModeAlignment: HistogramModeAlignments.Center,
-  };
-  componentDidMount() {
-    const { chartStore, children, ...config } = this.props;
-    chartStore!.addSeriesSpec({ ...config });
-  }
-  componentDidUpdate(prevProps: LineSpecProps) {
-    const { chartStore, children, ...config } = this.props;
-    chartStore!.addSeriesSpec({ ...config });
-    if (prevProps.id !== this.props.id) {
-      chartStore!.removeSeriesSpec(prevProps.id);
-    }
-  }
-  componentWillUnmount() {
-    const { chartStore, id } = this.props;
-    chartStore!.removeSeriesSpec(id);
-  }
-  render() {
-    return null;
-  }
-}
-
-export const LineSeries = inject('chartStore')(LineSeriesSpecComponent);
+export const LineSeries: React.FunctionComponent<SpecRequiredProps & SpecOptionalProps> = getConnect()(
+  specComponentFactory<
+    LineSeriesSpec,
+    | 'seriesType'
+    | 'groupId'
+    | 'xScaleType'
+    | 'yScaleType'
+    | 'xAccessor'
+    | 'yAccessors'
+    | 'yScaleToDataExtent'
+    | 'hideInLegend'
+    | 'histogramModeAlignment'
+  >(defaultProps),
+);
diff --git a/src/chart_types/xy_chart/specs/rect_annotation.tsx b/src/chart_types/xy_chart/specs/rect_annotation.tsx
index f31788fc7b..7d3655d257 100644
--- a/src/chart_types/xy_chart/specs/rect_annotation.tsx
+++ b/src/chart_types/xy_chart/specs/rect_annotation.tsx
@@ -1,33 +1,24 @@
-import { inject } from 'mobx-react';
-import { PureComponent } from 'react';
-import { RectAnnotationSpec, DEFAULT_GLOBAL_ID } from '../utils/specs';
-import { getGroupId } from '../../../utils/ids';
-import { SpecProps } from '../../../specs/specs_parser';
+import { RectAnnotationSpec, DEFAULT_GLOBAL_ID, SpecTypes, AnnotationTypes } from '../utils/specs';
+import { specComponentFactory, getConnect } from '../../../state/spec_factory';
+import { DEFAULT_ANNOTATION_RECT_STYLE } from '../../../utils/themes/theme';
+import { ChartTypes } from '../../index';
 
-type RectAnnotationProps = SpecProps & RectAnnotationSpec;
+const defaultProps = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Annotation,
+  groupId: DEFAULT_GLOBAL_ID,
+  annotationType: AnnotationTypes.Rectangle,
+  zIndex: -1,
+  style: DEFAULT_ANNOTATION_RECT_STYLE,
+};
 
-export class RectAnnotationSpecComponent extends PureComponent<RectAnnotationProps> {
-  static defaultProps: Partial<RectAnnotationProps> = {
-    groupId: getGroupId(DEFAULT_GLOBAL_ID),
-    annotationType: 'rectangle',
-    zIndex: -1,
-  };
-
-  componentDidMount() {
-    const { chartStore, children, ...config } = this.props;
-    chartStore!.addAnnotationSpec({ ...config });
-  }
-  componentDidUpdate() {
-    const { chartStore, children, ...config } = this.props;
-    chartStore!.addAnnotationSpec({ ...config });
-  }
-  componentWillUnmount() {
-    const { chartStore, annotationId } = this.props;
-    chartStore!.removeAnnotationSpec(annotationId);
-  }
-  render() {
-    return null;
-  }
-}
-
-export const RectAnnotation = inject('chartStore')(RectAnnotationSpecComponent);
+type SpecRequiredProps = Pick<RectAnnotationSpec, 'id' | 'dataValues'>;
+type SpecOptionalProps = Partial<
+  Omit<
+    RectAnnotationSpec,
+    'chartType' | 'specType' | 'seriesType' | 'id' | 'dataValues' | 'domainType' | 'annotationType'
+  >
+>;
+export const RectAnnotation: React.FunctionComponent<SpecRequiredProps & SpecOptionalProps> = getConnect()(
+  specComponentFactory<RectAnnotationSpec, 'groupId' | 'annotationType' | 'zIndex' | 'style'>(defaultProps),
+);
diff --git a/src/chart_types/xy_chart/store/__snapshots__/utils.test.ts.snap b/src/chart_types/xy_chart/state/__snapshots__/utils.test.ts.snap
similarity index 100%
rename from src/chart_types/xy_chart/store/__snapshots__/utils.test.ts.snap
rename to src/chart_types/xy_chart/state/__snapshots__/utils.test.ts.snap
diff --git a/src/chart_types/xy_chart/state/chart_state.interactions.test.ts b/src/chart_types/xy_chart/state/chart_state.interactions.test.ts
new file mode 100644
index 0000000000..2d7bb31c4c
--- /dev/null
+++ b/src/chart_types/xy_chart/state/chart_state.interactions.test.ts
@@ -0,0 +1,655 @@
+import { createStore, Store } from 'redux';
+import { BarSeriesSpec, BasicSeriesSpec, AxisSpec, Position, SpecTypes, SeriesTypes } from '../utils/specs';
+import { TooltipType } from '../utils/interactions';
+import { ScaleType } from '../../../utils/scales/scales';
+import { chartStoreReducer, GlobalChartState } from '../../../state/chart_state';
+import { SettingsSpec, DEFAULT_SETTINGS_SPEC } from '../../../specs';
+import { computeSeriesGeometriesSelector } from './selectors/compute_series_geometries';
+import { getProjectedPointerPositionSelector } from './selectors/get_projected_pointer_position';
+import {
+  getHighlightedGeomsSelector,
+  getTooltipValuesAndGeometriesSelector,
+} from './selectors/get_tooltip_values_highlighted_geoms';
+import { isTooltipVisibleSelector } from './selectors/is_tooltip_visible';
+import { createOnElementOutCaller } from './selectors/on_element_out_caller';
+import { createOnElementOverCaller } from './selectors/on_element_over_caller';
+import { getCursorBandPositionSelector } from './selectors/get_cursor_band';
+import { getSettingsSpecSelector } from '../../../state/selectors/get_settings_specs';
+import { upsertSpec, specParsed } from '../../../state/actions/specs';
+import { updateParentDimensions } from '../../../state/actions/chart_settings';
+import { onPointerMove } from '../../../state/actions/mouse';
+import { ChartTypes } from '../..';
+
+const SPEC_ID = 'spec_1';
+const GROUP_ID = 'group_1';
+
+const ordinalBarSeries: BarSeriesSpec = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Series,
+  id: SPEC_ID,
+  groupId: GROUP_ID,
+  seriesType: SeriesTypes.Bar,
+  yScaleToDataExtent: false,
+  data: [[0, 10], [1, 5]],
+  xAccessor: 0,
+  yAccessors: [1],
+  xScaleType: ScaleType.Ordinal,
+  yScaleType: ScaleType.Linear,
+  hideInLegend: false,
+};
+const linearBarSeries: BarSeriesSpec = {
+  chartType: ChartTypes.XYAxis,
+  specType: SpecTypes.Series,
+  id: SPEC_ID,
+  groupId: GROUP_ID,
+  seriesType: SeriesTypes.Bar,
+  yScaleToDataExtent: false,
+  data: [[0, 10], [1, 5]],
+  xAccessor: 0,
+  yAccessors: [1],
+  xScaleType: ScaleType.Linear,
+  yScaleType: ScaleType.Linear,
+  hideInLegend: false,
+};
+const chartTop = 10;
+const chartLeft = 10;
+const settingSpec: SettingsSpec = {
+  ...DEFAULT_SETTINGS_SPEC,
+  tooltip: {
+    type: TooltipType.VerticalCursor,
+  },
+  hideDuplicateAxes: false,
+  theme: {
+    chartPaddings: { top: 0, left: 0, bottom: 0, right: 0 },
+    chartMargins: { top: 10, left: 10, bottom: 0, right: 0 },
+    scales: {
+      barsPadding: 0,
+    },
+  },
+};
+
+function initStore(spec: BasicSeriesSpec) {
+  const storeReducer = chartStoreReducer('chartId');
+  const store = createStore(storeReducer);
+
+  store.dispatch(upsertSpec(settingSpec));
+  store.dispatch(upsertSpec(spec));
+  store.dispatch(specParsed());
+  store.dispatch(updateParentDimensions({ width: 100, height: 100, top: chartTop, left: chartLeft }));
+
+  return store;
+}
+
+// const barStyle = {
+//   rect: {
+//     opacity: 1,
+//   },
+//   rectBorder: {
+//     strokeWidth: 1,
+//     visible: false,
+//   },
+//   displayValue: {
+//     fill: 'black',
+//     fontFamily: '',
+//     fontSize: 2,
+//     offsetX: 0,
+//     offsetY: 0,
+//     padding: 2,
+//   },
+// };
+// const indexedGeom1Red: BarGeometry = {
+//   color: 'red',
+//   x: 0,
+//   y: 0,
+//   width: 50,
+//   height: 100,
+//   value: {
+//     x: 0,
+//     y: 10,
+//     accessor: 'y1',
+//   },
+//   geometryId: {
+//     specId: SPEC_ID,
+//     seriesKey: [],
+//   },
+//   seriesStyle: barStyle,
+// };
+// const indexedGeom2Blue: BarGeometry = {
+//   color: 'blue',
+//   x: 50,
+//   y: 50,
+//   width: 50,
+//   height: 50,
+//   value: {
+//     x: 1,
+//     y: 5,
+//     accessor: 'y1',
+//   },
+//   geometryId: {
+//     specId: SPEC_ID,
+//     seriesKey: [],
+//   },
+//   seriesStyle: barStyle,
+// };
+
+describe('Chart state pointer interactions', () => {
+  let store: Store<GlobalChartState>;
+  const onElementOutCaller = createOnElementOutCaller();
+  const onElementOverCaller = createOnElementOverCaller();
+  beforeEach(() => {
+    store = initStore(ordinalBarSeries);
+  });
+  test('check initial geoms', () => {
+    const { geometries } = computeSeriesGeometriesSelector(store.getState());
+    expect(geometries).toBeDefined();
+    expect(geometries.bars).toBeDefined();
+    expect(geometries.bars.length).toBe(2);
+  });
+
+  test('can convert/limit mouse pointer positions relative to chart projection', () => {
+    store.dispatch(onPointerMove({ x: 20, y: 20 }, 0));
+    let projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition.x).toBe(10);
+    expect(projectedPointerPosition.y).toBe(10);
+
+    store.dispatch(onPointerMove({ x: 10, y: 10 }, 1));
+    projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition.x).toBe(0);
+    expect(projectedPointerPosition.y).toBe(0);
+    store.dispatch(onPointerMove({ x: 5, y: 5 }, 2));
+    projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition.x).toBe(-1);
+    expect(projectedPointerPosition.y).toBe(-1);
+    store.dispatch(onPointerMove({ x: 200, y: 20 }, 3));
+    projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition.x).toBe(-1);
+    expect(projectedPointerPosition.y).toBe(10);
+    store.dispatch(onPointerMove({ x: 20, y: 200 }, 4));
+    projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition.x).toBe(10);
+    expect(projectedPointerPosition.y).toBe(-1);
+    store.dispatch(onPointerMove({ x: 200, y: 200 }, 5));
+    projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition.x).toBe(-1);
+    expect(projectedPointerPosition.y).toBe(-1);
+    store.dispatch(onPointerMove({ x: -20, y: -20 }, 6));
+    projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition.x).toBe(-1);
+    expect(projectedPointerPosition.y).toBe(-1);
+  });
+
+  test('call onElementOut if moving the mouse out from the chart', () => {
+    const onOutListener = jest.fn((): undefined => undefined);
+    const settingsWithListeners: SettingsSpec = {
+      ...settingSpec,
+      onElementOut: onOutListener,
+    };
+    store.dispatch(upsertSpec(settingsWithListeners));
+    store.dispatch(specParsed());
+    // registering the out/over listener caller
+    store.subscribe(() => {
+      onElementOutCaller(store.getState());
+      onElementOverCaller(store.getState());
+    });
+    store.dispatch(onPointerMove({ x: 20, y: 20 }, 0));
+    expect(onOutListener).toBeCalledTimes(0);
+
+    // no more calls after the first out one outside chart
+    store.dispatch(onPointerMove({ x: 5, y: 5 }, 1));
+    expect(onOutListener).toBeCalledTimes(1);
+    store.dispatch(onPointerMove({ x: 3, y: 3 }, 2));
+    expect(onOutListener).toBeCalledTimes(1);
+  });
+
+  test('can respond to tooltip types changes', () => {
+    let updatedSettings: SettingsSpec = {
+      ...settingSpec,
+      tooltip: {
+        type: TooltipType.None,
+      },
+    };
+    store.dispatch(upsertSpec(updatedSettings));
+    store.dispatch(specParsed());
+    store.dispatch(onPointerMove({ x: 10, y: 10 + 70 }, 0));
+    const tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.tooltipValues.length).toBe(2);
+    expect(tooltipData.tooltipValues[0].isXValue).toBe(true);
+    expect(tooltipData.tooltipValues[1].isXValue).toBe(false);
+    expect(tooltipData.tooltipValues[1].isHighlighted).toBe(true);
+    let isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(false);
+
+    updatedSettings = {
+      ...settingSpec,
+      tooltip: {
+        type: TooltipType.Follow,
+      },
+    };
+    store.dispatch(upsertSpec(updatedSettings));
+    store.dispatch(specParsed());
+    store.dispatch(onPointerMove({ x: 10, y: 10 + 70 }, 1));
+    const { geometriesIndex } = computeSeriesGeometriesSelector(store.getState());
+    expect(geometriesIndex.size).toBe(2);
+    const highlightedGeometries = getHighlightedGeomsSelector(store.getState());
+    expect(highlightedGeometries.length).toBe(1);
+    isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(true);
+  });
+
+  describe('mouse over with Ordinal scale', () => {
+    mouseOverTestSuite(ScaleType.Ordinal);
+  });
+  describe('mouse over with Linear scale', () => {
+    mouseOverTestSuite(ScaleType.Linear);
+  });
+
+  // TODO add test for point series
+  // TODO add test for mixed series
+  // TODO add test for clicks
+});
+
+function mouseOverTestSuite(scaleType: ScaleType) {
+  let store: Store<GlobalChartState>;
+  let onOverListener: jest.Mock<undefined>;
+  let onOutListener: jest.Mock<undefined>;
+  const spec = scaleType === ScaleType.Ordinal ? ordinalBarSeries : linearBarSeries;
+  beforeEach(() => {
+    store = initStore(spec);
+    onOverListener = jest.fn((): undefined => undefined);
+    onOutListener = jest.fn((): undefined => undefined);
+    const settingsWithListeners: SettingsSpec = {
+      ...settingSpec,
+      onElementOver: onOverListener,
+      onElementOut: onOutListener,
+    };
+    store.dispatch(upsertSpec(settingsWithListeners));
+    store.dispatch(specParsed());
+    const onElementOutCaller = createOnElementOutCaller();
+    const onElementOverCaller = createOnElementOverCaller();
+    store.subscribe(() => {
+      onElementOutCaller(store.getState());
+      onElementOverCaller(store.getState());
+    });
+    const tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.tooltipValues).toEqual([]);
+  });
+
+  test('store is correctly configured', () => {
+    // checking this to avoid broken tests due to nested describe and before
+    const seriesGeoms = computeSeriesGeometriesSelector(store.getState());
+    expect(seriesGeoms.scales.xScale).not.toBeUndefined();
+    expect(seriesGeoms.scales.yScales).not.toBeUndefined();
+  });
+
+  test.skip('set cursor from external source', () => {
+    // store.setCursorValue(0);
+    // expect(store.externalCursorShown.get()).toBe(true);
+    // expect(store.cursorBandPosition).toEqual({
+    //   height: 100,
+    //   left: 10,
+    //   top: 10,
+    //   visible: true,
+    //   width: 50,
+    // });
+    // store.setCursorValue(1);
+    // expect(store.externalCursorShown.get()).toBe(true);
+    // expect(store.cursorBandPosition).toEqual({
+    //   height: 100,
+    //   left: 60,
+    //   top: 10,
+    //   visible: true,
+    //   width: 50,
+    // });
+    // store.setCursorValue(2);
+    // expect(store.externalCursorShown.get()).toBe(true);
+    // // equal to the latest except the visiblility
+    // expect(store.cursorBandPosition).toEqual({
+    //   height: 100,
+    //   left: 60,
+    //   top: 10,
+    //   visible: false,
+    //   width: 50,
+    // });
+  });
+  test.skip('can determine which tooltip to display if chart & annotation tooltips possible', () => {
+    // const annotationDimensions = [{ rect: { x: 49, y: -1, width: 3, height: 99 } }];
+    // const rectAnnotationSpec: RectAnnotationSpec = {
+    //   id: 'rect',
+    //   groupId: GROUP_ID,
+    //   annotationType: 'rectangle',
+    //   dataValues: [{ coordinates: { x0: 1, x1: 1.5, y0: 0.5, y1: 10 } }],
+    // };
+    // store.annotationSpecs.set(rectAnnotationSpec.annotationId, rectAnnotationSpec);
+    // store.annotationDimensions.set(rectAnnotationSpec.annotationId, annotationDimensions);
+    // debugger;
+    // // isHighlighted false, chart tooltip true; should show annotationTooltip only
+    // store.setCursorPosition(chartLeft + 51, chartTop + 1);
+    // expect(store.isTooltipVisible.get()).toBe(false);
+  });
+
+  test('can hover top-left corner of the first bar', () => {
+    let tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.tooltipValues).toEqual([]);
+    store.dispatch(onPointerMove({ x: chartLeft + 0, y: chartTop + 0 }, 0));
+    let projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition).toEqual({ x: 0, y: 0 });
+    const cursorBandPosition = getCursorBandPositionSelector(store.getState());
+    expect(cursorBandPosition).toBeDefined();
+    expect(cursorBandPosition!.left).toBe(chartLeft + 0);
+    expect(cursorBandPosition!.width).toBe(45);
+    let isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(true);
+    tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.tooltipValues.length).toBe(2); // x value + 1 y value
+    expect(tooltipData.highlightedGeometries.length).toBe(1);
+    expect(onOverListener).toBeCalledTimes(1);
+    expect(onOutListener).toBeCalledTimes(0);
+    expect(onOverListener.mock.calls[0][0]).toEqual([
+      {
+        x: 0,
+        y: 10,
+        accessor: 'y1',
+      },
+    ]);
+
+    store.dispatch(onPointerMove({ x: chartLeft - 1, y: chartTop - 1 }, 1));
+    projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition).toEqual({ x: -1, y: -1 });
+    isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(false);
+    tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.tooltipValues.length).toBe(0);
+    expect(tooltipData.highlightedGeometries.length).toBe(0);
+    expect(onOverListener).toBeCalledTimes(1);
+    expect(onOutListener).toBeCalledTimes(1);
+  });
+
+  test('can hover bottom-left corner of the first bar', () => {
+    store.dispatch(onPointerMove({ x: chartLeft + 0, y: chartTop + 89 }, 0));
+    let projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition).toEqual({ x: 0, y: 89 });
+    const cursorBandPosition = getCursorBandPositionSelector(store.getState());
+    expect(cursorBandPosition).toBeDefined();
+    expect(cursorBandPosition!.left).toBe(chartLeft + 0);
+    expect(cursorBandPosition!.width).toBe(45);
+    let isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(true);
+    let tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.highlightedGeometries.length).toBe(1);
+    expect(tooltipData.tooltipValues.length).toBe(2); // x value + 1 y value
+    expect(onOverListener).toBeCalledTimes(1);
+    expect(onOutListener).toBeCalledTimes(0);
+    expect(onOverListener.mock.calls[0][0]).toEqual([
+      {
+        x: 0,
+        y: 10,
+        accessor: 'y1',
+      },
+    ]);
+    store.dispatch(onPointerMove({ x: chartLeft - 1, y: chartTop + 89 }, 1));
+    projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition).toEqual({ x: -1, y: 89 });
+    isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(false);
+    tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.tooltipValues.length).toBe(0);
+    expect(tooltipData.highlightedGeometries.length).toBe(0);
+    expect(onOverListener).toBeCalledTimes(1);
+    expect(onOutListener).toBeCalledTimes(1);
+  });
+
+  test('can hover top-right corner of the first bar', () => {
+    let scaleOffset = 0;
+    if (scaleType !== ScaleType.Ordinal) {
+      scaleOffset = 1;
+    }
+    store.dispatch(onPointerMove({ x: chartLeft + 44 + scaleOffset, y: chartTop + 0 }, 0));
+    let projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition).toEqual({ x: 44 + scaleOffset, y: 0 });
+    let cursorBandPosition = getCursorBandPositionSelector(store.getState());
+    expect(cursorBandPosition).toBeDefined();
+    expect(cursorBandPosition!.left).toBe(chartLeft + 0);
+    expect(cursorBandPosition!.width).toBe(45);
+    let isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(true);
+    let tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.highlightedGeometries.length).toBe(1);
+    expect(tooltipData.tooltipValues.length).toBe(2);
+    expect(onOverListener).toBeCalledTimes(1);
+    expect(onOutListener).toBeCalledTimes(0);
+    expect(onOverListener.mock.calls[0][0]).toEqual([
+      {
+        x: 0,
+        y: 10,
+        accessor: 'y1',
+      },
+    ]);
+
+    store.dispatch(onPointerMove({ x: chartLeft + 45 + scaleOffset, y: chartTop + 0 }, 1));
+    projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition).toEqual({ x: 45 + scaleOffset, y: 0 });
+    cursorBandPosition = getCursorBandPositionSelector(store.getState());
+    expect(cursorBandPosition).toBeDefined();
+    expect(cursorBandPosition!.left).toBe(chartLeft + 45);
+    expect(cursorBandPosition!.width).toBe(45);
+    isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(true);
+    tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.tooltipValues.length).toBe(2);
+    expect(tooltipData.highlightedGeometries.length).toBe(0);
+    expect(onOverListener).toBeCalledTimes(1);
+    expect(onOutListener).toBeCalledTimes(1);
+  });
+
+  test('can hover bottom-right corner of the first bar', () => {
+    let scaleOffset = 0;
+    if (scaleType !== ScaleType.Ordinal) {
+      scaleOffset = 1;
+    }
+    store.dispatch(onPointerMove({ x: chartLeft + 44 + scaleOffset, y: chartTop + 89 }, 0));
+    let projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition).toEqual({ x: 44 + scaleOffset, y: 89 });
+    let cursorBandPosition = getCursorBandPositionSelector(store.getState());
+    expect(cursorBandPosition).toBeDefined();
+    expect(cursorBandPosition!.left).toBe(chartLeft + 0);
+    expect(cursorBandPosition!.width).toBe(45);
+    let isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(true);
+    let tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.highlightedGeometries.length).toBe(1);
+    expect(tooltipData.tooltipValues.length).toBe(2);
+    expect(onOverListener).toBeCalledTimes(1);
+    expect(onOutListener).toBeCalledTimes(0);
+    expect(onOverListener.mock.calls[0][0]).toEqual([
+      {
+        x: spec.data[0][0],
+        y: spec.data[0][1],
+        accessor: 'y1',
+      },
+    ]);
+
+    store.dispatch(onPointerMove({ x: chartLeft + 45 + scaleOffset, y: chartTop + 89 }, 1));
+    projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition).toEqual({ x: 45 + scaleOffset, y: 89 });
+    cursorBandPosition = getCursorBandPositionSelector(store.getState());
+    expect(cursorBandPosition).toBeDefined();
+    expect(cursorBandPosition!.left).toBe(chartLeft + 45);
+    expect(cursorBandPosition!.width).toBe(45);
+    isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(true);
+    tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.tooltipValues.length).toBe(2);
+    // we are over the second bar here
+    expect(tooltipData.highlightedGeometries.length).toBe(1);
+    expect(onOverListener).toBeCalledTimes(2);
+    expect(onOverListener.mock.calls[1][0]).toEqual([
+      {
+        x: spec.data[1][0],
+        y: spec.data[1][1],
+        accessor: 'y1',
+      },
+    ]);
+
+    expect(onOutListener).toBeCalledTimes(0);
+
+    store.dispatch(onPointerMove({ x: chartLeft + 47 + scaleOffset, y: chartTop + 89 }, 2));
+  });
+
+  test('can hover top-right corner of the chart', () => {
+    expect(onOverListener).toBeCalledTimes(0);
+    expect(onOutListener).toBeCalledTimes(0);
+    let tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.highlightedGeometries.length).toBe(0);
+    expect(tooltipData.tooltipValues.length).toBe(0);
+
+    store.dispatch(onPointerMove({ x: chartLeft + 89, y: chartTop + 0 }, 0));
+    const projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    expect(projectedPointerPosition).toEqual({ x: 89, y: 0 });
+    const cursorBandPosition = getCursorBandPositionSelector(store.getState());
+    expect(cursorBandPosition).toBeDefined();
+    expect(cursorBandPosition!.left).toBe(chartLeft + 45);
+    expect(cursorBandPosition!.width).toBe(45);
+
+    const isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(true);
+    tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.highlightedGeometries.length).toBe(0);
+    expect(tooltipData.tooltipValues.length).toBe(2);
+    expect(onOverListener).toBeCalledTimes(0);
+    expect(onOutListener).toBeCalledTimes(0);
+  });
+
+  test('will call only one time the listener with the same values', () => {
+    expect(onOverListener).toBeCalledTimes(0);
+    expect(onOutListener).toBeCalledTimes(0);
+    let halfWidth = 45;
+    if (scaleType !== ScaleType.Ordinal) {
+      halfWidth = 46;
+    }
+    let timeCounter = 0;
+    for (let i = 0; i < halfWidth; i++) {
+      store.dispatch(onPointerMove({ x: chartLeft + i, y: chartTop + 89 }, timeCounter));
+      expect(onOverListener).toBeCalledTimes(1);
+      expect(onOutListener).toBeCalledTimes(0);
+      timeCounter++;
+    }
+    for (let i = halfWidth; i < 90; i++) {
+      store.dispatch(onPointerMove({ x: chartLeft + i, y: chartTop + 89 }, timeCounter));
+      expect(onOverListener).toBeCalledTimes(2);
+      expect(onOutListener).toBeCalledTimes(0);
+      timeCounter++;
+    }
+    for (let i = 0; i < halfWidth; i++) {
+      store.dispatch(onPointerMove({ x: chartLeft + i, y: chartTop + 0 }, timeCounter));
+      expect(onOverListener).toBeCalledTimes(3);
+      expect(onOutListener).toBeCalledTimes(0);
+      timeCounter++;
+    }
+    for (let i = halfWidth; i < 90; i++) {
+      store.dispatch(onPointerMove({ x: chartLeft + i, y: chartTop + 0 }, timeCounter));
+      expect(onOverListener).toBeCalledTimes(3);
+      expect(onOutListener).toBeCalledTimes(1);
+      timeCounter++;
+    }
+  });
+
+  test('can hover bottom-right corner of the chart', () => {
+    store.dispatch(onPointerMove({ x: chartLeft + 89, y: chartTop + 89 }, 0));
+    const projectedPointerPosition = getProjectedPointerPositionSelector(store.getState());
+    // store.setCursorPosition(chartLeft + 99, chartTop + 99);
+    expect(projectedPointerPosition).toEqual({ x: 89, y: 89 });
+    const cursorBandPosition = getCursorBandPositionSelector(store.getState());
+    expect(cursorBandPosition).toBeDefined();
+    expect(cursorBandPosition!.left).toBe(chartLeft + 45);
+    expect(cursorBandPosition!.width).toBe(45);
+    const isTooltipVisible = isTooltipVisibleSelector(store.getState());
+    expect(isTooltipVisible).toBe(true);
+    const tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+    expect(tooltipData.highlightedGeometries.length).toBe(1);
+    expect(tooltipData.tooltipValues.length).toBe(2);
+    expect(onOverListener).toBeCalledTimes(1);
+    expect(onOverListener.mock.calls[0][0]).toEqual([
+      {
+        x: 1,
+        y: 5,
+        accessor: 'y1',
+      },
+    ]);
+    expect(onOutListener).toBeCalledTimes(0);
+  });
+
+  describe.skip('can position tooltip within chart when xScale is a single value scale', () => {
+    beforeEach(() => {
+      // const singleValueScale =
+      //   store.xScale!.type === ScaleType.Ordinal
+      //     ? new ScaleBand(['a'], [0, 0])
+      //     : new ScaleContinuous({ type: ScaleType.Linear, domain: [1, 1], range: [0, 0] });
+      // store.xScale = singleValueScale;
+    });
+    test.skip('horizontal chart rotation', () => {
+      // store.setCursorPosition(chartLeft + 99, chartTop + 99);
+      // const expectedTransform = `translateX(${chartLeft}px) translateX(-0%) translateY(109px) translateY(-100%)`;
+      // expect(store.tooltipPosition.transform).toBe(expectedTransform);
+    });
+
+    test.skip('vertical chart rotation', () => {
+      // store.chartRotation = 90;
+      // store.setCursorPosition(chartLeft + 99, chartTop + 99);
+      // const expectedTransform = `translateX(109px) translateX(-100%) translateY(${chartTop}px) translateY(-0%)`;
+      // expect(store.tooltipPosition.transform).toBe(expectedTransform);
+    });
+  });
+  describe('can format tooltip values on rotated chart', () => {
+    beforeEach(() => {
+      const leftAxis: AxisSpec = {
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Axis,
+        hide: true,
+        id: 'yaxis',
+        groupId: GROUP_ID,
+        position: Position.Left,
+        tickFormat: (value) => `left ${Number(value)}`,
+        showOverlappingLabels: false,
+        showOverlappingTicks: false,
+        tickPadding: 0,
+        tickSize: 0,
+      };
+      const bottomAxis: AxisSpec = {
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Axis,
+        hide: true,
+        id: 'xaxis',
+        groupId: GROUP_ID,
+        position: Position.Bottom,
+        tickFormat: (value) => `bottom ${Number(value)}`,
+        showOverlappingLabels: false,
+        showOverlappingTicks: false,
+        tickPadding: 0,
+        tickSize: 0,
+      };
+      store.dispatch(upsertSpec(leftAxis));
+      store.dispatch(upsertSpec(bottomAxis));
+      store.dispatch(specParsed());
+    });
+    test('chart 0 rotation', () => {
+      store.dispatch(onPointerMove({ x: chartLeft + 0, y: chartTop + 89 }, 0));
+      const tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+      expect(tooltipData.tooltipValues[0].value).toBe('bottom 0');
+      expect(tooltipData.tooltipValues[1].value).toBe('left 10');
+    });
+
+    test('chart 90 deg rotated', () => {
+      const settings = getSettingsSpecSelector(store.getState());
+      const updatedSettings: SettingsSpec = {
+        ...settings,
+        rotation: 90,
+      };
+      store.dispatch(upsertSpec(updatedSettings));
+      store.dispatch(specParsed());
+      store.dispatch(onPointerMove({ x: chartLeft + 0, y: chartTop + 89 }, 0));
+      const tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
+      expect(tooltipData.tooltipValues[0].value).toBe('left 1');
+      expect(tooltipData.tooltipValues[1].value).toBe('bottom 5');
+    });
+  });
+}
diff --git a/src/chart_types/xy_chart/store/chart_state.test.ts b/src/chart_types/xy_chart/state/chart_state.test.ts
similarity index 85%
rename from src/chart_types/xy_chart/store/chart_state.test.ts
rename to src/chart_types/xy_chart/state/chart_state.test.ts
index 7d640d9b3e..b9d103517e 100644
--- a/src/chart_types/xy_chart/store/chart_state.test.ts
+++ b/src/chart_types/xy_chart/state/chart_state.test.ts
@@ -1,5 +1,3 @@
-import { LegendItem } from '../legend/legend';
-import { GeometryValue, IndexedGeometry, AccessorType } from '../rendering/rendering';
 import {
   AnnotationDomainTypes,
   AnnotationSpec,
@@ -8,28 +6,35 @@ import {
   BarSeriesSpec,
   Position,
   RectAnnotationSpec,
+  SpecTypes,
+  SeriesTypes,
 } from '../utils/specs';
 import { LIGHT_THEME } from '../../../utils/themes/light_theme';
 import { mergeWithDefaultTheme } from '../../../utils/themes/theme';
-import { getAnnotationId, getAxisId, getGroupId, getSpecId, AxisId } from '../../../utils/ids';
 import { TooltipType, TooltipValue } from '../utils/interactions';
 import { ScaleBand } from '../../../utils/scales/scale_band';
 import { ScaleContinuous } from '../../../utils/scales/scale_continuous';
 import { ScaleType } from '../../../utils/scales/scales';
-import { ChartStore, isDuplicateAxis } from './chart_state';
-import { AxisTicksDimensions } from '../utils/axis_utils';
+// import { ChartStore } from './chart_state';
+import { IndexedGeometry, GeometryValue, AccessorType } from '../../../utils/geometry';
+import { AxisTicksDimensions, isDuplicateAxis } from '../utils/axis_utils';
+import { AxisId } from '../../../utils/ids';
+import { LegendItem } from '../legend/legend';
+import { ChartTypes } from '../..';
 
-describe('Chart Store', () => {
-  let store = new ChartStore();
+describe.skip('Chart Store', () => {
+  let store: any = null; //
 
-  const SPEC_ID = getSpecId('spec_1');
-  const AXIS_ID = getAxisId('axis_1');
-  const GROUP_ID = getGroupId('group_1');
+  const SPEC_ID = 'spec_1';
+  const AXIS_ID = 'axis_1';
+  const GROUP_ID = 'group_1';
 
   const spec: BarSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: SPEC_ID,
     groupId: GROUP_ID,
-    seriesType: 'bar',
+    seriesType: SeriesTypes.Bar,
     yScaleToDataExtent: false,
     data: [{ x: 1, y: 1, g: 0 }, { x: 2, y: 2, g: 1 }, { x: 3, y: 3, g: 3 }],
     xAccessor: 'x',
@@ -79,17 +84,19 @@ describe('Chart Store', () => {
     },
   };
   beforeEach(() => {
-    store = new ChartStore();
+    store = null; // new ChartStore();
     store.updateParentDimensions(600, 600, 0, 0);
     store.computeChart();
   });
 
   describe('isDuplicateAxis', () => {
-    const AXIS_1_ID = getAxisId('spec_1');
-    const AXIS_2_ID = getAxisId('spec_1');
+    const AXIS_1_ID = 'spec_1';
+    const AXIS_2_ID = 'spec_1';
     const axis1: AxisSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Axis,
       id: AXIS_1_ID,
-      groupId: getGroupId('group_1'),
+      groupId: 'group_1',
       hide: false,
       showOverlappingTicks: false,
       showOverlappingLabels: false,
@@ -101,7 +108,7 @@ describe('Chart Store', () => {
     const axis2: AxisSpec = {
       ...axis1,
       id: AXIS_2_ID,
-      groupId: getGroupId('group_2'),
+      groupId: 'group_2',
     };
     const axisTicksDimensions: AxisTicksDimensions = {
       tickValues: [],
@@ -112,16 +119,16 @@ describe('Chart Store', () => {
       maxLabelTextHeight: 1,
     };
     let tickMap: Map<AxisId, AxisTicksDimensions>;
-    let specMap: Map<AxisId, AxisSpec>;
+    let specMap: AxisSpec[];
 
     beforeEach(() => {
       tickMap = new Map<AxisId, AxisTicksDimensions>();
-      specMap = new Map<AxisId, AxisSpec>();
+      specMap = [];
     });
 
     it('should return true if axisSpecs and ticks match', () => {
       tickMap.set(AXIS_2_ID, axisTicksDimensions);
-      specMap.set(AXIS_2_ID, axis2);
+      specMap.push(axis2);
       const result = isDuplicateAxis(axis1, axisTicksDimensions, tickMap, specMap);
 
       expect(result).toBe(true);
@@ -129,7 +136,7 @@ describe('Chart Store', () => {
 
     it('should return false if axisSpecs, ticks AND title match', () => {
       tickMap.set(AXIS_2_ID, axisTicksDimensions);
-      specMap.set(AXIS_2_ID, {
+      specMap.push({
         ...axis2,
         title: 'TESTING',
       });
@@ -152,7 +159,7 @@ describe('Chart Store', () => {
         tickLabels: ['10'],
       };
       tickMap.set(AXIS_2_ID, newAxisTicksDimensions);
-      specMap.set(AXIS_2_ID, axis2);
+      specMap.push(axis2);
 
       const result = isDuplicateAxis(axis1, newAxisTicksDimensions, tickMap, specMap);
 
@@ -161,7 +168,7 @@ describe('Chart Store', () => {
 
     it('should return false if axisSpecs and ticks match but title is different', () => {
       tickMap.set(AXIS_2_ID, axisTicksDimensions);
-      specMap.set(AXIS_2_ID, {
+      specMap.push({
         ...axis2,
         title: 'TESTING',
       });
@@ -180,7 +187,7 @@ describe('Chart Store', () => {
 
     it('should return false if axisSpecs and ticks match but position is different', () => {
       tickMap.set(AXIS_2_ID, axisTicksDimensions);
-      specMap.set(AXIS_2_ID, axis2);
+      specMap.push(axis2);
       const result = isDuplicateAxis(
         {
           ...axis1,
@@ -199,7 +206,7 @@ describe('Chart Store', () => {
         ...axisTicksDimensions,
         tickLabels: ['10%', '20%', '30%'],
       });
-      specMap.set(AXIS_2_ID, axis2);
+      specMap.push(axis2);
 
       const result = isDuplicateAxis(axis1, axisTicksDimensions, tickMap, specMap);
 
@@ -211,7 +218,7 @@ describe('Chart Store', () => {
         ...axisTicksDimensions,
         tickLabels: ['10', '20', '25', '30'],
       });
-      specMap.set(AXIS_2_ID, axis2);
+      specMap.push(axis2);
 
       const result = isDuplicateAxis(axis1, axisTicksDimensions, tickMap, specMap);
 
@@ -226,7 +233,7 @@ describe('Chart Store', () => {
     });
   });
 
-  test('can add a single spec', () => {
+  test.skip('can add a single spec', () => {
     store.addSeriesSpec(spec);
     store.updateParentDimensions(600, 600, 0, 0);
     store.computeChart();
@@ -234,15 +241,17 @@ describe('Chart Store', () => {
     expect(seriesDomainsAndData).not.toBeUndefined();
   });
 
-  test('can initialize deselectedDataSeries depending on previous state', () => {
+  test.skip('can initialize deselectedDataSeries depending on previous state', () => {
     store.specsInitialized.set(false);
     store.computeChart();
     expect(store.deselectedDataSeries).toEqual(null);
   });
 
-  test('can add an axis', () => {
+  test.skip('can add an axis', () => {
     store.addSeriesSpec(spec);
     const axisSpec: AxisSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Axis,
       id: AXIS_ID,
       groupId: GROUP_ID,
       hide: false,
@@ -263,14 +272,14 @@ describe('Chart Store', () => {
     expect(axesTicks.get(AXIS_ID)).not.toBeUndefined();
   });
 
-  test('can set legend visibility', () => {
+  test.skip('can set legend visibility', () => {
     store.showLegend.set(false);
     store.setShowLegend(true);
 
     expect(store.showLegend.get()).toEqual(true);
   });
 
-  test('can get highlighted legend item', () => {
+  test.skip('can get highlighted legend item', () => {
     store.legendItems = new Map([[firstLegendItem.key, firstLegendItem], [secondLegendItem.key, secondLegendItem]]);
 
     store.highlightedLegendItemKey.set(null);
@@ -280,7 +289,7 @@ describe('Chart Store', () => {
     expect(store.highlightedLegendItem.get()).toEqual(secondLegendItem);
   });
 
-  test('can respond to legend item mouseover event', () => {
+  test.skip('can respond to legend item mouseover event', () => {
     const legendListener = jest.fn(
       (): void => {
         return;
@@ -304,7 +313,7 @@ describe('Chart Store', () => {
     expect(legendListener).toBeCalledWith(null);
   });
 
-  test('can respond to legend item mouseout event', () => {
+  test.skip('can respond to legend item mouseout event', () => {
     const outListener = jest.fn((): undefined => undefined);
 
     store.highlightedLegendItemKey.set(firstLegendItem.key);
@@ -321,7 +330,7 @@ describe('Chart Store', () => {
     expect(outListener.mock.calls.length).toBe(1);
   });
 
-  test('do nothing when mouseover an hidden series', () => {
+  test.skip('do nothing when mouseover an hidden series', () => {
     const legendListener = jest.fn(
       (): void => {
         return;
@@ -349,7 +358,7 @@ describe('Chart Store', () => {
     store.removeOnLegendItemOutListener();
   });
 
-  test('can respond to legend item click event', () => {
+  test.skip('can respond to legend item click event', () => {
     const legendListener = jest.fn(
       (): void => {
         return;
@@ -377,7 +386,7 @@ describe('Chart Store', () => {
     expect(legendListener).toBeCalledWith(secondLegendItem.value);
   });
 
-  test('can respond to a legend item plus click event', () => {
+  test.skip('can respond to a legend item plus click event', () => {
     const legendListener = jest.fn(
       (): void => {
         return;
@@ -400,7 +409,7 @@ describe('Chart Store', () => {
     expect(legendListener).toBeCalledWith(firstLegendItem.value);
   });
 
-  test('can respond to a legend item minus click event', () => {
+  test.skip('can respond to a legend item minus click event', () => {
     const legendListener = jest.fn(
       (): void => {
         return;
@@ -423,7 +432,7 @@ describe('Chart Store', () => {
     expect(legendListener).toBeCalledWith(firstLegendItem.value);
   });
 
-  test('can toggle series visibility', () => {
+  test.skip('can toggle series visibility', () => {
     const computeChart = jest.fn(
       (): void => {
         return;
@@ -448,7 +457,7 @@ describe('Chart Store', () => {
     expect(store.deselectedDataSeries).toEqual([]);
   });
 
-  test('can toggle single series visibility', () => {
+  test.skip('can toggle single series visibility', () => {
     const computeChart = jest.fn(
       (): void => {
         return;
@@ -470,7 +479,7 @@ describe('Chart Store', () => {
     expect(store.deselectedDataSeries).toEqual([secondLegendItem.value]);
   });
 
-  test('can set an element click listener', () => {
+  test.skip('can set an element click listener', () => {
     const clickListener = (): void => {
       return;
     };
@@ -479,7 +488,7 @@ describe('Chart Store', () => {
     expect(store.onElementClickListener).toEqual(clickListener);
   });
 
-  test('can set a brush end listener', () => {
+  test.skip('can set a brush end listener', () => {
     const brushEndListener = (): void => {
       return;
     };
@@ -488,7 +497,7 @@ describe('Chart Store', () => {
     expect(store.onBrushEndListener).toEqual(brushEndListener);
   });
 
-  test('can set a cursor hover listener', () => {
+  test.skip('can set a cursor hover listener', () => {
     const listener = (): void => {
       return;
     };
@@ -497,7 +506,7 @@ describe('Chart Store', () => {
     expect(store.onCursorUpdateListener).toEqual(listener);
   });
 
-  test('can set a render change listener', () => {
+  test.skip('can set a render change listener', () => {
     const listener = (): void => {
       return;
     };
@@ -506,7 +515,7 @@ describe('Chart Store', () => {
     expect(store.onRenderChangeListener).toEqual(listener);
   });
 
-  test('should observe chartInitialized value', () => {
+  test.skip('should observe chartInitialized value', () => {
     const listener = jest.fn();
     store.chartInitialized.set(false);
     store.setOnRenderChangeListener(listener);
@@ -515,7 +524,7 @@ describe('Chart Store', () => {
     expect(listener).toBeCalledWith(true);
   });
 
-  test('should observe chartInitialized value only on change', () => {
+  test.skip('should observe chartInitialized value only on change', () => {
     const listener = jest.fn();
     store.chartInitialized.set(false);
     store.setOnRenderChangeListener(listener);
@@ -524,7 +533,7 @@ describe('Chart Store', () => {
     expect(listener).not.toBeCalled();
   });
 
-  test('can remove listeners', () => {
+  test.skip('can remove listeners', () => {
     store.removeElementClickListener();
     expect(store.onElementClickListener).toBeUndefined();
 
@@ -550,7 +559,7 @@ describe('Chart Store', () => {
     expect(store.onRenderChangeListener).toBeUndefined();
   });
 
-  test('can respond to a brush end event', () => {
+  test.skip('can respond to a brush end event', () => {
     const brushEndListener = jest.fn<void, [number, number]>(
       (): void => {
         return;
@@ -595,7 +604,7 @@ describe('Chart Store', () => {
     expect(brushEndListener.mock.calls[1][1]).toBe(2.5);
   });
 
-  test('can update parent dimensions', () => {
+  test.skip('can update parent dimensions', () => {
     const computeChart = jest.fn(
       (): void => {
         return;
@@ -629,14 +638,16 @@ describe('Chart Store', () => {
     expect(computeChart).toBeCalled();
   });
 
-  test('can remove a series spec', () => {
+  test.skip('can remove a series spec', () => {
     store.addSeriesSpec(spec);
     store.removeSeriesSpec(SPEC_ID);
     expect(store.seriesSpecs.get(SPEC_ID)).toBe(undefined);
   });
 
-  test('can remove an axis spec', () => {
+  test.skip('can remove an axis spec', () => {
     const axisSpec: AxisSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Axis,
       id: AXIS_ID,
       groupId: GROUP_ID,
       hide: false,
@@ -654,8 +665,8 @@ describe('Chart Store', () => {
   });
 
   test('can add and remove an annotation spec', () => {
-    const annotationId = getAnnotationId('annotation');
-    const groupId = getGroupId('group');
+    const annotationId = 'annotation';
+    const groupId = 'group';
 
     const customStyle = {
       line: {
@@ -673,8 +684,10 @@ describe('Chart Store', () => {
     };
 
     const lineAnnotation: AnnotationSpec = {
-      annotationType: 'line',
-      annotationId,
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      annotationType: AnnotationTypes.Line,
+      id: annotationId,
       domainType: AnnotationDomainTypes.YDomain,
       dataValues: [{ dataValue: 2, details: 'foo' }],
       groupId,
@@ -692,19 +705,21 @@ describe('Chart Store', () => {
     expect(store.annotationSpecs).toEqual(new Map());
 
     const rectAnnotation: RectAnnotationSpec = {
-      annotationId: getAnnotationId('rect'),
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      id: 'rect',
       groupId: GROUP_ID,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       dataValues: [{ coordinates: { x0: 1, x1: 2, y0: 3, y1: 5 } }],
     };
     store.addAnnotationSpec(rectAnnotation);
     expectedAnnotationSpecs.clear();
-    expectedAnnotationSpecs.set(rectAnnotation.annotationId, rectAnnotation);
+    expectedAnnotationSpecs.set(rectAnnotation.id, rectAnnotation);
     expect(store.annotationSpecs).toEqual(expectedAnnotationSpecs);
   });
 
-  test('only computes chart if parent dimensions are computed', () => {
-    const localStore = new ChartStore();
+  test.skip('only computes chart if parent dimensions are computed', () => {
+    const localStore: any = null; //new ChartStore();
 
     localStore.parentDimensions = {
       width: 0,
@@ -717,8 +732,8 @@ describe('Chart Store', () => {
     expect(localStore.chartInitialized.get()).toBe(false);
   });
 
-  test('only computes chart if series specs exist', () => {
-    const localStore = new ChartStore();
+  test.skip('only computes chart if series specs exist', () => {
+    const localStore: any = null; //new ChartStore();
 
     localStore.parentDimensions = {
       width: 100,
@@ -732,7 +747,7 @@ describe('Chart Store', () => {
     expect(localStore.chartInitialized.get()).toBe(false);
   });
 
-  test('can set the color for a series', () => {
+  test.skip('can set the color for a series', () => {
     const computeChart = jest.fn(
       (): void => {
         return;
@@ -760,12 +775,12 @@ describe('Chart Store', () => {
     expect(spec.customSeriesColors).toEqual(expectedSpecCustomColorSeries);
   });
 
-  test('can reset selectedDataSeries', () => {
+  test.skip('can reset selectedDataSeries', () => {
     store.deselectedDataSeries = [firstLegendItem.value];
     store.resetDeselectedDataSeries();
     expect(store.deselectedDataSeries).toBe(null);
   });
-  test('can update the crosshair visibility', () => {
+  test.skip('can update the crosshair visibility', () => {
     store.cursorPosition.x = -1;
     store.cursorPosition.y = 1;
     store.tooltipType.set(TooltipType.Crosshairs);
@@ -787,7 +802,7 @@ describe('Chart Store', () => {
     expect(store.isCrosshairVisible.get()).toBe(true);
   });
 
-  test('can update the tooltip visibility', () => {
+  test.skip('can update the tooltip visibility', () => {
     const tooltipValue: TooltipValue = {
       name: 'a',
       value: 'a',
@@ -834,6 +849,8 @@ describe('Chart Store', () => {
 
     beforeEach(() => {
       const axisSpec: AxisSpec = {
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Axis,
         id: AXIS_ID,
         groupId: spec.groupId,
         hide: true,
@@ -851,19 +868,19 @@ describe('Chart Store', () => {
       store.computeChart();
     });
 
-    test('with no tooltipHeaderFormatter defined, should return value formatted using xAxis tickFormatter', () => {
+    test.skip('with no tooltipHeaderFormatter defined, should return value formatted using xAxis tickFormatter', () => {
       store.tooltipHeaderFormatter = undefined;
       store.setCursorPosition(10, 10);
       expect(store.tooltipData[0].value).toBe('foo 1');
     });
 
-    test('with tooltipHeaderFormatter defined, should return value formatted', () => {
+    test.skip('with tooltipHeaderFormatter defined, should return value formatted', () => {
       store.tooltipHeaderFormatter = (value: TooltipValue) => `${value}`;
       store.setCursorPosition(10, 10);
       expect(store.tooltipData[0].value).toBe(1);
     });
 
-    test('should update cursor postion with hover event', () => {
+    test.skip('should update cursor postion with hover event', () => {
       const legendListener = jest.fn(
         (): void => {
           return;
@@ -883,7 +900,7 @@ describe('Chart Store', () => {
     });
   });
 
-  test('can disable brush based on scale and listener', () => {
+  test.skip('can disable brush based on scale and listener', () => {
     store.xScale = undefined;
     expect(store.isBrushEnabled()).toBe(false);
     store.xScale = new ScaleContinuous({ type: ScaleType.Linear, domain: [0, 100], range: [0, 100] });
@@ -895,7 +912,7 @@ describe('Chart Store', () => {
     expect(store.isBrushEnabled()).toBe(false);
   });
 
-  test('can disable tooltip on brushing', () => {
+  test.skip('can disable tooltip on brushing', () => {
     store.addSeriesSpec(spec);
     store.setOnBrushEndListener(() => ({}));
     const tooltipValue: TooltipValue = {
@@ -924,7 +941,7 @@ describe('Chart Store', () => {
     expect(store.isBrushing.get()).toBe(false);
     expect(store.isTooltipVisible.get()).toBe(true);
   });
-  test('handle click on chart', () => {
+  test.skip('handle click on chart', () => {
     const barStyle = {
       rect: {
         opacity: 1,
@@ -945,7 +962,7 @@ describe('Chart Store', () => {
     const geom1: IndexedGeometry = {
       color: 'red',
       geometryId: {
-        specId: getSpecId('specId1'),
+        specId: 'specId1',
         seriesKey: [2],
       },
       value: {
@@ -962,7 +979,7 @@ describe('Chart Store', () => {
     const geom2: IndexedGeometry = {
       color: 'blue',
       geometryId: {
-        specId: getSpecId('specId2'),
+        specId: 'specId2',
         seriesKey: [2],
       },
       value: {
@@ -997,11 +1014,11 @@ describe('Chart Store', () => {
     expect(clickListener).toBeCalledTimes(2);
     expect(clickListener.mock.calls[1][0]).toEqual([geom1.value, geom2.value]);
   });
-  test('can compute annotation tooltip state', () => {
+  test.skip('can compute annotation tooltip state', () => {
     const scale = new ScaleContinuous({ type: ScaleType.Linear, domain: [0, 100], range: [0, 100] });
 
-    store.rawCursorPosition.x = -1;
-    store.rawCursorPosition.y = 0;
+    store.currentPointerPosition.x = -1;
+    store.currentPointerPosition.y = 0;
 
     expect(store.annotationTooltipState.get()).toBe(null);
 
@@ -1016,24 +1033,26 @@ describe('Chart Store', () => {
     store.yScales = new Map();
     store.yScales.set(GROUP_ID, scale);
 
-    store.rawCursorPosition.x = 0;
+    store.currentPointerPosition.x = 0;
     expect(store.annotationTooltipState.get()).toBe(null);
 
     // If there's a rect annotation & there's also a highlight chart element tooltip, ignore annotation tooltip
-    store.rawCursorPosition.x = 18;
-    store.rawCursorPosition.y = 9;
+    store.currentPointerPosition.x = 18;
+    store.currentPointerPosition.y = 9;
     store.chartDimensions = { width: 10, height: 20, top: 5, left: 15 };
 
     const annotationDimensions = [{ rect: { x: 2, y: 3, width: 3, height: 5 } }];
     const rectAnnotationSpec: RectAnnotationSpec = {
-      annotationId: getAnnotationId('rect'),
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Annotation,
+      id: 'rect',
       groupId: GROUP_ID,
-      annotationType: 'rectangle',
+      annotationType: AnnotationTypes.Rectangle,
       dataValues: [{ coordinates: { x0: 1, x1: 2, y0: 3, y1: 5 } }],
     };
 
-    store.annotationSpecs.set(rectAnnotationSpec.annotationId, rectAnnotationSpec);
-    store.annotationDimensions.set(rectAnnotationSpec.annotationId, annotationDimensions);
+    store.annotationSpecs.set(rectAnnotationSpec.id, rectAnnotationSpec);
+    store.annotationDimensions.set(rectAnnotationSpec.id, annotationDimensions);
 
     const highlightedTooltipValue = {
       name: 'foo',
@@ -1058,8 +1077,8 @@ describe('Chart Store', () => {
       isVisible: true,
       annotationType: AnnotationTypes.Rectangle,
       anchor: {
-        top: store.rawCursorPosition.y - store.chartDimensions.top,
-        left: store.rawCursorPosition.x - store.chartDimensions.left,
+        top: store.currentPointerPosition.y - store.chartDimensions.top,
+        left: store.currentPointerPosition.x - store.chartDimensions.left,
       },
     };
     store.tooltipData.push(unhighlightedTooltipValue);
@@ -1068,7 +1087,7 @@ describe('Chart Store', () => {
     store.tooltipData.push(highlightedTooltipValue);
     expect(store.annotationTooltipState.get()).toBe(null);
   });
-  test('can get tooltipValues by seriesKeys', () => {
+  test.skip('can get tooltipValues by seriesKeys', () => {
     store.tooltipData.clear();
 
     expect(store.legendItemTooltipValues.get()).toEqual(new Map());
@@ -1114,34 +1133,34 @@ describe('Chart Store', () => {
       store.xScale = new ScaleContinuous({ type: ScaleType.Linear, domain: [0, 100], range: [0, 100] });
     });
 
-    test('when cursor is outside of chart bounds', () => {
+    test.skip('when cursor is outside of chart bounds', () => {
       store.cursorPosition.x = -1;
       store.cursorPosition.y = -1;
       store.onBrushEndListener = brushEndListener;
       expect(store.chartCursor.get()).toBe('default');
     });
 
-    test('when cursor is within chart bounds and brush enabled', () => {
+    test.skip('when cursor is within chart bounds and brush enabled', () => {
       store.cursorPosition.x = 10;
       store.cursorPosition.y = 10;
       store.onBrushEndListener = brushEndListener;
       expect(store.chartCursor.get()).toBe('crosshair');
     });
 
-    test('when cursor is within chart bounds and brush disabled', () => {
+    test.skip('when cursor is within chart bounds and brush disabled', () => {
       store.cursorPosition.x = 10;
       store.cursorPosition.y = 10;
       store.onBrushEndListener = undefined;
       expect(store.chartCursor.get()).toBe('default');
     });
-    test('when cursor is within chart bounds and brush enabled but over one geom', () => {
+    test.skip('when cursor is within chart bounds and brush enabled but over one geom', () => {
       store.cursorPosition.x = 10;
       store.cursorPosition.y = 10;
       store.onBrushEndListener = brushEndListener;
       const geom1: IndexedGeometry = {
         color: 'red',
         geometryId: {
-          specId: getSpecId('specId1'),
+          specId: 'specId1',
           seriesKey: [2],
         },
         value: {
@@ -1177,11 +1196,13 @@ describe('Chart Store', () => {
       expect(store.chartCursor.get()).toBe('pointer');
     });
   });
-  test('should set tooltip type to follow when single value x scale', () => {
+  test.skip('should set tooltip type to follow when single value x scale', () => {
     const singleValueSpec: BarSeriesSpec = {
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
       id: SPEC_ID,
       groupId: GROUP_ID,
-      seriesType: 'bar',
+      seriesType: SeriesTypes.Bar,
       yScaleToDataExtent: false,
       data: [{ x: 1, y: 1, g: 0 }],
       xAccessor: 'x',
@@ -1196,7 +1217,7 @@ describe('Chart Store', () => {
     expect(store.tooltipType.get()).toBe(TooltipType.Follow);
   });
 
-  describe('isActiveChart', () => {
+  describe.skip('isActiveChart', () => {
     it('should return true if no activeChartId is defined', () => {
       store.activeChartId = undefined;
       expect(store.isActiveChart.get()).toBe(true);
@@ -1213,7 +1234,7 @@ describe('Chart Store', () => {
     });
   });
 
-  describe('setActiveChartId', () => {
+  describe.skip('setActiveChartId', () => {
     it('should set activeChartId with value', () => {
       store.activeChartId = undefined;
       store.setActiveChartId('test-id');
diff --git a/src/chart_types/xy_chart/state/chart_state.timescales.test.ts b/src/chart_types/xy_chart/state/chart_state.timescales.test.ts
new file mode 100644
index 0000000000..a6fbc1368c
--- /dev/null
+++ b/src/chart_types/xy_chart/state/chart_state.timescales.test.ts
@@ -0,0 +1,232 @@
+import { LineSeriesSpec, SpecTypes, SeriesTypes } from '../utils/specs';
+import { ScaleType } from '../../../utils/scales/scales';
+import { createStore, Store } from 'redux';
+import { chartStoreReducer, GlobalChartState } from '../../../state/chart_state';
+import { upsertSpec, specParsed } from '../../../state/actions/specs';
+import { SettingsSpec, DEFAULT_SETTINGS_SPEC } from '../../../specs';
+import { mergeWithDefaultTheme } from '../../../utils/themes/theme';
+import { LIGHT_THEME } from '../../../utils/themes/light_theme';
+import { updateParentDimensions } from '../../../state/actions/chart_settings';
+import { computeSeriesGeometriesSelector } from './selectors/compute_series_geometries';
+import { onPointerMove } from '../../../state/actions/mouse';
+import { getTooltipValuesSelector } from './selectors/get_tooltip_values_highlighted_geoms';
+import { DateTime } from 'luxon';
+import { getComputedScalesSelector } from './selectors/get_computed_scales';
+import { ChartTypes } from '../..';
+
+describe('Render chart', () => {
+  describe('line, utc-time, day interval', () => {
+    let store: Store<GlobalChartState>;
+    const day1 = 1546300800000; // 2019-01-01T00:00:00.000Z
+    const day2 = day1 + 1000 * 60 * 60 * 24;
+    const day3 = day2 + 1000 * 60 * 60 * 24;
+    beforeEach(() => {
+      const storeReducer = chartStoreReducer('chartId');
+      store = createStore(storeReducer);
+
+      const lineSeries: LineSeriesSpec = {
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'lines',
+        groupId: 'line',
+        seriesType: SeriesTypes.Line,
+        xScaleType: ScaleType.Time,
+        yScaleType: ScaleType.Linear,
+        xAccessor: 0,
+        yAccessors: [1],
+        data: [[day1, 10], [day2, 22], [day3, 6]],
+        yScaleToDataExtent: false,
+      };
+      store.dispatch(upsertSpec(lineSeries));
+
+      const settingSpec: SettingsSpec = {
+        ...DEFAULT_SETTINGS_SPEC,
+        theme: mergeWithDefaultTheme(
+          {
+            chartPaddings: { top: 0, left: 0, bottom: 0, right: 0 },
+            chartMargins: { top: 0, left: 0, bottom: 0, right: 0 },
+          },
+          LIGHT_THEME,
+        ),
+      };
+      store.dispatch(upsertSpec(settingSpec));
+      store.dispatch(specParsed());
+      store.dispatch(updateParentDimensions({ width: 100, height: 100, top: 0, left: 0 }));
+      const state = store.getState();
+      expect(state.specs['lines']).toBeDefined();
+      expect(state.chartType).toBe(ChartTypes.XYAxis);
+    });
+    test('check rendered geometries', () => {
+      const { geometries } = computeSeriesGeometriesSelector(store.getState());
+      expect(geometries).toBeDefined();
+      expect(geometries.lines).toBeDefined();
+      expect(geometries.lines.length).toBe(1);
+      expect(geometries.lines[0].points.length).toBe(3);
+    });
+    test('check mouse position correctly return inverted value', () => {
+      store.dispatch(onPointerMove({ x: 15, y: 10 }, 0)); // check first valid tooltip
+      let tooltipData = getTooltipValuesSelector(store.getState());
+      expect(tooltipData.length).toBe(2); // x value + y value
+      expect(tooltipData[0].value).toBe(day1); // x value
+      expect(tooltipData[1].value).toBe(10); // y value
+      store.dispatch(onPointerMove({ x: 35, y: 10 }, 1)); // check second valid tooltip
+      tooltipData = getTooltipValuesSelector(store.getState());
+      expect(tooltipData.length).toBe(2); // x value + y value
+      expect(tooltipData[0].value).toBe(day2); // x value
+      expect(tooltipData[1].value).toBe(22); // y value
+      store.dispatch(onPointerMove({ x: 76, y: 10 }, 2)); // check third valid tooltip
+      tooltipData = getTooltipValuesSelector(store.getState());
+      expect(tooltipData.length).toBe(2); // x value + y value
+      expect(tooltipData[0].value).toBe(day3); // x value
+      expect(tooltipData[1].value).toBe(6); // y value
+    });
+  });
+  describe('line, utc-time, 5m interval', () => {
+    let store: Store<GlobalChartState>;
+    const date1 = 1546300800000; // 2019-01-01T00:00:00.000Z
+    const date2 = date1 + 1000 * 60 * 5;
+    const date3 = date2 + 1000 * 60 * 5;
+    beforeEach(() => {
+      const storeReducer = chartStoreReducer('chartId');
+      store = createStore(storeReducer);
+
+      const lineSeries: LineSeriesSpec = {
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'lines',
+        groupId: 'line',
+        seriesType: SeriesTypes.Line,
+        xScaleType: ScaleType.Time,
+        yScaleType: ScaleType.Linear,
+        xAccessor: 0,
+        yAccessors: [1],
+        data: [[date1, 10], [date2, 22], [date3, 6]],
+        yScaleToDataExtent: false,
+      };
+      store.dispatch(upsertSpec(lineSeries));
+      const settingSpec: SettingsSpec = {
+        ...DEFAULT_SETTINGS_SPEC,
+        theme: mergeWithDefaultTheme(
+          {
+            chartPaddings: { top: 0, left: 0, bottom: 0, right: 0 },
+            chartMargins: { top: 0, left: 0, bottom: 0, right: 0 },
+          },
+          LIGHT_THEME,
+        ),
+      };
+      store.dispatch(upsertSpec(settingSpec));
+      store.dispatch(specParsed());
+      store.dispatch(updateParentDimensions({ width: 100, height: 100, top: 0, left: 0 }));
+      const state = store.getState();
+      expect(state.specs['lines']).toBeDefined();
+      expect(state.chartType).toBe(ChartTypes.XYAxis);
+    });
+    test('check rendered geometries', () => {
+      const { geometries } = computeSeriesGeometriesSelector(store.getState());
+      expect(geometries).toBeDefined();
+      expect(geometries.lines).toBeDefined();
+      expect(geometries.lines.length).toBe(1);
+      expect(geometries.lines[0].points.length).toBe(3);
+    });
+    test('check mouse position correctly return inverted value', () => {
+      store.dispatch(onPointerMove({ x: 15, y: 10 }, 0)); // check first valid tooltip
+      let tooltipData = getTooltipValuesSelector(store.getState());
+      expect(tooltipData.length).toBe(2); // x value + y value
+      expect(tooltipData[0].value).toBe(date1); // x value
+      expect(tooltipData[1].value).toBe(10); // y value
+      store.dispatch(onPointerMove({ x: 35, y: 10 }, 1)); // check second valid tooltip
+      tooltipData = getTooltipValuesSelector(store.getState());
+      expect(tooltipData.length).toBe(2); // x value + y value
+      expect(tooltipData[0].value).toBe(date2); // x value
+      expect(tooltipData[1].value).toBe(22); // y value
+      store.dispatch(onPointerMove({ x: 76, y: 10 }, 2)); // check third valid tooltip
+      tooltipData = getTooltipValuesSelector(store.getState());
+      expect(tooltipData.length).toBe(2); // x value + y value
+      expect(tooltipData[0].value).toBe(date3); // x value
+      expect(tooltipData[1].value).toBe(6); // y value
+    });
+  });
+  describe('line, non utc-time, 5m + 1s interval', () => {
+    let store: Store<GlobalChartState>;
+    const date1 = DateTime.fromISO('2019-01-01T00:00:01.000-0300', { setZone: true }).toMillis();
+    const date2 = date1 + 1000 * 60 * 5;
+    const date3 = date2 + 1000 * 60 * 5;
+    beforeEach(() => {
+      const storeReducer = chartStoreReducer('chartId');
+      store = createStore(storeReducer);
+      const lineSeries: LineSeriesSpec = {
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'lines',
+        groupId: 'line',
+        seriesType: SeriesTypes.Line,
+        xScaleType: ScaleType.Time,
+        yScaleType: ScaleType.Linear,
+        xAccessor: 0,
+        yAccessors: [1],
+        data: [[date1, 10], [date2, 22], [date3, 6]],
+        yScaleToDataExtent: false,
+      };
+      store.dispatch(upsertSpec(lineSeries));
+      const settingSpec: SettingsSpec = {
+        ...DEFAULT_SETTINGS_SPEC,
+        theme: mergeWithDefaultTheme(
+          {
+            chartPaddings: { top: 0, left: 0, bottom: 0, right: 0 },
+            chartMargins: { top: 0, left: 0, bottom: 0, right: 0 },
+          },
+          LIGHT_THEME,
+        ),
+      };
+      store.dispatch(upsertSpec(settingSpec));
+      store.dispatch(specParsed());
+      store.dispatch(updateParentDimensions({ width: 100, height: 100, top: 0, left: 0 }));
+      const state = store.getState();
+      expect(state.specs['lines']).toBeDefined();
+      expect(state.chartType).toBe(ChartTypes.XYAxis);
+    });
+    test('check rendered geometries', () => {
+      const { geometries } = computeSeriesGeometriesSelector(store.getState());
+      expect(geometries).toBeDefined();
+      expect(geometries.lines).toBeDefined();
+      expect(geometries.lines.length).toBe(1);
+      expect(geometries.lines[0].points.length).toBe(3);
+    });
+    test('check scale values', () => {
+      const xValues = [date1, date2, date3];
+      const state = store.getState();
+      const { xScale } = getComputedScalesSelector(state);
+
+      expect(xScale.minInterval).toBe(1000 * 60 * 5);
+      expect(xScale.domain).toEqual([date1, date3]);
+      expect(xScale.range).toEqual([0, 100]);
+      expect(xScale.invert(0)).toBe(date1);
+      expect(xScale.invert(50)).toBe(date2);
+      expect(xScale.invert(100)).toBe(date3);
+      expect(xScale.invertWithStep(5, xValues)).toEqual({ value: date1, withinBandwidth: true });
+      expect(xScale.invertWithStep(20, xValues)).toEqual({ value: date1, withinBandwidth: true });
+      expect(xScale.invertWithStep(30, xValues)).toEqual({ value: date2, withinBandwidth: true });
+      expect(xScale.invertWithStep(50, xValues)).toEqual({ value: date2, withinBandwidth: true });
+      expect(xScale.invertWithStep(70, xValues)).toEqual({ value: date2, withinBandwidth: true });
+      expect(xScale.invertWithStep(80, xValues)).toEqual({ value: date3, withinBandwidth: true });
+      expect(xScale.invertWithStep(100, xValues)).toEqual({ value: date3, withinBandwidth: true });
+    });
+    test('check mouse position correctly return inverted value', () => {
+      store.dispatch(onPointerMove({ x: 15, y: 10 }, 0)); // check first valid tooltip
+      let tooltipData = getTooltipValuesSelector(store.getState());
+      expect(tooltipData.length).toBe(2); // x value + y value
+      expect(tooltipData[0].value).toBe(date1); // x value
+      expect(tooltipData[1].value).toBe(10); // y value
+      store.dispatch(onPointerMove({ x: 35, y: 10 }, 1)); // check second valid tooltip
+      tooltipData = getTooltipValuesSelector(store.getState());
+      expect(tooltipData.length).toBe(2); // x value + y value
+      expect(tooltipData[0].value).toBe(date2); // x value
+      expect(tooltipData[1].value).toBe(22); // y value
+      store.dispatch(onPointerMove({ x: 76, y: 10 }, 2)); // check third valid tooltip
+      tooltipData = getTooltipValuesSelector(store.getState());
+      expect(tooltipData.length).toBe(2); // x value + y value
+      expect(tooltipData[0].value).toBe(date3); // x value
+      expect(tooltipData[1].value).toBe(6); // y value
+    });
+  });
+});
diff --git a/src/chart_types/xy_chart/state/chart_state.tsx b/src/chart_types/xy_chart/state/chart_state.tsx
new file mode 100644
index 0000000000..86ad9f7eb6
--- /dev/null
+++ b/src/chart_types/xy_chart/state/chart_state.tsx
@@ -0,0 +1,49 @@
+import React, { RefObject } from 'react';
+import { InternalChartState, GlobalChartState, BackwardRef } from '../../../state/chart_state';
+import { ChartTypes } from '../..';
+import { Tooltips } from '../renderer/dom/tooltips';
+import { htmlIdGenerator } from '../../../utils/commons';
+import { Highlighter } from '../renderer/dom/highlighter';
+import { Crosshair } from '../renderer/dom/crosshair';
+import { AnnotationTooltip } from '../renderer/dom/annotation_tooltips';
+import { isBrushAvailableSelector } from './selectors/is_brush_available';
+import { BrushTool } from '../renderer/dom/brush';
+import { isChartEmptySelector } from './selectors/is_chart_empty';
+import { ReactiveChart } from '../renderer/canvas/reactive_chart';
+import { computeLegendSelector } from './selectors/compute_legend';
+import { getLegendTooltipValuesSelector } from './selectors/get_legend_tooltip_values';
+import { TooltipLegendValue } from '../tooltip/tooltip';
+import { getPointerCursorSelector } from './selectors/get_cursor_pointer';
+import { Stage } from 'react-konva';
+
+export class XYAxisChartState implements InternalChartState {
+  chartType = ChartTypes.XYAxis;
+  legendId: string = htmlIdGenerator()('legend');
+  isBrushAvailable(globalState: GlobalChartState) {
+    return isBrushAvailableSelector(globalState);
+  }
+  isChartEmpty(globalState: GlobalChartState) {
+    return isChartEmptySelector(globalState);
+  }
+  getLegendItems(globalState: GlobalChartState) {
+    return computeLegendSelector(globalState);
+  }
+  getLegendItemsValues(globalState: GlobalChartState): Map<string, TooltipLegendValue> {
+    return getLegendTooltipValuesSelector(globalState);
+  }
+  chartRenderer(containerRef: BackwardRef, forwardStageRef: RefObject<Stage>) {
+    return (
+      <React.Fragment>
+        <Crosshair />
+        <ReactiveChart forwardStageRef={forwardStageRef} />
+        <Tooltips getChartContainerRef={containerRef} />
+        <AnnotationTooltip getChartContainerRef={containerRef} />
+        <Highlighter />
+        <BrushTool />
+      </React.Fragment>
+    );
+  }
+  getPointerCursor(globalState: GlobalChartState) {
+    return getPointerCursorSelector(globalState);
+  }
+}
diff --git a/src/chart_types/xy_chart/state/selectors/compute_annotations.ts b/src/chart_types/xy_chart/state/selectors/compute_annotations.ts
new file mode 100644
index 0000000000..0e4ecd8073
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/compute_annotations.ts
@@ -0,0 +1,44 @@
+import createCachedSelector from 're-reselect';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getAxisSpecsSelector, getAnnotationSpecsSelector } from './get_specs';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { countBarsInClusterSelector } from './count_bars_in_cluster';
+import { isHistogramModeEnabledSelector } from './is_histogram_mode_enabled';
+import { computeAnnotationDimensions, AnnotationDimensions } from '../../annotations/annotation_utils';
+import { computeSeriesGeometriesSelector } from './compute_series_geometries';
+import { AnnotationId } from '../../../../utils/ids';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const computeAnnotationDimensionsSelector = createCachedSelector(
+  [
+    getAnnotationSpecsSelector,
+    computeChartDimensionsSelector,
+    getSettingsSpecSelector,
+    computeSeriesGeometriesSelector,
+    getAxisSpecsSelector,
+    countBarsInClusterSelector,
+    isHistogramModeEnabledSelector,
+    getAxisSpecsSelector,
+  ],
+  (
+    annotationSpecs,
+    chartDimensions,
+    settingsSpec,
+    seriesGeometries,
+    axesSpecs,
+    totalBarsInCluster,
+    isHistogramMode,
+  ): Map<AnnotationId, AnnotationDimensions> => {
+    const { yScales, xScale } = seriesGeometries.scales;
+    return computeAnnotationDimensions(
+      annotationSpecs,
+      chartDimensions.chartDimensions,
+      settingsSpec.rotation,
+      yScales,
+      xScale,
+      axesSpecs,
+      totalBarsInCluster,
+      isHistogramMode,
+    );
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/compute_axis_ticks_dimensions.ts b/src/chart_types/xy_chart/state/selectors/compute_axis_ticks_dimensions.ts
new file mode 100644
index 0000000000..a791fe58bc
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/compute_axis_ticks_dimensions.ts
@@ -0,0 +1,60 @@
+import createCachedSelector from 're-reselect';
+import { isHistogramModeEnabledSelector } from './is_histogram_mode_enabled';
+import { computeSeriesDomainsSelector } from './compute_series_domains';
+import { CanvasTextBBoxCalculator } from '../../../../utils/bbox/canvas_text_bbox_calculator';
+import { computeAxisTicksDimensions, AxisTicksDimensions, isDuplicateAxis } from '../../utils/axis_utils';
+import { countBarsInClusterSelector } from './count_bars_in_cluster';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { AxisId } from '../../../../utils/ids';
+import { getAxisSpecsSelector } from './get_specs';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getBarPaddingsSelector } from './get_bar_paddings';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const computeAxisTicksDimensionsSelector = createCachedSelector(
+  [
+    getBarPaddingsSelector,
+    isHistogramModeEnabledSelector,
+    getAxisSpecsSelector,
+    getChartThemeSelector,
+    getSettingsSpecSelector,
+    computeSeriesDomainsSelector,
+    countBarsInClusterSelector,
+  ],
+  (
+    barsPadding,
+    isHistogramMode,
+    axesSpecs,
+    chartTheme,
+    settingsSpec,
+    seriesDomainsAndData,
+    totalBarsInCluster,
+  ): Map<AxisId, AxisTicksDimensions> => {
+    const { xDomain, yDomain } = seriesDomainsAndData;
+
+    const bboxCalculator = new CanvasTextBBoxCalculator();
+    const axesTicksDimensions: Map<AxisId, AxisTicksDimensions> = new Map();
+    axesSpecs.forEach((axisSpec) => {
+      const { id } = axisSpec;
+      const dimensions = computeAxisTicksDimensions(
+        axisSpec,
+        xDomain,
+        yDomain,
+        totalBarsInCluster,
+        bboxCalculator,
+        settingsSpec.rotation,
+        chartTheme.axes,
+        barsPadding,
+        isHistogramMode,
+      );
+      if (
+        dimensions &&
+        (!settingsSpec.hideDuplicateAxes || !isDuplicateAxis(axisSpec, dimensions, axesTicksDimensions, axesSpecs))
+      ) {
+        axesTicksDimensions.set(id, dimensions);
+      }
+    });
+    bboxCalculator.destroy();
+    return axesTicksDimensions;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/compute_axis_visible_ticks.ts b/src/chart_types/xy_chart/state/selectors/compute_axis_visible_ticks.ts
new file mode 100644
index 0000000000..59bfa4358a
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/compute_axis_visible_ticks.ts
@@ -0,0 +1,59 @@
+import createCachedSelector from 're-reselect';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getAxisSpecsSelector } from './get_specs';
+import { getAxisTicksPositions, AxisTick, AxisLinePosition } from '../../utils/axis_utils';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { computeAxisTicksDimensionsSelector } from './compute_axis_ticks_dimensions';
+import { computeSeriesDomainsSelector } from './compute_series_domains';
+import { countBarsInClusterSelector } from './count_bars_in_cluster';
+import { isHistogramModeEnabledSelector } from './is_histogram_mode_enabled';
+import { getBarPaddingsSelector } from './get_bar_paddings';
+import { AxisId } from '../../../../utils/ids';
+import { Dimensions } from '../../../../utils/dimensions';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+interface AxisVisibleTicks {
+  axisPositions: Map<AxisId, Dimensions>;
+  axisTicks: Map<AxisId, AxisTick[]>;
+  axisVisibleTicks: Map<AxisId, AxisTick[]>;
+  axisGridLinesPositions: Map<AxisId, AxisLinePosition[]>;
+}
+export const computeAxisVisibleTicksSelector = createCachedSelector(
+  [
+    computeChartDimensionsSelector,
+    getChartThemeSelector,
+    getSettingsSpecSelector,
+    getAxisSpecsSelector,
+    computeAxisTicksDimensionsSelector,
+    computeSeriesDomainsSelector,
+    countBarsInClusterSelector,
+    isHistogramModeEnabledSelector,
+    getBarPaddingsSelector,
+  ],
+  (
+    chartDimensions,
+    chartTheme,
+    settingsSpec,
+    axesSpecs,
+    axesTicksDimensions,
+    seriesDomainsAndData,
+    totalBarsInCluster,
+    isHistogramMode,
+    barsPadding,
+  ): AxisVisibleTicks => {
+    const { xDomain, yDomain } = seriesDomainsAndData;
+    return getAxisTicksPositions(
+      chartDimensions,
+      chartTheme,
+      settingsSpec.rotation,
+      axesSpecs,
+      axesTicksDimensions,
+      xDomain,
+      yDomain,
+      totalBarsInCluster,
+      isHistogramMode,
+      barsPadding,
+    );
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/compute_chart_dimensions.ts b/src/chart_types/xy_chart/state/selectors/compute_chart_dimensions.ts
new file mode 100644
index 0000000000..145c554120
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/compute_chart_dimensions.ts
@@ -0,0 +1,28 @@
+import createCachedSelector from 're-reselect';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { getAxisSpecsSelector } from './get_specs';
+import { computeChartDimensions } from '../../utils/dimensions';
+import { computeAxisTicksDimensionsSelector } from './compute_axis_ticks_dimensions';
+import { Dimensions } from '../../../../utils/dimensions';
+import { getChartContainerDimensionsSelector } from '../../../../state/selectors/get_chart_container_dimensions';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const computeChartDimensionsSelector = createCachedSelector(
+  [
+    getChartContainerDimensionsSelector,
+    getChartThemeSelector,
+    computeAxisTicksDimensionsSelector,
+    getAxisSpecsSelector,
+  ],
+  (
+    chartContainerDimensions,
+    chartTheme,
+    axesTicksDimensions,
+    axesSpecs,
+  ): {
+    chartDimensions: Dimensions;
+    leftMargin: number;
+  } => {
+    return computeChartDimensions(chartContainerDimensions, chartTheme, axesTicksDimensions, axesSpecs);
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/compute_chart_transform.ts b/src/chart_types/xy_chart/state/selectors/compute_chart_transform.ts
new file mode 100644
index 0000000000..8acf6e023b
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/compute_chart_transform.ts
@@ -0,0 +1,12 @@
+import createCachedSelector from 're-reselect';
+import { computeChartTransform, Transform } from '../utils';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const computeChartTransformSelector = createCachedSelector(
+  [computeChartDimensionsSelector, getSettingsSpecSelector],
+  (chartDimensions, settingsSpecs): Transform => {
+    return computeChartTransform(chartDimensions.chartDimensions, settingsSpecs.rotation);
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/compute_legend.ts b/src/chart_types/xy_chart/state/selectors/compute_legend.ts
new file mode 100644
index 0000000000..1f54097f50
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/compute_legend.ts
@@ -0,0 +1,38 @@
+import createCachedSelector from 're-reselect';
+import { computeSeriesDomainsSelector } from './compute_series_domains';
+import { getSeriesSpecsSelector, getAxisSpecsSelector } from './get_specs';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { getSeriesColorMapSelector } from './get_series_color_map';
+import { computeLegend, LegendItem } from '../../legend/legend';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getDeselectedSeriesSelector = (state: GlobalChartState) => state.interactions.deselectedDataSeries;
+
+export const computeLegendSelector = createCachedSelector(
+  [
+    getSeriesSpecsSelector,
+    computeSeriesDomainsSelector,
+    getChartThemeSelector,
+    getSeriesColorMapSelector,
+    getAxisSpecsSelector,
+    getDeselectedSeriesSelector,
+  ],
+  (
+    seriesSpecs,
+    seriesDomainsAndData,
+    chartTheme,
+    seriesColorMap,
+    axesSpecs,
+    deselectedDataSeries,
+  ): Map<string, LegendItem> => {
+    return computeLegend(
+      seriesDomainsAndData.seriesColors,
+      seriesColorMap,
+      seriesSpecs,
+      chartTheme.colors.defaultVizColor,
+      axesSpecs,
+      deselectedDataSeries,
+    );
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/compute_series_domains.ts b/src/chart_types/xy_chart/state/selectors/compute_series_domains.ts
new file mode 100644
index 0000000000..ca82793476
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/compute_series_domains.ts
@@ -0,0 +1,23 @@
+import createCachedSelector from 're-reselect';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getSeriesSpecsSelector } from './get_specs';
+import { mergeYCustomDomainsByGroupIdSelector } from './merge_y_custom_domains';
+import { computeSeriesDomains } from '../utils';
+import { SeriesDomainsAndData } from '../utils';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getDeselectedSeriesSelector = (state: GlobalChartState) => state.interactions.deselectedDataSeries;
+
+export const computeSeriesDomainsSelector = createCachedSelector(
+  [getSeriesSpecsSelector, mergeYCustomDomainsByGroupIdSelector, getDeselectedSeriesSelector, getSettingsSpecSelector],
+  (seriesSpecs, customYDomainsByGroupId, deselectedDataSeries, settingsSpec): SeriesDomainsAndData => {
+    const domains = computeSeriesDomains(
+      seriesSpecs,
+      customYDomainsByGroupId,
+      deselectedDataSeries,
+      settingsSpec.xDomain,
+    );
+    return domains;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/compute_series_geometries.ts b/src/chart_types/xy_chart/state/selectors/compute_series_geometries.ts
new file mode 100644
index 0000000000..db235a2b46
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/compute_series_geometries.ts
@@ -0,0 +1,47 @@
+import createCachedSelector from 're-reselect';
+import { isHistogramModeEnabledSelector } from './is_histogram_mode_enabled';
+import { computeSeriesDomainsSelector } from './compute_series_domains';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { getSeriesSpecsSelector, getAxisSpecsSelector } from './get_specs';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { computeSeriesGeometries, ComputedGeometries } from '../utils';
+import { getSeriesColorMapSelector } from './get_series_color_map';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const computeSeriesGeometriesSelector = createCachedSelector(
+  [
+    getSettingsSpecSelector,
+    getSeriesSpecsSelector,
+    computeSeriesDomainsSelector,
+    getSeriesColorMapSelector,
+    getChartThemeSelector,
+    computeChartDimensionsSelector,
+    getAxisSpecsSelector,
+    isHistogramModeEnabledSelector,
+  ],
+  (
+    settingsSpec,
+    seriesSpecs,
+    seriesDomainsAndData,
+    seriesColorMap,
+    chartTheme,
+    chartDimensions,
+    axesSpecs,
+    isHistogramMode,
+  ): ComputedGeometries => {
+    const { xDomain, yDomain, formattedDataSeries } = seriesDomainsAndData;
+    return computeSeriesGeometries(
+      seriesSpecs,
+      xDomain,
+      yDomain,
+      formattedDataSeries,
+      seriesColorMap,
+      chartTheme,
+      chartDimensions.chartDimensions,
+      settingsSpec.rotation,
+      axesSpecs,
+      isHistogramMode,
+    );
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/count_bars_in_cluster.ts b/src/chart_types/xy_chart/state/selectors/count_bars_in_cluster.ts
new file mode 100644
index 0000000000..3349e8aceb
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/count_bars_in_cluster.ts
@@ -0,0 +1,14 @@
+import createCachedSelector from 're-reselect';
+import { computeSeriesDomainsSelector } from './compute_series_domains';
+import { countBarsInCluster } from '../../utils/scales';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const countBarsInClusterSelector = createCachedSelector(
+  [computeSeriesDomainsSelector],
+  (seriesDomainsAndData): number => {
+    const { formattedDataSeries } = seriesDomainsAndData;
+
+    const { totalBarsInCluster } = countBarsInCluster(formattedDataSeries.stacked, formattedDataSeries.nonStacked);
+    return totalBarsInCluster;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_annotation_tooltip_state.ts b/src/chart_types/xy_chart/state/selectors/get_annotation_tooltip_state.ts
new file mode 100644
index 0000000000..5dbb58c6f5
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_annotation_tooltip_state.ts
@@ -0,0 +1,84 @@
+import createCachedSelector from 're-reselect';
+import { Dimensions } from '../../../../utils/dimensions';
+import { Point } from '../../../../utils/point';
+import { TooltipValue } from '../../utils/interactions';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { getAxisSpecsSelector, getAnnotationSpecsSelector } from './get_specs';
+import { AxisSpec, AnnotationSpec, Rotation, AnnotationTypes } from '../../utils/specs';
+import {
+  computeAnnotationTooltipState,
+  AnnotationTooltipState,
+  AnnotationDimensions,
+} from '../../annotations/annotation_utils';
+import { computeAnnotationDimensionsSelector } from './compute_annotations';
+import { getChartRotationSelector } from '../../../../state/selectors/get_chart_rotation';
+import { AnnotationId } from '../../../../utils/ids';
+import { computeSeriesGeometriesSelector } from './compute_series_geometries';
+import { ComputedGeometries } from '../utils';
+import { getTooltipValuesSelector } from './get_tooltip_values_highlighted_geoms';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+import { GlobalChartState } from '../../../../state/chart_state';
+
+const getCurrentPointerPosition = (state: GlobalChartState) => state.interactions.pointer.current.position;
+
+export const getAnnotationTooltipStateSelector = createCachedSelector(
+  [
+    getCurrentPointerPosition,
+    computeChartDimensionsSelector,
+    computeSeriesGeometriesSelector,
+    getChartRotationSelector,
+    getAnnotationSpecsSelector,
+    getAxisSpecsSelector,
+    computeAnnotationDimensionsSelector,
+    getTooltipValuesSelector,
+  ],
+  getAnnotationTooltipState,
+)(getChartIdSelector);
+
+function getAnnotationTooltipState(
+  { x, y }: Point,
+  {
+    chartDimensions,
+  }: {
+    chartDimensions: Dimensions;
+  },
+  geometries: ComputedGeometries,
+  chartRotation: Rotation,
+  annotationSpecs: AnnotationSpec[],
+  axesSpecs: AxisSpec[],
+  annotationDimensions: Map<AnnotationId, AnnotationDimensions>,
+  tooltipValues: TooltipValue[],
+): AnnotationTooltipState | null {
+  // get positions relative to chart
+  if (x < 0 || y < 0) {
+    return null;
+  }
+  const { xScale, yScales } = geometries.scales;
+  // only if we have a valid cursor position and the necessary scale
+  if (!xScale || !yScales) {
+    return null;
+  }
+  // use area chart projected coordinates of the pointer
+  const chartAreaProjectedPointer = { x: x - chartDimensions.left, y: y - chartDimensions.top };
+  const tooltipState = computeAnnotationTooltipState(
+    chartAreaProjectedPointer,
+    annotationDimensions,
+    annotationSpecs,
+    chartRotation,
+    axesSpecs,
+    chartDimensions,
+  );
+
+  // If there's a highlighted chart element tooltip value, don't show annotation tooltip
+  const isChartTooltipDisplayed = tooltipValues.some(({ isHighlighted }) => isHighlighted);
+  if (
+    tooltipState &&
+    tooltipState.isVisible &&
+    tooltipState.annotationType === AnnotationTypes.Rectangle &&
+    isChartTooltipDisplayed
+  ) {
+    return null;
+  }
+
+  return tooltipState;
+}
diff --git a/src/chart_types/xy_chart/state/selectors/get_bar_paddings.ts b/src/chart_types/xy_chart/state/selectors/get_bar_paddings.ts
new file mode 100644
index 0000000000..08e461ec5c
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_bar_paddings.ts
@@ -0,0 +1,11 @@
+import createCachedSelector from 're-reselect';
+import { isHistogramModeEnabledSelector } from './is_histogram_mode_enabled';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getBarPaddingsSelector = createCachedSelector(
+  [isHistogramModeEnabledSelector, getChartThemeSelector],
+  (isHistogramMode, chartTheme): number => {
+    return isHistogramMode ? chartTheme.scales.histogramPadding : chartTheme.scales.barsPadding;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_brush_area.ts b/src/chart_types/xy_chart/state/selectors/get_brush_area.ts
new file mode 100644
index 0000000000..2d97a0ee0e
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_brush_area.ts
@@ -0,0 +1,47 @@
+import createCachedSelector from 're-reselect';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { Dimensions } from '../../../../utils/dimensions';
+import { computeChartTransformSelector } from './compute_chart_transform';
+import { getChartRotationSelector } from '../../../../state/selectors/get_chart_rotation';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getMouseDownPosition = (state: GlobalChartState) => state.interactions.pointer.down;
+const getCurrentPointerPosition = (state: GlobalChartState) => {
+  return state.interactions.pointer.current.position;
+};
+
+export const getBrushAreaSelector = createCachedSelector(
+  [
+    getMouseDownPosition,
+    getCurrentPointerPosition,
+    getChartRotationSelector,
+    computeChartDimensionsSelector,
+    computeChartTransformSelector,
+  ],
+  (mouseDownPosition, cursorPosition, chartRotation, { chartDimensions }, chartTransform): Dimensions | null => {
+    if (!mouseDownPosition) {
+      return null;
+    }
+    const brushStart = {
+      x: mouseDownPosition.position.x - chartDimensions.left,
+      y: mouseDownPosition.position.y - chartDimensions.top,
+    };
+    if (chartRotation === 0 || chartRotation === 180) {
+      const area = {
+        left: brushStart.x,
+        top: 0,
+        width: cursorPosition.x - brushStart.x - chartDimensions.left,
+        height: chartDimensions.height,
+      };
+      return area;
+    } else {
+      return {
+        left: chartDimensions.left + chartTransform.x,
+        top: brushStart.y - chartDimensions.top,
+        width: chartDimensions.width,
+        height: cursorPosition.y - brushStart.y - chartDimensions.top,
+      };
+    }
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_computed_scales.ts b/src/chart_types/xy_chart/state/selectors/get_computed_scales.ts
new file mode 100644
index 0000000000..e76c303706
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_computed_scales.ts
@@ -0,0 +1,11 @@
+import createCachedSelector from 're-reselect';
+import { ComputedScales } from '../utils';
+import { computeSeriesGeometriesSelector } from './compute_series_geometries';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getComputedScalesSelector = createCachedSelector(
+  [computeSeriesGeometriesSelector],
+  (geometries): ComputedScales => {
+    return geometries.scales;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_cursor_band.ts b/src/chart_types/xy_chart/state/selectors/get_cursor_band.ts
new file mode 100644
index 0000000000..58751e1077
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_cursor_band.ts
@@ -0,0 +1,107 @@
+import { Dimensions } from '../../../../utils/dimensions';
+import createCachedSelector from 're-reselect';
+import { Point } from '../../../../utils/point';
+import { Scale } from '../../../../utils/scales/scales';
+import { isLineAreaOnlyChart } from '../utils';
+import { getCursorBandPosition } from '../../crosshair/crosshair_utils';
+import { SettingsSpec, CursorEvent } from '../../../../specs/settings';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { BasicSeriesSpec } from '../../utils/specs';
+import { countBarsInClusterSelector } from './count_bars_in_cluster';
+import { getSeriesSpecsSelector } from './get_specs';
+import { computeSeriesGeometriesSelector } from './compute_series_geometries';
+import { getOrientedProjectedPointerPositionSelector } from './get_oriented_projected_pointer_position';
+import { isTooltipSnapEnableSelector } from './is_tooltip_snap_enabled';
+import { getGeometriesIndexKeysSelector } from './get_geometries_index_keys';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { isValidExternalPointerEvent } from '../../../../utils/events';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getExternalPointerEventStateSelector = (state: GlobalChartState) => state.externalEvents.pointer;
+
+export const getCursorBandPositionSelector = createCachedSelector(
+  [
+    getOrientedProjectedPointerPositionSelector,
+    getExternalPointerEventStateSelector,
+    computeChartDimensionsSelector,
+    getSettingsSpecSelector,
+    computeSeriesGeometriesSelector,
+    getSeriesSpecsSelector,
+    countBarsInClusterSelector,
+    isTooltipSnapEnableSelector,
+    getGeometriesIndexKeysSelector,
+  ],
+  (
+    orientedProjectedPointerPosition,
+    externalPointerEvent,
+    chartDimensions,
+    settingsSpec,
+    seriesGeometries,
+    seriesSpec,
+    totalBarsInCluster,
+    isTooltipSnapEnabled,
+    geometriesIndexKeys,
+  ) => {
+    return getCursorBand(
+      orientedProjectedPointerPosition,
+      externalPointerEvent,
+      chartDimensions.chartDimensions,
+      settingsSpec,
+      seriesGeometries.scales.xScale,
+      seriesSpec,
+      totalBarsInCluster,
+      isTooltipSnapEnabled,
+      geometriesIndexKeys,
+    );
+  },
+)(getChartIdSelector);
+
+function getCursorBand(
+  orientedProjectedPoinerPosition: Point,
+  externalPointerEvent: CursorEvent | null,
+  chartDimensions: Dimensions,
+  settingsSpec: SettingsSpec,
+  xScale: Scale | undefined,
+  seriesSpecs: BasicSeriesSpec[],
+  totalBarsInCluster: number,
+  isTooltipSnapEnabled: boolean,
+  geometriesIndexKeys: any[],
+): Dimensions & { visible: boolean } | undefined {
+  // update che cursorBandPosition based on chart configuration
+  const isLineAreaOnly = isLineAreaOnlyChart(seriesSpecs);
+  if (!xScale) {
+    return;
+  }
+  let pointerPosition = orientedProjectedPoinerPosition;
+  let xValue;
+  if (externalPointerEvent && isValidExternalPointerEvent(externalPointerEvent, xScale)) {
+    const x = xScale.pureScale(externalPointerEvent.value);
+
+    if (x == null || x > chartDimensions.width + chartDimensions.left) {
+      return;
+    }
+    pointerPosition = { x, y: 0 };
+    xValue = {
+      value: externalPointerEvent.value,
+      withinBandwidth: true,
+    };
+  } else {
+    xValue = xScale.invertWithStep(orientedProjectedPoinerPosition.x, geometriesIndexKeys);
+    if (!xValue) {
+      return;
+    }
+  }
+  return getCursorBandPosition(
+    settingsSpec.rotation,
+    chartDimensions,
+    pointerPosition,
+    {
+      value: xValue.value,
+      withinBandwidth: true,
+    },
+    isTooltipSnapEnabled,
+    xScale,
+    isLineAreaOnly ? 1 : totalBarsInCluster,
+  );
+}
diff --git a/src/chart_types/xy_chart/state/selectors/get_cursor_line.ts b/src/chart_types/xy_chart/state/selectors/get_cursor_line.ts
new file mode 100644
index 0000000000..e727635af4
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_cursor_line.ts
@@ -0,0 +1,13 @@
+import createCachedSelector from 're-reselect';
+import { getCursorLinePosition } from '../../crosshair/crosshair_utils';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { getProjectedPointerPositionSelector } from './get_projected_pointer_position';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getCursorLinePositionSelector = createCachedSelector(
+  [computeChartDimensionsSelector, getSettingsSpecSelector, getProjectedPointerPositionSelector],
+  (chartDimensions, settingsSpec, projectedPointerPosition) => {
+    return getCursorLinePosition(settingsSpec.rotation, chartDimensions.chartDimensions, projectedPointerPosition);
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_cursor_pointer.ts b/src/chart_types/xy_chart/state/selectors/get_cursor_pointer.ts
new file mode 100644
index 0000000000..9c7848057c
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_cursor_pointer.ts
@@ -0,0 +1,37 @@
+import createCachedSelector from 're-reselect';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { getHighlightedGeomsSelector } from './get_tooltip_values_highlighted_geoms';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { isBrushAvailableSelector } from './is_brush_available';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getCurrentPointerPositionSelector = (state: GlobalChartState) => state.interactions.pointer.current.position;
+
+export const getPointerCursorSelector = createCachedSelector(
+  [
+    getHighlightedGeomsSelector,
+    getSettingsSpecSelector,
+    getCurrentPointerPositionSelector,
+    computeChartDimensionsSelector,
+    isBrushAvailableSelector,
+  ],
+  (highlightedGeometries, settingsSpec, currentPointerPosition, { chartDimensions }, isBrushAvailable): string => {
+    const { x, y } = currentPointerPosition;
+    // get positions relative to chart
+    const xPos = x - chartDimensions.left;
+    const yPos = y - chartDimensions.top;
+
+    // limit cursorPosition to chartDimensions
+    if (xPos < 0 || xPos >= chartDimensions.width) {
+      return 'default';
+    }
+    if (yPos < 0 || yPos >= chartDimensions.height) {
+      return 'default';
+    }
+    if (highlightedGeometries.length > 0 && (settingsSpec.onElementClick || settingsSpec.onElementOver)) {
+      return 'pointer';
+    }
+    return isBrushAvailable ? 'crosshair' : 'default';
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_elements_at_cursor_pos.ts b/src/chart_types/xy_chart/state/selectors/get_elements_at_cursor_pos.ts
new file mode 100644
index 0000000000..fb92a0175d
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_elements_at_cursor_pos.ts
@@ -0,0 +1,56 @@
+import createCachedSelector from 're-reselect';
+import { Point } from '../../../../utils/point';
+import { getOrientedProjectedPointerPositionSelector } from './get_oriented_projected_pointer_position';
+import { ComputedScales } from '../utils';
+import { getComputedScalesSelector } from './get_computed_scales';
+import { getGeometriesIndexKeysSelector } from './get_geometries_index_keys';
+import { getGeometriesIndexSelector } from './get_geometries_index';
+import { IndexedGeometry } from '../../../../utils/geometry';
+import { CursorEvent } from '../../../../specs';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { Dimensions } from '../../../../utils/dimensions';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { isValidExternalPointerEvent } from '../../../../utils/events';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getExternalPointerEventStateSelector = (state: GlobalChartState) => state.externalEvents.pointer;
+
+export const getElementAtCursorPositionSelector = createCachedSelector(
+  [
+    getOrientedProjectedPointerPositionSelector,
+    getComputedScalesSelector,
+    getGeometriesIndexKeysSelector,
+    getGeometriesIndexSelector,
+    getExternalPointerEventStateSelector,
+    computeChartDimensionsSelector,
+  ],
+  getElementAtCursorPosition,
+)(getChartIdSelector);
+
+function getElementAtCursorPosition(
+  orientedProjectedPoinerPosition: Point,
+  scales: ComputedScales,
+  geometriesIndexKeys: any,
+  geometriesIndex: Map<any, IndexedGeometry[]>,
+  externalPointerEvent: CursorEvent | null,
+  {
+    chartDimensions,
+  }: {
+    chartDimensions: Dimensions;
+  },
+): IndexedGeometry[] {
+  if (externalPointerEvent && isValidExternalPointerEvent(externalPointerEvent, scales.xScale)) {
+    const x = scales.xScale.pureScale(externalPointerEvent.value);
+
+    if (x == null || x > chartDimensions.width + chartDimensions.left) {
+      return [];
+    }
+    return geometriesIndex.get(externalPointerEvent.value) || [];
+  }
+  const xValue = scales.xScale.invertWithStep(orientedProjectedPoinerPosition.x, geometriesIndexKeys);
+  if (!xValue) {
+    return [];
+  }
+  // get the elements on at this cursor position
+  return geometriesIndex.get(xValue.value) || [];
+}
diff --git a/src/chart_types/xy_chart/state/selectors/get_geometries_index.ts b/src/chart_types/xy_chart/state/selectors/get_geometries_index.ts
new file mode 100644
index 0000000000..05c77897ca
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_geometries_index.ts
@@ -0,0 +1,11 @@
+import createCachedSelector from 're-reselect';
+import { IndexedGeometry } from '../../../../utils/geometry';
+import { computeSeriesGeometriesSelector } from './compute_series_geometries';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getGeometriesIndexSelector = createCachedSelector(
+  [computeSeriesGeometriesSelector],
+  (geometries): Map<any, IndexedGeometry[]> => {
+    return geometries.geometriesIndex;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_geometries_index_keys.ts b/src/chart_types/xy_chart/state/selectors/get_geometries_index_keys.ts
new file mode 100644
index 0000000000..f18e8ddb20
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_geometries_index_keys.ts
@@ -0,0 +1,11 @@
+import createCachedSelector from 're-reselect';
+import { compareByValueAsc } from '../../../../utils/commons';
+import { computeSeriesGeometriesSelector } from './compute_series_geometries';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getGeometriesIndexKeysSelector = createCachedSelector(
+  [computeSeriesGeometriesSelector],
+  (seriesGeometries): any[] => {
+    return [...seriesGeometries.geometriesIndex.keys()].sort(compareByValueAsc);
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_highlighted_series.ts b/src/chart_types/xy_chart/state/selectors/get_highlighted_series.ts
new file mode 100644
index 0000000000..ad2204ceb1
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_highlighted_series.ts
@@ -0,0 +1,17 @@
+import createCachedSelector from 're-reselect';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { computeLegendSelector } from './compute_legend';
+import { LegendItem } from '../../../../chart_types/xy_chart/legend/legend';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getHighlightedLegendItemKey = (state: GlobalChartState) => state.interactions.highlightedLegendItemKey;
+
+export const getHighlightedSeriesSelector = createCachedSelector(
+  [getHighlightedLegendItemKey, computeLegendSelector],
+  (highlightedLegendItemKey, legendItems): LegendItem | undefined => {
+    if (!highlightedLegendItemKey) {
+      return undefined;
+    }
+    return legendItems.get(highlightedLegendItemKey);
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_legend_tooltip_values.ts b/src/chart_types/xy_chart/state/selectors/get_legend_tooltip_values.ts
new file mode 100644
index 0000000000..6c4e692ad4
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_legend_tooltip_values.ts
@@ -0,0 +1,11 @@
+import createCachedSelector from 're-reselect';
+import { getSeriesTooltipValues, TooltipLegendValue } from '../../tooltip/tooltip';
+import { getTooltipValuesSelector } from './get_tooltip_values_highlighted_geoms';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getLegendTooltipValuesSelector = createCachedSelector(
+  [getTooltipValuesSelector],
+  (tooltipData): Map<string, TooltipLegendValue> => {
+    return getSeriesTooltipValues(tooltipData);
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_oriented_projected_pointer_position.ts b/src/chart_types/xy_chart/state/selectors/get_oriented_projected_pointer_position.ts
new file mode 100644
index 0000000000..6c9d2c938b
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_oriented_projected_pointer_position.ts
@@ -0,0 +1,30 @@
+import { Dimensions } from '../../../../utils/dimensions';
+import createCachedSelector from 're-reselect';
+import { getProjectedPointerPositionSelector } from './get_projected_pointer_position';
+import { Point } from '../../../../utils/point';
+import { getOrientedXPosition, getOrientedYPosition } from '../../utils/interactions';
+import { SettingsSpec } from '../../../../specs/settings';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getOrientedProjectedPointerPositionSelector = createCachedSelector(
+  [getProjectedPointerPositionSelector, computeChartDimensionsSelector, getSettingsSpecSelector],
+  getOrientedProjectedPointerPosition,
+)(getChartIdSelector);
+
+function getOrientedProjectedPointerPosition(
+  projectedPointerPosition: Point,
+  chartDimensions: { chartDimensions: Dimensions },
+  settingsSpec: SettingsSpec,
+): Point {
+  const xPos = projectedPointerPosition.x;
+  const yPos = projectedPointerPosition.y;
+  // get the oriented projected pointer position
+  const x = getOrientedXPosition(xPos, yPos, settingsSpec.rotation, chartDimensions.chartDimensions);
+  const y = getOrientedYPosition(xPos, yPos, settingsSpec.rotation, chartDimensions.chartDimensions);
+  return {
+    x,
+    y,
+  };
+}
diff --git a/src/chart_types/xy_chart/state/selectors/get_projected_pointer_position.ts b/src/chart_types/xy_chart/state/selectors/get_projected_pointer_position.ts
new file mode 100644
index 0000000000..4bc89b50e3
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_projected_pointer_position.ts
@@ -0,0 +1,38 @@
+import createCachedSelector from 're-reselect';
+import { Dimensions } from '../../../../utils/dimensions';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { Point } from '../../../../utils/point';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getCurrentPointerPosition = (state: GlobalChartState) => state.interactions.pointer.current.position;
+
+export const getProjectedPointerPositionSelector = createCachedSelector(
+  [getCurrentPointerPosition, computeChartDimensionsSelector],
+  (currentPointerPosition, chartDimensions): Point => {
+    return getProjectedPointerPosition(currentPointerPosition, chartDimensions.chartDimensions);
+  },
+)(getChartIdSelector);
+
+/**
+ * Get the x and y pointer position relative to the chart projection area
+ * @param chartAreaPointerPosition the pointer position relative to the chart area
+ * @param chartAreaDimensions the chart dimensions
+ */
+function getProjectedPointerPosition(chartAreaPointerPosition: Point, chartAreaDimensions: Dimensions): Point {
+  const { x, y } = chartAreaPointerPosition;
+  // get positions relative to chart
+  let xPos = x - chartAreaDimensions.left;
+  let yPos = y - chartAreaDimensions.top;
+  // limit cursorPosition to the chart area
+  if (xPos < 0 || xPos >= chartAreaDimensions.width) {
+    xPos = -1;
+  }
+  if (yPos < 0 || yPos >= chartAreaDimensions.height) {
+    yPos = -1;
+  }
+  return {
+    x: xPos,
+    y: yPos,
+  };
+}
diff --git a/src/chart_types/xy_chart/state/selectors/get_series_color_map.ts b/src/chart_types/xy_chart/state/selectors/get_series_color_map.ts
new file mode 100644
index 0000000000..a109514788
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_series_color_map.ts
@@ -0,0 +1,21 @@
+import createCachedSelector from 're-reselect';
+import { computeSeriesDomainsSelector } from './compute_series_domains';
+import { getSeriesSpecsSelector } from './get_specs';
+import { getUpdatedCustomSeriesColors } from '../utils';
+import { getSeriesColorMap } from '../../utils/series';
+import { getChartThemeSelector } from '../../../../state/selectors/get_chart_theme';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getSeriesColorMapSelector = createCachedSelector(
+  [getSeriesSpecsSelector, computeSeriesDomainsSelector, getChartThemeSelector],
+  (seriesSpecs, seriesDomainsAndData, chartTheme): Map<string, string> => {
+    const updatedCustomSeriesColors = getUpdatedCustomSeriesColors(seriesSpecs);
+
+    const seriesColorMap = getSeriesColorMap(
+      seriesDomainsAndData.seriesColors,
+      chartTheme.colors,
+      updatedCustomSeriesColors,
+    );
+    return seriesColorMap;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_specs.test.ts b/src/chart_types/xy_chart/state/selectors/get_specs.test.ts
new file mode 100644
index 0000000000..2f5092986a
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_specs.test.ts
@@ -0,0 +1,28 @@
+import { getSeriesSpecsSelector } from './get_specs';
+import { getInitialState } from '../../../../state/chart_state';
+import { ChartTypes } from '../../..';
+import { SpecTypes } from '../../utils/specs';
+
+describe('selector - get_specs', () => {
+  const state = getInitialState('chartId1');
+  const barSpec1 = {
+    id: 'bars1',
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
+  };
+  const barSpec2 = {
+    id: 'bars2',
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
+  };
+  beforeEach(() => {
+    state.specs['bars1'] = barSpec1;
+    state.specs['bars2'] = barSpec2;
+  });
+  it('shall return the same ref objects', () => {
+    const series = getSeriesSpecsSelector(state);
+    expect(series.length).toBe(2);
+    const seriesSecondCall = getSeriesSpecsSelector({ ...state, specsInitialized: true });
+    expect(series).toBe(seriesSecondCall);
+  });
+});
diff --git a/src/chart_types/xy_chart/state/selectors/get_specs.ts b/src/chart_types/xy_chart/state/selectors/get_specs.ts
new file mode 100644
index 0000000000..2d7eb779bc
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_specs.ts
@@ -0,0 +1,24 @@
+import createCachedSelector from 're-reselect';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { getSpecsFromStore } from '../../../../state/utils';
+import { AxisSpec, BasicSeriesSpec, AnnotationSpec, SpecTypes } from '../../utils/specs';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+import { ChartTypes } from '../../..';
+
+const getSpecs = (state: GlobalChartState) => state.specs;
+
+export const getAxisSpecsSelector = createCachedSelector(
+  [getSpecs],
+  (specs): AxisSpec[] => {
+    return getSpecsFromStore<AxisSpec>(specs, ChartTypes.XYAxis, SpecTypes.Axis);
+  },
+)(getChartIdSelector);
+
+export const getSeriesSpecsSelector = createCachedSelector([getSpecs], (specs) => {
+  const seriesSpec = getSpecsFromStore<BasicSeriesSpec>(specs, ChartTypes.XYAxis, SpecTypes.Series);
+  return seriesSpec;
+})(getChartIdSelector);
+
+export const getAnnotationSpecsSelector = createCachedSelector([getSpecs], (specs) => {
+  return getSpecsFromStore<AnnotationSpec>(specs, ChartTypes.XYAxis, SpecTypes.Annotation);
+})(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_tooltip_header_formatter.ts b/src/chart_types/xy_chart/state/selectors/get_tooltip_header_formatter.ts
new file mode 100644
index 0000000000..5f9f0cfff8
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_tooltip_header_formatter.ts
@@ -0,0 +1,18 @@
+import createCachedSelector from 're-reselect';
+import { isTooltipProps, TooltipValueFormatter } from '../../utils/interactions';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { SettingsSpec } from '../../../../specs/settings';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getTooltipHeaderFormatterSelector = createCachedSelector(
+  [getSettingsSpecSelector],
+  getTooltipHeaderFormatter,
+)(getChartIdSelector);
+
+function getTooltipHeaderFormatter(settings: SettingsSpec): TooltipValueFormatter | undefined {
+  const { tooltip } = settings;
+  if (tooltip && isTooltipProps(tooltip)) {
+    return tooltip.headerFormatter;
+  }
+  return undefined;
+}
diff --git a/src/chart_types/xy_chart/state/selectors/get_tooltip_position.ts b/src/chart_types/xy_chart/state/selectors/get_tooltip_position.ts
new file mode 100644
index 0000000000..3e6364890d
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_tooltip_position.ts
@@ -0,0 +1,30 @@
+import createCachedSelector from 're-reselect';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getTooltipPosition, TooltipPosition } from '../../crosshair/crosshair_utils';
+import { getProjectedPointerPositionSelector } from './get_projected_pointer_position';
+import { getComputedScalesSelector } from './get_computed_scales';
+import { getCursorBandPositionSelector } from './get_cursor_band';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getTooltipPositionSelector = createCachedSelector(
+  [
+    computeChartDimensionsSelector,
+    getSettingsSpecSelector,
+    getCursorBandPositionSelector,
+    getProjectedPointerPositionSelector,
+    getComputedScalesSelector,
+  ],
+  ({ chartDimensions }, settings, cursorBandPosition, projectedPointerPosition, scales): TooltipPosition | null => {
+    if (!cursorBandPosition) {
+      return null;
+    }
+    return getTooltipPosition(
+      chartDimensions,
+      settings.rotation,
+      cursorBandPosition,
+      projectedPointerPosition,
+      scales.xScale.isSingleValue(),
+    );
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/get_tooltip_snap.ts b/src/chart_types/xy_chart/state/selectors/get_tooltip_snap.ts
new file mode 100644
index 0000000000..341f27284c
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_tooltip_snap.ts
@@ -0,0 +1,18 @@
+import createCachedSelector from 're-reselect';
+import { isTooltipProps } from '../../utils/interactions';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { SettingsSpec } from '../../../../specs/settings';
+import { DEFAULT_TOOLTIP_SNAP } from '../../../../specs/settings';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getTooltipSnapSelector = createCachedSelector([getSettingsSpecSelector], getTooltipSnap)(
+  getChartIdSelector,
+);
+
+function getTooltipSnap(settings: SettingsSpec): boolean {
+  const { tooltip } = settings;
+  if (tooltip && isTooltipProps(tooltip)) {
+    return tooltip.snap || false;
+  }
+  return DEFAULT_TOOLTIP_SNAP;
+}
diff --git a/src/chart_types/xy_chart/state/selectors/get_tooltip_type.ts b/src/chart_types/xy_chart/state/selectors/get_tooltip_type.ts
new file mode 100644
index 0000000000..4069cb0c83
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_tooltip_type.ts
@@ -0,0 +1,23 @@
+import createCachedSelector from 're-reselect';
+import { TooltipType, isTooltipProps, isTooltipType } from '../../utils/interactions';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { SettingsSpec } from '../../../../specs/settings';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const getTooltipTypeSelector = createCachedSelector([getSettingsSpecSelector], getTooltipType)(
+  getChartIdSelector,
+);
+
+function getTooltipType(settings: SettingsSpec): TooltipType {
+  const { tooltip } = settings;
+  if (tooltip === undefined || tooltip === null) {
+    return TooltipType.VerticalCursor;
+  }
+  if (isTooltipType(tooltip)) {
+    return tooltip;
+  }
+  if (isTooltipProps(tooltip)) {
+    return tooltip.type || TooltipType.VerticalCursor;
+  }
+  return TooltipType.VerticalCursor;
+}
diff --git a/src/chart_types/xy_chart/state/selectors/get_tooltip_values_highlighted_geoms.ts b/src/chart_types/xy_chart/state/selectors/get_tooltip_values_highlighted_geoms.ts
new file mode 100644
index 0000000000..c0739b65c9
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/get_tooltip_values_highlighted_geoms.ts
@@ -0,0 +1,150 @@
+import createCachedSelector from 're-reselect';
+import { TooltipValue, isFollowTooltipType, TooltipType, TooltipValueFormatter } from '../../utils/interactions';
+import { getProjectedPointerPositionSelector } from './get_projected_pointer_position';
+import { Point } from '../../../../utils/point';
+import { getOrientedProjectedPointerPositionSelector } from './get_oriented_projected_pointer_position';
+import { ComputedScales, getAxesSpecForSpecId, getSpecsById } from '../utils';
+import { getComputedScalesSelector } from './get_computed_scales';
+import { getElementAtCursorPositionSelector } from './get_elements_at_cursor_pos';
+import { IndexedGeometry } from '../../../../utils/geometry';
+import { getSeriesSpecsSelector, getAxisSpecsSelector } from './get_specs';
+import { BasicSeriesSpec, AxisSpec, Rotation } from '../../utils/specs';
+import { getTooltipTypeSelector } from './get_tooltip_type';
+import { formatTooltip } from '../../tooltip/tooltip';
+import { getTooltipHeaderFormatterSelector } from './get_tooltip_header_formatter';
+import { isPointOnGeometry } from '../../rendering/rendering';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { CursorEvent } from '../../../../specs';
+import { isValidExternalPointerEvent } from '../../../../utils/events';
+import { getChartRotationSelector } from '../../../../state/selectors/get_chart_rotation';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const EMPTY_VALUES = Object.freeze({
+  tooltipValues: [],
+  highlightedGeometries: [],
+});
+
+export interface TooltipAndHighlightedGeoms {
+  tooltipValues: TooltipValue[];
+  highlightedGeometries: IndexedGeometry[];
+}
+
+const getExternalPointerEventStateSelector = (state: GlobalChartState) => state.externalEvents.pointer;
+
+export const getTooltipValuesAndGeometriesSelector = createCachedSelector(
+  [
+    getSeriesSpecsSelector,
+    getAxisSpecsSelector,
+    getProjectedPointerPositionSelector,
+    getOrientedProjectedPointerPositionSelector,
+    getChartRotationSelector,
+    getComputedScalesSelector,
+    getElementAtCursorPositionSelector,
+    getTooltipTypeSelector,
+    getExternalPointerEventStateSelector,
+    getTooltipHeaderFormatterSelector,
+  ],
+  getTooltipAndHighlightFromXValue,
+)((state: GlobalChartState) => {
+  return state.chartId;
+});
+
+function getTooltipAndHighlightFromXValue(
+  seriesSpecs: BasicSeriesSpec[],
+  axesSpecs: AxisSpec[],
+  projectedPointerPosition: Point,
+  orientedProjectedPointerPosition: Point,
+  chartRotation: Rotation,
+  scales: ComputedScales,
+  xMatchingGeoms: IndexedGeometry[],
+  tooltipType: TooltipType,
+  externalPointerEvent: CursorEvent | null,
+  tooltipHeaderFormatter?: TooltipValueFormatter,
+): TooltipAndHighlightedGeoms {
+  if (!scales.xScale || !scales.yScales) {
+    return EMPTY_VALUES;
+  }
+  let x = orientedProjectedPointerPosition.x;
+  let y = orientedProjectedPointerPosition.y;
+  if (externalPointerEvent && isValidExternalPointerEvent(externalPointerEvent, scales.xScale)) {
+    x = scales.xScale.pureScale(externalPointerEvent.value);
+    y = 0;
+  } else if (projectedPointerPosition.x === -1 || projectedPointerPosition.y === -1) {
+    return EMPTY_VALUES;
+  }
+
+  if (xMatchingGeoms.length === 0) {
+    return EMPTY_VALUES;
+  }
+
+  // build the tooltip value list
+  let xValueInfo: TooltipValue | null = null;
+  const highlightedGeometries: IndexedGeometry[] = [];
+  const tooltipValues = xMatchingGeoms
+    .filter(({ value: { y } }) => y !== null)
+    .reduce<TooltipValue[]>((acc, indexedGeometry) => {
+      const {
+        geometryId: { specId },
+      } = indexedGeometry;
+      const spec = getSpecsById<BasicSeriesSpec>(seriesSpecs, specId);
+
+      // safe guard check
+      if (!spec) {
+        return acc;
+      }
+      const { xAxis, yAxis } = getAxesSpecForSpecId(axesSpecs, spec.groupId);
+
+      // yScales is ensured by the enclosing if
+      const yScale = scales.yScales.get(spec.groupId);
+      if (!yScale) {
+        return acc;
+      }
+
+      // check if the pointer is on the geometry (avoid checking if using external pointer event)
+      let isHighlighted = false;
+      if (!externalPointerEvent && isPointOnGeometry(x, y, indexedGeometry)) {
+        isHighlighted = true;
+        highlightedGeometries.push(indexedGeometry);
+      }
+
+      // if it's a follow tooltip, and no element is highlighted
+      // not add that element into the tooltip list
+      if (!isHighlighted && isFollowTooltipType(tooltipType)) {
+        return acc;
+      }
+
+      // format the tooltip values
+      const yAxisFormatSpec = [0, 180].includes(chartRotation) ? yAxis : xAxis;
+      const formattedTooltip = formatTooltip(indexedGeometry, spec, false, isHighlighted, yAxisFormatSpec);
+
+      // format only one time the x value
+      if (!xValueInfo) {
+        // if we have a tooltipHeaderFormatter, then don't pass in the xAxis as the user will define a formatter
+        const xAxisFormatSpec = [0, 180].includes(chartRotation) ? xAxis : yAxis;
+        const formatterAxis = tooltipHeaderFormatter ? undefined : xAxisFormatSpec;
+        xValueInfo = formatTooltip(indexedGeometry, spec, true, false, formatterAxis);
+        return [xValueInfo, ...acc, formattedTooltip];
+      }
+
+      return [...acc, formattedTooltip];
+    }, []);
+
+  return {
+    tooltipValues,
+    highlightedGeometries,
+  };
+}
+
+export const getTooltipValuesSelector = createCachedSelector(
+  [getTooltipValuesAndGeometriesSelector],
+  (values): TooltipValue[] => {
+    return values.tooltipValues;
+  },
+)(getChartIdSelector);
+
+export const getHighlightedGeomsSelector = createCachedSelector(
+  [getTooltipValuesAndGeometriesSelector],
+  (values): IndexedGeometry[] => {
+    return values.highlightedGeometries;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/is_annotation_tooltip_visible.ts b/src/chart_types/xy_chart/state/selectors/is_annotation_tooltip_visible.ts
new file mode 100644
index 0000000000..27242608a3
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/is_annotation_tooltip_visible.ts
@@ -0,0 +1,10 @@
+import { getAnnotationTooltipStateSelector } from './get_annotation_tooltip_state';
+import createCachedSelector from 're-reselect';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const isAnnotationTooltipVisibleSelector = createCachedSelector(
+  [getAnnotationTooltipStateSelector],
+  (annotationTooltipState): boolean => {
+    return annotationTooltipState !== null && annotationTooltipState.isVisible;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/is_brush_available.ts b/src/chart_types/xy_chart/state/selectors/is_brush_available.ts
new file mode 100644
index 0000000000..4c36e69418
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/is_brush_available.ts
@@ -0,0 +1,19 @@
+import createCachedSelector from 're-reselect';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getComputedScalesSelector } from './get_computed_scales';
+import { ScaleType } from '../../../../utils/scales/scales';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+/**
+ * The brush is available only for Ordinal xScales charts and
+ * if we have configured an onBrushEnd listener
+ */
+export const isBrushAvailableSelector = createCachedSelector(
+  [getSettingsSpecSelector, getComputedScalesSelector],
+  (settingsSpec, scales): boolean => {
+    if (!scales.xScale) {
+      return false;
+    }
+    return scales.xScale.type !== ScaleType.Ordinal && Boolean(settingsSpec.onBrushEnd);
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/is_brushing.ts b/src/chart_types/xy_chart/state/selectors/is_brushing.ts
new file mode 100644
index 0000000000..ed7521f05b
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/is_brushing.ts
@@ -0,0 +1,17 @@
+import createCachedSelector from 're-reselect';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { isBrushAvailableSelector } from './is_brush_available';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getPointerSelector = (state: GlobalChartState) => state.interactions.pointer;
+
+export const isBrushingSelector = createCachedSelector(
+  [isBrushAvailableSelector, getPointerSelector],
+  (isBrushAvailable, pointer): boolean => {
+    if (!isBrushAvailable) {
+      return false;
+    }
+
+    return pointer.dragging;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/is_chart_animatable.ts b/src/chart_types/xy_chart/state/selectors/is_chart_animatable.ts
new file mode 100644
index 0000000000..eaf5cf9656
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/is_chart_animatable.ts
@@ -0,0 +1,16 @@
+import createCachedSelector from 're-reselect';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { computeSeriesGeometriesSelector } from './compute_series_geometries';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+// import { isChartAnimatable } from '../utils';
+
+export const isChartAnimatableSelector = createCachedSelector(
+  [computeSeriesGeometriesSelector, getSettingsSpecSelector],
+  () => {
+    // const { geometriesCounts } = seriesGeometries;
+    // temporary disabled until
+    // https://github.com/elastic/elastic-charts/issues/89 and https://github.com/elastic/elastic-charts/issues/41
+    // return isChartAnimatable(geometriesCounts, settingsSpec.animateData);
+    return false;
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/is_chart_empty.ts b/src/chart_types/xy_chart/state/selectors/is_chart_empty.ts
new file mode 100644
index 0000000000..f77ad9a15f
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/is_chart_empty.ts
@@ -0,0 +1,10 @@
+import createCachedSelector from 're-reselect';
+import { isAllSeriesDeselected } from '../utils';
+import { computeLegendSelector } from './compute_legend';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+export const isChartEmptySelector = createCachedSelector(
+  [computeLegendSelector],
+  (legendItems): boolean => {
+    return isAllSeriesDeselected(legendItems);
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/is_histogram_mode_enabled.ts b/src/chart_types/xy_chart/state/selectors/is_histogram_mode_enabled.ts
new file mode 100644
index 0000000000..db92e8992e
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/is_histogram_mode_enabled.ts
@@ -0,0 +1,11 @@
+import createCachedSelector from 're-reselect';
+import { getSeriesSpecsSelector } from './get_specs';
+import { isHistogramModeEnabled } from '../utils';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const isHistogramModeEnabledSelector = createCachedSelector(
+  [getSeriesSpecsSelector],
+  (seriesSpecs): boolean => {
+    return isHistogramModeEnabled(seriesSpecs);
+  },
+)(getChartIdSelector);
diff --git a/src/chart_types/xy_chart/state/selectors/is_tooltip_snap_enabled.ts b/src/chart_types/xy_chart/state/selectors/is_tooltip_snap_enabled.ts
new file mode 100644
index 0000000000..b1ef7e2ea2
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/is_tooltip_snap_enabled.ts
@@ -0,0 +1,16 @@
+import createCachedSelector from 're-reselect';
+import { computeSeriesGeometriesSelector } from './compute_series_geometries';
+import { Scale } from '../../../../utils/scales/scales';
+import { getTooltipSnapSelector } from './get_tooltip_snap';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const isTooltipSnapEnableSelector = createCachedSelector(
+  [computeSeriesGeometriesSelector, getTooltipSnapSelector],
+  (seriesGeometries, snap) => {
+    return isTooltipSnapEnabled(seriesGeometries.scales.xScale, snap);
+  },
+)(getChartIdSelector);
+
+function isTooltipSnapEnabled(xScale: Scale, snap: boolean) {
+  return (xScale && xScale.bandwidth > 0) || snap;
+}
diff --git a/src/chart_types/xy_chart/state/selectors/is_tooltip_visible.ts b/src/chart_types/xy_chart/state/selectors/is_tooltip_visible.ts
new file mode 100644
index 0000000000..931919ac5a
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/is_tooltip_visible.ts
@@ -0,0 +1,42 @@
+import createCachedSelector from 're-reselect';
+import { TooltipType, TooltipValue, isTooltipType, isTooltipProps } from '../../utils/interactions';
+import { Point } from '../../../../utils/point';
+import { GlobalChartState, PointerStates } from '../../../../state/chart_state';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getProjectedPointerPositionSelector } from './get_projected_pointer_position';
+import { getTooltipValuesSelector } from './get_tooltip_values_highlighted_geoms';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getTooltipType = (state: GlobalChartState): TooltipType | undefined => {
+  const tooltip = getSettingsSpecSelector(state).tooltip;
+  if (!tooltip) {
+    return undefined;
+  }
+  if (isTooltipType(tooltip)) {
+    return tooltip;
+  }
+  if (isTooltipProps(tooltip)) {
+    return tooltip.type;
+  }
+};
+const getPointerSelector = (state: GlobalChartState) => state.interactions.pointer;
+
+export const isTooltipVisibleSelector = createCachedSelector(
+  [getTooltipType, getPointerSelector, getProjectedPointerPositionSelector, getTooltipValuesSelector],
+  isTooltipVisible,
+)(getChartIdSelector);
+
+function isTooltipVisible(
+  tooltipType: TooltipType | undefined,
+  pointer: PointerStates,
+  projectedPointerPosition: Point,
+  tooltipValues: TooltipValue[],
+) {
+  return (
+    tooltipType !== TooltipType.None &&
+    pointer.down === null &&
+    projectedPointerPosition.x > -1 &&
+    projectedPointerPosition.y > -1 &&
+    tooltipValues.length > 0
+  );
+}
diff --git a/src/chart_types/xy_chart/state/selectors/merge_y_custom_domains.ts b/src/chart_types/xy_chart/state/selectors/merge_y_custom_domains.ts
new file mode 100644
index 0000000000..40ff022f8e
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/merge_y_custom_domains.ts
@@ -0,0 +1,70 @@
+import createCachedSelector from 're-reselect';
+import { getAxisSpecsSelector } from './get_specs';
+import { isYDomain, isCompleteBound, isLowerBound, isUpperBound, isBounded } from '../../utils/axis_utils';
+import { AxisSpec, DomainRange, Rotation } from '../../utils/specs';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+export const mergeYCustomDomainsByGroupIdSelector = createCachedSelector(
+  [getAxisSpecsSelector, getSettingsSpecSelector],
+  (axisSpecs, settingsSpec): Map<string, DomainRange> => {
+    return mergeYCustomDomainsByGroupId(axisSpecs, settingsSpec ? settingsSpec.rotation : 0);
+  },
+)(getChartIdSelector);
+
+export function mergeYCustomDomainsByGroupId(axesSpecs: AxisSpec[], chartRotation: Rotation): Map<string, DomainRange> {
+  const domainsByGroupId = new Map<string, DomainRange>();
+
+  axesSpecs.forEach((spec: AxisSpec) => {
+    const { id, groupId, domain } = spec;
+
+    if (!domain) {
+      return;
+    }
+
+    const isAxisYDomain = isYDomain(spec.position, chartRotation);
+
+    if (!isAxisYDomain) {
+      const errorMessage = `[Axis ${id}]: custom domain for xDomain should be defined in Settings`;
+      throw new Error(errorMessage);
+    }
+
+    if (isCompleteBound(domain) && domain.min > domain.max) {
+      const errorMessage = `[Axis ${id}]: custom domain is invalid, min is greater than max`;
+      throw new Error(errorMessage);
+    }
+
+    const prevGroupDomain = domainsByGroupId.get(groupId);
+
+    if (prevGroupDomain) {
+      const prevDomain = prevGroupDomain as DomainRange;
+
+      const prevMin = isLowerBound(prevDomain) ? prevDomain.min : undefined;
+      const prevMax = isUpperBound(prevDomain) ? prevDomain.max : undefined;
+
+      let max = prevMax;
+      let min = prevMin;
+
+      if (isCompleteBound(domain)) {
+        min = prevMin != null ? Math.min(domain.min, prevMin) : domain.min;
+        max = prevMax != null ? Math.max(domain.max, prevMax) : domain.max;
+      } else if (isLowerBound(domain)) {
+        min = prevMin != null ? Math.min(domain.min, prevMin) : domain.min;
+      } else if (isUpperBound(domain)) {
+        max = prevMax != null ? Math.max(domain.max, prevMax) : domain.max;
+      }
+
+      const mergedDomain = {
+        min,
+        max,
+      };
+
+      if (isBounded(mergedDomain)) {
+        domainsByGroupId.set(groupId, mergedDomain);
+      }
+    } else {
+      domainsByGroupId.set(groupId, domain);
+    }
+  });
+  return domainsByGroupId;
+}
diff --git a/src/chart_types/xy_chart/state/selectors/on_brush_end_caller.ts b/src/chart_types/xy_chart/state/selectors/on_brush_end_caller.ts
new file mode 100644
index 0000000000..b2bb04e192
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/on_brush_end_caller.ts
@@ -0,0 +1,93 @@
+import createCachedSelector from 're-reselect';
+import { Selector } from 'reselect';
+import { GlobalChartState, DragState } from '../../../../state/chart_state';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { SettingsSpec } from '../../../../specs';
+import { ChartTypes } from '../../../index';
+import { getComputedScalesSelector } from './get_computed_scales';
+import { computeChartDimensionsSelector } from './compute_chart_dimensions';
+import { isHistogramModeEnabledSelector } from './is_histogram_mode_enabled';
+import { isBrushAvailableSelector } from './is_brush_available';
+
+const getLastDragSelector = (state: GlobalChartState) => state.interactions.pointer.lastDrag;
+
+interface Props {
+  settings: SettingsSpec | undefined;
+  lastDrag: DragState | null;
+}
+
+function hasDragged(prevProps: Props | null, nextProps: Props | null) {
+  if (nextProps === null) {
+    return false;
+  }
+  if (!nextProps.settings || !nextProps.settings.onBrushEnd) {
+    return false;
+  }
+  const prevLastDrag = prevProps !== null ? prevProps.lastDrag : null;
+  const nextLastDrag = nextProps !== null ? nextProps.lastDrag : null;
+
+  if (prevLastDrag === null && nextLastDrag !== null) {
+    return true;
+  }
+  if (prevLastDrag !== null && nextLastDrag !== null && prevLastDrag.end.time !== nextLastDrag.end.time) {
+    return true;
+  }
+  return false;
+}
+
+/**
+ * Will call the onBrushEnd listener every time the following preconditions are met:
+ * - the onBrushEnd listener is available
+ * - we dragged the mouse pointer
+ */
+export function createOnBrushEndCaller(): (state: GlobalChartState) => void {
+  let prevProps: Props | null = null;
+  let selector: Selector<GlobalChartState, void> | null = null;
+  return (state: GlobalChartState) => {
+    if (selector === null && state.chartType === ChartTypes.XYAxis) {
+      if (!isBrushAvailableSelector(state)) {
+        selector = null;
+        prevProps = null;
+        return;
+      }
+      selector = createCachedSelector(
+        [
+          getLastDragSelector,
+          getSettingsSpecSelector,
+          getComputedScalesSelector,
+          computeChartDimensionsSelector,
+          isHistogramModeEnabledSelector,
+        ],
+        (lastDrag, settings, computedScales, { chartDimensions }, histogramMode): void => {
+          const nextProps = {
+            lastDrag,
+            settings,
+          };
+
+          if (lastDrag !== null && hasDragged(prevProps, nextProps)) {
+            if (settings && settings.onBrushEnd) {
+              const minValue = Math.min(lastDrag.start.position.x, lastDrag.end.position.x);
+              const maxValue = Math.max(lastDrag.start.position.x, lastDrag.end.position.x);
+              if (maxValue === minValue) {
+                // if 0 size brush, avoid computing the value
+                return;
+              }
+
+              const { xScale } = computedScales;
+              const offset = histogramMode ? 0 : -(xScale.bandwidth + xScale.bandwidthPadding) / 2;
+              const min = xScale.invert(minValue - chartDimensions.left + offset);
+              const max = xScale.invert(maxValue - chartDimensions.left + offset);
+              settings.onBrushEnd(min, max);
+            }
+          }
+          prevProps = nextProps;
+        },
+      )({
+        keySelector: (state: GlobalChartState) => state.chartId,
+      });
+    }
+    if (selector) {
+      selector(state);
+    }
+  };
+}
diff --git a/src/chart_types/xy_chart/state/selectors/on_element_click_caller.ts b/src/chart_types/xy_chart/state/selectors/on_element_click_caller.ts
new file mode 100644
index 0000000000..fd6d9fe9b1
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/on_element_click_caller.ts
@@ -0,0 +1,72 @@
+import createCachedSelector from 're-reselect';
+import { Selector } from 'reselect';
+import { GlobalChartState, PointerState } from '../../../../state/chart_state';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { getHighlightedGeomsSelector } from './get_tooltip_values_highlighted_geoms';
+import { SettingsSpec } from '../../../../specs';
+import { IndexedGeometry } from '../../../../utils/geometry';
+import { ChartTypes } from '../../../index';
+
+const getLastClickSelector = (state: GlobalChartState) => state.interactions.pointer.lastClick;
+
+interface Props {
+  settings: SettingsSpec | undefined;
+  lastClick: PointerState | null;
+  indexedGeometries: IndexedGeometry[];
+}
+
+function isClicking(prevProps: Props | null, nextProps: Props | null) {
+  if (nextProps === null) {
+    return false;
+  }
+  if (!nextProps.settings || !nextProps.settings.onElementClick || nextProps.indexedGeometries.length === 0) {
+    return false;
+  }
+  const prevLastClick = prevProps !== null ? prevProps.lastClick : null;
+  const nextLastClick = nextProps !== null ? nextProps.lastClick : null;
+
+  if (prevLastClick === null && nextLastClick !== null) {
+    return true;
+  }
+  if (prevLastClick !== null && nextLastClick !== null && prevLastClick.time !== nextLastClick.time) {
+    return true;
+  }
+  return false;
+}
+
+/**
+ * Will call the onElementClick listener every time the following preconditions are met:
+ * - the onElementClick listener is available
+ * - we have at least one highlighted geometry
+ * - the pointer state goes from down state to up state
+ */
+export function createOnElementClickCaller(): (state: GlobalChartState) => void {
+  let prevProps: Props | null = null;
+  let selector: Selector<GlobalChartState, void> | null = null;
+  return (state: GlobalChartState) => {
+    if (selector === null && state.chartType === ChartTypes.XYAxis) {
+      selector = createCachedSelector(
+        [getLastClickSelector, getSettingsSpecSelector, getHighlightedGeomsSelector],
+        (lastClick: PointerState | null, settings: SettingsSpec, indexedGeometries: IndexedGeometry[]): void => {
+          const nextProps = {
+            lastClick,
+            settings,
+            indexedGeometries,
+          };
+
+          if (isClicking(prevProps, nextProps)) {
+            if (settings && settings.onElementClick) {
+              settings.onElementClick(indexedGeometries.map(({ value }) => value));
+            }
+          }
+          prevProps = nextProps;
+        },
+      )({
+        keySelector: (state: GlobalChartState) => state.chartId,
+      });
+    }
+    if (selector) {
+      selector(state);
+    }
+  };
+}
diff --git a/src/chart_types/xy_chart/state/selectors/on_element_out_caller.ts b/src/chart_types/xy_chart/state/selectors/on_element_out_caller.ts
new file mode 100644
index 0000000000..cf4042073b
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/on_element_out_caller.ts
@@ -0,0 +1,63 @@
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import createCachedSelector from 're-reselect';
+import {
+  getTooltipValuesAndGeometriesSelector,
+  TooltipAndHighlightedGeoms,
+} from './get_tooltip_values_highlighted_geoms';
+import { SettingsSpec } from '../../../../specs';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { IndexedGeometry } from '../../../../utils/geometry';
+import { Selector } from 'react-redux';
+import { ChartTypes } from '../../../index';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+interface Props {
+  settings: SettingsSpec | undefined;
+  highlightedGeometries: IndexedGeometry[];
+}
+
+function isOutElement(prevProps: Props | null, nextProps: Props | null) {
+  if (!nextProps || !prevProps) {
+    return false;
+  }
+  if (!nextProps.settings || !nextProps.settings.onElementOut) {
+    return false;
+  }
+  if (prevProps.highlightedGeometries.length > 0 && nextProps.highlightedGeometries.length === 0) {
+    return true;
+  }
+  return false;
+}
+
+/**
+ * Will call the onElementOut listener every time the following preconditions are met:
+ * - the onElementOut listener is available
+ * - the highlighted geometries list goes from a list of at least one object to an empty one
+ */
+export function createOnElementOutCaller(): (state: GlobalChartState) => void {
+  let prevProps: Props | null = null;
+  let selector: Selector<GlobalChartState, void> | null = null;
+  return (state: GlobalChartState) => {
+    if (selector === null && state.chartType === ChartTypes.XYAxis) {
+      selector = createCachedSelector(
+        [getTooltipValuesAndGeometriesSelector, getSettingsSpecSelector],
+        ({ highlightedGeometries }: TooltipAndHighlightedGeoms, settings: SettingsSpec): void => {
+          const nextProps = {
+            settings,
+            highlightedGeometries,
+          };
+
+          if (isOutElement(prevProps, nextProps) && settings.onElementOut) {
+            settings.onElementOut();
+          }
+          prevProps = nextProps;
+        },
+      )({
+        keySelector: getChartIdSelector,
+      });
+    }
+    if (selector) {
+      selector(state);
+    }
+  };
+}
diff --git a/src/chart_types/xy_chart/state/selectors/on_element_over_caller.ts b/src/chart_types/xy_chart/state/selectors/on_element_over_caller.ts
new file mode 100644
index 0000000000..ee6dea8ba0
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/on_element_over_caller.ts
@@ -0,0 +1,72 @@
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import createCachedSelector from 're-reselect';
+import {
+  getTooltipValuesAndGeometriesSelector,
+  TooltipAndHighlightedGeoms,
+} from './get_tooltip_values_highlighted_geoms';
+import { SettingsSpec } from '../../../../specs';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { IndexedGeometry } from '../../../../utils/geometry';
+import { Selector } from 'react-redux';
+import { ChartTypes } from '../../../index';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+interface Props {
+  settings: SettingsSpec | undefined;
+  highlightedGeometries: IndexedGeometry[];
+}
+
+function isOverElement(prevProps: Props | null, nextProps: Props | null) {
+  if (!nextProps) {
+    return false;
+  }
+  if (!nextProps.settings || !nextProps.settings.onElementOver) {
+    return false;
+  }
+  const { highlightedGeometries: nextGeomValues } = nextProps;
+  const prevGeomValues = prevProps ? prevProps.highlightedGeometries : [];
+  if (nextGeomValues.length > 0) {
+    if (nextGeomValues.length !== prevGeomValues.length) {
+      return true;
+    }
+    return !nextGeomValues.every(({ value: next }, index) => {
+      const prev = prevGeomValues[index].value;
+      return prev && prev.x === next.x && prev.y === next.y && prev.accessor === next.accessor;
+    });
+  }
+
+  return false;
+}
+
+/**
+ * Will call the onElementOver listener every time the following preconditions are met:
+ * - the onElementOver listener is available
+ * - we have a new set of highlighted geometries on our state
+ */
+export function createOnElementOverCaller(): (state: GlobalChartState) => void {
+  let prevProps: Props | null = null;
+  let selector: Selector<GlobalChartState, void> | null = null;
+  return (state: GlobalChartState) => {
+    if (selector === null && state.chartType === ChartTypes.XYAxis) {
+      selector = createCachedSelector(
+        [getTooltipValuesAndGeometriesSelector, getSettingsSpecSelector],
+        ({ highlightedGeometries }: TooltipAndHighlightedGeoms, settings: SettingsSpec): void => {
+          const nextProps = {
+            settings,
+            highlightedGeometries,
+          };
+
+          if (isOverElement(prevProps, nextProps) && settings.onElementOver) {
+            settings.onElementOver(highlightedGeometries.map(({ value }) => value));
+          }
+          prevProps = nextProps;
+        },
+      )({
+        keySelector: getChartIdSelector,
+      });
+    }
+    if (selector) {
+      selector(state);
+    }
+  };
+}
diff --git a/src/chart_types/xy_chart/state/selectors/on_pointer_move_caller.ts b/src/chart_types/xy_chart/state/selectors/on_pointer_move_caller.ts
new file mode 100644
index 0000000000..616cfe2154
--- /dev/null
+++ b/src/chart_types/xy_chart/state/selectors/on_pointer_move_caller.ts
@@ -0,0 +1,118 @@
+import createCachedSelector from 're-reselect';
+import { Selector } from 'reselect';
+import { GlobalChartState } from '../../../../state/chart_state';
+import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs';
+import { SettingsSpec, CursorEvent } from '../../../../specs';
+import { ChartTypes } from '../../../index';
+import { Scale } from '../../../../utils/scales/scales';
+import { Point } from '../../../../utils/point';
+import { getOrientedProjectedPointerPositionSelector } from './get_oriented_projected_pointer_position';
+import { computeSeriesGeometriesSelector } from './compute_series_geometries';
+import { getGeometriesIndexKeysSelector } from './get_geometries_index_keys';
+import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
+
+const getPointerEventSelector = createCachedSelector(
+  [
+    getChartIdSelector,
+    getOrientedProjectedPointerPositionSelector,
+    computeSeriesGeometriesSelector,
+    getGeometriesIndexKeysSelector,
+  ],
+  (chartId, orientedProjectedPointerPosition, seriesGeometries, geometriesIndexKeys) => {
+    return getCursorBand(
+      chartId,
+      orientedProjectedPointerPosition,
+      seriesGeometries.scales.xScale,
+      geometriesIndexKeys,
+    );
+  },
+)(getChartIdSelector);
+
+function getCursorBand(
+  chartId: string,
+  orientedProjectedPoinerPosition: Point,
+  xScale: Scale | undefined,
+  geometriesIndexKeys: any[],
+): CursorEvent | null {
+  // update che cursorBandPosition based on chart configuration
+  if (!xScale) {
+    return null;
+  }
+  const { x, y } = orientedProjectedPoinerPosition;
+  if (x === -1 || y === -1) {
+    return null;
+  }
+  const xValue = xScale.invertWithStep(x, geometriesIndexKeys);
+  if (!xValue) {
+    return null;
+  }
+  return {
+    chartId,
+    scale: xScale.type,
+    unit: xScale.unit,
+    value: xValue.value,
+  };
+}
+interface Props {
+  settings: SettingsSpec;
+  pointerEvent: CursorEvent | null;
+}
+
+function hasPointerEventChanged(prevProps: Props, nextProps: Props | null) {
+  // new pointer event, pointer over
+  if (prevProps.pointerEvent === null && nextProps && nextProps.pointerEvent) {
+    return true;
+  }
+
+  // new pointer event, pointer out
+  if (prevProps.pointerEvent !== null && nextProps && nextProps.pointerEvent === null) {
+    return true;
+  }
+
+  const prevPointerEvent = prevProps.pointerEvent;
+  const nextPointerEvent = nextProps && nextProps.pointerEvent;
+
+  // if something changed in the pointerEvent than recompute
+  if (
+    prevPointerEvent !== null &&
+    nextPointerEvent !== null &&
+    (prevPointerEvent.value !== nextPointerEvent.value ||
+      prevPointerEvent.scale !== nextPointerEvent.scale ||
+      prevPointerEvent.unit !== nextPointerEvent.unit)
+  ) {
+    return true;
+  }
+  return false;
+}
+
+export function createOnPointerMoveCaller(): (state: GlobalChartState) => void {
+  let prevProps: Props | null = null;
+  let selector: Selector<GlobalChartState, void> | null = null;
+  return (state: GlobalChartState) => {
+    if (selector === null && state.chartType === ChartTypes.XYAxis) {
+      selector = createCachedSelector(
+        [getSettingsSpecSelector, getPointerEventSelector],
+        (settings: SettingsSpec, pointerEvent: CursorEvent | null): void => {
+          const nextProps = {
+            settings,
+            pointerEvent,
+          };
+
+          if (prevProps === null && nextProps.pointerEvent === null) {
+            prevProps = nextProps;
+            return;
+          }
+          if (settings && settings.onCursorUpdate && hasPointerEventChanged(prevProps!, nextProps)) {
+            settings.onCursorUpdate(pointerEvent ? pointerEvent : undefined);
+          }
+          prevProps = nextProps;
+        },
+      )({
+        keySelector: getChartIdSelector,
+      });
+    }
+    if (selector) {
+      selector(state);
+    }
+  };
+}
diff --git a/src/chart_types/xy_chart/store/utils.test.ts b/src/chart_types/xy_chart/state/utils.test.ts
similarity index 79%
rename from src/chart_types/xy_chart/store/utils.test.ts
rename to src/chart_types/xy_chart/state/utils.test.ts
index 9cfb7d8e62..4d62ede289 100644
--- a/src/chart_types/xy_chart/store/utils.test.ts
+++ b/src/chart_types/xy_chart/state/utils.test.ts
@@ -1,5 +1,3 @@
-import { mergeYCustomDomainsByGroupId } from '../utils/axis_utils';
-import { IndexedGeometry, AccessorType } from '../rendering/rendering';
 import { DataSeriesColorsValues, findDataSeriesByColorValues, getSeriesColorMap } from '../utils/series';
 import {
   AreaSeriesSpec,
@@ -8,10 +6,12 @@ import {
   BasicSeriesSpec,
   HistogramModeAlignments,
   LineSeriesSpec,
+  SpecTypes,
+  SeriesTypes,
 } from '../utils/specs';
 import { BARCHART_1Y0G, BARCHART_1Y1G } from '../../../utils/data_samples/test_dataset';
 import { LIGHT_THEME } from '../../../utils/themes/light_theme';
-import { AxisId, getGroupId, getSpecId, SpecId } from '../../../utils/ids';
+import { SpecId } from '../../../utils/ids';
 import { ScaleContinuous } from '../../../utils/scales/scale_continuous';
 import { ScaleType } from '../../../utils/scales/scales';
 import {
@@ -27,16 +27,21 @@ import {
   isVerticalRotation,
   mergeGeometriesIndexes,
   setBarSeriesAccessors,
-  updateDeselectedDataSeries,
-} from '../store/utils';
+} from './utils';
+import { IndexedGeometry, AccessorType } from '../../../utils/geometry';
+import { mergeYCustomDomainsByGroupId } from './selectors/merge_y_custom_domains';
+import { updateDeselectedDataSeries } from './utils';
 import { LegendItem } from '../legend/legend';
+import { ChartTypes } from '../..';
 
 describe('Chart State utils', () => {
   it('should compute and format specifications for non stacked chart', () => {
     const spec1: BasicSeriesSpec = {
-      id: getSpecId('spec1'),
-      groupId: getGroupId('group1'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec1',
+      groupId: 'group1',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -45,9 +50,11 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y0G,
     };
     const spec2: BasicSeriesSpec = {
-      id: getSpecId('spec2'),
-      groupId: getGroupId('group2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec2',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -55,10 +62,7 @@ describe('Chart State utils', () => {
       yScaleToDataExtent: false,
       data: BARCHART_1Y0G,
     };
-    const specs = new Map<SpecId, BasicSeriesSpec>();
-    specs.set(spec1.id, spec1);
-    specs.set(spec2.id, spec2);
-    const domains = computeSeriesDomains(specs, new Map(), undefined);
+    const domains = computeSeriesDomains([spec1, spec2], new Map(), undefined);
     expect(domains.xDomain).toEqual({
       domain: [0, 3],
       isBandScale: false,
@@ -87,9 +91,11 @@ describe('Chart State utils', () => {
   });
   it('should compute and format specifications for stacked chart', () => {
     const spec1: BasicSeriesSpec = {
-      id: getSpecId('spec1'),
-      groupId: getGroupId('group1'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec1',
+      groupId: 'group1',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -99,9 +105,11 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y1G,
     };
     const spec2: BasicSeriesSpec = {
-      id: getSpecId('spec2'),
-      groupId: getGroupId('group2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec2',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -111,10 +119,7 @@ describe('Chart State utils', () => {
       yScaleToDataExtent: false,
       data: BARCHART_1Y1G,
     };
-    const specs = new Map<SpecId, BasicSeriesSpec>();
-    specs.set(spec1.id, spec1);
-    specs.set(spec2.id, spec2);
-    const domains = computeSeriesDomains(specs, new Map(), undefined);
+    const domains = computeSeriesDomains([spec1, spec2], new Map(), undefined);
     expect(domains.xDomain).toEqual({
       domain: [0, 3],
       isBandScale: false,
@@ -143,17 +148,17 @@ describe('Chart State utils', () => {
   });
   it('should check if a DataSeriesColorValues item exists in a list of DataSeriesColorValues', () => {
     const dataSeriesValuesA: DataSeriesColorsValues = {
-      specId: getSpecId('a'),
+      specId: 'a',
       colorValues: ['a', 'b', 'c'],
     };
 
     const dataSeriesValuesB: DataSeriesColorsValues = {
-      specId: getSpecId('b'),
+      specId: 'b',
       colorValues: ['a', 'b', 'c'],
     };
 
     const dataSeriesValuesC: DataSeriesColorsValues = {
-      specId: getSpecId('a'),
+      specId: 'a',
       colorValues: ['a', 'b', 'd'],
     };
 
@@ -165,17 +170,17 @@ describe('Chart State utils', () => {
   });
   it('should update a list of DataSeriesColorsValues given a selected DataSeriesColorValues item', () => {
     const dataSeriesValuesA: DataSeriesColorsValues = {
-      specId: getSpecId('a'),
+      specId: 'a',
       colorValues: ['a', 'b', 'c'],
     };
 
     const dataSeriesValuesB: DataSeriesColorsValues = {
-      specId: getSpecId('b'),
+      specId: 'b',
       colorValues: ['a', 'b', 'c'],
     };
 
     const dataSeriesValuesC: DataSeriesColorsValues = {
-      specId: getSpecId('a'),
+      specId: 'a',
       colorValues: ['a', 'b', 'd'],
     };
 
@@ -189,9 +194,11 @@ describe('Chart State utils', () => {
   });
   it('should get an updated customSeriesColor based on specs', () => {
     const spec1: BasicSeriesSpec = {
-      id: getSpecId('spec1'),
-      groupId: getGroupId('group1'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'spec1',
+      groupId: 'group1',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -200,10 +207,7 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y0G,
     };
 
-    const specs = new Map<SpecId, BasicSeriesSpec>();
-    specs.set(spec1.id, spec1);
-
-    const emptyCustomSeriesColors = getUpdatedCustomSeriesColors(specs);
+    const emptyCustomSeriesColors = getUpdatedCustomSeriesColors([spec1]);
     expect(emptyCustomSeriesColors).toEqual(new Map());
 
     const dataSeriesColorValues = {
@@ -213,7 +217,7 @@ describe('Chart State utils', () => {
     spec1.customSeriesColors = new Map();
     spec1.customSeriesColors.set(dataSeriesColorValues, 'custom_color');
 
-    const updatedCustomSeriesColors = getUpdatedCustomSeriesColors(specs);
+    const updatedCustomSeriesColors = getUpdatedCustomSeriesColors([spec1]);
     const expectedCustomSeriesColors = new Map();
     expectedCustomSeriesColors.set('specId:{spec1},colors:{bar}', 'custom_color');
 
@@ -239,9 +243,11 @@ describe('Chart State utils', () => {
   });
   test('is an area or line only map', () => {
     const area: AreaSeriesSpec = {
-      id: getSpecId('area'),
-      groupId: getGroupId('group1'),
-      seriesType: 'area',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'area',
+      groupId: 'group1',
+      seriesType: SeriesTypes.Area,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -251,9 +257,11 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y1G,
     };
     const line: LineSeriesSpec = {
-      id: getSpecId('line'),
-      groupId: getGroupId('group2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'line',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -264,9 +272,11 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y1G,
     };
     const bar: BarSeriesSpec = {
-      id: getSpecId('bar'),
-      groupId: getGroupId('group2'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'bar',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Bar,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -276,16 +286,16 @@ describe('Chart State utils', () => {
       yScaleToDataExtent: false,
       data: BARCHART_1Y1G,
     };
-    let seriesMap = new Map<SpecId, BasicSeriesSpec>([[area.id, area], [line.id, line], [bar.id, bar]]);
-    expect(isLineAreaOnlyChart(seriesMap)).toBe(false);
-    seriesMap = new Map<SpecId, BasicSeriesSpec>([[area.id, area], [line.id, line]]);
-    expect(isLineAreaOnlyChart(seriesMap)).toBe(true);
-    seriesMap = new Map<SpecId, BasicSeriesSpec>([[area.id, area]]);
-    expect(isLineAreaOnlyChart(seriesMap)).toBe(true);
-    seriesMap = new Map<SpecId, BasicSeriesSpec>([[line.id, line]]);
-    expect(isLineAreaOnlyChart(seriesMap)).toBe(true);
-    seriesMap = new Map<SpecId, BasicSeriesSpec>([[bar.id, bar], [getSpecId('bar2'), bar]]);
-    expect(isLineAreaOnlyChart(seriesMap)).toBe(false);
+    let series = [area, line, bar];
+    expect(isLineAreaOnlyChart(series)).toBe(false);
+    series = [area, line];
+    expect(isLineAreaOnlyChart(series)).toBe(true);
+    series = [area];
+    expect(isLineAreaOnlyChart(series)).toBe(true);
+    series = [line];
+    expect(isLineAreaOnlyChart(series)).toBe(true);
+    series = [bar, { ...bar, id: 'bar2' }];
+    expect(isLineAreaOnlyChart(series)).toBe(false);
   });
   test('can enable the chart animation if we have a valid number of elements', () => {
     const geometriesCounts = {
@@ -311,9 +321,11 @@ describe('Chart State utils', () => {
   describe('Geometries counts', () => {
     test('can compute stacked geometries counts', () => {
       const area: AreaSeriesSpec = {
-        id: getSpecId('area'),
-        groupId: getGroupId('group1'),
-        seriesType: 'area',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'area',
+        groupId: 'group1',
+        seriesType: SeriesTypes.Area,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -323,9 +335,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const line: LineSeriesSpec = {
-        id: getSpecId('line'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -336,9 +350,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const bar: BarSeriesSpec = {
-        id: getSpecId('bar'),
-        groupId: getGroupId('group2'),
-        seriesType: 'bar',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'bar',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Bar,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -348,8 +364,8 @@ describe('Chart State utils', () => {
         yScaleToDataExtent: false,
         data: BARCHART_1Y1G,
       };
-      const seriesSpecs = new Map<SpecId, BasicSeriesSpec>([[area.id, area], [line.id, line], [bar.id, bar]]);
-      const axesSpecs = new Map<AxisId, AxisSpec>();
+      const seriesSpecs: BasicSeriesSpec[] = [area, line, bar];
+      const axesSpecs: AxisSpec[] = [];
       const chartRotation = 0;
       const chartDimensions = { width: 100, height: 100, top: 0, left: 0 };
       const chartColors = {
@@ -380,9 +396,11 @@ describe('Chart State utils', () => {
     });
     test('can compute non stacked geometries indexes', () => {
       const line1: LineSeriesSpec = {
-        id: getSpecId('line1'),
-        groupId: getGroupId('group1'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line1',
+        groupId: 'group1',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Ordinal,
         xAccessor: 'x',
@@ -391,9 +409,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y0G,
       };
       const line2: LineSeriesSpec = {
-        id: getSpecId('line2'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line2',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Ordinal,
         xAccessor: 'x',
@@ -401,8 +421,8 @@ describe('Chart State utils', () => {
         yScaleToDataExtent: false,
         data: BARCHART_1Y0G,
       };
-      const seriesSpecs = new Map<SpecId, BasicSeriesSpec>([[line1.id, line1], [line2.id, line2]]);
-      const axesSpecs = new Map<AxisId, AxisSpec>();
+      const seriesSpecs: BasicSeriesSpec[] = [line1, line2];
+      const axesSpecs: AxisSpec[] = [];
       const chartRotation = 0;
       const chartDimensions = { width: 100, height: 100, top: 0, left: 0 };
       const chartColors = {
@@ -433,9 +453,11 @@ describe('Chart State utils', () => {
     });
     test('can compute stacked geometries indexes', () => {
       const line1: LineSeriesSpec = {
-        id: getSpecId('line1'),
-        groupId: getGroupId('group1'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line1',
+        groupId: 'group1',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Ordinal,
         xAccessor: 'x',
@@ -445,9 +467,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y0G,
       };
       const line2: LineSeriesSpec = {
-        id: getSpecId('line2'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line2',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Ordinal,
         xAccessor: 'x',
@@ -456,8 +480,8 @@ describe('Chart State utils', () => {
         yScaleToDataExtent: false,
         data: BARCHART_1Y0G,
       };
-      const seriesSpecs = new Map<SpecId, BasicSeriesSpec>([[line1.id, line1], [line2.id, line2]]);
-      const axesSpecs = new Map<AxisId, AxisSpec>();
+      const seriesSpecs: BasicSeriesSpec[] = [line1, line2];
+      const axesSpecs: AxisSpec[] = [];
       const chartRotation = 0;
       const chartDimensions = { width: 100, height: 100, top: 0, left: 0 };
       const chartColors = {
@@ -488,9 +512,11 @@ describe('Chart State utils', () => {
     });
     test('can compute non stacked geometries counts', () => {
       const area: AreaSeriesSpec = {
-        id: getSpecId('area'),
-        groupId: getGroupId('group1'),
-        seriesType: 'area',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'area',
+        groupId: 'group1',
+        seriesType: SeriesTypes.Area,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -500,9 +526,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const line: LineSeriesSpec = {
-        id: getSpecId('line'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -512,9 +540,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const bar: BarSeriesSpec = {
-        id: getSpecId('bar'),
-        groupId: getGroupId('group2'),
-        seriesType: 'bar',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'bar',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Bar,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -536,8 +566,8 @@ describe('Chart State utils', () => {
           showValueLabel: true,
         },
       };
-      const seriesSpecs = new Map<SpecId, BasicSeriesSpec>([[area.id, area], [line.id, line], [bar.id, bar]]);
-      const axesSpecs = new Map<AxisId, AxisSpec>();
+      const seriesSpecs: BasicSeriesSpec[] = [area, line, bar];
+      const axesSpecs: AxisSpec[] = [];
       const chartRotation = 0;
       const chartDimensions = { width: 100, height: 100, top: 0, left: 0 };
       const chartColors = {
@@ -568,9 +598,11 @@ describe('Chart State utils', () => {
     });
     test('can compute line geometries counts', () => {
       const line1: LineSeriesSpec = {
-        id: getSpecId('line1'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line1',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -580,9 +612,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const line2: LineSeriesSpec = {
-        id: getSpecId('line2'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line2',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -592,9 +626,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const line3: LineSeriesSpec = {
-        id: getSpecId('line3'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line3',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -603,8 +639,8 @@ describe('Chart State utils', () => {
         yScaleToDataExtent: false,
         data: BARCHART_1Y1G,
       };
-      const seriesSpecs = new Map<SpecId, BasicSeriesSpec>([[line1.id, line1], [line2.id, line2], [line3.id, line3]]);
-      const axesSpecs = new Map<AxisId, AxisSpec>();
+      const seriesSpecs: BasicSeriesSpec[] = [line1, line2, line3];
+      const axesSpecs: AxisSpec[] = [];
       const chartRotation = 0;
       const chartDimensions = { width: 100, height: 100, top: 0, left: 0 };
       const chartColors = {
@@ -635,9 +671,11 @@ describe('Chart State utils', () => {
     });
     test('can compute area geometries counts', () => {
       const area1: AreaSeriesSpec = {
-        id: getSpecId('area1'),
-        groupId: getGroupId('group2'),
-        seriesType: 'area',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'area1',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Area,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -647,9 +685,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const area2: AreaSeriesSpec = {
-        id: getSpecId('area2'),
-        groupId: getGroupId('group2'),
-        seriesType: 'area',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'area2',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Area,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -659,9 +699,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const area3: AreaSeriesSpec = {
-        id: getSpecId('area3'),
-        groupId: getGroupId('group2'),
-        seriesType: 'area',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'area3',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Area,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -670,8 +712,8 @@ describe('Chart State utils', () => {
         yScaleToDataExtent: false,
         data: BARCHART_1Y1G,
       };
-      const seriesSpecs = new Map<SpecId, BasicSeriesSpec>([[area1.id, area1], [area2.id, area2], [area3.id, area3]]);
-      const axesSpecs = new Map<AxisId, AxisSpec>();
+      const seriesSpecs: BasicSeriesSpec[] = [area1, area2, area3];
+      const axesSpecs: AxisSpec[] = [];
       const chartRotation = 0;
       const chartDimensions = { width: 100, height: 100, top: 0, left: 0 };
       const chartColors = {
@@ -702,9 +744,11 @@ describe('Chart State utils', () => {
     });
     test('can compute line geometries with custom style', () => {
       const line1: LineSeriesSpec = {
-        id: getSpecId('line1'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line1',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -722,9 +766,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const line2: LineSeriesSpec = {
-        id: getSpecId('line2'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line2',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -734,9 +780,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const line3: LineSeriesSpec = {
-        id: getSpecId('line3'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line3',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -745,8 +793,8 @@ describe('Chart State utils', () => {
         yScaleToDataExtent: false,
         data: BARCHART_1Y1G,
       };
-      const seriesSpecs = new Map<SpecId, BasicSeriesSpec>([[line1.id, line1], [line2.id, line2], [line3.id, line3]]);
-      const axesSpecs = new Map<AxisId, AxisSpec>();
+      const seriesSpecs: BasicSeriesSpec[] = [line1, line2, line3];
+      const axesSpecs: AxisSpec[] = [];
       const chartRotation = 0;
       const chartDimensions = { width: 100, height: 100, top: 0, left: 0 };
       const chartColors = {
@@ -785,9 +833,11 @@ describe('Chart State utils', () => {
     });
     test('can compute area geometries with custom style', () => {
       const area1: AreaSeriesSpec = {
-        id: getSpecId('area1'),
-        groupId: getGroupId('group2'),
-        seriesType: 'area',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'area1',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Area,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -809,9 +859,11 @@ describe('Chart State utils', () => {
         },
       };
       const area2: AreaSeriesSpec = {
-        id: getSpecId('area2'),
-        groupId: getGroupId('group2'),
-        seriesType: 'area',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'area2',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Area,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -821,9 +873,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const area3: AreaSeriesSpec = {
-        id: getSpecId('area3'),
-        groupId: getGroupId('group2'),
-        seriesType: 'area',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'area3',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Area,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -832,8 +886,8 @@ describe('Chart State utils', () => {
         yScaleToDataExtent: false,
         data: BARCHART_1Y1G,
       };
-      const seriesSpecs = new Map<SpecId, BasicSeriesSpec>([[area1.id, area1], [area2.id, area2], [area3.id, area3]]);
-      const axesSpecs = new Map<AxisId, AxisSpec>();
+      const seriesSpecs: BasicSeriesSpec[] = [area1, area2, area3];
+      const axesSpecs: AxisSpec[] = [];
       const chartRotation = 0;
       const chartDimensions = { width: 100, height: 100, top: 0, left: 0 };
       const chartColors = {
@@ -877,9 +931,11 @@ describe('Chart State utils', () => {
     });
     test('can compute bars geometries counts', () => {
       const bars1: BarSeriesSpec = {
-        id: getSpecId('bars1'),
-        groupId: getGroupId('group2'),
-        seriesType: 'bar',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'bars1',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Bar,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -889,9 +945,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const bars2: BarSeriesSpec = {
-        id: getSpecId('bars2'),
-        groupId: getGroupId('group2'),
-        seriesType: 'bar',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'bars2',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Bar,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -901,9 +959,11 @@ describe('Chart State utils', () => {
         data: BARCHART_1Y1G,
       };
       const bars3: BarSeriesSpec = {
-        id: getSpecId('bars3'),
-        groupId: getGroupId('group2'),
-        seriesType: 'bar',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'bars3',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Bar,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -912,8 +972,8 @@ describe('Chart State utils', () => {
         yScaleToDataExtent: false,
         data: BARCHART_1Y1G,
       };
-      const seriesSpecs = new Map<SpecId, BasicSeriesSpec>([[bars1.id, bars1], [bars2.id, bars2], [bars3.id, bars3]]);
-      const axesSpecs = new Map<AxisId, AxisSpec>();
+      const seriesSpecs: BasicSeriesSpec[] = [bars1, bars2, bars3];
+      const axesSpecs: AxisSpec[] = [];
       const chartRotation = 0;
       const chartDimensions = { width: 100, height: 100, top: 0, left: 0 };
       const chartColors = {
@@ -944,9 +1004,11 @@ describe('Chart State utils', () => {
     });
     test('can compute the bar offset in mixed charts', () => {
       const line1: LineSeriesSpec = {
-        id: getSpecId('line1'),
-        groupId: getGroupId('group2'),
-        seriesType: 'line',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line1',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Line,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -957,9 +1019,11 @@ describe('Chart State utils', () => {
       };
 
       const bar1: BarSeriesSpec = {
-        id: getSpecId('line3'),
-        groupId: getGroupId('group2'),
-        seriesType: 'bar',
+        chartType: ChartTypes.XYAxis,
+        specType: SpecTypes.Series,
+        id: 'line3',
+        groupId: 'group2',
+        seriesType: SeriesTypes.Bar,
         yScaleType: ScaleType.Log,
         xScaleType: ScaleType.Linear,
         xAccessor: 'x',
@@ -968,8 +1032,8 @@ describe('Chart State utils', () => {
         yScaleToDataExtent: false,
         data: BARCHART_1Y1G,
       };
-      const seriesSpecs = new Map<SpecId, BasicSeriesSpec>([[line1.id, line1], [bar1.id, bar1]]);
-      const axesSpecs = new Map<AxisId, AxisSpec>();
+      const seriesSpecs: BasicSeriesSpec[] = [line1, bar1];
+      const axesSpecs: AxisSpec[] = [];
       const chartRotation = 0;
       const chartDimensions = { width: 100, height: 100, top: 0, left: 0 };
       const chartColors = {
@@ -1011,7 +1075,7 @@ describe('Chart State utils', () => {
         color: '#1EA593',
         value: { x: 0, y: 5, accessor: AccessorType.Y1 },
         transform: { x: 0, y: 0 },
-        geometryId: { specId: getSpecId('line1'), seriesKey: [] },
+        geometryId: { specId: 'line1', seriesKey: [] },
       },
     ]);
     const map2 = new Map<string, IndexedGeometry[]>();
@@ -1023,7 +1087,7 @@ describe('Chart State utils', () => {
         color: '#2B70F7',
         value: { x: 0, y: 2, accessor: AccessorType.Y1 },
         transform: { x: 0, y: 0 },
-        geometryId: { specId: getSpecId('line2'), seriesKey: [] },
+        geometryId: { specId: 'line2', seriesKey: [] },
       },
     ]);
     const merged = mergeGeometriesIndexes(map1, map2);
@@ -1056,9 +1120,11 @@ describe('Chart State utils', () => {
   });
   test('can determine if histogram mode is enabled', () => {
     const area: AreaSeriesSpec = {
-      id: getSpecId('area'),
-      groupId: getGroupId('group1'),
-      seriesType: 'area',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'area',
+      groupId: 'group1',
+      seriesType: SeriesTypes.Area,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -1068,9 +1134,11 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y1G,
     };
     const line: LineSeriesSpec = {
-      id: getSpecId('line'),
-      groupId: getGroupId('group2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'line',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -1081,9 +1149,11 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y1G,
     };
     const basicBar: BarSeriesSpec = {
-      id: getSpecId('bar'),
-      groupId: getGroupId('group2'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'bar',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Bar,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -1094,9 +1164,11 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y1G,
     };
     const histogramBar: BarSeriesSpec = {
-      id: getSpecId('histo'),
-      groupId: getGroupId('group2'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'histo',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Bar,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -1107,19 +1179,14 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y1G,
       enableHistogramMode: true,
     };
-    const seriesMap = new Map<SpecId, BasicSeriesSpec>([
-      [area.id, area],
-      [line.id, line],
-      [basicBar.id, basicBar],
-      [histogramBar.id, histogramBar],
-    ]);
+    let seriesMap: BasicSeriesSpec[] = [area, line, basicBar, histogramBar];
 
     expect(isHistogramModeEnabled(seriesMap)).toBe(true);
 
-    seriesMap.delete(histogramBar.id);
+    seriesMap = [area, line, basicBar];
     expect(isHistogramModeEnabled(seriesMap)).toBe(false);
 
-    seriesMap.delete(basicBar.id);
+    seriesMap = [area, line];
     expect(isHistogramModeEnabled(seriesMap)).toBe(false);
   });
   test('can set the bar series accessors dependent on histogram mode', () => {
@@ -1127,9 +1194,11 @@ describe('Chart State utils', () => {
     const isHistogramEnabled = true;
 
     const area: AreaSeriesSpec = {
-      id: getSpecId('area'),
-      groupId: getGroupId('group1'),
-      seriesType: 'area',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'area',
+      groupId: 'group1',
+      seriesType: SeriesTypes.Area,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -1139,9 +1208,11 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y1G,
     };
     const line: LineSeriesSpec = {
-      id: getSpecId('line'),
-      groupId: getGroupId('group2'),
-      seriesType: 'line',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'line',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -1152,9 +1223,11 @@ describe('Chart State utils', () => {
       data: BARCHART_1Y1G,
     };
     const bar: BarSeriesSpec = {
-      id: getSpecId('bar'),
-      groupId: getGroupId('group2'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'bar',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Bar,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -1181,9 +1254,11 @@ describe('Chart State utils', () => {
 
     // add another bar
     const bar2: BarSeriesSpec = {
-      id: getSpecId('bar2'),
-      groupId: getGroupId('group2'),
-      seriesType: 'bar',
+      chartType: ChartTypes.XYAxis,
+      specType: SpecTypes.Series,
+      id: 'bar2',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Bar,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -1203,7 +1278,7 @@ describe('Chart State utils', () => {
       key: 'specId:{bars},colors:{a}',
       color: '#1EA593',
       label: 'a',
-      value: { specId: getSpecId('bars'), colorValues: ['a'], lastValue: { y0: null, y1: 6 } },
+      value: { specId: 'bars', colorValues: ['a'], lastValue: { y0: null, y1: 6 } },
       displayValue: { raw: { y0: null, y1: 6 }, formatted: { y0: null, y1: '6.00' } },
       isSeriesVisible: false,
     });
@@ -1211,7 +1286,7 @@ describe('Chart State utils', () => {
       key: 'specId:{bars},colors:{b}',
       color: '#2B70F7',
       label: 'b',
-      value: { specId: getSpecId('bars'), colorValues: ['b'], lastValue: { y0: null, y1: 2 } },
+      value: { specId: 'bars', colorValues: ['b'], lastValue: { y0: null, y1: 2 } },
       displayValue: { raw: { y0: null, y1: 2 }, formatted: { y0: null, y1: '2.00' } },
       isSeriesVisible: false,
     });
@@ -1223,7 +1298,7 @@ describe('Chart State utils', () => {
       key: 'specId:{bars},colors:{a}',
       color: '#1EA593',
       label: 'a',
-      value: { specId: getSpecId('bars'), colorValues: ['a'], lastValue: { y0: null, y1: 6 } },
+      value: { specId: 'bars', colorValues: ['a'], lastValue: { y0: null, y1: 6 } },
       displayValue: { raw: { y0: null, y1: 6 }, formatted: { y0: null, y1: '6.00' } },
       isSeriesVisible: true,
     });
@@ -1231,7 +1306,7 @@ describe('Chart State utils', () => {
       key: 'specId:{bars},colors:{b}',
       color: '#2B70F7',
       label: 'b',
-      value: { specId: getSpecId('bars'), colorValues: ['b'], lastValue: { y0: null, y1: 2 } },
+      value: { specId: 'bars', colorValues: ['b'], lastValue: { y0: null, y1: 2 } },
       displayValue: { raw: { y0: null, y1: 2 }, formatted: { y0: null, y1: '2.00' } },
       isSeriesVisible: false,
     });
diff --git a/src/chart_types/xy_chart/store/utils.ts b/src/chart_types/xy_chart/state/utils.ts
similarity index 88%
rename from src/chart_types/xy_chart/store/utils.ts
rename to src/chart_types/xy_chart/state/utils.ts
index b4c3e2f637..56c4a79b54 100644
--- a/src/chart_types/xy_chart/store/utils.ts
+++ b/src/chart_types/xy_chart/state/utils.ts
@@ -2,26 +2,17 @@ import { isVerticalAxis } from '../utils/axis_utils';
 import { CurveType } from '../../../utils/curves';
 import { mergeXDomain, XDomain } from '../domains/x_domain';
 import { mergeYDomain, YDomain } from '../domains/y_domain';
-import {
-  AreaGeometry,
-  BarGeometry,
-  IndexedGeometry,
-  LineGeometry,
-  mutableIndexedGeometryMapUpsert,
-  PointGeometry,
-  renderArea,
-  renderBars,
-  renderLine,
-} from '../rendering/rendering';
+import { mutableIndexedGeometryMapUpsert, renderArea, renderBars, renderLine } from '../rendering/rendering';
 import { computeXScale, computeYScales, countBarsInCluster } from '../utils/scales';
 import {
   DataSeries,
   DataSeriesColorsValues,
-  findDataSeriesByColorValues,
   FormattedDataSeries,
   getColorValuesAsString,
   getFormattedDataseries,
   getSplittedSeries,
+  RawDataSeries,
+  findDataSeriesByColorValues,
 } from '../utils/series';
 import {
   AreaSeriesSpec,
@@ -38,15 +29,17 @@ import {
   isBandedSpec,
   Fit,
   FitConfig,
+  SeriesTypes,
 } from '../utils/specs';
 import { ColorConfig, Theme } from '../../../utils/themes/theme';
 import { identity, mergePartial } from '../../../utils/commons';
 import { Dimensions } from '../../../utils/dimensions';
 import { Domain } from '../../../utils/domain';
-import { AxisId, GroupId, SpecId } from '../../../utils/ids';
+import { GroupId, SpecId } from '../../../utils/ids';
 import { Scale } from '../../../utils/scales/scales';
-import { SeriesDomainsAndData } from './chart_state';
+import { PointGeometry, BarGeometry, AreaGeometry, LineGeometry, IndexedGeometry } from '../../../utils/geometry';
 import { LegendItem } from '../legend/legend';
+import { Spec } from '../../../specs';
 
 const MAX_ANIMATABLE_BARS = 300;
 const MAX_ANIMATABLE_LINES_AREA_POINTS = 600;
@@ -72,6 +65,35 @@ export interface GeometriesCounts {
   linePoints: number;
 }
 
+export interface ComputedScales {
+  xScale: Scale;
+  yScales: Map<GroupId, Scale>;
+}
+export interface Geometries {
+  points: PointGeometry[];
+  bars: BarGeometry[];
+  areas: AreaGeometry[];
+  lines: LineGeometry[];
+}
+
+export interface ComputedGeometries {
+  scales: ComputedScales;
+  geometries: Geometries;
+  geometriesIndex: Map<any, IndexedGeometry[]>;
+  geometriesCounts: GeometriesCounts;
+}
+
+export interface SeriesDomainsAndData {
+  xDomain: XDomain;
+  yDomain: YDomain[];
+  splittedDataSeries: RawDataSeries[][];
+  formattedDataSeries: {
+    stacked: FormattedDataSeries[];
+    nonStacked: FormattedDataSeries[];
+  };
+  seriesColors: Map<string, DataSeriesColorsValues>;
+}
+
 export function updateDeselectedDataSeries(
   series: DataSeriesColorsValues[] | null,
   value: DataSeriesColorsValues,
@@ -87,7 +109,7 @@ export function updateDeselectedDataSeries(
   return updatedSeries;
 }
 
-export function getUpdatedCustomSeriesColors(seriesSpecs: Map<SpecId, BasicSeriesSpec>): Map<string, string> {
+export function getUpdatedCustomSeriesColors(seriesSpecs: BasicSeriesSpec[]): Map<string, string> {
   const updatedCustomSeriesColors = new Map();
   seriesSpecs.forEach((spec: BasicSeriesSpec) => {
     if (spec.customSeriesColors) {
@@ -106,7 +128,7 @@ export interface LastValues {
   y1: number | null;
 }
 
-export function getLastValues(formattedDataSeries: {
+function getLastValues(formattedDataSeries: {
   stacked: FormattedDataSeries[];
   nonStacked: FormattedDataSeries[];
 }): Map<string, LastValues> {
@@ -154,10 +176,10 @@ export function getLastValues(formattedDataSeries: {
  * @returns `SeriesDomainsAndData`
  */
 export function computeSeriesDomains(
-  seriesSpecs: Map<SpecId, BasicSeriesSpec>,
-  customYDomainsByGroupId: Map<GroupId, DomainRange>,
+  seriesSpecs: BasicSeriesSpec[],
+  customYDomainsByGroupId: Map<GroupId, DomainRange> = new Map(),
+  deselectedDataSeries: DataSeriesColorsValues[] = [],
   customXDomain?: DomainRange | Domain,
-  deselectedDataSeries?: DataSeriesColorsValues[] | null,
 ): SeriesDomainsAndData {
   const { splittedSeries, xValues, seriesColors } = getSplittedSeries(seriesSpecs, deselectedDataSeries);
 
@@ -197,7 +219,7 @@ export function computeSeriesDomains(
 }
 
 export function computeSeriesGeometries(
-  seriesSpecs: Map<SpecId, BasicSeriesSpec>,
+  seriesSpecs: BasicSeriesSpec[],
   xDomain: XDomain,
   yDomain: YDomain[],
   formattedDataSeries: {
@@ -208,22 +230,9 @@ export function computeSeriesGeometries(
   chartTheme: Theme,
   chartDims: Dimensions,
   chartRotation: Rotation,
-  axesSpecs: Map<AxisId, AxisSpec>,
+  axesSpecs: AxisSpec[],
   enableHistogramMode: boolean,
-): {
-  scales: {
-    xScale: Scale;
-    yScales: Map<GroupId, Scale>;
-  };
-  geometries: {
-    points: PointGeometry[];
-    bars: BarGeometry[];
-    areas: AreaGeometry[];
-    lines: LineGeometry[];
-  };
-  geometriesIndex: Map<any, IndexedGeometry[]>;
-  geometriesCounts: GeometriesCounts;
-} {
+): ComputedGeometries {
   const chartColors: ColorConfig = chartTheme.colors;
   const barsPadding = enableHistogramMode ? chartTheme.scales.histogramPadding : chartTheme.scales.barsPadding;
 
@@ -364,13 +373,10 @@ export function setBarSeriesAccessors(isHistogramMode: boolean, seriesSpecs: Map
   return;
 }
 
-export function isHistogramModeEnabled(seriesSpecs: Map<SpecId, BasicSeriesSpec>): boolean {
-  for (const [, spec] of seriesSpecs) {
-    if (isBarSeriesSpec(spec) && spec.enableHistogramMode) {
-      return true;
-    }
-  }
-  return false;
+export function isHistogramModeEnabled(seriesSpecs: BasicSeriesSpec[]): boolean {
+  return seriesSpecs.some((spec) => {
+    return isBarSeriesSpec(spec) && spec.enableHistogramMode;
+  });
 }
 
 export function computeXScaleOffset(
@@ -398,17 +404,17 @@ export function computeXScaleOffset(
   }
 }
 
-export function renderGeometries(
+function renderGeometries(
   indexOffset: number,
   clusteredCount: number,
   isStacked: boolean,
   dataSeries: DataSeries[],
   xScale: Scale,
   yScale: Scale,
-  seriesSpecs: Map<SpecId, BasicSeriesSpec>,
+  seriesSpecs: BasicSeriesSpec[],
   seriesColorsMap: Map<string, string>,
   defaultColor: string,
-  axesSpecs: Map<AxisId, AxisSpec>,
+  axesSpecs: AxisSpec[],
   chartTheme: Theme,
   enableHistogramMode: boolean,
 ): {
@@ -440,7 +446,7 @@ export function renderGeometries(
   let barIndexOffset = 0;
   for (i = 0; i < len; i++) {
     const ds = dataSeries[i];
-    const spec = getSpecById(seriesSpecs, ds.specId);
+    const spec = getSpecsById<BasicSeriesSpec>(seriesSpecs, ds.specId);
     if (spec === undefined) {
       continue;
     }
@@ -553,14 +559,14 @@ export function renderGeometries(
   };
 }
 
-export function getSpecById(seriesSpecs: Map<SpecId, BasicSeriesSpec>, specId: SpecId) {
-  return seriesSpecs.get(specId);
+export function getSpecsById<T extends Spec>(specs: T[], id: string): T | undefined {
+  return specs.find((spec) => spec.id === id);
 }
 
-export function getAxesSpecForSpecId(axesSpecs: Map<AxisId, AxisSpec>, groupId: GroupId) {
+export function getAxesSpecForSpecId(axesSpecs: AxisSpec[], groupId: GroupId) {
   let xAxis;
   let yAxis;
-  for (const axisSpec of axesSpecs.values()) {
+  for (const axisSpec of axesSpecs) {
     if (axisSpec.groupId !== groupId) {
       continue;
     }
@@ -604,27 +610,6 @@ export function computeChartTransform(chartDimensions: Dimensions, chartRotation
   }
 }
 
-export function computeBrushExtent(
-  chartDimensions: Dimensions,
-  chartRotation: Rotation,
-  chartTransform: Transform,
-): BrushExtent {
-  const minX = [0, 180].includes(chartRotation)
-    ? chartDimensions.left + chartTransform.x
-    : chartDimensions.top + chartTransform.y;
-  const minY = [0, 180].includes(chartRotation)
-    ? chartDimensions.top + chartTransform.y
-    : chartDimensions.left + chartTransform.x;
-  const maxX = minX + chartDimensions.width;
-  const maxY = minY + chartDimensions.height;
-  return {
-    minX,
-    minY,
-    maxX,
-    maxY,
-  };
-}
-
 /**
  * Merge multiple geometry indexes maps together.
  * @param iterables a set of maps to be merged
@@ -654,9 +639,9 @@ export function isVerticalRotation(chartRotation: Rotation) {
  * Check if a specs map contains only line or area specs
  * @param specs Map<SpecId, BasicSeriesSpec>
  */
-export function isLineAreaOnlyChart(specs: Map<SpecId, BasicSeriesSpec>) {
-  return ![...specs.values()].some((spec) => {
-    return spec.seriesType === 'bar';
+export function isLineAreaOnlyChart(specs: BasicSeriesSpec[]) {
+  return !specs.some((spec) => {
+    return spec.seriesType === SeriesTypes.Bar;
   });
 }
 
diff --git a/src/chart_types/xy_chart/store/chart_state.interactions.test.ts b/src/chart_types/xy_chart/store/chart_state.interactions.test.ts
deleted file mode 100644
index c957dd0c06..0000000000
--- a/src/chart_types/xy_chart/store/chart_state.interactions.test.ts
+++ /dev/null
@@ -1,483 +0,0 @@
-import { BarGeometry } from '../rendering/rendering';
-import { computeXScale, computeYScales } from '../utils/scales';
-import { DataSeriesColorsValues } from '../utils/series';
-import { BarSeriesSpec, BasicSeriesSpec, RectAnnotationSpec, Position } from '../utils/specs';
-import { getAnnotationId, getGroupId, getSpecId, getAxisId } from '../../../utils/ids';
-import { TooltipType } from '../utils/interactions';
-import { ScaleContinuous } from '../../../utils/scales/scale_continuous';
-import { ScaleType } from '../../../utils/scales/scales';
-import { ChartStore } from './chart_state';
-import { computeSeriesDomains } from './utils';
-import { ScaleBand } from '../../../utils/scales/scale_band';
-
-const SPEC_ID = getSpecId('spec_1');
-const GROUP_ID = getGroupId('group_1');
-
-const ordinalBarSeries: BarSeriesSpec = {
-  id: SPEC_ID,
-  groupId: GROUP_ID,
-  seriesType: 'bar',
-  yScaleToDataExtent: false,
-  data: [[0, 10], [1, 5]],
-  xAccessor: 0,
-  yAccessors: [1],
-  xScaleType: ScaleType.Ordinal,
-  yScaleType: ScaleType.Linear,
-  hideInLegend: false,
-};
-const linearBarSeries: BarSeriesSpec = {
-  id: SPEC_ID,
-  groupId: GROUP_ID,
-  seriesType: 'bar',
-  yScaleToDataExtent: false,
-  data: [[0, 10], [1, 5]],
-  xAccessor: 0,
-  yAccessors: [1],
-  xScaleType: ScaleType.Linear,
-  yScaleType: ScaleType.Linear,
-  hideInLegend: false,
-};
-const chartTop = 10;
-const chartLeft = 10;
-
-function initStore(spec: BasicSeriesSpec) {
-  const store = new ChartStore();
-  store.chartDimensions.width = 100;
-  store.chartDimensions.height = 100;
-  store.chartDimensions.top = chartTop;
-  store.chartDimensions.left = chartLeft;
-  store.chartRotation = 0;
-  store.seriesDomainsAndData = {
-    splittedDataSeries: [],
-    formattedDataSeries: {
-      stacked: [],
-      nonStacked: [],
-    },
-    seriesColors: new Map<string, DataSeriesColorsValues>(),
-    xDomain: {
-      scaleType: spec.xScaleType,
-      domain: [0, 1],
-      isBandScale: true,
-      minInterval: 1,
-      type: 'xDomain',
-    },
-    yDomain: [
-      {
-        scaleType: spec.yScaleType,
-        domain: [0, 20],
-        isBandScale: false,
-        groupId: GROUP_ID,
-        type: 'yDomain',
-      },
-    ],
-  };
-  store.tooltipType.set(TooltipType.VerticalCursor);
-  store.seriesSpecs.set(spec.id, spec);
-  return store;
-}
-
-const barStyle = {
-  rect: {
-    opacity: 1,
-  },
-  rectBorder: {
-    strokeWidth: 1,
-    visible: false,
-  },
-  displayValue: {
-    fill: 'black',
-    fontFamily: '',
-    fontSize: 2,
-    offsetX: 0,
-    offsetY: 0,
-    padding: 2,
-  },
-};
-const indexedGeom1Red: BarGeometry = {
-  color: 'red',
-  x: 0,
-  y: 0,
-  width: 50,
-  height: 100,
-  value: {
-    x: 0,
-    y: 10,
-    accessor: 'y1',
-  },
-  geometryId: {
-    specId: SPEC_ID,
-    seriesKey: [],
-  },
-  seriesStyle: barStyle,
-};
-const indexedGeom2Blue: BarGeometry = {
-  color: 'blue',
-  x: 50,
-  y: 50,
-  width: 50,
-  height: 50,
-  value: {
-    x: 1,
-    y: 5,
-    accessor: 'y1',
-  },
-  geometryId: {
-    specId: SPEC_ID,
-    seriesKey: [],
-  },
-  seriesStyle: barStyle,
-};
-
-describe('Chart state pointer interactions', () => {
-  let store: ChartStore;
-
-  beforeEach(() => {
-    store = initStore(ordinalBarSeries);
-  });
-
-  test('can convert/limit cursor positions relative to chart dimensions', () => {
-    store.setCursorPosition(20, 20);
-    expect(store.cursorPosition.x).toBe(10);
-    expect(store.cursorPosition.y).toBe(10);
-    store.setCursorPosition(10, 10);
-    expect(store.cursorPosition.x).toBe(0);
-    expect(store.cursorPosition.y).toBe(0);
-    store.setCursorPosition(5, 5);
-    expect(store.cursorPosition.x).toBe(-1);
-    expect(store.cursorPosition.y).toBe(-1);
-    store.setCursorPosition(200, 20);
-    expect(store.cursorPosition.x).toBe(-1);
-    expect(store.cursorPosition.y).toBe(10);
-    store.setCursorPosition(20, 200);
-    expect(store.cursorPosition.x).toBe(10);
-    expect(store.cursorPosition.y).toBe(-1);
-    store.setCursorPosition(200, 200);
-    expect(store.cursorPosition.x).toBe(-1);
-    expect(store.cursorPosition.y).toBe(-1);
-    store.setCursorPosition(-20, -20);
-    expect(store.cursorPosition.x).toBe(-1);
-    expect(store.cursorPosition.y).toBe(-1);
-  });
-
-  test('call onElementOut if moving the mouse out from the chart', () => {
-    store.highlightedGeometries.push(indexedGeom1Red);
-    const listener = jest.fn((): undefined => undefined);
-    store.setOnElementOutListener(listener);
-    store.setCursorPosition(5, 5);
-    expect(listener).toBeCalledTimes(1);
-
-    // no more calls after the first out one outside chart
-    store.setCursorPosition(5, 5);
-    expect(listener).toBeCalledTimes(1);
-    store.setCursorPosition(3, 3);
-    expect(listener).toBeCalledTimes(1);
-  });
-
-  test('can respond to tooltip types changes', () => {
-    store.xScale = new ScaleContinuous(
-      {
-        type: ScaleType.Linear,
-        domain: [0, 1],
-        range: [0, 100],
-      },
-      { bandwidth: 50, minInterval: 0.5 },
-    );
-    store.yScales = new Map();
-    store.yScales.set(GROUP_ID, new ScaleContinuous({ type: ScaleType.Linear, domain: [0, 1], range: [0, 100] }));
-    store.geometriesIndex.set(0, [indexedGeom1Red]);
-    store.geometriesIndexKeys.push(0);
-    store.tooltipType.set(TooltipType.None);
-    store.setCursorPosition(10, 10 + 70);
-    expect(store.tooltipData).toEqual([]);
-    expect(store.isTooltipVisible.get()).toBe(false);
-
-    store.tooltipType.set(TooltipType.Follow);
-    store.setCursorPosition(10, 10 + 70);
-    expect(store.geometriesIndexKeys.length).toBe(1);
-    expect(store.isTooltipVisible.get()).toBe(true);
-    expect(store.highlightedGeometries.length).toBe(1);
-  });
-
-  describe('mouse over with Ordinal scale', () => {
-    mouseOverTestSuite(ScaleType.Ordinal);
-  });
-  describe('mouse over with Linear scale', () => {
-    mouseOverTestSuite(ScaleType.Linear);
-  });
-
-  // TODO add test for point series
-  // TODO add test for mixed series
-  // TODO add test for clicks
-});
-
-function mouseOverTestSuite(scaleType: ScaleType) {
-  let store: ChartStore;
-  let onOverListener: jest.Mock<undefined>;
-  let onOutListener: jest.Mock<undefined>;
-
-  beforeEach(() => {
-    const spec = scaleType === ScaleType.Ordinal ? ordinalBarSeries : linearBarSeries;
-    store = initStore(spec);
-    const barSeriesMap = new Map();
-    barSeriesMap.set(SPEC_ID, spec);
-    const barSeriesDomains = computeSeriesDomains(barSeriesMap, new Map());
-    const barSeriesScale = computeXScale({
-      xDomain: barSeriesDomains.xDomain,
-      totalBarsInCluster: barSeriesMap.size,
-      range: [0, 100],
-    });
-    const yScales = computeYScales({ yDomains: barSeriesDomains.yDomain, range: [0, 100] });
-    store.xScale = barSeriesScale;
-    store.yScales = yScales;
-    store.geometriesIndex.set(0, [indexedGeom1Red]);
-    store.geometriesIndex.set(1, [indexedGeom2Blue]);
-    store.geometriesIndexKeys.push(0);
-    store.geometriesIndexKeys.push(1);
-    onOverListener = jest.fn((): undefined => undefined);
-    onOutListener = jest.fn((): undefined => undefined);
-    store.setOnElementOverListener(onOverListener);
-    store.setOnElementOutListener(onOutListener);
-    expect(store.xScale).not.toBeUndefined();
-    expect(store.tooltipData).toEqual([]);
-  });
-
-  test('store is correctly configured', () => {
-    // checking this to avoid broken tests due to nested describe and before
-    expect(store.xScale).not.toBeUndefined();
-    expect(store.yScales).not.toBeUndefined();
-  });
-
-  test('set cursor from external source', () => {
-    store.setCursorValue(0);
-    expect(store.externalCursorShown.get()).toBe(true);
-    expect(store.cursorBandPosition).toEqual({
-      height: 100,
-      left: 10,
-      top: 10,
-      visible: true,
-      width: 50,
-    });
-
-    store.setCursorValue(1);
-    expect(store.externalCursorShown.get()).toBe(true);
-    expect(store.cursorBandPosition).toEqual({
-      height: 100,
-      left: 60,
-      top: 10,
-      visible: true,
-      width: 50,
-    });
-
-    store.setCursorValue(2);
-    expect(store.externalCursorShown.get()).toBe(true);
-    // equal to the latest except the visiblility
-    expect(store.cursorBandPosition).toEqual({
-      height: 100,
-      left: 60,
-      top: 10,
-      visible: false,
-      width: 50,
-    });
-  });
-  test('can determine which tooltip to display if chart & annotation tooltips possible', () => {
-    const annotationDimensions = [{ rect: { x: 49, y: -1, width: 3, height: 99 } }];
-    const rectAnnotationSpec: RectAnnotationSpec = {
-      annotationId: getAnnotationId('rect'),
-      groupId: GROUP_ID,
-      annotationType: 'rectangle',
-      dataValues: [{ coordinates: { x0: 1, x1: 1.5, y0: 0.5, y1: 10 } }],
-    };
-
-    store.annotationSpecs.set(rectAnnotationSpec.annotationId, rectAnnotationSpec);
-    store.annotationDimensions.set(rectAnnotationSpec.annotationId, annotationDimensions);
-    // isHighlighted false, chart tooltip true; should show annotationTooltip only
-    store.setCursorPosition(chartLeft + 51, chartTop + 1);
-    expect(store.isTooltipVisible.get()).toBe(false);
-  });
-
-  test('can hover top-left corner of the first bar', () => {
-    expect(store.tooltipData).toEqual([]);
-    store.setCursorPosition(chartLeft + 0, chartTop + 0);
-    expect(store.cursorPosition).toEqual({ x: 0, y: 0 });
-    expect(store.cursorBandPosition.left).toBe(chartLeft + 0);
-    expect(store.cursorBandPosition.width).toBe(50);
-    expect(store.isTooltipVisible.get()).toBe(true);
-    expect(store.tooltipData.length).toBe(2); // x value + 1 y value
-    expect(store.highlightedGeometries.length).toBe(1);
-    expect(onOverListener).toBeCalledTimes(1);
-    expect(onOutListener).toBeCalledTimes(0);
-    expect(onOverListener.mock.calls[0][0]).toEqual([indexedGeom1Red.value]);
-
-    store.setCursorPosition(chartLeft - 1, chartTop - 1);
-    expect(store.cursorPosition).toEqual({ x: -1, y: -1 });
-    expect(store.isTooltipVisible.get()).toBe(false);
-    expect(store.tooltipData.length).toBe(0);
-    expect(store.highlightedGeometries.length).toBe(0);
-    expect(onOverListener).toBeCalledTimes(1);
-    expect(onOutListener).toBeCalledTimes(1);
-  });
-
-  test('can hover bottom-left corner of the first bar', () => {
-    store.setCursorPosition(chartLeft + 0, chartTop + 99);
-    expect(store.cursorPosition).toEqual({ x: 0, y: 99 });
-    expect(store.cursorBandPosition.left).toBe(chartLeft + 0);
-    expect(store.cursorBandPosition.width).toBe(50);
-    expect(store.isTooltipVisible.get()).toBe(true);
-    expect(store.highlightedGeometries.length).toBe(1);
-    expect(store.tooltipData.length).toBe(2); // x value + 1 y value
-    expect(onOverListener).toBeCalledTimes(1);
-    expect(onOutListener).toBeCalledTimes(0);
-    expect(onOverListener.mock.calls[0][0]).toEqual([indexedGeom1Red.value]);
-
-    store.setCursorPosition(chartLeft - 1, chartTop + 99);
-    expect(store.cursorPosition).toEqual({ x: -1, y: 99 });
-    expect(store.isTooltipVisible.get()).toBe(false);
-    expect(store.tooltipData.length).toBe(0);
-    expect(store.highlightedGeometries.length).toBe(0);
-    expect(onOverListener).toBeCalledTimes(1);
-    expect(onOutListener).toBeCalledTimes(1);
-  });
-
-  test('can hover top-right corner of the first bar', () => {
-    let scaleOffset = 0;
-    if (scaleType !== ScaleType.Ordinal) {
-      scaleOffset = 1;
-    }
-    store.setCursorPosition(chartLeft + 49 + scaleOffset, chartTop + 0);
-    expect(store.cursorPosition).toEqual({ x: 49 + scaleOffset, y: 0 });
-    expect(store.cursorBandPosition.left).toBe(chartLeft + 0);
-    expect(store.cursorBandPosition.width).toBe(50);
-    expect(store.isTooltipVisible.get()).toBe(true);
-    expect(store.highlightedGeometries.length).toBe(1);
-    expect(store.tooltipData.length).toBe(2);
-    expect(onOverListener).toBeCalledTimes(1);
-    expect(onOutListener).toBeCalledTimes(0);
-    expect(onOverListener.mock.calls[0][0]).toEqual([indexedGeom1Red.value]);
-
-    store.setCursorPosition(chartLeft + 50 + scaleOffset, chartTop + 0);
-    expect(store.cursorPosition).toEqual({ x: 50 + scaleOffset, y: 0 });
-    expect(store.cursorBandPosition.left).toBe(chartLeft + 50);
-    expect(store.cursorBandPosition.width).toBe(50);
-    expect(store.isTooltipVisible.get()).toBe(true);
-    expect(store.tooltipData.length).toBe(2);
-    expect(store.highlightedGeometries.length).toBe(0);
-    expect(onOverListener).toBeCalledTimes(1);
-    expect(onOutListener).toBeCalledTimes(1);
-  });
-
-  test('can hover bottom-right corner of the first bar', () => {
-    let scaleOffset = 0;
-    if (scaleType !== ScaleType.Ordinal) {
-      scaleOffset = 1;
-    }
-    store.setCursorPosition(chartLeft + 49 + scaleOffset, chartTop + 99);
-    expect(store.cursorPosition).toEqual({ x: 49 + scaleOffset, y: 99 });
-    expect(store.cursorBandPosition.left).toBe(chartLeft + 0);
-    expect(store.cursorBandPosition.width).toBe(50);
-    expect(store.isTooltipVisible.get()).toBe(true);
-    expect(store.highlightedGeometries.length).toBe(1);
-    expect(store.tooltipData.length).toBe(2);
-    expect(onOverListener).toBeCalledTimes(1);
-    expect(onOutListener).toBeCalledTimes(0);
-    expect(onOverListener.mock.calls[0][0]).toEqual([indexedGeom1Red.value]);
-
-    store.setCursorPosition(chartLeft + 50 + scaleOffset, chartTop + 99);
-    expect(store.cursorPosition).toEqual({ x: 50 + scaleOffset, y: 99 });
-    expect(store.cursorBandPosition.left).toBe(chartLeft + 50);
-    expect(store.cursorBandPosition.width).toBe(50);
-    expect(store.isTooltipVisible.get()).toBe(true);
-    expect(store.tooltipData.length).toBe(2);
-    // we are over the second bar here
-    expect(store.highlightedGeometries.length).toBe(1);
-    expect(onOverListener).toBeCalledTimes(2);
-    expect(onOverListener.mock.calls[1][0]).toEqual([indexedGeom2Blue.value]);
-
-    expect(onOutListener).toBeCalledTimes(0);
-  });
-
-  test('can hover top-right corner of the chart', () => {
-    store.setCursorPosition(chartLeft + 99, chartTop + 0);
-    expect(store.cursorPosition).toEqual({ x: 99, y: 0 });
-    expect(store.cursorBandPosition.left).toBe(chartLeft + 50);
-    expect(store.cursorBandPosition.width).toBe(50);
-
-    expect(store.isTooltipVisible.get()).toBe(true);
-    expect(store.highlightedGeometries.length).toBe(0);
-    expect(store.tooltipData.length).toBe(2);
-    expect(onOverListener).toBeCalledTimes(0);
-    expect(onOutListener).toBeCalledTimes(0);
-  });
-
-  test('can hover bottom-right corner of the chart', () => {
-    store.setCursorPosition(chartLeft + 99, chartTop + 99);
-    expect(store.cursorPosition).toEqual({ x: 99, y: 99 });
-    expect(store.cursorBandPosition.left).toBe(chartLeft + 50);
-    expect(store.cursorBandPosition.width).toBe(50);
-    expect(store.isTooltipVisible.get()).toBe(true);
-    expect(store.highlightedGeometries.length).toBe(1);
-    expect(store.tooltipData.length).toBe(2);
-    expect(onOverListener).toBeCalledTimes(1);
-    expect(onOverListener.mock.calls[0][0]).toEqual([indexedGeom2Blue.value]);
-    expect(onOutListener).toBeCalledTimes(0);
-  });
-
-  describe('can position tooltip within chart when xScale is a single value scale', () => {
-    beforeEach(() => {
-      const singleValueScale =
-        store.xScale!.type === ScaleType.Ordinal
-          ? new ScaleBand(['a'], [0, 0])
-          : new ScaleContinuous({ type: ScaleType.Linear, domain: [1, 1], range: [0, 0] });
-      store.xScale = singleValueScale;
-    });
-    test('horizontal chart rotation', () => {
-      store.setCursorPosition(chartLeft + 99, chartTop + 99);
-      expect(store.tooltipPosition.hPosition.bandLeft).toBe(chartLeft);
-      expect(store.tooltipPosition.vPosition.bandTop).toBe(109);
-    });
-
-    test('vertical chart rotation', () => {
-      store.chartRotation = 90;
-      store.setCursorPosition(chartLeft + 99, chartTop + 99);
-      expect(store.tooltipPosition.hPosition.bandLeft).toBe(109);
-      expect(store.tooltipPosition.vPosition.bandTop).toBe(chartTop);
-    });
-  });
-  describe('can format tooltip values on rotated chart', () => {
-    beforeEach(() => {
-      store.addAxisSpec({
-        hide: true,
-        id: getAxisId('yaxis'),
-        groupId: GROUP_ID,
-        position: Position.Left,
-        tickFormat: (value) => `left ${Number(value)}`,
-        showOverlappingLabels: false,
-        showOverlappingTicks: false,
-        tickPadding: 0,
-        tickSize: 0,
-      });
-      store.addAxisSpec({
-        hide: true,
-        id: getAxisId('xaxis'),
-        groupId: GROUP_ID,
-        position: Position.Bottom,
-        tickFormat: (value) => `bottom ${Number(value)}`,
-        showOverlappingLabels: false,
-        showOverlappingTicks: false,
-        tickPadding: 0,
-        tickSize: 0,
-      });
-    });
-    test('chart 0 rotation', () => {
-      store.setCursorPosition(chartLeft + 0, chartTop + 99);
-      expect(store.tooltipData[0].value).toBe('bottom 0');
-      expect(store.tooltipData[1].value).toBe('left 10');
-    });
-
-    test('chart 90 deg rotated', () => {
-      store.chartRotation = 90;
-      store.setCursorPosition(chartLeft + 0, chartTop + 99);
-      expect(store.tooltipData[0].value).toBe('left 1');
-      expect(store.tooltipData[1].value).toBe('bottom 5');
-    });
-  });
-}
diff --git a/src/chart_types/xy_chart/store/chart_state.timescales.test.ts b/src/chart_types/xy_chart/store/chart_state.timescales.test.ts
deleted file mode 100644
index c15125f172..0000000000
--- a/src/chart_types/xy_chart/store/chart_state.timescales.test.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-import { DateTime } from 'luxon';
-import { LineSeriesSpec } from '../utils/specs';
-import { LIGHT_THEME } from '../../../utils/themes/light_theme';
-import { mergeWithDefaultTheme } from '../../../utils/themes/theme';
-import { getGroupId, getSpecId } from '../../../utils/ids';
-import { ScaleType } from '../../../utils/scales/scales';
-import { ChartStore } from './chart_state';
-
-describe('Render chart', () => {
-  describe('line, utc-time, day interval', () => {
-    let store: ChartStore;
-    const day1 = 1546300800000; // 2019-01-01T00:00:00.000Z
-    const day2 = day1 + 1000 * 60 * 60 * 24;
-    const day3 = day2 + 1000 * 60 * 60 * 24;
-    beforeEach(() => {
-      store = new ChartStore();
-
-      const lineSeries: LineSeriesSpec = {
-        id: getSpecId('lines'),
-        groupId: getGroupId('line'),
-        seriesType: 'line',
-        xScaleType: ScaleType.Time,
-        yScaleType: ScaleType.Linear,
-        xAccessor: 0,
-        yAccessors: [1],
-        data: [[day1, 10], [day2, 22], [day3, 6]],
-        yScaleToDataExtent: false,
-      };
-      store.chartTheme = mergeWithDefaultTheme(
-        {
-          chartPaddings: { top: 0, left: 0, bottom: 0, right: 0 },
-          chartMargins: { top: 0, left: 0, bottom: 0, right: 0 },
-        },
-        LIGHT_THEME,
-      );
-
-      store.addSeriesSpec(lineSeries);
-      store.updateParentDimensions(100, 100, 0, 0);
-    });
-    test('check rendered geometries', () => {
-      expect(store.geometries).toBeTruthy();
-      expect(store.geometries!.lines).toBeDefined();
-      expect(store.geometries!.lines.length).toBe(1);
-      expect(store.geometries!.lines[0].points.length).toBe(3);
-    });
-    test('check mouse position correctly return inverted value', () => {
-      store.setCursorPosition(15, 10); // check first valid tooltip
-      expect(store.tooltipData.length).toBe(2); // x value + y value
-      expect(store.tooltipData[0].value).toBe(day1); // x value
-      expect(store.tooltipData[1].value).toBe(10); // y value
-      store.setCursorPosition(35, 10); // check first valid tooltip
-      expect(store.tooltipData.length).toBe(2); // x value + y value
-      expect(store.tooltipData[0].value).toBe(day2); // x value
-      expect(store.tooltipData[1].value).toBe(22); // y value
-      store.setCursorPosition(76, 10); // check first valid tooltip
-      expect(store.tooltipData.length).toBe(2); // x value + y value
-      expect(store.tooltipData[0].value).toBe(day3); // x value
-      expect(store.tooltipData[1].value).toBe(6); // y value
-    });
-  });
-  describe('line, utc-time, 5m interval', () => {
-    let store: ChartStore;
-    const date1 = 1546300800000; // 2019-01-01T00:00:00.000Z
-    const date2 = date1 + 1000 * 60 * 5;
-    const date3 = date2 + 1000 * 60 * 5;
-    beforeEach(() => {
-      store = new ChartStore();
-
-      const lineSeries: LineSeriesSpec = {
-        id: getSpecId('lines'),
-        groupId: getGroupId('line'),
-        seriesType: 'line',
-        xScaleType: ScaleType.Time,
-        yScaleType: ScaleType.Linear,
-        xAccessor: 0,
-        yAccessors: [1],
-        data: [[date1, 10], [date2, 22], [date3, 6]],
-        yScaleToDataExtent: false,
-      };
-      store.chartTheme = mergeWithDefaultTheme(
-        {
-          chartPaddings: { top: 0, left: 0, bottom: 0, right: 0 },
-          chartMargins: { top: 0, left: 0, bottom: 0, right: 0 },
-        },
-        LIGHT_THEME,
-      );
-
-      store.addSeriesSpec(lineSeries);
-      store.updateParentDimensions(100, 100, 0, 0);
-    });
-    test('check rendered geometries', () => {
-      expect(store.geometries).toBeTruthy();
-      expect(store.geometries!.lines).toBeDefined();
-      expect(store.geometries!.lines.length).toBe(1);
-      expect(store.geometries!.lines[0].points.length).toBe(3);
-    });
-    test('check mouse position correctly return inverted value', () => {
-      store.setCursorPosition(15, 10); // check first valid tooltip
-      expect(store.tooltipData.length).toBe(2); // x value + y value
-      expect(store.tooltipData[0].value).toBe(date1); // x value
-      expect(store.tooltipData[1].value).toBe(10); // y value
-      store.setCursorPosition(35, 10); // check first valid tooltip
-      expect(store.tooltipData.length).toBe(2); // x value + y value
-      expect(store.tooltipData[0].value).toBe(date2); // x value
-      expect(store.tooltipData[1].value).toBe(22); // y value
-      store.setCursorPosition(76, 10); // check first valid tooltip
-      expect(store.tooltipData.length).toBe(2); // x value + y value
-      expect(store.tooltipData[0].value).toBe(date3); // x value
-      expect(store.tooltipData[1].value).toBe(6); // y value
-    });
-  });
-  describe('line, non utc-time, 5m + 1s interval', () => {
-    let store: ChartStore;
-    const date1 = DateTime.fromISO('2019-01-01T00:00:01.000-0300', { setZone: true }).toMillis();
-    const date2 = date1 + 1000 * 60 * 5;
-    const date3 = date2 + 1000 * 60 * 5;
-    beforeEach(() => {
-      store = new ChartStore();
-
-      const lineSeries: LineSeriesSpec = {
-        id: getSpecId('lines'),
-        groupId: getGroupId('line'),
-        seriesType: 'line',
-        xScaleType: ScaleType.Time,
-        yScaleType: ScaleType.Linear,
-        xAccessor: 0,
-        yAccessors: [1],
-        data: [[date1, 10], [date2, 22], [date3, 6]],
-        yScaleToDataExtent: false,
-      };
-      store.chartTheme = mergeWithDefaultTheme(
-        {
-          chartPaddings: { top: 0, left: 0, bottom: 0, right: 0 },
-          chartMargins: { top: 0, left: 0, bottom: 0, right: 0 },
-        },
-        LIGHT_THEME,
-      );
-
-      store.addSeriesSpec(lineSeries);
-      store.updateParentDimensions(100, 100, 0, 0);
-    });
-    test('check rendered geometries', () => {
-      expect(store.geometries).toBeTruthy();
-      expect(store.geometries!.lines).toBeDefined();
-      expect(store.geometries!.lines.length).toBe(1);
-      expect(store.geometries!.lines[0].points.length).toBe(3);
-    });
-    test('check scale values', () => {
-      const xValues = [date1, date2, date3];
-      expect(store.xScale!.minInterval).toBe(1000 * 60 * 5);
-      expect(store.xScale!.domain).toEqual([date1, date3]);
-      expect(store.xScale!.range).toEqual([0, 100]);
-      expect(store.xScale!.invert(0)).toBe(date1);
-      expect(store.xScale!.invert(50)).toBe(date2);
-      expect(store.xScale!.invert(100)).toBe(date3);
-      expect(store.xScale!.invertWithStep(5, xValues)).toEqual({ value: date1, withinBandwidth: true });
-      expect(store.xScale!.invertWithStep(20, xValues)).toEqual({ value: date1, withinBandwidth: true });
-      expect(store.xScale!.invertWithStep(30, xValues)).toEqual({ value: date2, withinBandwidth: true });
-      expect(store.xScale!.invertWithStep(50, xValues)).toEqual({ value: date2, withinBandwidth: true });
-      expect(store.xScale!.invertWithStep(70, xValues)).toEqual({ value: date2, withinBandwidth: true });
-      expect(store.xScale!.invertWithStep(80, xValues)).toEqual({ value: date3, withinBandwidth: true });
-      expect(store.xScale!.invertWithStep(100, xValues)).toEqual({ value: date3, withinBandwidth: true });
-    });
-    test('check mouse position correctly return inverted value', () => {
-      store.setCursorPosition(15, 10); // check first valid tooltip
-      expect(store.tooltipData.length).toBe(2); // x value + y value
-      expect(store.tooltipData[0].value).toBe(date1); // x value
-      expect(store.tooltipData[1].value).toBe(10); // y value
-      store.setCursorPosition(35, 10); // check first valid tooltip
-      expect(store.tooltipData.length).toBe(2); // x value + y value
-      expect(store.tooltipData[0].value).toBe(date2); // x value
-      expect(store.tooltipData[1].value).toBe(22); // y value
-      store.setCursorPosition(76, 10); // check first valid tooltip
-      expect(store.tooltipData.length).toBe(2); // x value + y value
-      expect(store.tooltipData[0].value).toBe(date3); // x value
-      expect(store.tooltipData[1].value).toBe(6); // y value
-    });
-  });
-});
diff --git a/src/chart_types/xy_chart/store/chart_state.ts b/src/chart_types/xy_chart/store/chart_state.ts
deleted file mode 100644
index 2b2daaaa01..0000000000
--- a/src/chart_types/xy_chart/store/chart_state.ts
+++ /dev/null
@@ -1,1081 +0,0 @@
-import { set, action, computed, IObservableValue, observable } from 'mobx';
-import * as uuid from 'uuid';
-
-import {
-  AxisLinePosition,
-  AxisTick,
-  AxisTicksDimensions,
-  computeAxisTicksDimensions,
-  getAxisTicksPositions,
-  mergeYCustomDomainsByGroupId,
-} from '../utils/axis_utils';
-import { CanvasTextBBoxCalculator } from '../../../utils/bbox/canvas_text_bbox_calculator';
-import { XDomain } from '../domains/x_domain';
-import { YDomain } from '../domains/y_domain';
-import { computeLegend, LegendItem } from '../legend/legend';
-import {
-  AreaGeometry,
-  BarGeometry,
-  GeometryValue,
-  IndexedGeometry,
-  LineGeometry,
-  PointGeometry,
-} from '../rendering/rendering';
-import { countBarsInCluster } from '../utils/scales';
-import {
-  DataSeriesColorsValues,
-  findDataSeriesByColorValues,
-  FormattedDataSeries,
-  getSeriesColorMap,
-  RawDataSeries,
-} from '../utils/series';
-import {
-  AnnotationSpec,
-  AnnotationTypes,
-  AreaSeriesSpec,
-  AxisSpec,
-  BarSeriesSpec,
-  BasicSeriesSpec,
-  DomainRange,
-  isLineAnnotation,
-  isRectAnnotation,
-  LineSeriesSpec,
-  Position,
-  Rendering,
-  Rotation,
-} from '../utils/specs';
-import { getSeriesTooltipValues, getTooltipAndHighlightFromXValue } from '../tooltip/tooltip';
-import { mergeWithDefaultAnnotationLine, mergeWithDefaultAnnotationRect, Theme } from '../../../utils/themes/theme';
-import { compareByValueAsc } from '../../../utils/commons';
-import { computeChartDimensions } from '../utils/dimensions';
-import { Dimensions } from '../../../utils/dimensions';
-import { Domain } from '../../../utils/domain';
-import { AnnotationId, AxisId, GroupId, SpecId } from '../../../utils/ids';
-import {
-  areIndexedGeometryArraysEquals,
-  getValidXPosition,
-  getValidYPosition,
-  isCrosshairTooltipType,
-  isNoneTooltipType,
-  TooltipType,
-  TooltipValue,
-  TooltipValueFormatter,
-} from '../utils/interactions';
-import { Scale, ScaleType } from '../../../utils/scales/scales';
-import { DEFAULT_TOOLTIP_SNAP, DEFAULT_TOOLTIP_TYPE, CursorEvent } from '../../../specs/settings';
-import {
-  AnnotationDimensions,
-  computeAnnotationDimensions,
-  computeAnnotationTooltipState,
-} from '../annotations/annotation_utils';
-import {
-  getCursorBandPosition,
-  getCursorLinePosition,
-  getTooltipPosition,
-  TooltipPosition,
-} from '../crosshair/crosshair_utils';
-import {
-  BrushExtent,
-  computeBrushExtent,
-  computeChartTransform,
-  computeSeriesDomains,
-  computeSeriesGeometries,
-  getUpdatedCustomSeriesColors,
-  isAllSeriesDeselected,
-  isChartAnimatable,
-  isHistogramModeEnabled,
-  isLineAreaOnlyChart,
-  setBarSeriesAccessors,
-  Transform,
-  updateDeselectedDataSeries,
-} from './utils';
-import { LIGHT_THEME } from '../../../utils/themes/light_theme';
-
-export interface Point {
-  x: number;
-  y: number;
-}
-export interface SeriesDomainsAndData {
-  xDomain: XDomain;
-  yDomain: YDomain[];
-  splittedDataSeries: RawDataSeries[][];
-  formattedDataSeries: {
-    stacked: FormattedDataSeries[];
-    nonStacked: FormattedDataSeries[];
-  };
-  seriesColors: Map<string, DataSeriesColorsValues>;
-}
-
-export type ElementClickListener = (values: GeometryValue[]) => void;
-export type ElementOverListener = (values: GeometryValue[]) => void;
-export type BrushEndListener = (min: number, max: number) => void;
-export type LegendItemListener = (dataSeriesIdentifiers: DataSeriesColorsValues | null) => void;
-export type CursorUpdateListener = (event?: CursorEvent) => void;
-/**
- * Listener to be called when chart render state changes
- *
- * `isRendered` value is `true` when rendering is complete and `false` otherwise
- */
-export type RenderChangeListener = (isRendered: boolean) => void;
-export type BasicListener = () => undefined | void;
-
-export const isDuplicateAxis = (
-  { position, title }: AxisSpec,
-  { tickLabels }: AxisTicksDimensions,
-  tickMap: Map<AxisId, AxisTicksDimensions>,
-  specMap: Map<AxisId, AxisSpec>,
-): boolean => {
-  const firstTickLabel = tickLabels[0];
-  const lastTickLabel = tickLabels.slice(-1)[0];
-
-  let hasDuplicate = false;
-  tickMap.forEach(({ tickLabels: axisTickLabels }, axisId) => {
-    if (
-      !hasDuplicate &&
-      axisTickLabels &&
-      tickLabels.length === axisTickLabels.length &&
-      firstTickLabel === axisTickLabels[0] &&
-      lastTickLabel === axisTickLabels.slice(-1)[0]
-    ) {
-      const spec = specMap.get(axisId);
-
-      if (spec && spec.position === position && title === spec.title) {
-        hasDuplicate = true;
-      }
-    }
-  });
-
-  return hasDuplicate;
-};
-
-export class ChartStore {
-  constructor(id?: string) {
-    this.id = id || uuid.v4();
-  }
-  debug = false;
-  id = uuid.v4();
-  specsInitialized = observable.box(false);
-  chartInitialized = observable.box(false);
-  legendInitialized = observable.box(false);
-  enableHistogramMode = observable.box(false);
-
-  parentDimensions: Dimensions = {
-    width: 0,
-    height: 0,
-    top: 0,
-    left: 0,
-  };
-  chartDimensions: Dimensions = {
-    width: 0,
-    height: 0,
-    top: 0,
-    left: 0,
-  };
-  chartTransform: Transform = {
-    x: 0,
-    y: 0,
-    rotate: 0,
-  };
-  isBrushing = observable.box(false);
-  brushExtent: BrushExtent = {
-    minX: 0,
-    minY: 0,
-    maxX: 0,
-    maxY: 0,
-  };
-
-  resizeDebounce = 10;
-
-  chartRotation: Rotation = 0; // updated from jsx
-  chartRendering: Rendering = 'canvas'; // updated from jsx
-  chartTheme: Theme = LIGHT_THEME;
-  hideDuplicateAxes = false; // updated from jsx
-  axesSpecs: Map<AxisId, AxisSpec> = new Map(); // readed from jsx
-  axesTicksDimensions: Map<AxisId, AxisTicksDimensions> = new Map(); // computed
-  axesPositions: Map<AxisId, Dimensions> = new Map(); // computed
-  axesVisibleTicks: Map<AxisId, AxisTick[]> = new Map(); // computed
-  axesTicks: Map<AxisId, AxisTick[]> = new Map(); // computed
-  axesGridLinesPositions: Map<AxisId, AxisLinePosition[]> = new Map(); // computed
-
-  annotationSpecs = new Map<AnnotationId, AnnotationSpec>(); // read from jsx
-
-  annotationDimensions = observable.map<AnnotationId, AnnotationDimensions>(new Map());
-
-  seriesSpecs: Map<SpecId, BasicSeriesSpec> = new Map(); // readed from jsx
-  isChartEmpty = observable.box(false);
-  activeChartId?: string;
-  seriesDomainsAndData?: SeriesDomainsAndData; // computed
-  xScale?: Scale;
-  yScales?: Map<GroupId, Scale>;
-  // custom X domain passed via <Settings />
-  customXDomain?: Domain | DomainRange;
-
-  legendItems: Map<string, LegendItem> = new Map();
-  highlightedLegendItemKey: IObservableValue<string | null> = observable.box(null);
-  selectedLegendItemKey: IObservableValue<string | null> = observable.box(null);
-  // deselected/hidden data series from the legend
-  deselectedDataSeries: DataSeriesColorsValues[] | null = null;
-  customSeriesColors: Map<string, string> = new Map();
-  seriesColorMap: Map<string, string> = new Map();
-  totalBarsInCluster?: number;
-
-  tooltipData = observable.array<TooltipValue>([], { deep: false });
-  tooltipType = observable.box<TooltipType>(DEFAULT_TOOLTIP_TYPE);
-  tooltipSnap = observable.box<boolean>(DEFAULT_TOOLTIP_SNAP);
-  tooltipPosition = observable.object<TooltipPosition>({
-    isRotatedHorizontal: true,
-    vPosition: {
-      bandTop: 0,
-      bandHeight: 0,
-    },
-    hPosition: {
-      bandLeft: 0,
-      bandWidth: 0,
-    },
-  });
-  tooltipHeaderFormatter?: TooltipValueFormatter;
-
-  /** cursorPosition is used by tooltip, so this is a way to expose the position for other uses */
-  rawCursorPosition = observable.object<{ x: number; y: number }>({ x: 100, y: 100 }, undefined, {
-    deep: false,
-  });
-
-  /** position of the cursor relative to the chart */
-  cursorPosition = observable.object<{ x: number; y: number }>({ x: -1, y: -1 }, undefined, {
-    deep: false,
-  });
-  cursorBandPosition = observable.object<Dimensions & { visible: boolean }>(
-    { top: -1, left: -1, height: -1, width: -1, visible: false },
-    undefined,
-    {
-      deep: false,
-    },
-  );
-  cursorLinePosition = observable.object<Dimensions>({ top: -1, left: -1, height: -1, width: -1 }, undefined, {
-    deep: false,
-  });
-  externalCursorShown = observable.box(false);
-
-  onElementClickListener?: ElementClickListener;
-  onElementOverListener?: ElementOverListener;
-  onElementOutListener?: BasicListener;
-  onBrushEndListener?: BrushEndListener;
-  onLegendItemOverListener?: LegendItemListener;
-  onLegendItemOutListener?: BasicListener;
-  onLegendItemClickListener?: LegendItemListener;
-  onLegendItemPlusClickListener?: LegendItemListener;
-  onLegendItemMinusClickListener?: LegendItemListener;
-  onLegendItemVisibilityToggleClickListener?: LegendItemListener;
-  onCursorUpdateListener?: CursorUpdateListener;
-  onRenderChangeListener?: RenderChangeListener;
-
-  geometries: {
-    points: PointGeometry[];
-    bars: BarGeometry[];
-    areas: AreaGeometry[];
-    lines: LineGeometry[];
-  } | null = null;
-
-  geometriesIndex: Map<any, IndexedGeometry[]> = new Map();
-  geometriesIndexKeys: any[] = [];
-  highlightedGeometries = observable.array<IndexedGeometry>([], { deep: false });
-
-  animateData = false;
-  /**
-   * Define if the chart can be animated or not depending
-   * on the global configuration and on the number of elements per series
-   */
-  canDataBeAnimated = false;
-
-  showLegend = observable.box(false);
-  legendPosition = observable.box<Position>(Position.Right);
-  showLegendDisplayValue = observable.box(true);
-  isCursorOnChart = observable.box(false);
-
-  chartCursor = computed(() => {
-    const { x: xPos, y: yPos } = this.cursorPosition;
-    if (yPos < 0 || xPos < 0) {
-      return 'default';
-    }
-    if (this.highlightedGeometries.length > 0 && (this.onElementClickListener || this.onElementOverListener)) {
-      return 'pointer';
-    }
-    return this.isBrushEnabled() ? 'crosshair' : 'default';
-  });
-
-  /**
-   * determine if chart is currently active
-   */
-  isActiveChart = computed(() => {
-    return !this.activeChartId ? true : this.activeChartId === this.id;
-  });
-
-  /**
-   * set activeChartId
-   */
-  setActiveChartId = (chartId?: string) => {
-    this.activeChartId = chartId;
-  };
-
-  /**
-   * set the x value of the cursor
-   */
-  setCursorValue = action((value: string | number) => {
-    this.externalCursorShown.set(true);
-    this.isCursorOnChart.set(true);
-
-    if (!this.xScale) {
-      return;
-    }
-
-    const xPosition = this.xScale.pureScale(value);
-
-    if (xPosition == null || xPosition > this.chartDimensions.width + this.chartDimensions.left) {
-      this.clearTooltipAndHighlighted();
-      return;
-    }
-
-    const isLineAreaOnly = isLineAreaOnlyChart(this.seriesSpecs);
-
-    const updatedCursorBand = getCursorBandPosition(
-      this.chartRotation,
-      this.chartDimensions,
-      { x: xPosition, y: 0 },
-      {
-        value,
-        withinBandwidth: true,
-      },
-      this.isTooltipSnapEnabled.get(),
-      this.xScale,
-      isLineAreaOnly ? 1 : this.totalBarsInCluster,
-    );
-
-    Object.assign(this.cursorBandPosition, updatedCursorBand);
-
-    const tooltipAndHighlight = getTooltipAndHighlightFromXValue(
-      { x: xPosition, y: 0 },
-      this.seriesSpecs,
-      this.axesSpecs,
-      this.geometriesIndex,
-      {
-        value,
-        withinBandwidth: true,
-      },
-      this.isActiveChart.get(),
-      this.tooltipType.get(),
-      this.chartRotation,
-      this.yScales,
-      this.tooltipHeaderFormatter,
-    );
-    if (!tooltipAndHighlight || tooltipAndHighlight.tooltipData.length === 0) {
-      this.clearTooltipAndHighlighted(false);
-      return;
-    }
-    // update tooltip visibility
-    if (tooltipAndHighlight.tooltipData.length === 0) {
-      this.tooltipData.clear();
-    } else {
-      this.tooltipData.replace(tooltipAndHighlight.tooltipData);
-    }
-  });
-
-  /**
-   * x and y values are relative to the container.
-   */
-  setCursorPosition = action((x: number, y: number, updateCursor: boolean = true) => {
-    this.isCursorOnChart.set(true);
-    this.rawCursorPosition.x = x;
-    this.rawCursorPosition.y = y;
-
-    if (!this.seriesDomainsAndData || this.tooltipType.get() === TooltipType.None) {
-      return;
-    }
-    this.externalCursorShown.set(false);
-
-    // get positions relative to chart
-    let xPos = x - this.chartDimensions.left;
-    let yPos = y - this.chartDimensions.top;
-    // limit cursorPosition to chartDimensions
-    // note: to debug and inspect tooltip html, just comment the following ifs
-    if (xPos < 0 || xPos >= this.chartDimensions.width) {
-      xPos = -1;
-    }
-    if (yPos < 0 || yPos >= this.chartDimensions.height) {
-      yPos = -1;
-    }
-    this.cursorPosition.x = xPos;
-    this.cursorPosition.y = yPos;
-
-    // hide tooltip if outside chart dimensions
-    if (yPos === -1 || xPos === -1) {
-      this.isCursorOnChart.set(false);
-      if (this.onCursorUpdateListener && this.isActiveChart.get()) {
-        this.onCursorUpdateListener();
-      }
-      this.clearTooltipAndHighlighted();
-      return;
-    }
-
-    // get the cursor position depending on the chart rotation
-    const xAxisCursorPosition = getValidXPosition(xPos, yPos, this.chartRotation, this.chartDimensions);
-    const yAxisCursorPosition = getValidYPosition(xPos, yPos, this.chartRotation, this.chartDimensions);
-    const axisCursorPosition = { x: xAxisCursorPosition, y: yAxisCursorPosition };
-
-    // only if we have a valid cursor position and the necessary scale
-    if (xAxisCursorPosition < 0 || !this.xScale || !this.yScales) {
-      this.clearTooltipAndHighlighted();
-      return;
-    }
-
-    // invert the cursor position to get the scale value
-    const xValue = this.xScale.invertWithStep(xAxisCursorPosition, this.geometriesIndexKeys);
-    if (updateCursor && this.onCursorUpdateListener) {
-      this.onCursorUpdateListener({
-        chartId: this.id,
-        scale: this.xScale.type,
-        unit: this.xScale.unit,
-        value: xValue.value,
-      });
-    }
-
-    // update che cursorBandPosition based on chart configuration
-    const isLineAreaOnly = isLineAreaOnlyChart(this.seriesSpecs);
-    const updatedCursorBand = getCursorBandPosition(
-      this.chartRotation,
-      this.chartDimensions,
-      axisCursorPosition,
-      {
-        value: xValue.value,
-        withinBandwidth: true,
-      },
-      this.isTooltipSnapEnabled.get(),
-      this.xScale,
-      isLineAreaOnly ? 1 : this.totalBarsInCluster,
-    );
-    Object.assign(this.cursorBandPosition, updatedCursorBand);
-
-    const updatedCursorLine = getCursorLinePosition(this.chartRotation, this.chartDimensions, this.cursorPosition);
-    Object.assign(this.cursorLinePosition, updatedCursorLine);
-
-    const isSingleValueXScale = this.xScale.isSingleValue();
-
-    set(
-      this.tooltipPosition,
-      getTooltipPosition(
-        this.chartDimensions,
-        this.chartRotation,
-        this.cursorBandPosition,
-        this.cursorPosition,
-        isSingleValueXScale,
-      ),
-    );
-
-    const tooltipAndHighlight = getTooltipAndHighlightFromXValue(
-      axisCursorPosition,
-      this.seriesSpecs,
-      this.axesSpecs,
-      this.geometriesIndex,
-      xValue,
-      this.isActiveChart.get(),
-      this.tooltipType.get(),
-      this.chartRotation,
-      this.yScales,
-      this.tooltipHeaderFormatter,
-    );
-
-    // if no element, hide everything keep crosshair
-    if (!tooltipAndHighlight || tooltipAndHighlight.tooltipData.length === 0) {
-      this.clearTooltipAndHighlighted(false);
-      return;
-    }
-    const { highlightedGeometries, tooltipData } = tooltipAndHighlight;
-
-    // if there's an annotation rect tooltip & there isn't a single highlighted element, hide
-    const annotationTooltip = this.annotationTooltipState.get();
-    const hasRectAnnotationToolip =
-      annotationTooltip &&
-      annotationTooltip.isVisible &&
-      annotationTooltip.annotationType === AnnotationTypes.Rectangle;
-    if (hasRectAnnotationToolip && highlightedGeometries.length === 0) {
-      this.clearTooltipAndHighlighted();
-      return;
-    }
-
-    // check if we already have send out an over/out event on highlighted elements
-    if (
-      this.onElementOverListener &&
-      !areIndexedGeometryArraysEquals(highlightedGeometries, this.highlightedGeometries.toJS())
-    ) {
-      if (highlightedGeometries.length > 0) {
-        this.onElementOverListener(highlightedGeometries.map(({ value }) => value));
-      } else {
-        if (this.onElementOutListener) {
-          this.onElementOutListener();
-        }
-      }
-    }
-
-    // update highlighted geometries observer
-    this.highlightedGeometries.replace(highlightedGeometries);
-
-    // update tooltip visibility
-    if (tooltipData.length === 0) {
-      this.tooltipData.clear();
-    } else {
-      this.tooltipData.replace(tooltipData);
-    }
-  });
-
-  legendItemTooltipValues = computed(() => {
-    const xPos = this.rawCursorPosition.x - this.chartDimensions.left;
-    const yPos = this.rawCursorPosition.y - this.chartDimensions.top;
-    if (xPos > 0 && xPos <= this.chartDimensions.width && yPos > 0 && yPos <= this.chartDimensions.height) {
-      return getSeriesTooltipValues(this.tooltipData, '');
-    }
-    // update legend items with value to display
-    return getSeriesTooltipValues(this.tooltipData);
-  });
-
-  annotationTooltipState = computed(() => {
-    // get positions relative to chart
-    const xPos = this.rawCursorPosition.x - this.chartDimensions.left;
-    const yPos = this.rawCursorPosition.y - this.chartDimensions.top;
-
-    // only if we have a valid cursor position and the necessary scale
-    if (!this.xScale || !this.yScales) {
-      return null;
-    }
-
-    const cursorPosition = {
-      x: xPos,
-      y: yPos,
-    };
-
-    const tooltipState = computeAnnotationTooltipState(
-      cursorPosition,
-      this.annotationDimensions,
-      this.annotationSpecs,
-      this.chartRotation,
-      this.axesSpecs,
-      this.chartDimensions,
-    );
-
-    // If there's a highlighted chart element tooltip value, don't show annotation tooltip
-    if (tooltipState && tooltipState.isVisible && tooltipState.annotationType === AnnotationTypes.Rectangle) {
-      for (const tooltipValue of this.tooltipData) {
-        if (tooltipValue.isHighlighted) {
-          return null;
-        }
-      }
-    }
-
-    return tooltipState;
-  });
-
-  isTooltipVisible = computed(() => {
-    return (
-      !this.isBrushing.get() &&
-      this.tooltipType.get() !== TooltipType.None &&
-      this.cursorPosition.x > -1 &&
-      this.cursorPosition.y > -1 &&
-      this.tooltipData.length > 0 &&
-      this.isActiveChart.get()
-    );
-  });
-
-  isCrosshairVisible = computed(() => {
-    return (
-      !this.isBrushing.get() &&
-      isCrosshairTooltipType(this.tooltipType.get()) &&
-      !this.isChartEmpty.get() &&
-      (this.externalCursorShown.get() || (this.cursorPosition.x > -1 && this.cursorPosition.y > -1))
-    );
-  });
-
-  isTooltipSnapEnabled = computed(() => {
-    return (this.xScale && this.xScale.bandwidth > 0) || this.tooltipSnap.get();
-  });
-
-  clearTooltipAndHighlighted = action((clearCursorBand = true) => {
-    // if exist any highlighted geometry, send an out element event
-    if (this.onElementOutListener && this.highlightedGeometries.length > 0) {
-      this.onElementOutListener();
-    }
-    // clear highlight geoms
-    this.highlightedGeometries.clear();
-    this.tooltipData.clear();
-    if (clearCursorBand) {
-      Object.assign(this.cursorBandPosition, { visible: false });
-    }
-  });
-
-  setShowLegend = action((showLegend: boolean) => {
-    this.showLegend.set(showLegend);
-  });
-
-  highlightedLegendItem = computed(() => {
-    const key = this.highlightedLegendItemKey.get();
-    return key == null ? null : this.legendItems.get(key);
-  });
-
-  selectedLegendItem = computed(() => {
-    const key = this.selectedLegendItemKey.get();
-    return key == null ? null : this.legendItems.get(key);
-  });
-
-  onLegendItemOver = action((legendItemKey: string | null) => {
-    if (legendItemKey) {
-      const legendItem = this.legendItems.get(legendItemKey);
-      if (legendItem && findDataSeriesByColorValues(this.deselectedDataSeries, legendItem.value) > -1) {
-        return;
-      }
-    }
-    this.highlightedLegendItemKey.set(legendItemKey);
-    if (this.onLegendItemOverListener) {
-      const currentLegendItem = this.highlightedLegendItem.get();
-      const listenerData = currentLegendItem ? currentLegendItem.value : null;
-      this.onLegendItemOverListener(listenerData);
-    }
-  });
-
-  onLegendItemOut = action(() => {
-    this.highlightedLegendItemKey.set(null);
-    if (this.onLegendItemOutListener) {
-      this.onLegendItemOutListener();
-    }
-  });
-
-  onLegendItemClick = action((legendItemKey: string) => {
-    // Disabling the select until we implement the right contextual menu
-    // with extend possibility
-    // if (legendItemKey !== this.selectedLegendItemKey.get()) {
-    // this.selectedLegendItemKey.set(legendItemKey);
-    // } else {
-    //   this.selectedLegendItemKey.set(null);
-    // }
-    if (this.onLegendItemClickListener) {
-      const currentLegendItem = legendItemKey == null ? null : this.legendItems.get(legendItemKey);
-      const listenerData = currentLegendItem ? currentLegendItem.value : null;
-      this.onLegendItemClickListener(listenerData);
-    }
-  });
-
-  onLegendItemPlusClick = action(() => {
-    if (this.onLegendItemPlusClickListener) {
-      const currentLegendItem = this.selectedLegendItem.get();
-      const listenerData = currentLegendItem ? currentLegendItem.value : null;
-      this.onLegendItemPlusClickListener(listenerData);
-    }
-  });
-
-  onLegendItemMinusClick = action(() => {
-    if (this.onLegendItemMinusClickListener) {
-      const currentLegendItem = this.selectedLegendItem.get();
-      const listenerData = currentLegendItem ? currentLegendItem.value : null;
-      this.onLegendItemMinusClickListener(listenerData);
-    }
-  });
-
-  toggleSingleSeries = action((legendItemKey: string) => {
-    const legendItem = this.legendItems.get(legendItemKey);
-
-    if (legendItem) {
-      if (findDataSeriesByColorValues(this.deselectedDataSeries, legendItem.value) > -1) {
-        this.deselectedDataSeries = [...this.legendItems.values()]
-          .filter((item: LegendItem) => item.key !== legendItemKey)
-          .map((item: LegendItem) => item.value);
-      } else {
-        this.deselectedDataSeries = [legendItem.value];
-      }
-
-      this.computeChart();
-    }
-  });
-
-  updateHighlightedLegendItemKey = action((legendItemKey: string, deselected: boolean) => {
-    if (deselected) {
-      this.highlightedLegendItemKey.set(null);
-    } else {
-      this.highlightedLegendItemKey.set(legendItemKey);
-    }
-  });
-
-  toggleSeriesVisibility = action((legendItemKey: string) => {
-    const legendItem = this.legendItems.get(legendItemKey);
-
-    if (legendItem) {
-      this.deselectedDataSeries = updateDeselectedDataSeries(this.deselectedDataSeries, legendItem.value);
-      const deselected = findDataSeriesByColorValues(this.deselectedDataSeries, legendItem.value) > -1;
-      this.updateHighlightedLegendItemKey(legendItemKey, deselected);
-      this.computeChart();
-    }
-  });
-
-  setSeriesColor = action((legendItemKey: string, color: string) => {
-    const legendItem = this.legendItems.get(legendItemKey);
-
-    if (legendItem) {
-      const { specId } = legendItem.value;
-
-      const spec = this.seriesSpecs.get(specId);
-      if (spec) {
-        if (spec.customSeriesColors) {
-          spec.customSeriesColors.set(legendItem.value, color);
-        } else {
-          const specCustomSeriesColors = new Map();
-          spec.customSeriesColors = specCustomSeriesColors;
-          spec.customSeriesColors.set(legendItem.value, color);
-        }
-      }
-
-      this.computeChart();
-    }
-  });
-
-  onBrushStart = action(() => {
-    if (!this.onBrushEndListener) {
-      return;
-    }
-    this.isBrushing.set(true);
-  });
-
-  onBrushEnd = action((start: Point, end: Point) => {
-    if (!this.onBrushEndListener) {
-      return;
-    }
-    this.isBrushing.set(false);
-    const minValue = Math.min(start.x, end.x);
-    const maxValue = Math.max(start.x, end.x);
-    if (maxValue === minValue) {
-      // if 0 size brush, avoid computing the value
-      return;
-    }
-    const min = this.xScale!.invert(minValue - this.chartDimensions.left);
-    const max = this.xScale!.invert(maxValue - this.chartDimensions.left);
-    this.onBrushEndListener(min, max);
-  });
-
-  handleChartClick() {
-    if (this.highlightedGeometries.length > 0 && this.onElementClickListener) {
-      this.onElementClickListener(this.highlightedGeometries.toJS().map(({ value }) => value));
-    }
-  }
-
-  resetDeselectedDataSeries() {
-    this.deselectedDataSeries = null;
-  }
-
-  setOnElementClickListener(listener: ElementClickListener) {
-    this.onElementClickListener = listener;
-  }
-  setOnElementOverListener(listener: ElementOverListener) {
-    this.onElementOverListener = listener;
-  }
-  setOnElementOutListener(listener: BasicListener) {
-    this.onElementOutListener = listener;
-  }
-  setOnBrushEndListener(listener: BrushEndListener) {
-    this.onBrushEndListener = listener;
-  }
-  setOnLegendItemOverListener(listener: LegendItemListener) {
-    this.onLegendItemOverListener = listener;
-  }
-  setOnLegendItemOutListener(listener: BasicListener) {
-    this.onLegendItemOutListener = listener;
-  }
-  setOnLegendItemClickListener(listener: LegendItemListener) {
-    this.onLegendItemClickListener = listener;
-  }
-  setOnLegendItemPlusClickListener(listener: LegendItemListener) {
-    this.onLegendItemPlusClickListener = listener;
-  }
-  setOnLegendItemMinusClickListener(listener: LegendItemListener) {
-    this.onLegendItemMinusClickListener = listener;
-  }
-  setOnCursorUpdateListener(listener: CursorUpdateListener) {
-    this.onCursorUpdateListener = listener;
-  }
-  setOnRenderChangeListener(listener: RenderChangeListener) {
-    this.onRenderChangeListener = listener;
-
-    this.chartInitialized.observe(({ newValue, oldValue }) => {
-      if (this.onRenderChangeListener && newValue !== oldValue) {
-        this.onRenderChangeListener(newValue);
-      }
-    });
-  }
-  removeElementClickListener() {
-    this.onElementClickListener = undefined;
-  }
-  removeElementOverListener() {
-    this.onElementOverListener = undefined;
-  }
-  removeElementOutListener() {
-    this.onElementOutListener = undefined;
-  }
-  removeOnLegendItemOverListener() {
-    this.onLegendItemOverListener = undefined;
-  }
-  removeOnLegendItemOutListener() {
-    this.onLegendItemOutListener = undefined;
-  }
-  removeOnLegendItemPlusClickListener() {
-    this.onLegendItemPlusClickListener = undefined;
-  }
-  removeOnLegendItemMinusClickListener() {
-    this.onLegendItemMinusClickListener = undefined;
-  }
-  removeOnCursorUpdateListener() {
-    this.onCursorUpdateListener = undefined;
-  }
-  removeOnRenderChangeListener() {
-    this.onRenderChangeListener = undefined;
-  }
-
-  isBrushEnabled(): boolean {
-    if (!this.xScale) {
-      return false;
-    }
-    return this.xScale.type !== ScaleType.Ordinal && Boolean(this.onBrushEndListener);
-  }
-
-  updateParentDimensions(width: number, height: number, top: number, left: number) {
-    let isChanged = false;
-    if (width !== this.parentDimensions.width) {
-      isChanged = true;
-      this.parentDimensions.width = width;
-    }
-    if (height !== this.parentDimensions.height) {
-      isChanged = true;
-      this.parentDimensions.height = height;
-    }
-    if (top !== this.parentDimensions.top) {
-      isChanged = true;
-      this.parentDimensions.top = top;
-    }
-    if (left !== this.parentDimensions.left) {
-      isChanged = true;
-      this.parentDimensions.left = left;
-    }
-    if (isChanged) {
-      this.computeChart();
-    }
-  }
-  addSeriesSpec(seriesSpec: BasicSeriesSpec | LineSeriesSpec | AreaSeriesSpec | BarSeriesSpec) {
-    this.seriesSpecs.set(seriesSpec.id, seriesSpec);
-
-    const isEnabled = isHistogramModeEnabled(this.seriesSpecs);
-    this.enableHistogramMode.set(isEnabled);
-
-    setBarSeriesAccessors(isEnabled, this.seriesSpecs);
-  }
-  removeSeriesSpec(specId: SpecId) {
-    this.seriesSpecs.delete(specId);
-
-    const isEnabled = isHistogramModeEnabled(this.seriesSpecs);
-    this.enableHistogramMode.set(isEnabled);
-
-    setBarSeriesAccessors(isEnabled, this.seriesSpecs);
-  }
-
-  /**
-   * Add an axis spec to the store
-   * @param axisSpec an axis spec
-   */
-  addAxisSpec(axisSpec: AxisSpec) {
-    this.axesSpecs.set(axisSpec.id, axisSpec);
-  }
-  removeAxisSpec(axisId: AxisId) {
-    this.axesSpecs.delete(axisId);
-  }
-
-  addAnnotationSpec(annotationSpec: AnnotationSpec) {
-    if (isLineAnnotation(annotationSpec)) {
-      const { style } = annotationSpec;
-
-      const mergedLineStyle = mergeWithDefaultAnnotationLine(style);
-      annotationSpec.style = mergedLineStyle;
-    }
-    if (isRectAnnotation(annotationSpec)) {
-      const { style } = annotationSpec;
-
-      const mergedRectStyle = mergeWithDefaultAnnotationRect(style);
-      annotationSpec.style = mergedRectStyle;
-    }
-    this.annotationSpecs.set(annotationSpec.annotationId, annotationSpec);
-  }
-
-  removeAnnotationSpec(annotationId: AnnotationId) {
-    this.annotationSpecs.delete(annotationId);
-  }
-
-  computeChart() {
-    this.chartInitialized.set(false);
-    // compute only if parent dimensions are computed
-    if (this.parentDimensions.width === 0 || this.parentDimensions.height === 0) {
-      return;
-    }
-    // avoid compute if no specs are specified
-    if (this.seriesSpecs.size === 0) {
-      return;
-    }
-
-    // When specs are not initialized, reset selectedDataSeries to null
-    if (!this.specsInitialized.get()) {
-      this.deselectedDataSeries = null;
-    }
-
-    // merge Y custom domains specified on the axis
-    const customYDomainsByGroupId = mergeYCustomDomainsByGroupId(this.axesSpecs, this.chartRotation);
-
-    // compute general X and Y domains, split series based on split accessors
-    // process stacked and non-stacked values series formatting the data
-    this.seriesDomainsAndData = computeSeriesDomains(
-      this.seriesSpecs,
-      customYDomainsByGroupId,
-      this.customXDomain,
-      this.deselectedDataSeries,
-    );
-
-    // Merge all series spec custom colors with state custom colors map
-    const updatedCustomSeriesColors = getUpdatedCustomSeriesColors(this.seriesSpecs);
-    this.customSeriesColors = new Map([...this.customSeriesColors, ...updatedCustomSeriesColors]);
-
-    this.seriesColorMap = getSeriesColorMap(
-      this.seriesDomainsAndData.seriesColors,
-      this.chartTheme.colors,
-      this.customSeriesColors,
-    );
-
-    this.legendItems = computeLegend(
-      this.seriesDomainsAndData.seriesColors,
-      this.seriesColorMap,
-      this.seriesSpecs,
-      this.chartTheme.colors.defaultVizColor,
-      this.axesSpecs,
-      this.deselectedDataSeries,
-    );
-
-    if (!this.legendInitialized.get()) {
-      this.legendInitialized.set(true);
-
-      if (this.legendItems.size > 0 && this.showLegend.get()) {
-        return;
-      }
-    }
-    this.isChartEmpty.set(isAllSeriesDeselected(this.legendItems));
-
-    const { xDomain, yDomain, formattedDataSeries } = this.seriesDomainsAndData;
-
-    // compute how many bar series are clustered
-    const { totalBarsInCluster } = countBarsInCluster(formattedDataSeries.stacked, formattedDataSeries.nonStacked);
-    this.totalBarsInCluster = totalBarsInCluster;
-
-    // compute axis dimensions
-    const bboxCalculator = new CanvasTextBBoxCalculator();
-    const barsPadding = this.enableHistogramMode.get()
-      ? this.chartTheme.scales.histogramPadding
-      : this.chartTheme.scales.barsPadding;
-
-    this.axesTicksDimensions.clear();
-    this.axesSpecs.forEach((axisSpec) => {
-      const { id } = axisSpec;
-      const dimensions = computeAxisTicksDimensions(
-        axisSpec,
-        xDomain,
-        yDomain,
-        totalBarsInCluster,
-        bboxCalculator,
-        this.chartRotation,
-        this.chartTheme.axes,
-        barsPadding,
-        this.enableHistogramMode.get(),
-      );
-
-      if (
-        dimensions &&
-        (!this.hideDuplicateAxes || !isDuplicateAxis(axisSpec, dimensions, this.axesTicksDimensions, this.axesSpecs))
-      ) {
-        this.axesTicksDimensions.set(id, dimensions);
-      }
-    });
-    bboxCalculator.destroy();
-
-    // compute chart dimensions
-    const computedChartDims = computeChartDimensions(
-      this.parentDimensions,
-      this.chartTheme,
-      this.axesTicksDimensions,
-      this.axesSpecs,
-    );
-    this.chartDimensions = computedChartDims.chartDimensions;
-
-    this.chartTransform = computeChartTransform(this.chartDimensions, this.chartRotation);
-    this.brushExtent = computeBrushExtent(this.chartDimensions, this.chartRotation, this.chartTransform);
-
-    const seriesGeometries = computeSeriesGeometries(
-      this.seriesSpecs,
-      xDomain,
-      yDomain,
-      formattedDataSeries,
-      this.seriesColorMap,
-      this.chartTheme,
-      this.chartDimensions,
-      this.chartRotation,
-      this.axesSpecs,
-      this.enableHistogramMode.get(),
-    );
-
-    this.geometries = seriesGeometries.geometries;
-    this.xScale = seriesGeometries.scales.xScale;
-
-    const isSingleValueXScale = this.xScale.isSingleValue();
-    if (isSingleValueXScale && !isNoneTooltipType(this.tooltipType.get())) {
-      this.tooltipType.set(TooltipType.Follow);
-    }
-
-    this.yScales = seriesGeometries.scales.yScales;
-    this.geometriesIndex = seriesGeometries.geometriesIndex;
-    this.geometriesIndexKeys = [...this.geometriesIndex.keys()].sort(compareByValueAsc);
-
-    // compute visible ticks and their positions
-    const axisTicksPositions = getAxisTicksPositions(
-      computedChartDims,
-      this.chartTheme,
-      this.chartRotation,
-      this.axesSpecs,
-      this.axesTicksDimensions,
-      xDomain,
-      yDomain,
-      totalBarsInCluster,
-      this.enableHistogramMode.get(),
-      barsPadding,
-    );
-
-    this.axesPositions = axisTicksPositions.axisPositions;
-    this.axesTicks = axisTicksPositions.axisTicks;
-    this.axesVisibleTicks = axisTicksPositions.axisVisibleTicks;
-    this.axesGridLinesPositions = axisTicksPositions.axisGridLinesPositions;
-
-    // annotation computations
-    const updatedAnnotationDimensions = computeAnnotationDimensions(
-      this.annotationSpecs,
-      this.chartDimensions,
-      this.chartRotation,
-      this.yScales,
-      this.xScale,
-      this.axesSpecs,
-      this.totalBarsInCluster,
-      this.enableHistogramMode.get(),
-    );
-
-    this.annotationDimensions.replace(updatedAnnotationDimensions);
-
-    this.canDataBeAnimated = isChartAnimatable(seriesGeometries.geometriesCounts, this.animateData);
-    // temporary disabled until
-    // https://github.com/elastic/elastic-charts/issues/89 and https://github.com/elastic/elastic-charts/issues/41
-    this.canDataBeAnimated = false;
-    this.chartInitialized.set(true);
-    // this.setCursorPosition(100, 100);
-  }
-}
diff --git a/src/chart_types/xy_chart/tooltip/tooltip.test.ts b/src/chart_types/xy_chart/tooltip/tooltip.test.ts
index e648255312..dd79b82f80 100644
--- a/src/chart_types/xy_chart/tooltip/tooltip.test.ts
+++ b/src/chart_types/xy_chart/tooltip/tooltip.test.ts
@@ -1,16 +1,18 @@
-import { getAxisId, getGroupId, getSpecId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
-import { BarGeometry } from '../rendering/rendering';
-import { AxisSpec, BarSeriesSpec, Position } from '../utils/specs';
+import { AxisSpec, BarSeriesSpec, Position, SpecTypes, SeriesTypes } from '../utils/specs';
 import { formatTooltip } from './tooltip';
+import { BarGeometry } from '../../../utils/geometry';
+import { ChartTypes } from '../..';
 
 describe('Tooltip formatting', () => {
-  const SPEC_ID_1 = getSpecId('bar_1');
-  const SPEC_GROUP_ID_1 = getGroupId('bar_group_1');
+  const SPEC_ID_1 = 'bar_1';
+  const SPEC_GROUP_ID_1 = 'bar_group_1';
   const SPEC_1: BarSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: SPEC_ID_1,
     groupId: SPEC_GROUP_ID_1,
-    seriesType: 'bar',
+    seriesType: SeriesTypes.Bar,
     data: [],
     xAccessor: 0,
     yAccessors: [1],
@@ -23,7 +25,9 @@ describe('Tooltip formatting', () => {
     y0Accessors: [1],
   };
   const YAXIS_SPEC: AxisSpec = {
-    id: getAxisId('axis_1'),
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Axis,
+    id: 'axis_1',
     groupId: SPEC_GROUP_ID_1,
     hide: false,
     position: Position.Left,
diff --git a/src/chart_types/xy_chart/tooltip/tooltip.ts b/src/chart_types/xy_chart/tooltip/tooltip.ts
index 607a51ecd2..45e2b0e32d 100644
--- a/src/chart_types/xy_chart/tooltip/tooltip.ts
+++ b/src/chart_types/xy_chart/tooltip/tooltip.ts
@@ -1,19 +1,14 @@
-import { TooltipValue, isFollowTooltipType, TooltipType, TooltipValueFormatter } from '../utils/interactions';
-import { IndexedGeometry, isPointOnGeometry, AccessorType } from '../rendering/rendering';
+import { TooltipValue } from '../utils/interactions';
 import { getColorValuesAsString } from '../utils/series';
 import {
   AxisSpec,
   BasicSeriesSpec,
-  Rotation,
-  isAreaSeriesSpec,
   isBandedSpec,
+  isAreaSeriesSpec,
   isBarSeriesSpec,
   TickFormatterOptions,
 } from '../utils/specs';
-import { SpecId, AxisId, GroupId } from '../../../utils/ids';
-import { getAxesSpecForSpecId } from '../store/utils';
-import { Scale } from '../../../utils/scales/scales';
-import { Point } from '../store/chart_state';
+import { IndexedGeometry, AccessorType } from '../../../utils/geometry';
 import { getAccessorFormatLabel } from '../../../utils/accessor';
 
 export interface TooltipLegendValue {
@@ -85,90 +80,6 @@ export function formatTooltip(
   };
 }
 
-export function emptyFormatter<T>(value: T): T {
+function emptyFormatter<T>(value: T): T {
   return value;
 }
-
-export function getTooltipAndHighlightFromXValue(
-  axisCursorPosition: Point,
-  seriesSpecs: Map<SpecId, BasicSeriesSpec>,
-  axesSpecs: Map<AxisId, AxisSpec>,
-  geometriesIndex: Map<any, IndexedGeometry[]>,
-  xValue: {
-    value: any;
-    withinBandwidth: boolean;
-  },
-  isActiveChart: boolean,
-  tooltipType: TooltipType,
-  chartRotation: Rotation,
-  yScales?: Map<GroupId, Scale>,
-  tooltipHeaderFormatter?: TooltipValueFormatter,
-):
-  | {
-      tooltipData: TooltipValue[];
-      highlightedGeometries: IndexedGeometry[];
-    }
-  | undefined {
-  // get the elements on at this cursor position
-  const elements = geometriesIndex.get(xValue.value);
-
-  // if no element, hide everything
-  if (!elements || elements.length === 0) {
-    return;
-  }
-
-  // build the tooltip value list
-  let xValueInfo: TooltipValue | null = null;
-  const highlightedGeometries: IndexedGeometry[] = [];
-  const tooltipData = elements
-    .filter(({ value: { y } }) => y !== null)
-    .reduce<TooltipValue[]>((acc, indexedGeometry) => {
-      const {
-        geometryId: { specId },
-      } = indexedGeometry;
-      const spec = seriesSpecs.get(specId);
-
-      // safe guard check
-      if (!spec) {
-        return acc;
-      }
-      const { xAxis, yAxis } = getAxesSpecForSpecId(axesSpecs, spec.groupId);
-
-      // yScales is ensured by the enclosing if
-      const yScale = yScales!.get(spec.groupId);
-      if (!yScale) {
-        return acc;
-      }
-
-      // check if the pointer is on the geometry
-      let isHighlighted = false;
-      if (isActiveChart && isPointOnGeometry(axisCursorPosition.x, axisCursorPosition.y, indexedGeometry)) {
-        isHighlighted = true;
-        highlightedGeometries.push(indexedGeometry);
-      }
-
-      // if it's a follow tooltip, and no element is highlighted
-      // not add that element into the tooltip list
-      if (!isHighlighted && isFollowTooltipType(tooltipType)) {
-        return acc;
-      }
-      // format the tooltip values
-      const yAxisFormatSpec = [0, 180].includes(chartRotation) ? yAxis : xAxis;
-      const formattedTooltip = formatTooltip(indexedGeometry, spec, false, isHighlighted, yAxisFormatSpec);
-      // format only one time the x value
-      if (!xValueInfo) {
-        // if we have a tooltipHeaderFormatter, then don't pass in the xAxis as the user will define a formatter
-        const xAxisFormatSpec = [0, 180].includes(chartRotation) ? xAxis : yAxis;
-        const formatterAxis = tooltipHeaderFormatter ? undefined : xAxisFormatSpec;
-        xValueInfo = formatTooltip(indexedGeometry, spec, true, false, formatterAxis);
-        return [xValueInfo, ...acc, formattedTooltip];
-      }
-
-      return [...acc, formattedTooltip];
-    }, []);
-
-  return {
-    tooltipData,
-    highlightedGeometries,
-  };
-}
diff --git a/src/chart_types/xy_chart/utils/axis_utils.test.ts b/src/chart_types/xy_chart/utils/axis_utils.test.ts
index b2b57f2474..daed9569fc 100644
--- a/src/chart_types/xy_chart/utils/axis_utils.test.ts
+++ b/src/chart_types/xy_chart/utils/axis_utils.test.ts
@@ -1,8 +1,8 @@
 import { XDomain } from '../domains/x_domain';
 import { YDomain } from '../domains/y_domain';
-import { AxisSpec, DomainRange, Position, AxisStyle } from './specs';
+import { AxisSpec, DomainRange, Position, AxisStyle, SpecTypes } from './specs';
 import { LIGHT_THEME } from '../../../utils/themes/light_theme';
-import { AxisId, getAxisId, getGroupId, GroupId } from '../../../utils/ids';
+import { AxisId, GroupId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
 import {
   AxisTick,
@@ -28,13 +28,14 @@ import {
   isVerticalAxis,
   isYDomain,
   getAxisTickLabelPadding,
-  mergeYCustomDomainsByGroupId,
   isVerticalGrid,
   isHorizontalGrid,
 } from './axis_utils';
 import { CanvasTextBBoxCalculator } from '../../../utils/bbox/canvas_text_bbox_calculator';
 import { SvgTextBBoxCalculator } from '../../../utils/bbox/svg_text_bbox_calculator';
 import { niceTimeFormatter } from '../../../utils/data/formatters';
+import { mergeYCustomDomainsByGroupId } from '../state/selectors/merge_y_custom_domains';
+import { ChartTypes } from '../..';
 
 describe('Axis computational utils', () => {
   const mockedRect = {
@@ -74,8 +75,10 @@ describe('Axis computational utils', () => {
     maxLabelTextHeight: 10,
   };
   const verticalAxisSpec: AxisSpec = {
-    id: getAxisId('axis_1'),
-    groupId: getGroupId('group_1'),
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Axis,
+    id: 'axis_1',
+    groupId: 'group_1',
     hide: false,
     showOverlappingTicks: false,
     showOverlappingLabels: false,
@@ -90,8 +93,10 @@ describe('Axis computational utils', () => {
   };
 
   const horizontalAxisSpec: AxisSpec = {
-    id: getAxisId('axis_2'),
-    groupId: getGroupId('group_1'),
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Axis,
+    id: 'axis_2',
+    groupId: 'group_1',
     hide: false,
     showOverlappingTicks: false,
     showOverlappingLabels: false,
@@ -105,8 +110,10 @@ describe('Axis computational utils', () => {
   };
 
   const verticalAxisSpecWTitle: AxisSpec = {
-    id: getAxisId('axis_1'),
-    groupId: getGroupId('group_1'),
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Axis,
+    id: 'axis_1',
+    groupId: 'group_1',
     title: 'v axis',
     hide: false,
     showOverlappingTicks: false,
@@ -121,8 +128,10 @@ describe('Axis computational utils', () => {
     integersOnly: false,
   };
   const xAxisWithTime: AxisSpec = {
-    id: getAxisId('axis_1'),
-    groupId: getGroupId('group_1'),
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Axis,
+    id: 'axis_1',
+    groupId: 'group_1',
     title: 'v axis',
     hide: false,
     showOverlappingTicks: false,
@@ -136,8 +145,8 @@ describe('Axis computational utils', () => {
   };
 
   // const horizontalAxisSpecWTitle: AxisSpec = {
-  //   id: getAxisId('axis_2'),
-  //   groupId: getGroupId('group_1'),
+  //   id: ('axis_2'),
+  //   groupId: ('group_1'),
   //   title: 'h axis',
   //   hide: false,
   //   showOverlappingTicks: false,
@@ -160,7 +169,7 @@ describe('Axis computational utils', () => {
 
   const yDomain: YDomain = {
     scaleType: ScaleType.Linear,
-    groupId: getGroupId('group_1'),
+    groupId: 'group_1',
     type: 'yDomain',
     domain: [0, 1],
     isBandScale: false,
@@ -177,7 +186,7 @@ describe('Axis computational utils', () => {
       computeAxisTicksDimensions(ungroupedAxisSpec, xDomain, [yDomain], 1, bboxCalculator, 0, axes);
     };
 
-    const ungroupedAxisSpec = { ...verticalAxisSpec, groupId: getGroupId('foo') };
+    const ungroupedAxisSpec = { ...verticalAxisSpec, groupId: 'foo' };
     expect(computeScalelessSpec).toThrowError('Cannot compute scale for axis spec axis_1');
 
     bboxCalculator.destroy();
@@ -263,7 +272,7 @@ describe('Axis computational utils', () => {
     expect(yScale!.range).toEqual([100, 0]);
     expect(yScale!.ticks()).toEqual([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]);
 
-    const ungroupedAxisSpec = { ...verticalAxisSpec, groupId: getGroupId('foo') };
+    const ungroupedAxisSpec = { ...verticalAxisSpec, groupId: 'foo' };
     const nullYScale = getScaleForAxisSpec(ungroupedAxisSpec, xDomain, [yDomain], 0, 0, 100, 0);
     expect(nullYScale).toBe(null);
 
@@ -843,8 +852,7 @@ describe('Axis computational utils', () => {
     // validate assumptions for test
     expect(verticalAxisSpec.id).toEqual(verticalAxisSpecWTitle.id);
 
-    const axisSpecs = new Map();
-    axisSpecs.set(verticalAxisSpecWTitle.id, verticalAxisSpecWTitle);
+    const axisSpecs = [verticalAxisSpecWTitle];
 
     const axisDims = new Map();
     axisDims.set(verticalAxisSpecWTitle.id, axis1Dims);
@@ -871,7 +879,7 @@ describe('Axis computational utils', () => {
       height: 100,
     });
 
-    axisSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+    axisSpecs[0] = verticalAxisSpec;
 
     axisDims.set(verticalAxisSpec.id, axis1Dims);
 
@@ -1044,11 +1052,11 @@ describe('Axis computational utils', () => {
 
   test('should not compute axis ticks positions if missaligned specs', () => {
     const chartRotation = 0;
-    const axisSpecs = new Map<AxisId, AxisSpec>();
-    axisSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+
+    const axisSpecs = [verticalAxisSpec];
 
     const axisDims = new Map<AxisId, AxisTicksDimensions>();
-    axisDims.set(getAxisId('not_a_mapped_one'), axis1Dims);
+    axisDims.set('not_a_mapped_one', axis1Dims);
 
     const axisTicksPosition = getAxisTicksPositions(
       {
@@ -1072,8 +1080,8 @@ describe('Axis computational utils', () => {
 
   test('should compute axis ticks positions', () => {
     const chartRotation = 0;
-    const axisSpecs = new Map<AxisId, AxisSpec>();
-    axisSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+
+    const axisSpecs = [verticalAxisSpec];
 
     const axisDims = new Map<AxisId, AxisTicksDimensions>();
     axisDims.set(verticalAxisSpec.id, axis1Dims);
@@ -1133,9 +1141,8 @@ describe('Axis computational utils', () => {
     const verticalAxisWithTopLegendPosition = axisTicksPositionWithTopLegend.axisPositions.get(verticalAxisSpec.id);
     expect(verticalAxisWithTopLegendPosition).toEqual(expectedPositionWithTopLegend);
 
-    const ungroupedAxisSpec = { ...verticalAxisSpec, groupId: getGroupId('foo') };
-    const invalidSpecs = new Map<AxisId, AxisSpec>();
-    invalidSpecs.set(verticalAxisSpec.id, ungroupedAxisSpec);
+    const ungroupedAxisSpec = { ...verticalAxisSpec, groupId: 'foo' };
+    const invalidSpecs = [ungroupedAxisSpec];
     const computeScalelessSpec = () => {
       getAxisTicksPositions(
         {
@@ -1203,7 +1210,7 @@ describe('Axis computational utils', () => {
   });
 
   test('should merge axis domains by group id', () => {
-    const groupId = getGroupId('group_1');
+    const groupId = 'group_1';
     const domainRange1 = {
       min: 2,
       max: 9,
@@ -1211,8 +1218,7 @@ describe('Axis computational utils', () => {
 
     verticalAxisSpec.domain = domainRange1;
 
-    const axesSpecs = new Map<AxisId, AxisSpec>();
-    axesSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+    const axesSpecs = [verticalAxisSpec];
 
     // Base case
     const expectedSimpleMap = new Map<GroupId, DomainRange>();
@@ -1227,10 +1233,10 @@ describe('Axis computational utils', () => {
       max: 7,
     };
 
-    const altVerticalAxisSpec = { ...verticalAxisSpec, id: getAxisId('axis2') };
+    const altVerticalAxisSpec = { ...verticalAxisSpec, id: 'axis2' };
 
     altVerticalAxisSpec.domain = domainRange2;
-    axesSpecs.set(altVerticalAxisSpec.id, altVerticalAxisSpec);
+    axesSpecs.push(altVerticalAxisSpec);
 
     const expectedMergedMap = new Map<GroupId, DomainRange>();
     expectedMergedMap.set(groupId, { min: 0, max: 9 });
@@ -1243,7 +1249,7 @@ describe('Axis computational utils', () => {
       min: 5,
       max: 15,
     };
-    axesSpecs.set(horizontalAxisSpec.id, horizontalAxisSpec);
+    axesSpecs.push(horizontalAxisSpec);
 
     const attemptToMerge = () => {
       mergeYCustomDomainsByGroupId(axesSpecs, 0);
@@ -1253,7 +1259,7 @@ describe('Axis computational utils', () => {
   });
 
   test('should merge axis domains by group id: partial upper bounded prevDomain with complete domain', () => {
-    const groupId = getGroupId('group_1');
+    const groupId = 'group_1';
     const domainRange1 = {
       max: 9,
     };
@@ -1265,13 +1271,10 @@ describe('Axis computational utils', () => {
 
     verticalAxisSpec.domain = domainRange1;
 
-    const axesSpecs = new Map<AxisId, AxisSpec>();
-    axesSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
-
-    const axis2 = { ...verticalAxisSpec, id: getAxisId('axis2') };
+    const axis2 = { ...verticalAxisSpec, id: 'axis2' };
 
     axis2.domain = domainRange2;
-    axesSpecs.set(axis2.id, axis2);
+    const axesSpecs = [verticalAxisSpec, axis2];
 
     const expectedMergedMap = new Map<GroupId, DomainRange>();
     expectedMergedMap.set(groupId, { min: 0, max: 9 });
@@ -1281,7 +1284,7 @@ describe('Axis computational utils', () => {
   });
 
   test('should merge axis domains by group id: partial lower bounded prevDomain with complete domain', () => {
-    const groupId = getGroupId('group_1');
+    const groupId = 'group_1';
     const domainRange1 = {
       min: -1,
     };
@@ -1292,14 +1295,11 @@ describe('Axis computational utils', () => {
     };
 
     verticalAxisSpec.domain = domainRange1;
+    const axis2 = { ...verticalAxisSpec, id: 'axis2' };
 
-    const axesSpecs = new Map<AxisId, AxisSpec>();
-    axesSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
-
-    const axis2 = { ...verticalAxisSpec, id: getAxisId('axis2') };
+    const axesSpecs = [verticalAxisSpec, axis2];
 
     axis2.domain = domainRange2;
-    axesSpecs.set(axis2.id, axis2);
 
     const expectedMergedMap = new Map<GroupId, DomainRange>();
     expectedMergedMap.set(groupId, { min: -1, max: 7 });
@@ -1309,7 +1309,7 @@ describe('Axis computational utils', () => {
   });
 
   test('should merge axis domains by group id: partial upper bounded prevDomain with lower bounded domain', () => {
-    const groupId = getGroupId('group_1');
+    const groupId = 'group_1';
     const domainRange1 = {
       max: 9,
     };
@@ -1324,18 +1324,18 @@ describe('Axis computational utils', () => {
 
     verticalAxisSpec.domain = domainRange1;
 
-    const axesSpecs = new Map<AxisId, AxisSpec>();
-    axesSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+    const axesSpecs = [];
+    axesSpecs.push(verticalAxisSpec);
 
-    const axis2 = { ...verticalAxisSpec, id: getAxisId('axis2') };
+    const axis2 = { ...verticalAxisSpec, id: 'axis2' };
 
     axis2.domain = domainRange2;
-    axesSpecs.set(axis2.id, axis2);
+    axesSpecs.push(axis2);
 
-    const axis3 = { ...verticalAxisSpec, id: getAxisId('axis3') };
+    const axis3 = { ...verticalAxisSpec, id: 'axis3' };
 
     axis3.domain = domainRange3;
-    axesSpecs.set(axis3.id, axis3);
+    axesSpecs.push(axis3);
 
     const expectedMergedMap = new Map<GroupId, DomainRange>();
     expectedMergedMap.set(groupId, { min: -1, max: 9 });
@@ -1345,7 +1345,7 @@ describe('Axis computational utils', () => {
   });
 
   test('should merge axis domains by group id: partial lower bounded prevDomain with upper bounded domain', () => {
-    const groupId = getGroupId('group_1');
+    const groupId = 'group_1';
     const domainRange1 = {
       min: 2,
     };
@@ -1360,18 +1360,18 @@ describe('Axis computational utils', () => {
 
     verticalAxisSpec.domain = domainRange1;
 
-    const axesSpecs = new Map<AxisId, AxisSpec>();
-    axesSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+    const axesSpecs = [];
+    axesSpecs.push(verticalAxisSpec);
 
-    const axis2 = { ...verticalAxisSpec, id: getAxisId('axis2') };
+    const axis2 = { ...verticalAxisSpec, id: 'axis2' };
 
     axis2.domain = domainRange2;
-    axesSpecs.set(axis2.id, axis2);
+    axesSpecs.push(axis2);
 
-    const axis3 = { ...verticalAxisSpec, id: getAxisId('axis3') };
+    const axis3 = { ...verticalAxisSpec, id: 'axis3' };
 
     axis3.domain = domainRange3;
-    axesSpecs.set(axis3.id, axis3);
+    axesSpecs.push(axis3);
 
     const expectedMergedMap = new Map<GroupId, DomainRange>();
     expectedMergedMap.set(groupId, { min: 2, max: 9 });
@@ -1388,8 +1388,7 @@ describe('Axis computational utils', () => {
 
     verticalAxisSpec.domain = domainRange1;
 
-    const axesSpecs = new Map<AxisId, AxisSpec>();
-    axesSpecs.set(verticalAxisSpec.id, verticalAxisSpec);
+    const axesSpecs = [verticalAxisSpec];
 
     const attemptToMerge = () => {
       mergeYCustomDomainsByGroupId(axesSpecs, 0);
diff --git a/src/chart_types/xy_chart/utils/axis_utils.ts b/src/chart_types/xy_chart/utils/axis_utils.ts
index eabff98bf2..37a1f78abf 100644
--- a/src/chart_types/xy_chart/utils/axis_utils.ts
+++ b/src/chart_types/xy_chart/utils/axis_utils.ts
@@ -15,9 +15,10 @@ import {
 } from './specs';
 import { AxisConfig, Theme } from '../../../utils/themes/theme';
 import { Dimensions, Margins } from '../../../utils/dimensions';
-import { AxisId, GroupId } from '../../../utils/ids';
+import { AxisId } from '../../../utils/ids';
 import { Scale } from '../../../utils/scales/scales';
 import { BBox, BBoxCalculator } from '../../../utils/bbox/bbox_calculator';
+import { getSpecsById } from '../state/utils';
 
 export type AxisLinePosition = [number, number, number, number];
 
@@ -184,10 +185,7 @@ export const getMaxBboxDimensions = (
   maxLabelTextWidth: number;
   maxLabelTextHeight: number;
 } => {
-  const bbox = bboxCalculator.compute(tickLabel, tickLabelPadding, fontSize, fontFamily).getOrElse({
-    width: 0,
-    height: 0,
-  });
+  const bbox = bboxCalculator.compute(tickLabel, tickLabelPadding, fontSize, fontFamily);
 
   const rotatedBbox = computeRotatedLabelDimensions(bbox, tickLabelRotation);
 
@@ -374,7 +372,7 @@ export function getMinMaxRange(
   }
 }
 
-export function getBottomTopAxisMinMaxRange(chartRotation: Rotation, width: number) {
+function getBottomTopAxisMinMaxRange(chartRotation: Rotation, width: number) {
   switch (chartRotation) {
     case 0:
       // dealing with x domain
@@ -390,7 +388,7 @@ export function getBottomTopAxisMinMaxRange(chartRotation: Rotation, width: numb
       return { minRange: width, maxRange: 0 };
   }
 }
-export function getLeftAxisMinMaxRange(chartRotation: Rotation, height: number) {
+function getLeftAxisMinMaxRange(chartRotation: Rotation, height: number) {
   switch (chartRotation) {
     case 0:
       // dealing with y domain
@@ -430,7 +428,6 @@ export function getAvailableTicks(
       }
     }
   }
-
   const shift = totalBarsInCluster > 0 ? totalBarsInCluster : 1;
 
   const band = scale.bandwidth / (1 - scale.barsPadding);
@@ -569,14 +566,19 @@ export function getAxisTicksPositions(
   },
   chartTheme: Theme,
   chartRotation: Rotation,
-  axisSpecs: Map<AxisId, AxisSpec>,
+  axisSpecs: AxisSpec[],
   axisDimensions: Map<AxisId, AxisTicksDimensions>,
   xDomain: XDomain,
   yDomain: YDomain[],
   totalGroupsCount: number,
   enableHistogramMode: boolean,
   barsPadding?: number,
-) {
+): {
+  axisPositions: Map<AxisId, Dimensions>;
+  axisTicks: Map<AxisId, AxisTick[]>;
+  axisVisibleTicks: Map<AxisId, AxisTick[]>;
+  axisGridLinesPositions: Map<AxisId, AxisLinePosition[]>;
+} {
   const { chartPaddings, chartMargins } = chartTheme;
   const axisPositions: Map<AxisId, Dimensions> = new Map();
   const axisVisibleTicks: Map<AxisId, AxisTick[]> = new Map();
@@ -589,7 +591,7 @@ export function getAxisTicksPositions(
   let cumRightSum = chartPaddings.right;
 
   axisDimensions.forEach((axisDim, id) => {
-    const axisSpec = axisSpecs.get(id);
+    const axisSpec = getSpecsById<AxisSpec>(axisSpecs, id);
 
     // Consider refactoring this so this condition can be tested
     // Given some of the values that get passed around, maybe re-write as a reduce instead of forEach?
@@ -689,63 +691,31 @@ export function isBounded(domain: Partial<CompleteBoundedDomain>): domain is Dom
   return domain.max != null || domain.min != null;
 }
 
-export function mergeYCustomDomainsByGroupId(
-  axesSpecs: Map<AxisId, AxisSpec>,
-  chartRotation: Rotation,
-): Map<GroupId, DomainRange> {
-  const domainsByGroupId = new Map<GroupId, DomainRange>();
-
-  axesSpecs.forEach((spec: AxisSpec, id: AxisId) => {
-    const { groupId, domain } = spec;
-
-    if (!domain) {
-      return;
-    }
-
-    const isAxisYDomain = isYDomain(spec.position, chartRotation);
-
-    if (!isAxisYDomain) {
-      const errorMessage = `[Axis ${id}]: custom domain for xDomain should be defined in Settings`;
-      throw new Error(errorMessage);
-    }
-
-    if (isCompleteBound(domain) && domain.min > domain.max) {
-      const errorMessage = `[Axis ${id}]: custom domain is invalid, min is greater than max`;
-      throw new Error(errorMessage);
-    }
-
-    const prevGroupDomain = domainsByGroupId.get(groupId);
-
-    if (prevGroupDomain) {
-      const prevDomain = prevGroupDomain as DomainRange;
-
-      const prevMin = isLowerBound(prevDomain) ? prevDomain.min : undefined;
-      const prevMax = isUpperBound(prevDomain) ? prevDomain.max : undefined;
-
-      let max = prevMax;
-      let min = prevMin;
-
-      if (isCompleteBound(domain)) {
-        min = prevMin != null ? Math.min(domain.min, prevMin) : domain.min;
-        max = prevMax != null ? Math.max(domain.max, prevMax) : domain.max;
-      } else if (isLowerBound(domain)) {
-        min = prevMin != null ? Math.min(domain.min, prevMin) : domain.min;
-      } else if (isUpperBound(domain)) {
-        max = prevMax != null ? Math.max(domain.max, prevMax) : domain.max;
+export const isDuplicateAxis = (
+  { position, title }: AxisSpec,
+  { tickLabels }: AxisTicksDimensions,
+  tickMap: Map<AxisId, AxisTicksDimensions>,
+  specs: AxisSpec[],
+): boolean => {
+  const firstTickLabel = tickLabels[0];
+  const lastTickLabel = tickLabels.slice(-1)[0];
+
+  let hasDuplicate = false;
+  tickMap.forEach(({ tickLabels: axisTickLabels }, axisId) => {
+    if (
+      !hasDuplicate &&
+      axisTickLabels &&
+      tickLabels.length === axisTickLabels.length &&
+      firstTickLabel === axisTickLabels[0] &&
+      lastTickLabel === axisTickLabels.slice(-1)[0]
+    ) {
+      const spec = getSpecsById<AxisSpec>(specs, axisId);
+
+      if (spec && spec.position === position && title === spec.title) {
+        hasDuplicate = true;
       }
-
-      const mergedDomain = {
-        min,
-        max,
-      };
-
-      if (isBounded(mergedDomain)) {
-        domainsByGroupId.set(groupId, mergedDomain);
-      }
-    } else {
-      domainsByGroupId.set(groupId, domain);
     }
   });
 
-  return domainsByGroupId;
-}
+  return hasDuplicate;
+};
diff --git a/src/chart_types/xy_chart/utils/dimensions.test.ts b/src/chart_types/xy_chart/utils/dimensions.test.ts
index dbf7e330bb..88a3f061c7 100644
--- a/src/chart_types/xy_chart/utils/dimensions.test.ts
+++ b/src/chart_types/xy_chart/utils/dimensions.test.ts
@@ -1,10 +1,11 @@
 import { AxisTicksDimensions } from './axis_utils';
-import { AxisSpec, Position } from './specs';
+import { AxisSpec, Position, SpecTypes } from './specs';
 import { LIGHT_THEME } from '../../../utils/themes/light_theme';
 import { LegendStyle } from '../../../utils/themes/theme';
 import { computeChartDimensions } from './dimensions';
-import { AxisId, getAxisId, getGroupId } from '../../../utils/ids';
+import { AxisId } from '../../../utils/ids';
 import { Margins } from '../../../utils/dimensions';
+import { ChartTypes } from '../..';
 
 describe('Computed chart dimensions', () => {
   const parentDim = {
@@ -35,8 +36,10 @@ describe('Computed chart dimensions', () => {
     maxLabelTextHeight: 10,
   };
   const axisLeftSpec: AxisSpec = {
-    id: getAxisId('axis_1'),
-    groupId: getGroupId('group_1'),
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Axis,
+    id: 'axis_1',
+    groupId: 'group_1',
     hide: false,
     showOverlappingTicks: false,
     showOverlappingLabels: false,
@@ -66,7 +69,7 @@ describe('Computed chart dimensions', () => {
   chartTheme.axes.axisTitleStyle.padding = 10;
   test('should be equal to parent dimension with no axis minus margins', () => {
     const axisDims = new Map<AxisId, AxisTicksDimensions>();
-    const axisSpecs = new Map<AxisId, AxisSpec>();
+    const axisSpecs: AxisSpec[] = [];
     const { chartDimensions } = computeChartDimensions(parentDim, chartTheme, axisDims, axisSpecs);
     expect(chartDimensions.left + chartDimensions.width).toBeLessThanOrEqual(parentDim.width);
     expect(chartDimensions.top + chartDimensions.height).toBeLessThanOrEqual(parentDim.height);
@@ -76,9 +79,8 @@ describe('Computed chart dimensions', () => {
     // |margin|titleFontSize|titlePadding|maxLabelBboxWidth|tickPadding|tickSize|padding|
     // \10|10|10|10|10|10|10| = 70px from left
     const axisDims = new Map<AxisId, AxisTicksDimensions>();
-    const axisSpecs = new Map<AxisId, AxisSpec>();
-    axisDims.set(getAxisId('axis_1'), axis1Dims);
-    axisSpecs.set(getAxisId('axis_1'), axisLeftSpec);
+    const axisSpecs = [axisLeftSpec];
+    axisDims.set('axis_1', axis1Dims);
     const { chartDimensions } = computeChartDimensions(parentDim, chartTheme, axisDims, axisSpecs);
     expect(chartDimensions.left + chartDimensions.width).toBeLessThanOrEqual(parentDim.width);
     expect(chartDimensions.top + chartDimensions.height).toBeLessThanOrEqual(parentDim.height);
@@ -88,9 +90,8 @@ describe('Computed chart dimensions', () => {
     // |padding|tickSize|tickPadding|maxLabelBBoxWidth|titlePadding|titleFontSize\margin|
     // \10|10|10|10|10|10|10| = 70px from right
     const axisDims = new Map<AxisId, AxisTicksDimensions>();
-    const axisSpecs = new Map<AxisId, AxisSpec>();
-    axisDims.set(getAxisId('axis_1'), axis1Dims);
-    axisSpecs.set(getAxisId('axis_1'), { ...axisLeftSpec, position: Position.Right });
+    const axisSpecs = [{ ...axisLeftSpec, position: Position.Right }];
+    axisDims.set('axis_1', axis1Dims);
     const { chartDimensions } = computeChartDimensions(parentDim, chartTheme, axisDims, axisSpecs);
     expect(chartDimensions.left + chartDimensions.width).toBeLessThanOrEqual(parentDim.width);
     expect(chartDimensions.top + chartDimensions.height).toBeLessThanOrEqual(parentDim.height);
@@ -100,12 +101,13 @@ describe('Computed chart dimensions', () => {
     // |margin|titleFontSize|titlePadding|maxLabelBboxHeight|tickPadding|tickSize|padding|
     // \10|10|10|10|10|10|10| = 70px from top
     const axisDims = new Map<AxisId, AxisTicksDimensions>();
-    const axisSpecs = new Map<AxisId, AxisSpec>();
-    axisDims.set(getAxisId('axis_1'), axis1Dims);
-    axisSpecs.set(getAxisId('axis_1'), {
-      ...axisLeftSpec,
-      position: Position.Top,
-    });
+    const axisSpecs = [
+      {
+        ...axisLeftSpec,
+        position: Position.Top,
+      },
+    ];
+    axisDims.set('axis_1', axis1Dims);
     const { chartDimensions } = computeChartDimensions(parentDim, chartTheme, axisDims, axisSpecs);
     expect(chartDimensions.left + chartDimensions.width).toBeLessThanOrEqual(parentDim.width);
     expect(chartDimensions.top + chartDimensions.height).toBeLessThanOrEqual(parentDim.height);
@@ -115,12 +117,13 @@ describe('Computed chart dimensions', () => {
     // |margin|titleFontSize|titlePadding|maxLabelBboxHeight|tickPadding|tickSize|padding|
     // \10|10|10|10|10|10|10| = 70px from bottom
     const axisDims = new Map<AxisId, AxisTicksDimensions>();
-    const axisSpecs = new Map<AxisId, AxisSpec>();
-    axisDims.set(getAxisId('axis_1'), axis1Dims);
-    axisSpecs.set(getAxisId('axis_1'), {
-      ...axisLeftSpec,
-      position: Position.Bottom,
-    });
+    const axisSpecs = [
+      {
+        ...axisLeftSpec,
+        position: Position.Bottom,
+      },
+    ];
+    axisDims.set('axis_1', axis1Dims);
     const { chartDimensions } = computeChartDimensions(parentDim, chartTheme, axisDims, axisSpecs);
     expect(chartDimensions.left + chartDimensions.width).toBeLessThanOrEqual(parentDim.width);
     expect(chartDimensions.top + chartDimensions.height).toBeLessThanOrEqual(parentDim.height);
@@ -128,12 +131,13 @@ describe('Computed chart dimensions', () => {
   });
   test('should not add space for axis when no spec for axis dimensions or axis is hidden', () => {
     const axisDims = new Map<AxisId, AxisTicksDimensions>();
-    const axisSpecs = new Map<AxisId, AxisSpec>();
-    axisDims.set(getAxisId('foo'), axis1Dims);
-    axisSpecs.set(getAxisId('axis_1'), {
-      ...axisLeftSpec,
-      position: Position.Bottom,
-    });
+    const axisSpecs = [
+      {
+        ...axisLeftSpec,
+        position: Position.Bottom,
+      },
+    ];
+    axisDims.set('foo', axis1Dims);
     const chartDimensions = computeChartDimensions(parentDim, chartTheme, axisDims, axisSpecs);
 
     const expectedDims = {
@@ -150,8 +154,8 @@ describe('Computed chart dimensions', () => {
 
     const hiddenAxisDims = new Map<AxisId, AxisTicksDimensions>();
     const hiddenAxisSpecs = new Map<AxisId, AxisSpec>();
-    hiddenAxisDims.set(getAxisId('axis_1'), axis1Dims);
-    hiddenAxisSpecs.set(getAxisId('axis_1'), {
+    hiddenAxisDims.set('axis_1', axis1Dims);
+    hiddenAxisSpecs.set('axis_1', {
       ...axisLeftSpec,
       hide: true,
       position: Position.Bottom,
diff --git a/src/chart_types/xy_chart/utils/dimensions.ts b/src/chart_types/xy_chart/utils/dimensions.ts
index 30b9588595..5a868a5171 100644
--- a/src/chart_types/xy_chart/utils/dimensions.ts
+++ b/src/chart_types/xy_chart/utils/dimensions.ts
@@ -3,6 +3,7 @@ import { AxisSpec, Position } from './specs';
 import { Theme } from '../../../utils/themes/theme';
 import { AxisId } from '../../../utils/ids';
 import { Dimensions } from '../../../utils/dimensions';
+import { getSpecsById } from '../state/utils';
 
 /**
  * Compute the chart dimensions. It's computed removing from the parent dimensions
@@ -18,11 +19,22 @@ export function computeChartDimensions(
   parentDimensions: Dimensions,
   chartTheme: Theme,
   axisDimensions: Map<AxisId, AxisTicksDimensions>,
-  axisSpecs: Map<AxisId, AxisSpec>,
+  axisSpecs: AxisSpec[],
 ): {
   chartDimensions: Dimensions;
   leftMargin: number;
 } {
+  if (parentDimensions.width <= 0 || parentDimensions.height <= 0) {
+    return {
+      chartDimensions: {
+        width: 0,
+        height: 0,
+        left: 0,
+        top: 0,
+      },
+      leftMargin: 0,
+    };
+  }
   const { chartMargins, chartPaddings } = chartTheme;
   const { axisTitleStyle } = chartTheme.axes;
 
@@ -35,7 +47,7 @@ export function computeChartDimensions(
   let horizontalEdgeLabelOverflow = 0;
   let verticalEdgeLabelOverflow = 0;
   axisDimensions.forEach(({ maxLabelBboxWidth = 0, maxLabelBboxHeight = 0 }, id) => {
-    const axisSpec = axisSpecs.get(id);
+    const axisSpec = getSpecsById<AxisSpec>(axisSpecs, id);
     if (!axisSpec || axisSpec.hide) {
       return;
     }
diff --git a/src/chart_types/xy_chart/utils/interactions.test.ts b/src/chart_types/xy_chart/utils/interactions.test.ts
index cbcbb661b1..e8e323dbbb 100644
--- a/src/chart_types/xy_chart/utils/interactions.test.ts
+++ b/src/chart_types/xy_chart/utils/interactions.test.ts
@@ -1,15 +1,14 @@
-import { IndexedGeometry, PointGeometry } from '../rendering/rendering';
 import { Dimensions } from '../../../utils/dimensions';
-import { getSpecId } from '../../../utils/ids';
 import {
   areIndexedGeometryArraysEquals,
   areIndexedGeomsEquals,
-  getValidXPosition,
-  getValidYPosition,
+  getOrientedXPosition,
+  getOrientedYPosition,
   isCrosshairTooltipType,
   isFollowTooltipType,
   TooltipType,
 } from './interactions';
+import { IndexedGeometry, PointGeometry } from '../../../utils/geometry';
 
 const seriesStyle = {
   rect: {
@@ -32,7 +31,7 @@ const seriesStyle = {
 const ig1: IndexedGeometry = {
   color: 'red',
   geometryId: {
-    specId: getSpecId('ig1'),
+    specId: 'ig1',
     seriesKey: [0, 1, 2],
   },
   value: {
@@ -48,7 +47,7 @@ const ig1: IndexedGeometry = {
 };
 const ig2: IndexedGeometry = {
   geometryId: {
-    specId: getSpecId('ig1'),
+    specId: 'ig1',
     seriesKey: [0, 1, 2],
   },
   value: {
@@ -65,7 +64,7 @@ const ig2: IndexedGeometry = {
 };
 const ig3: IndexedGeometry = {
   geometryId: {
-    specId: getSpecId('ig1'),
+    specId: 'ig1',
     seriesKey: [123, 123, 123],
   },
   value: {
@@ -83,7 +82,7 @@ const ig3: IndexedGeometry = {
 };
 const ig4: IndexedGeometry = {
   geometryId: {
-    specId: getSpecId('ig4'),
+    specId: 'ig4',
     seriesKey: [123, 123, 123],
   },
   value: {
@@ -100,7 +99,7 @@ const ig4: IndexedGeometry = {
 };
 const ig5: IndexedGeometry = {
   geometryId: {
-    specId: getSpecId('ig5'),
+    specId: 'ig5',
     seriesKey: [123, 123, 123],
   },
   value: {
@@ -117,7 +116,7 @@ const ig5: IndexedGeometry = {
 };
 const ig6: PointGeometry = {
   geometryId: {
-    specId: getSpecId('ig5'),
+    specId: 'ig5',
     seriesKey: [123, 123, 123],
   },
   value: {
@@ -145,25 +144,25 @@ describe('Interaction utils', () => {
   test('limit x position with x already relative to chart', () => {
     const xPos = 30;
     const yPos = 50;
-    let validPosition = getValidXPosition(xPos, yPos, 0, chartDimensions);
+    let validPosition = getOrientedXPosition(xPos, yPos, 0, chartDimensions);
     expect(validPosition).toBe(xPos);
-    validPosition = getValidXPosition(xPos, yPos, 180, chartDimensions);
+    validPosition = getOrientedXPosition(xPos, yPos, 180, chartDimensions);
     expect(validPosition).toBe(chartDimensions.width - xPos);
-    validPosition = getValidXPosition(xPos, yPos, 90, chartDimensions);
+    validPosition = getOrientedXPosition(xPos, yPos, 90, chartDimensions);
     expect(validPosition).toBe(yPos);
-    validPosition = getValidXPosition(xPos, yPos, -90, chartDimensions);
+    validPosition = getOrientedXPosition(xPos, yPos, -90, chartDimensions);
     expect(validPosition).toBe(chartDimensions.height - yPos);
   });
   test('limit y position with x already relative to chart', () => {
     const yPos = 30;
     const xPos = 50;
-    let validPosition = getValidYPosition(xPos, yPos, 0, chartDimensions);
+    let validPosition = getOrientedYPosition(xPos, yPos, 0, chartDimensions);
     expect(validPosition).toBe(yPos);
-    validPosition = getValidYPosition(xPos, yPos, 180, chartDimensions);
+    validPosition = getOrientedYPosition(xPos, yPos, 180, chartDimensions);
     expect(validPosition).toBe(chartDimensions.height - yPos);
-    validPosition = getValidYPosition(xPos, yPos, 90, chartDimensions);
+    validPosition = getOrientedYPosition(xPos, yPos, 90, chartDimensions);
     expect(validPosition).toBe(chartDimensions.width - xPos);
-    validPosition = getValidYPosition(xPos, yPos, -90, chartDimensions);
+    validPosition = getOrientedYPosition(xPos, yPos, -90, chartDimensions);
     expect(validPosition).toBe(xPos);
   });
   test('checks tooltip type helpers', () => {
diff --git a/src/chart_types/xy_chart/utils/interactions.ts b/src/chart_types/xy_chart/utils/interactions.ts
index ec5ea633d8..39aac2294a 100644
--- a/src/chart_types/xy_chart/utils/interactions.ts
+++ b/src/chart_types/xy_chart/utils/interactions.ts
@@ -1,9 +1,8 @@
 import { $Values } from 'utility-types';
-
-import { BarGeometry, IndexedGeometry, isBarGeometry, isPointGeometry, PointGeometry } from '../rendering/rendering';
 import { Datum, Rotation } from './specs';
 import { Dimensions } from '../../../utils/dimensions';
 import { Accessor } from '../../../utils/accessor';
+import { BarGeometry, PointGeometry, IndexedGeometry, isPointGeometry, isBarGeometry } from '../../../utils/geometry';
 
 /** The type of tooltip to use */
 export const TooltipType = Object.freeze({
@@ -29,6 +28,12 @@ export interface TooltipValue {
   yAccessor: Accessor;
 }
 
+export interface TooltipProps {
+  type?: TooltipType;
+  snap?: boolean;
+  headerFormatter?: TooltipValueFormatter;
+}
+
 export type TooltipValueFormatter = (data: TooltipValue) => JSX.Element | string;
 
 export interface HighlightedElement {
@@ -48,7 +53,7 @@ export interface HighlightedElement {
  * @param chartRotation the chart rotation
  * @param chartDimension the chart dimension
  */
-export function getValidXPosition(xPos: number, yPos: number, chartRotation: Rotation, chartDimension: Dimensions) {
+export function getOrientedXPosition(xPos: number, yPos: number, chartRotation: Rotation, chartDimension: Dimensions) {
   switch (chartRotation) {
     case 0:
       return xPos;
@@ -60,7 +65,7 @@ export function getValidXPosition(xPos: number, yPos: number, chartRotation: Rot
       return chartDimension.height - yPos;
   }
 }
-export function getValidYPosition(xPos: number, yPos: number, chartRotation: Rotation, chartDimension: Dimensions) {
+export function getOrientedYPosition(xPos: number, yPos: number, chartRotation: Rotation, chartDimension: Dimensions) {
   switch (chartRotation) {
     case 0:
       return yPos;
@@ -79,9 +84,6 @@ export function isCrosshairTooltipType(type: TooltipType) {
 export function isFollowTooltipType(type: TooltipType) {
   return type === TooltipType.Follow;
 }
-export function isNoneTooltipType(type: TooltipType) {
-  return type === TooltipType.None;
-}
 
 export function areIndexedGeometryArraysEquals(arr1: IndexedGeometry[], arr2: IndexedGeometry[]) {
   if (arr1.length !== arr2.length) {
@@ -103,7 +105,7 @@ export function areIndexedGeomsEquals(ig1: IndexedGeometry, ig2: IndexedGeometry
   return false;
 }
 
-export function arePointsEqual(ig1: PointGeometry, ig2: PointGeometry) {
+function arePointsEqual(ig1: PointGeometry, ig2: PointGeometry) {
   return (
     ig1.geometryId.specId === ig2.geometryId.specId &&
     ig1.color === ig2.color &&
@@ -114,7 +116,7 @@ export function arePointsEqual(ig1: PointGeometry, ig2: PointGeometry) {
     ig1.radius === ig2.radius
   );
 }
-export function areBarEqual(ig1: BarGeometry, ig2: BarGeometry) {
+function areBarEqual(ig1: BarGeometry, ig2: BarGeometry) {
   return (
     ig1.geometryId.specId === ig2.geometryId.specId &&
     ig1.color === ig2.color &&
@@ -124,3 +126,11 @@ export function areBarEqual(ig1: BarGeometry, ig2: BarGeometry) {
     ig1.height === ig2.height
   );
 }
+
+export function isTooltipProps(config: TooltipType | TooltipProps): config is TooltipProps {
+  return typeof config === 'object';
+}
+
+export function isTooltipType(config: TooltipType | TooltipProps): config is TooltipType {
+  return typeof config === 'string';
+}
diff --git a/src/chart_types/xy_chart/utils/nonstacked_series_utils.test.ts b/src/chart_types/xy_chart/utils/nonstacked_series_utils.test.ts
index d45235bab8..aa05e56385 100644
--- a/src/chart_types/xy_chart/utils/nonstacked_series_utils.test.ts
+++ b/src/chart_types/xy_chart/utils/nonstacked_series_utils.test.ts
@@ -1,4 +1,3 @@
-import { getSpecId } from '../../../utils/ids';
 import { RawDataSeries } from './series';
 import { ScaleType } from '../../../utils/scales/scales';
 import { MockRawDataSeries, MockDataSeries } from '../../../mocks';
@@ -13,7 +12,7 @@ const EMPTY_DATA_SET: RawDataSeries[] = [
     data: [],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec1'),
+    specId: 'spec1',
   },
 ];
 const STANDARD_DATA_SET: RawDataSeries[] = [
@@ -26,7 +25,7 @@ const STANDARD_DATA_SET: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec1'),
+    specId: 'spec1',
   },
   {
     data: [
@@ -37,7 +36,7 @@ const STANDARD_DATA_SET: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec2'),
+    specId: 'spec2',
   },
   {
     data: [
@@ -48,7 +47,7 @@ const STANDARD_DATA_SET: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec3'),
+    specId: 'spec3',
   },
 ];
 const WITH_NULL_DATASET: RawDataSeries[] = [
@@ -61,7 +60,7 @@ const WITH_NULL_DATASET: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec1'),
+    specId: 'spec1',
   },
   {
     data: [
@@ -72,7 +71,7 @@ const WITH_NULL_DATASET: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec2'),
+    specId: 'spec2',
   },
   {
     data: [
@@ -83,7 +82,7 @@ const WITH_NULL_DATASET: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec3'),
+    specId: 'spec3',
   },
 ];
 const STANDARD_DATA_SET_WY0: RawDataSeries[] = [
@@ -97,7 +96,7 @@ const STANDARD_DATA_SET_WY0: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec1'),
+    specId: 'spec1',
   },
   {
     data: [
@@ -109,7 +108,7 @@ const STANDARD_DATA_SET_WY0: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec2'),
+    specId: 'spec2',
   },
   {
     data: [
@@ -121,7 +120,7 @@ const STANDARD_DATA_SET_WY0: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec3'),
+    specId: 'spec3',
   },
 ];
 const WITH_NULL_DATASET_WY0: RawDataSeries[] = [
@@ -135,7 +134,7 @@ const WITH_NULL_DATASET_WY0: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec1'),
+    specId: 'spec1',
   },
   {
     data: [
@@ -146,7 +145,7 @@ const WITH_NULL_DATASET_WY0: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec2'),
+    specId: 'spec2',
   },
   {
     data: [
@@ -158,18 +157,18 @@ const WITH_NULL_DATASET_WY0: RawDataSeries[] = [
     ],
     key: [],
     seriesColorKey: 'color-key',
-    specId: getSpecId('spec3'),
+    specId: 'spec3',
   },
 ];
 const DATA_SET_WITH_NULL_2: RawDataSeries[] = [
   {
-    specId: getSpecId('spec1'),
+    specId: 'spec1',
     key: ['a'],
     seriesColorKey: 'a',
     data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 4, y1: 4 }],
   },
   {
-    specId: getSpecId('spec1'),
+    specId: 'spec1',
     key: ['b'],
     seriesColorKey: 'b',
     data: [{ x: 1, y1: 21 }, { x: 3, y1: 23 }],
diff --git a/src/chart_types/xy_chart/utils/nonstacked_series_utils.ts b/src/chart_types/xy_chart/utils/nonstacked_series_utils.ts
index 6b30fa3004..2c3980c8e2 100644
--- a/src/chart_types/xy_chart/utils/nonstacked_series_utils.ts
+++ b/src/chart_types/xy_chart/utils/nonstacked_series_utils.ts
@@ -1,7 +1,8 @@
 import { DataSeries, DataSeriesDatum, RawDataSeries } from './series';
 import { fitFunction } from './fit_function';
-import { isAreaSeriesSpec, isLineSeriesSpec, SeriesSpecs } from './specs';
+import { isAreaSeriesSpec, isLineSeriesSpec, SeriesSpecs, BasicSeriesSpec } from './specs';
 import { ScaleType } from '../../../utils/scales/scales';
+import { getSpecsById } from '../state/utils';
 
 export const formatNonStackedDataSeriesValues = (
   dataseries: RawDataSeries[],
@@ -13,7 +14,7 @@ export const formatNonStackedDataSeriesValues = (
   const formattedValues: DataSeries[] = [];
   for (let i = 0; i < len; i++) {
     const formattedDataValue = formatNonStackedDataValues(dataseries[i], scaleToExtent);
-    const spec = seriesSpecs.get(formattedDataValue.specId);
+    const spec = getSpecsById<BasicSeriesSpec>(seriesSpecs, formattedDataValue.specId);
 
     if (
       spec !== null &&
diff --git a/src/chart_types/xy_chart/utils/scales.test.ts b/src/chart_types/xy_chart/utils/scales.test.ts
index d247a92c1b..576b7ac596 100644
--- a/src/chart_types/xy_chart/utils/scales.test.ts
+++ b/src/chart_types/xy_chart/utils/scales.test.ts
@@ -1,4 +1,3 @@
-import { getGroupId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
 import { XDomain } from '../domains/x_domain';
 import { computeXScale, countBarsInCluster } from './scales';
@@ -106,7 +105,7 @@ describe('Series scales', () => {
   test('count bars required on a cluster', () => {
     const stacked: FormattedDataSeries[] = [
       {
-        groupId: getGroupId('g1'),
+        groupId: 'g1',
         dataSeries: [],
         counts: {
           areaSeries: 10,
@@ -115,7 +114,7 @@ describe('Series scales', () => {
         },
       },
       {
-        groupId: getGroupId('g2'),
+        groupId: 'g2',
         dataSeries: [],
         counts: {
           areaSeries: 10,
@@ -124,7 +123,7 @@ describe('Series scales', () => {
         },
       },
       {
-        groupId: getGroupId('g3'),
+        groupId: 'g3',
         dataSeries: [],
         counts: {
           areaSeries: 10,
@@ -135,7 +134,7 @@ describe('Series scales', () => {
     ];
     const nonStacked: FormattedDataSeries[] = [
       {
-        groupId: getGroupId('g1'),
+        groupId: 'g1',
         dataSeries: [],
         counts: {
           areaSeries: 10,
@@ -144,7 +143,7 @@ describe('Series scales', () => {
         },
       },
       {
-        groupId: getGroupId('g2'),
+        groupId: 'g2',
         dataSeries: [],
         counts: {
           areaSeries: 10,
diff --git a/src/chart_types/xy_chart/utils/series.test.ts b/src/chart_types/xy_chart/utils/series.test.ts
index ba284c5540..1185c058ca 100644
--- a/src/chart_types/xy_chart/utils/series.test.ts
+++ b/src/chart_types/xy_chart/utils/series.test.ts
@@ -1,5 +1,4 @@
 import { ColorConfig } from '../../../utils/themes/theme';
-import { getGroupId, getSpecId, SpecId } from '../../../utils/ids';
 import { ScaleType } from '../../../utils/scales/scales';
 import {
   DataSeriesColorsValues,
@@ -10,9 +9,10 @@ import {
   RawDataSeries,
   splitSeries,
 } from './series';
-import { BasicSeriesSpec } from './specs';
+import { BasicSeriesSpec, LineSeriesSpec, SpecTypes, SeriesTypes } from './specs';
 import { formatStackedDataSeriesValues } from './stacked_series_utils';
 import * as TestDataset from '../../../utils/data_samples/test_dataset';
+import { ChartTypes } from '../..';
 
 describe('Series', () => {
   test('Can split dataset into 1Y0G series', () => {
@@ -22,7 +22,7 @@ describe('Series', () => {
         xAccessor: 'x',
         yAccessors: ['y'],
       },
-      getSpecId('spec1'),
+      'spec1',
     );
     expect(splittedSeries.rawDataSeries).toMatchSnapshot();
   });
@@ -34,7 +34,7 @@ describe('Series', () => {
         yAccessors: ['y'],
         splitSeriesAccessors: ['g'],
       },
-      getSpecId('spec1'),
+      'spec1',
     );
     expect(splittedSeries.rawDataSeries).toMatchSnapshot();
   });
@@ -46,7 +46,7 @@ describe('Series', () => {
         yAccessors: ['y'],
         splitSeriesAccessors: ['g1', 'g2'],
       },
-      getSpecId('spec1'),
+      'spec1',
     );
     expect(splittedSeries.rawDataSeries).toMatchSnapshot();
   });
@@ -57,7 +57,7 @@ describe('Series', () => {
         xAccessor: 'x',
         yAccessors: ['y1', 'y2'],
       },
-      getSpecId('spec1'),
+      'spec1',
     );
     expect(splittedSeries.rawDataSeries).toMatchSnapshot();
   });
@@ -69,7 +69,7 @@ describe('Series', () => {
         yAccessors: ['y1', 'y2'],
         splitSeriesAccessors: ['g'],
       },
-      getSpecId('spec1'),
+      'spec1',
     );
     expect(splittedSeries.rawDataSeries).toMatchSnapshot();
   });
@@ -81,20 +81,20 @@ describe('Series', () => {
         yAccessors: ['y1', 'y2'],
         splitSeriesAccessors: ['g1', 'g2'],
       },
-      getSpecId('spec1'),
+      'spec1',
     );
     expect(splittedSeries.rawDataSeries).toMatchSnapshot();
   });
   test('Can stack simple dataseries', () => {
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['a'],
         seriesColorKey: 'a',
         data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 4, y1: 4 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 1, y1: 21 }, { x: 3, y1: 23 }],
@@ -107,25 +107,25 @@ describe('Series', () => {
   test('Can stack multiple dataseries', () => {
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['a'],
         seriesColorKey: 'a',
         data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 3, y1: 3 }, { x: 4, y1: 4 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 3, y1: 3 }, { x: 4, y1: 4 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 3, y1: 3 }, { x: 4, y1: 4 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 3, y1: 3 }, { x: 4, y1: 4 }],
@@ -138,13 +138,13 @@ describe('Series', () => {
   test('Can stack unsorted dataseries', () => {
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['a'],
         seriesColorKey: 'a',
         data: [{ x: 1, y1: 1 }, { x: 4, y1: 4 }, { x: 2, y1: 2 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 3, y1: 23 }, { x: 1, y1: 21 }],
@@ -158,13 +158,13 @@ describe('Series', () => {
     const maxArrayItems = 1000;
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['a'],
         seriesColorKey: 'a',
         data: new Array(maxArrayItems).fill(0).map((d, i) => ({ x: i, y1: i })),
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: new Array(maxArrayItems).fill(0).map((d, i) => ({ x: i, y1: i })),
@@ -177,13 +177,13 @@ describe('Series', () => {
   test('Can stack simple dataseries with scale to extent', () => {
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['a'],
         seriesColorKey: 'a',
         data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 4, y1: 4 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 1, y1: 21 }, { x: 3, y1: 23 }],
@@ -198,25 +198,25 @@ describe('Series', () => {
   test('Can stack multiple dataseries with scale to extent', () => {
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['a'],
         seriesColorKey: 'a',
         data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 3, y1: 3 }, { x: 4, y1: 4 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 3, y1: 3 }, { x: 4, y1: 4 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 3, y1: 3 }, { x: 4, y1: 4 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 3, y1: 3 }, { x: 4, y1: 4 }],
@@ -231,13 +231,13 @@ describe('Series', () => {
   test('Can stack simple dataseries with y0', () => {
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['a'],
         seriesColorKey: 'a',
         data: [{ x: 1, y1: 3, y0: 1 }, { x: 2, y1: 3, y0: 2 }, { x: 4, y1: 4, y0: 3 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 1, y1: 2, y0: 1 }, { x: 2, y1: 3, y0: 1 }, { x: 3, y1: 23, y0: 4 }, { x: 4, y1: 4, y0: 1 }],
@@ -263,13 +263,13 @@ describe('Series', () => {
   test('Can stack simple dataseries with scale to extent with y0', () => {
     const dataSeries: RawDataSeries[] = [
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['a'],
         seriesColorKey: 'a',
         data: [{ x: 1, y1: 3, y0: 1 }, { x: 2, y1: 3, y0: 2 }, { x: 4, y1: 4, y0: 3 }],
       },
       {
-        specId: getSpecId('spec1'),
+        specId: 'spec1',
         key: ['b'],
         seriesColorKey: 'b',
         data: [{ x: 1, y1: 2, y0: 1 }, { x: 2, y1: 3, y0: 1 }, { x: 3, y1: 23, y0: 4 }, { x: 4, y1: 4, y0: 1 }],
@@ -292,11 +292,12 @@ describe('Series', () => {
   });
 
   test('should split an array of specs into data series', () => {
-    const seriesSpecs = new Map<SpecId, BasicSeriesSpec>();
-    const spec1: BasicSeriesSpec = {
-      id: getSpecId('spec1'),
-      groupId: getGroupId('group'),
-      seriesType: 'line',
+    const spec1: LineSeriesSpec = {
+      specType: SpecTypes.Series,
+      chartType: ChartTypes.XYAxis,
+      id: 'spec1',
+      groupId: 'group',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -306,9 +307,11 @@ describe('Series', () => {
       hideInLegend: false,
     };
     const spec2: BasicSeriesSpec = {
-      id: getSpecId('spec2'),
-      groupId: getGroupId('group2'),
-      seriesType: 'line',
+      specType: SpecTypes.Series,
+      chartType: ChartTypes.XYAxis,
+      id: 'spec2',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -318,18 +321,18 @@ describe('Series', () => {
       data: TestDataset.BARCHART_2Y0G,
       hideInLegend: false,
     };
-    seriesSpecs.set(spec1.id, spec1);
-    seriesSpecs.set(spec2.id, spec2);
-    const splittedDataSeries = getSplittedSeries(seriesSpecs);
-    expect(splittedDataSeries.splittedSeries.get(getSpecId('spec1'))).toMatchSnapshot();
-    expect(splittedDataSeries.splittedSeries.get(getSpecId('spec2'))).toMatchSnapshot();
+
+    const splittedDataSeries = getSplittedSeries([spec1, spec2]);
+    expect(splittedDataSeries.splittedSeries.get('spec1')).toMatchSnapshot();
+    expect(splittedDataSeries.splittedSeries.get('spec2')).toMatchSnapshot();
   });
   test('should compute data series for stacked specs', () => {
-    const seriesSpecs = new Map<SpecId, BasicSeriesSpec>();
     const spec1: BasicSeriesSpec = {
-      id: getSpecId('spec1'),
-      groupId: getGroupId('group'),
-      seriesType: 'line',
+      specType: SpecTypes.Series,
+      chartType: ChartTypes.XYAxis,
+      id: 'spec1',
+      groupId: 'group',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -339,9 +342,11 @@ describe('Series', () => {
       hideInLegend: false,
     };
     const spec2: BasicSeriesSpec = {
-      id: getSpecId('spec2'),
-      groupId: getGroupId('group2'),
-      seriesType: 'line',
+      specType: SpecTypes.Series,
+      chartType: ChartTypes.XYAxis,
+      id: 'spec2',
+      groupId: 'group2',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -352,23 +357,23 @@ describe('Series', () => {
       hideInLegend: false,
     };
     const xValues = new Set([0, 1, 2, 3]);
-    seriesSpecs.set(spec1.id, spec1);
-    seriesSpecs.set(spec2.id, spec2);
-    const splittedDataSeries = getSplittedSeries(seriesSpecs);
+    const splittedDataSeries = getSplittedSeries([spec1, spec2]);
     const stackedDataSeries = getFormattedDataseries(
       [spec1, spec2],
       splittedDataSeries.splittedSeries,
       xValues,
       ScaleType.Linear,
-      new Map(),
+      [],
     );
     expect(stackedDataSeries.stacked).toMatchSnapshot();
   });
   test('should get series color map', () => {
     const spec1: BasicSeriesSpec = {
-      id: getSpecId('spec1'),
-      groupId: getGroupId('group'),
-      seriesType: 'line',
+      specType: SpecTypes.Series,
+      chartType: ChartTypes.XYAxis,
+      id: 'spec1',
+      groupId: 'group',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -382,7 +387,7 @@ describe('Series', () => {
     specs.set(spec1.id, spec1);
 
     const dataSeriesValuesA: DataSeriesColorsValues = {
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
       colorValues: ['a', 'b', 'c'],
     };
 
@@ -410,13 +415,14 @@ describe('Series', () => {
     expect(customizedColorMap).toEqual(expectedCustomizedColorMap);
   });
   test('should only include deselectedDataSeries when splitting series if deselectedDataSeries is defined', () => {
-    const seriesSpecs = new Map<SpecId, BasicSeriesSpec>();
-    const specId = getSpecId('splitSpec');
+    const specId = 'splitSpec';
 
     const splitSpec: BasicSeriesSpec = {
+      specType: SpecTypes.Series,
+      chartType: ChartTypes.XYAxis,
       id: specId,
-      groupId: getGroupId('group'),
-      seriesType: 'line',
+      groupId: 'group',
+      seriesType: SeriesTypes.Line,
       yScaleType: ScaleType.Log,
       xScaleType: ScaleType.Linear,
       xAccessor: 'x',
@@ -427,12 +433,10 @@ describe('Series', () => {
       hideInLegend: false,
     };
 
-    seriesSpecs.set(splitSpec.id, splitSpec);
-
-    const allSeries = getSplittedSeries(seriesSpecs, null);
+    const allSeries = getSplittedSeries([splitSpec]);
     expect(allSeries.splittedSeries.get(specId)!.length).toBe(2);
 
-    const emptyDeselected = getSplittedSeries(seriesSpecs, []);
+    const emptyDeselected = getSplittedSeries([splitSpec]);
     expect(emptyDeselected.splittedSeries.get(specId)!.length).toBe(2);
 
     const deselectedDataSeries: DataSeriesColorsValues[] = [
@@ -441,14 +445,14 @@ describe('Series', () => {
         colorValues: ['y1'],
       },
     ];
-    const subsetSplit = getSplittedSeries(seriesSpecs, deselectedDataSeries);
+    const subsetSplit = getSplittedSeries([splitSpec], deselectedDataSeries);
     expect(subsetSplit.splittedSeries.get(specId)!.length).toBe(1);
   });
 
   test('should sort series color by series spec sort index', () => {
-    const spec1Id = getSpecId('spec1');
-    const spec2Id = getSpecId('spec2');
-    const spec3Id = getSpecId('spec3');
+    const spec1Id = 'spec1';
+    const spec2Id = 'spec2';
+    const spec3Id = 'spec3';
 
     const colorValuesMap = new Map();
     const dataSeriesValues1: DataSeriesColorsValues = {
diff --git a/src/chart_types/xy_chart/utils/series.ts b/src/chart_types/xy_chart/utils/series.ts
index 9a68fde443..379ac72883 100644
--- a/src/chart_types/xy_chart/utils/series.ts
+++ b/src/chart_types/xy_chart/utils/series.ts
@@ -4,10 +4,10 @@ import { GroupId, SpecId } from '../../../utils/ids';
 import { splitSpecsByGroupId, YBasicSeriesSpec } from '../domains/y_domain';
 import { formatNonStackedDataSeriesValues } from './nonstacked_series_utils';
 import { isEqualSeriesKey } from './series_utils';
-import { BasicSeriesSpec, Datum, SeriesAccessors } from './specs';
+import { BasicSeriesSpec, Datum, SeriesAccessors, SeriesSpecs, SeriesTypes } from './specs';
 import { formatStackedDataSeriesValues } from './stacked_series_utils';
-import { LastValues } from '../store/utils';
 import { ScaleType } from '../../../utils/scales/scales';
+import { LastValues } from '../state/utils';
 
 export interface FilledValues {
   /** the x value */
@@ -218,7 +218,7 @@ export function getFormattedDataseries(
   dataSeries: Map<SpecId, RawDataSeries[]>,
   xValues: Set<string | number>,
   xScaleType: ScaleType,
-  seriesSpecs: Map<SpecId, BasicSeriesSpec>,
+  seriesSpecs: SeriesSpecs,
 ): {
   stacked: FormattedDataSeries[];
   nonStacked: FormattedDataSeries[];
@@ -268,7 +268,7 @@ export function getFormattedDataseries(
   };
 }
 
-export function getRawDataSeries(
+function getRawDataSeries(
   seriesSpecs: YBasicSeriesSpec[],
   dataSeries: Map<SpecId, RawDataSeries[]>,
 ): {
@@ -288,13 +288,13 @@ export function getRawDataSeries(
     const { id, seriesType } = spec;
     const ds = dataSeries.get(id);
     switch (seriesType) {
-      case 'bar':
+      case SeriesTypes.Bar:
         counts.barSeries += ds ? ds.length : 0;
         break;
-      case 'line':
+      case SeriesTypes.Line:
         counts.lineSeries += ds ? ds.length : 0;
         break;
-      case 'area':
+      case SeriesTypes.Area:
         counts.areaSeries += ds ? ds.length : 0;
         break;
     }
@@ -314,8 +314,8 @@ export function getRawDataSeries(
  * @param deselectedDataSeries the array of deselected/hidden data series
  */
 export function getSplittedSeries(
-  seriesSpecs: Map<SpecId, BasicSeriesSpec>,
-  deselectedDataSeries?: DataSeriesColorsValues[] | null,
+  seriesSpecs: BasicSeriesSpec[],
+  deselectedDataSeries: DataSeriesColorsValues[] = [],
 ): {
   splittedSeries: Map<SpecId, RawDataSeries[]>;
   seriesColors: Map<string, DataSeriesColorsValues>;
@@ -325,17 +325,17 @@ export function getSplittedSeries(
   const seriesColors = new Map<string, DataSeriesColorsValues>();
   let xValues: Set<string | number> = new Set();
   let isOrdinalScale = false;
-  for (const [specId, spec] of seriesSpecs) {
+  for (const spec of seriesSpecs) {
     if (spec.xScaleType === ScaleType.Ordinal) {
       isOrdinalScale = true;
     }
-    const dataSeries = splitSeries(spec.data, spec, specId);
+    const dataSeries = splitSeries(spec.data, spec, spec.id);
     let currentRawDataSeries = dataSeries.rawDataSeries;
-    if (deselectedDataSeries) {
+    if (deselectedDataSeries.length > 0) {
       currentRawDataSeries = dataSeries.rawDataSeries.filter(
         (series): boolean => {
           const seriesValues = {
-            specId,
+            specId: spec.id,
             colorValues: series.key,
           };
 
@@ -344,13 +344,13 @@ export function getSplittedSeries(
       );
     }
 
-    splittedSeries.set(specId, currentRawDataSeries);
+    splittedSeries.set(spec.id, currentRawDataSeries);
 
     const banded = spec.y0Accessors && spec.y0Accessors.length > 0;
 
     dataSeries.colorsValues.forEach((colorValues, key) => {
       seriesColors.set(key, {
-        specId,
+        specId: spec.id,
         specSortIndex: spec.sortIndex,
         banded,
         colorValues,
@@ -372,7 +372,7 @@ export function getSplittedSeries(
   };
 }
 
-export function getSortIndex({ specSortIndex }: DataSeriesColorsValues, total: number): number {
+function getSortIndex({ specSortIndex }: DataSeriesColorsValues, total: number): number {
   return specSortIndex != null ? specSortIndex : total;
 }
 
diff --git a/src/chart_types/xy_chart/utils/series_utils.test.ts b/src/chart_types/xy_chart/utils/series_utils.test.ts
index 8244bfc906..6c17e3f11a 100644
--- a/src/chart_types/xy_chart/utils/series_utils.test.ts
+++ b/src/chart_types/xy_chart/utils/series_utils.test.ts
@@ -1,7 +1,6 @@
-import { getSpecId } from '../../../utils/ids';
-import { GeometryId } from '../rendering/rendering';
 import { DataSeriesColorsValues } from './series';
 import { belongsToDataSeries, isEqualSeriesKey } from './series_utils';
+import { GeometryId } from '../../../utils/geometry';
 
 describe('Series utility functions', () => {
   test('can compare series keys for identity', () => {
@@ -20,22 +19,22 @@ describe('Series utility functions', () => {
 
   test('can determine if a geometry id belongs to a data series', () => {
     const geometryIdA: GeometryId = {
-      specId: getSpecId('a'),
+      specId: 'a',
       seriesKey: ['a', 'b', 'c'],
     };
 
     const dataSeriesValuesA: DataSeriesColorsValues = {
-      specId: getSpecId('a'),
+      specId: 'a',
       colorValues: ['a', 'b', 'c'],
     };
 
     const dataSeriesValuesB: DataSeriesColorsValues = {
-      specId: getSpecId('b'),
+      specId: 'b',
       colorValues: ['a', 'b', 'c'],
     };
 
     const dataSeriesValuesC: DataSeriesColorsValues = {
-      specId: getSpecId('a'),
+      specId: 'a',
       colorValues: ['a', 'b', 'd'],
     };
 
diff --git a/src/chart_types/xy_chart/utils/series_utils.ts b/src/chart_types/xy_chart/utils/series_utils.ts
index 69dcc2d722..aa77102942 100644
--- a/src/chart_types/xy_chart/utils/series_utils.ts
+++ b/src/chart_types/xy_chart/utils/series_utils.ts
@@ -1,5 +1,5 @@
-import { GeometryId } from '../rendering/rendering';
 import { DataSeriesColorsValues } from './series';
+import { GeometryId } from '../../../utils/geometry';
 
 export function isEqualSeriesKey(a: any[], b: any[]): boolean {
   if (a.length !== b.length) {
diff --git a/src/chart_types/xy_chart/utils/specs.ts b/src/chart_types/xy_chart/utils/specs.ts
index 999539b653..a7c73e494c 100644
--- a/src/chart_types/xy_chart/utils/specs.ts
+++ b/src/chart_types/xy_chart/utils/specs.ts
@@ -1,3 +1,4 @@
+import { $Values } from 'utility-types';
 import {
   AreaSeriesStyle,
   GridLineConfig,
@@ -9,13 +10,14 @@ import {
 } from '../../../utils/themes/theme';
 import { Accessor, AccessorFormat } from '../../../utils/accessor';
 import { RecursivePartial } from '../../../utils/commons';
-import { AnnotationId, AxisId, GroupId, SpecId } from '../../../utils/ids';
+import { AxisId, GroupId } from '../../../utils/ids';
 import { ScaleContinuousType, ScaleType } from '../../../utils/scales/scales';
 import { CurveType } from '../../../utils/curves';
-import { DataSeriesColorsValues, RawDataSeriesDatum } from './series';
-import { GeometryId } from '../rendering/rendering';
+import { RawDataSeriesDatum, DataSeriesColorsValues } from './series';
 import { AnnotationTooltipFormatter } from '../annotations/annotation_utils';
-import { $Values } from 'utility-types';
+import { GeometryId } from '../../../utils/geometry';
+import { Spec } from '../../..';
+import { ChartTypes } from '../..';
 
 export type Datum = any;
 export type Rotation = 0 | 90 | -90 | 180;
@@ -23,6 +25,24 @@ export type Rendering = 'canvas' | 'svg';
 export type Color = string;
 export type BarStyleOverride = RecursivePartial<BarSeriesStyle> | Color | null;
 export type PointStyleOverride = RecursivePartial<PointStyle> | Color | null;
+
+export const SeriesTypes = Object.freeze({
+  Area: 'area' as 'area',
+  Bar: 'bar' as 'bar',
+  Line: 'line' as 'line',
+});
+
+export type SeriesTypes = $Values<typeof SeriesTypes>;
+
+export const SpecTypes = Object.freeze({
+  Series: 'series' as 'series',
+  Axis: 'axis' as 'axis',
+  Annotation: 'annotation' as 'annotation',
+  Settings: 'settings' as 'settings',
+});
+
+export type SpecTypes = $Values<typeof SpecTypes>;
+
 /**
  * Override for bar styles per datum
  *
@@ -169,21 +189,21 @@ export interface DisplayValueSpec {
   hideClippedValue?: boolean;
 }
 
-export interface SeriesSpec {
-  /** The ID of the spec, generated via getSpecId method */
-  id: SpecId;
+export interface SeriesSpec extends Spec {
+  specType: typeof SpecTypes.Series;
+  chartType: typeof ChartTypes.XYAxis;
   /** The name or label of the spec */
   name?: string;
   /** The ID of the spec group, generated via getGroupId method
    * @default __global__
    */
-  groupId: GroupId;
+  groupId: string;
   /** when using a different groupId this option will allow compute in the same domain of the global domain */
   useDefaultGroupDomain?: boolean;
   /** An array of data */
   data: Datum[];
   /** The type of series you are looking to render */
-  seriesType: 'bar' | 'line' | 'area';
+  seriesType: SeriesTypes;
   /** Custom colors for series */
   customSeriesColors?: CustomSeriesColorsMap;
   /** If the series should appear in the legend
@@ -264,7 +284,7 @@ export interface SeriesScales {
 
 export type BasicSeriesSpec = SeriesSpec & SeriesAccessors & SeriesScales;
 
-export type SeriesSpecs<S extends BasicSeriesSpec = BasicSeriesSpec> = Map<SpecId, S>;
+export type SeriesSpecs<S extends BasicSeriesSpec = BasicSeriesSpec> = Array<S>;
 
 /**
  * This spec describe the dataset configuration used to display a bar series.
@@ -272,7 +292,7 @@ export type SeriesSpecs<S extends BasicSeriesSpec = BasicSeriesSpec> = Map<SpecI
 export type BarSeriesSpec = BasicSeriesSpec &
   Postfixes & {
     /** @default bar */
-    seriesType: 'bar';
+    seriesType: typeof SeriesTypes.Bar;
     /** If true, will stack all BarSeries and align bars to ticks (instead of centered on ticks) */
     enableHistogramMode?: boolean;
     barSeriesStyle?: RecursivePartial<BarSeriesStyle>;
@@ -327,7 +347,7 @@ export type FitConfig = {
 export type LineSeriesSpec = BasicSeriesSpec &
   HistogramConfig & {
     /** @default line */
-    seriesType: 'line';
+    seriesType: typeof SeriesTypes.Line;
     curve?: CurveType;
     lineSeriesStyle?: RecursivePartial<LineSeriesStyle>;
     /**
@@ -347,7 +367,7 @@ export type AreaSeriesSpec = BasicSeriesSpec &
   HistogramConfig &
   Postfixes & {
     /** @default area */
-    seriesType: 'area';
+    seriesType: typeof SeriesTypes.Area;
     /** The type of interpolator to be used to interpolate values between points */
     curve?: CurveType;
     areaSeriesStyle?: RecursivePartial<AreaSeriesStyle>;
@@ -365,7 +385,7 @@ export type AreaSeriesSpec = BasicSeriesSpec &
     fit?: Exclude<Fit, 'explicit'> | FitConfig;
   };
 
-interface HistogramConfig {
+export interface HistogramConfig {
   /**  Determines how points in the series will align to bands in histogram mode
    * @default 'start'
    */
@@ -383,8 +403,10 @@ export type HistogramModeAlignment = 'start' | 'center' | 'end';
 /**
  * This spec describe the configuration for a chart axis.
  */
-export interface AxisSpec {
-  /** The ID of the spec, generated via getSpecId method */
+export interface AxisSpec extends Spec {
+  specType: typeof SpecTypes.Axis;
+  chartType: typeof ChartTypes.XYAxis;
+  /** The ID of the spec */
   id: AxisId;
   /** Style options for grid line */
   gridLineStyle?: GridLineConfig;
@@ -468,7 +490,7 @@ export interface LineAnnotationDatum {
 }
 
 export type LineAnnotationSpec = BaseAnnotationSpec & {
-  annotationType: 'line';
+  annotationType: typeof AnnotationTypes.Line;
   domainType: AnnotationDomainType;
   /** Data values defined with value, details, and header */
   dataValues: LineAnnotationDatum[];
@@ -507,7 +529,7 @@ export interface RectAnnotationDatum {
 }
 
 export type RectAnnotationSpec = BaseAnnotationSpec & {
-  annotationType: 'rectangle';
+  annotationType: typeof AnnotationTypes.Rectangle;
   /** Custom rendering function for tooltip */
   renderTooltip?: AnnotationTooltipFormatter;
   /** Data values defined with coordinates and details */
@@ -520,9 +542,9 @@ export type RectAnnotationSpec = BaseAnnotationSpec & {
   zIndex?: number;
 };
 
-export interface BaseAnnotationSpec {
-  /** The id of the annotation */
-  annotationId: AnnotationId;
+export interface BaseAnnotationSpec extends Spec {
+  chartType: ChartTypes;
+  specType: typeof SpecTypes.Annotation;
   /** Annotation type: line, rectangle, text */
   annotationType: AnnotationType;
   /** The ID of the axis group, generated via getGroupId method
@@ -556,15 +578,15 @@ export function isRectAnnotation(spec: AnnotationSpec): spec is RectAnnotationSp
 }
 
 export function isBarSeriesSpec(spec: BasicSeriesSpec): spec is BarSeriesSpec {
-  return spec.seriesType === 'bar';
+  return spec.seriesType === SeriesTypes.Bar;
 }
 
 export function isLineSeriesSpec(spec: BasicSeriesSpec): spec is LineSeriesSpec {
-  return spec.seriesType === 'line';
+  return spec.seriesType === SeriesTypes.Line;
 }
 
 export function isAreaSeriesSpec(spec: BasicSeriesSpec): spec is AreaSeriesSpec {
-  return spec.seriesType === 'area';
+  return spec.seriesType === SeriesTypes.Area;
 }
 
 export function isBandedSpec(y0Accessors: SeriesAccessors['y0Accessors']): boolean {
diff --git a/src/chart_types/xy_chart/utils/stacked_percent_series_utils.test.ts b/src/chart_types/xy_chart/utils/stacked_percent_series_utils.test.ts
index 348c42645d..0e1c6559ba 100644
--- a/src/chart_types/xy_chart/utils/stacked_percent_series_utils.test.ts
+++ b/src/chart_types/xy_chart/utils/stacked_percent_series_utils.test.ts
@@ -1,4 +1,3 @@
-import { getSpecId } from '../../../utils/ids';
 import { RawDataSeries } from './series';
 import { formatStackedDataSeriesValues } from './stacked_series_utils';
 import { ScaleType } from '../../../utils/scales/scales';
@@ -14,7 +13,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
     },
     {
       data: [
@@ -25,7 +24,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec2'),
+      specId: 'spec2',
     },
     {
       data: [
@@ -36,7 +35,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec3'),
+      specId: 'spec3',
     },
   ];
   const WITH_NULL_DATASET: RawDataSeries[] = [
@@ -49,7 +48,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
     },
     {
       data: [
@@ -60,7 +59,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec2'),
+      specId: 'spec2',
     },
     {
       data: [
@@ -71,7 +70,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec3'),
+      specId: 'spec3',
     },
   ];
   const STANDARD_DATA_SET_WY0: RawDataSeries[] = [
@@ -85,7 +84,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
     },
     {
       data: [
@@ -97,7 +96,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec2'),
+      specId: 'spec2',
     },
     {
       data: [
@@ -109,7 +108,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec3'),
+      specId: 'spec3',
     },
   ];
   const WITH_NULL_DATASET_WY0: RawDataSeries[] = [
@@ -123,7 +122,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
     },
     {
       data: [
@@ -134,7 +133,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec2'),
+      specId: 'spec2',
     },
     {
       data: [
@@ -146,18 +145,18 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec3'),
+      specId: 'spec3',
     },
   ];
   const DATA_SET_WITH_NULL_2: RawDataSeries[] = [
     {
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
       key: ['a'],
       seriesColorKey: 'a',
       data: [{ x: 1, y1: 10 }, { x: 2, y1: 20 }, { x: 4, y1: 40 }],
     },
     {
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
       key: ['b'],
       seriesColorKey: 'b',
       data: [{ x: 1, y1: 90 }, { x: 3, y1: 30 }],
diff --git a/src/chart_types/xy_chart/utils/stacked_series_utils.test.ts b/src/chart_types/xy_chart/utils/stacked_series_utils.test.ts
index 0747bc2921..fccc54907c 100644
--- a/src/chart_types/xy_chart/utils/stacked_series_utils.test.ts
+++ b/src/chart_types/xy_chart/utils/stacked_series_utils.test.ts
@@ -1,4 +1,3 @@
-import { getSpecId } from '../../../utils/ids';
 import { RawDataSeries } from './series';
 import { computeYStackedMapValues, formatStackedDataSeriesValues, getYValueStackMap } from './stacked_series_utils';
 import { ScaleType } from '../../../utils/scales/scales';
@@ -9,7 +8,7 @@ describe('Stacked Series Utils', () => {
       data: [],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
     },
   ];
   const STANDARD_DATA_SET: RawDataSeries[] = [
@@ -22,7 +21,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
     },
     {
       data: [
@@ -33,7 +32,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec2'),
+      specId: 'spec2',
     },
     {
       data: [
@@ -44,7 +43,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec3'),
+      specId: 'spec3',
     },
   ];
   const WITH_NULL_DATASET: RawDataSeries[] = [
@@ -57,7 +56,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
     },
     {
       data: [
@@ -68,7 +67,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec2'),
+      specId: 'spec2',
     },
     {
       data: [
@@ -79,7 +78,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec3'),
+      specId: 'spec3',
     },
   ];
   const STANDARD_DATA_SET_WY0: RawDataSeries[] = [
@@ -93,7 +92,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
     },
     {
       data: [
@@ -105,7 +104,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec2'),
+      specId: 'spec2',
     },
     {
       data: [
@@ -117,7 +116,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec3'),
+      specId: 'spec3',
     },
   ];
   const WITH_NULL_DATASET_WY0: RawDataSeries[] = [
@@ -131,7 +130,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
     },
     {
       data: [
@@ -142,7 +141,7 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec2'),
+      specId: 'spec2',
     },
     {
       data: [
@@ -154,18 +153,18 @@ describe('Stacked Series Utils', () => {
       ],
       key: [],
       seriesColorKey: 'color-key',
-      specId: getSpecId('spec3'),
+      specId: 'spec3',
     },
   ];
   const DATA_SET_WITH_NULL_2: RawDataSeries[] = [
     {
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
       key: ['a'],
       seriesColorKey: 'a',
       data: [{ x: 1, y1: 1 }, { x: 2, y1: 2 }, { x: 4, y1: 4 }],
     },
     {
-      specId: getSpecId('spec1'),
+      specId: 'spec1',
       key: ['b'],
       seriesColorKey: 'b',
       data: [{ x: 1, y1: 21 }, { x: 3, y1: 23 }],
diff --git a/src/components/_container.scss b/src/components/_container.scss
index 4afb0d79cf..30f0eaf93a 100644
--- a/src/components/_container.scss
+++ b/src/components/_container.scss
@@ -1,22 +1,19 @@
-/**
- * The Base Elastic-Charts container
- */
-
-.echContainer {
-  flex: 1;
-  position: relative;
-}
-
 .echChart {
   display: flex;
   height: 100%;
+  position: relative;
 
   &--column {
     flex-direction: column;
   }
 }
 
-.echChartCursorContainer {
+.echContainer {
+  flex: 1;
+  position: relative;
+}
+
+.echChartPointerContainer {
   position: absolute;
   top: 0;
   bottom: 0;
diff --git a/src/components/_global.scss b/src/components/_global.scss
index 8099c94c55..b57fed5fa0 100644
--- a/src/components/_global.scss
+++ b/src/components/_global.scss
@@ -1,3 +1,12 @@
 .invisible {
   visibility: hidden;
 }
+
+.echChartStatus {
+  visibility: hidden;
+  pointer-events: none;
+  z-index: -100000;
+  width: 0;
+  height: 0;
+  position: absolute;
+}
diff --git a/src/components/_index.scss b/src/components/_index.scss
index de8ee6711d..74f4c59335 100644
--- a/src/components/_index.scss
+++ b/src/components/_index.scss
@@ -1,9 +1,9 @@
 @import 'global';
 @import 'container';
 @import 'annotation';
-@import 'crosshair';
-@import 'highlighter';
 @import 'tooltip';
 @import 'icons/index';
 @import 'legend/index';
 @import 'unavailable_chart';
+
+@import '../chart_types/xy_chart/renderer/index'
\ No newline at end of file
diff --git a/src/components/chart.tsx b/src/components/chart.tsx
index c51426c25d..fc02f1ab62 100644
--- a/src/components/chart.tsx
+++ b/src/components/chart.tsx
@@ -1,22 +1,30 @@
 import React, { CSSProperties, createRef } from 'react';
 import classNames from 'classnames';
-import { Provider } from 'mobx-react';
-
+import { Provider } from 'react-redux';
 import { SpecsParser } from '../specs/specs_parser';
-import { ChartStore } from '../chart_types/xy_chart/store/chart_state';
-import { AnnotationTooltip } from './annotation_tooltips';
 import { ChartResizer } from './chart_resizer';
-import { Crosshair } from './crosshair';
-import { Highlighter } from './highlighter';
 import { Legend } from './legend/legend';
-import { ChartContainer } from './react_canvas/chart_container';
-import { Tooltips } from './tooltips';
+import { ChartContainer } from './chart_container';
 import { isHorizontalAxis } from '../chart_types/xy_chart/utils/axis_utils';
 import { Position } from '../chart_types/xy_chart/utils/specs';
-import { CursorEvent } from '../specs/settings';
 import { ChartSize, getChartSize } from '../utils/chart_size';
-import { Stage } from 'react-konva';
+import { ChartStatus } from './chart_status';
+import { chartStoreReducer, GlobalChartState } from '../state/chart_state';
+import { createStore, Store } from 'redux';
+import uuid from 'uuid';
+import { devToolsEnhancer } from 'redux-devtools-extension';
+import { isInitialized } from '../state/selectors/is_initialized';
+import { createOnElementOutCaller } from '../chart_types/xy_chart/state/selectors/on_element_out_caller';
+import { createOnElementOverCaller } from '../chart_types/xy_chart/state/selectors/on_element_over_caller';
+import { createOnElementClickCaller } from '../chart_types/xy_chart/state/selectors/on_element_click_caller';
+import { ChartTypes } from '../chart_types/index';
+import { getSettingsSpecSelector } from '../state/selectors/get_settings_specs';
+import { createOnBrushEndCaller } from '../chart_types/xy_chart/state/selectors/on_brush_end_caller';
+import { onExternalPointerEvent } from '../state/actions/events';
+import { CursorEvent } from '../specs';
+import { createOnPointerMoveCaller } from '../chart_types/xy_chart/state/selectors/on_pointer_move_caller';
 import Konva from 'konva';
+import { Stage } from 'react-konva';
 
 interface ChartProps {
   /** The type of rendered
@@ -30,70 +38,70 @@ interface ChartProps {
 
 interface ChartState {
   legendPosition: Position;
-  renderComplete: boolean;
-  renderCount: number;
+}
+
+function getContainerStyle(size: any): CSSProperties {
+  if (size) {
+    return {
+      position: 'relative',
+      ...getChartSize(size),
+    };
+  }
+  return {};
 }
 
 export class Chart extends React.Component<ChartProps, ChartState> {
   static defaultProps: ChartProps = {
     renderer: 'canvas',
   };
-  private chartSpecStore: ChartStore;
+  private chartStore: Store<GlobalChartState>;
   private chartContainerRef: React.RefObject<HTMLDivElement>;
   private chartStageRef: React.RefObject<Stage>;
   constructor(props: any) {
     super(props);
     this.chartContainerRef = createRef();
     this.chartStageRef = createRef();
-    this.chartSpecStore = new ChartStore(props.id);
+
+    const storeReducer = chartStoreReducer(uuid.v4());
+    if (process.env.NODE_ENV !== 'production') {
+      this.chartStore = createStore(storeReducer, devToolsEnhancer({ trace: true }));
+    } else {
+      this.chartStore = createStore(storeReducer);
+    }
     this.state = {
-      legendPosition: this.chartSpecStore.legendPosition.get(),
-      renderComplete: false,
-      renderCount: 0,
+      legendPosition: Position.Right,
     };
 
-    this.chartSpecStore.chartInitialized.observe(({ newValue, oldValue }) => {
-      if (newValue !== oldValue) {
+    const onElementClickCaller = createOnElementClickCaller();
+    const onElementOverCaller = createOnElementOverCaller();
+    const onElementOutCaller = createOnElementOutCaller();
+    const onBrushEndCaller = createOnBrushEndCaller();
+    const onPointerMoveCaller = createOnPointerMoveCaller();
+    this.chartStore.subscribe(() => {
+      const state = this.chartStore.getState();
+      if (!isInitialized(state)) {
+        return;
+      }
+      const settings = getSettingsSpecSelector(state);
+      if (this.state.legendPosition !== settings.legendPosition) {
         this.setState({
-          renderComplete: newValue,
-          renderCount: newValue ? this.state.renderCount + 1 : this.state.renderCount,
+          legendPosition: settings.legendPosition,
         });
       }
-    });
-    // value is set to chart_store in settings so need to watch the value
-    this.chartSpecStore.legendPosition.observe(({ newValue: legendPosition }) => {
-      this.setState({
-        legendPosition,
-      });
+
+      if (state.chartType !== ChartTypes.XYAxis) {
+        return;
+      }
+      onElementOverCaller(state);
+      onElementOutCaller(state);
+      onElementClickCaller(state);
+      onBrushEndCaller(state);
+      onPointerMoveCaller(state);
     });
   }
 
-  static getContainerStyle = (size: any): CSSProperties => {
-    if (size) {
-      return {
-        position: 'relative',
-        ...getChartSize(size),
-      };
-    }
-    return {};
-  };
-
   dispatchExternalCursorEvent(event?: CursorEvent) {
-    this.chartSpecStore.setActiveChartId(event && event.chartId);
-    const isActiveChart = this.chartSpecStore.isActiveChart.get();
-
-    if (!event) {
-      this.chartSpecStore.externalCursorShown.set(false);
-      this.chartSpecStore.isCursorOnChart.set(false);
-    } else {
-      if (
-        !isActiveChart &&
-        this.chartSpecStore.xScale!.type === event.scale &&
-        (event.unit === undefined || event.unit === this.chartSpecStore.xScale!.unit)
-      ) {
-        this.chartSpecStore.setCursorValue(event.value);
-      }
-    }
+    this.chartStore.dispatch(onExternalPointerEvent(event));
   }
 
   getPNGSnapshot(
@@ -150,34 +158,21 @@ export class Chart extends React.Component<ChartProps, ChartState> {
   };
 
   render() {
-    const { renderer, size, className } = this.props;
-    const { renderComplete, renderCount } = this.state;
-    const containerStyle = Chart.getContainerStyle(size);
+    const { size, className } = this.props;
+    const containerStyle = getContainerStyle(size);
     const horizontal = isHorizontalAxis(this.state.legendPosition);
     const chartClassNames = classNames('echChart', className, {
       'echChart--column': horizontal,
     });
-
     return (
-      <Provider chartStore={this.chartSpecStore}>
-        <div
-          style={containerStyle}
-          className={chartClassNames}
-          data-ech-render-complete={renderComplete}
-          data-ech-render-count={renderCount}
-          ref={this.chartContainerRef}
-        >
+      <Provider store={this.chartStore}>
+        <div style={containerStyle} className={chartClassNames} ref={this.chartContainerRef}>
+          <ChartStatus />
+          <ChartResizer />
           <Legend />
           <SpecsParser>{this.props.children}</SpecsParser>
           <div className="echContainer">
-            <ChartResizer />
-            <Crosshair />
-            {// TODO reenable when SVG rendered is aligned with canvas one
-            renderer === 'svg' && <ChartContainer forwardRef={this.chartStageRef} />}
-            {renderer === 'canvas' && <ChartContainer forwardRef={this.chartStageRef} />}
-            <Tooltips getChartContainerRef={this.getChartContainerRef} />
-            <AnnotationTooltip getChartContainerRef={this.getChartContainerRef} />
-            <Highlighter />
+            <ChartContainer getChartContainerRef={this.getChartContainerRef} forwardStageRef={this.chartStageRef} />
           </div>
         </div>
       </Provider>
diff --git a/src/components/chart_container.tsx b/src/components/chart_container.tsx
new file mode 100644
index 0000000000..a477a32521
--- /dev/null
+++ b/src/components/chart_container.tsx
@@ -0,0 +1,173 @@
+import React from 'react';
+import { bindActionCreators, Dispatch } from 'redux';
+import { connect } from 'react-redux';
+import { GlobalChartState, BackwardRef } from '../state/chart_state';
+import { onMouseUp, onMouseDown, onPointerMove } from '../state/actions/mouse';
+import { getInternalChartRendererSelector } from '../state/selectors/get_chart_type_components';
+import { getInternalPointerCursor } from '../state/selectors/get_internal_cursor_pointer';
+import { getInternalIsBrushingAvailableSelector } from '../state/selectors/get_internal_is_brushing_available';
+import { isInternalChartEmptySelector } from '../state/selectors/is_chart_empty';
+import { isInitialized } from '../state/selectors/is_initialized';
+import { getSettingsSpecSelector } from '../state/selectors/get_settings_specs';
+import { SettingsSpec } from '../specs';
+import { isBrushingSelector } from '../chart_types/xy_chart/state/selectors/is_brushing';
+import { Stage } from 'react-konva';
+
+interface ReactiveChartStateProps {
+  initialized: boolean;
+  isChartEmpty?: boolean;
+  pointerCursor: string;
+  isBrushing: boolean;
+  isBrushingAvailable: boolean;
+  settings?: SettingsSpec;
+  internalChartRenderer: (containerRef: BackwardRef, forwardStageRef: React.RefObject<Stage>) => JSX.Element | null;
+}
+interface ReactiveChartDispatchProps {
+  onPointerMove: typeof onPointerMove;
+  onMouseUp: typeof onMouseUp;
+  onMouseDown: typeof onMouseDown;
+}
+
+interface ReactiveChartOwnProps {
+  getChartContainerRef: BackwardRef;
+  forwardStageRef: React.RefObject<Stage>;
+}
+
+type ReactiveChartProps = ReactiveChartStateProps & ReactiveChartDispatchProps & ReactiveChartOwnProps;
+
+class ChartContainerComponent extends React.Component<ReactiveChartProps> {
+  static displayName = 'ChartContainer';
+
+  shouldComponentUpdate(props: ReactiveChartProps) {
+    return props.initialized;
+  }
+  handleMouseMove = ({
+    nativeEvent: { offsetX, offsetY, timeStamp },
+  }: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
+    const { isChartEmpty, onPointerMove } = this.props;
+    if (isChartEmpty) {
+      return;
+    }
+    onPointerMove(
+      {
+        x: offsetX,
+        y: offsetY,
+      },
+      timeStamp,
+    );
+  };
+  handleMouseLeave = ({ nativeEvent: { timeStamp } }: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
+    const { isChartEmpty, onPointerMove, isBrushing } = this.props;
+    if (isChartEmpty) {
+      return;
+    }
+    if (isBrushing) {
+      return;
+    }
+    onPointerMove({ x: -1, y: -1 }, timeStamp);
+  };
+  handleMouseDown = ({
+    nativeEvent: { offsetX, offsetY, timeStamp },
+  }: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
+    const { isChartEmpty, onMouseDown, isBrushingAvailable } = this.props;
+    if (isChartEmpty) {
+      return;
+    }
+    if (isBrushingAvailable) {
+      window.addEventListener('mouseup', this.handleBrushEnd);
+    }
+    onMouseDown(
+      {
+        x: offsetX,
+        y: offsetY,
+      },
+      timeStamp,
+    );
+  };
+  handleMouseUp = ({ nativeEvent: { offsetX, offsetY, timeStamp } }: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
+    const { isChartEmpty, onMouseUp } = this.props;
+    if (isChartEmpty) {
+      return;
+    }
+    onMouseUp(
+      {
+        x: offsetX,
+        y: offsetY,
+      },
+      timeStamp,
+    );
+  };
+  handleBrushEnd = () => {
+    const { onMouseUp } = this.props;
+
+    window.removeEventListener('mouseup', this.handleBrushEnd);
+    requestAnimationFrame(() => {
+      onMouseUp(
+        {
+          x: -1,
+          y: -1,
+        },
+        Date.now(),
+      );
+    });
+  };
+
+  render() {
+    const { initialized } = this.props;
+    if (!initialized) {
+      return null;
+    }
+    const { pointerCursor, internalChartRenderer, getChartContainerRef, forwardStageRef } = this.props;
+    return (
+      <div
+        className="echChartPointerContainer"
+        style={{
+          cursor: pointerCursor,
+        }}
+        onMouseMove={this.handleMouseMove}
+        onMouseLeave={this.handleMouseLeave}
+        onMouseDown={this.handleMouseDown}
+        onMouseUp={this.handleMouseUp}
+      >
+        {internalChartRenderer(getChartContainerRef, forwardStageRef)}
+      </div>
+    );
+  }
+}
+
+const mapDispatchToProps = (dispatch: Dispatch): ReactiveChartDispatchProps =>
+  bindActionCreators(
+    {
+      onPointerMove,
+      onMouseUp,
+      onMouseDown,
+    },
+    dispatch,
+  );
+const mapStateToProps = (state: GlobalChartState): ReactiveChartStateProps => {
+  if (!isInitialized(state)) {
+    return {
+      initialized: false,
+      isChartEmpty: true,
+      pointerCursor: 'default',
+      isBrushingAvailable: false,
+      isBrushing: false,
+      internalChartRenderer: () => null,
+    };
+  }
+
+  return {
+    initialized: true,
+    isChartEmpty: isInternalChartEmptySelector(state),
+    pointerCursor: getInternalPointerCursor(state),
+    isBrushingAvailable: getInternalIsBrushingAvailableSelector(state),
+    isBrushing: isBrushingSelector(state),
+    internalChartRenderer: getInternalChartRendererSelector(state),
+    settings: getSettingsSpecSelector(state),
+  };
+};
+
+export const ChartContainer = connect(
+  mapStateToProps,
+  mapDispatchToProps,
+)(ChartContainerComponent);
diff --git a/src/components/chart_resizer.tsx b/src/components/chart_resizer.tsx
index fbf90322a0..8a309f1420 100644
--- a/src/components/chart_resizer.tsx
+++ b/src/components/chart_resizer.tsx
@@ -1,12 +1,23 @@
-import { inject, observer } from 'mobx-react';
 import React, { RefObject } from 'react';
 import ResizeObserver from 'resize-observer-polyfill';
 import { debounce } from 'ts-debounce';
-import { ChartStore } from '../chart_types/xy_chart/store/chart_state';
+import { Dimensions } from '../utils/dimensions';
+import { updateParentDimensions } from '../state/actions/chart_settings';
+import { Dispatch, bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+import { getSettingsSpecSelector } from '../state/selectors/get_settings_specs';
+import { GlobalChartState } from '../state/chart_state';
 
-interface ResizerProps {
-  chartStore?: ChartStore;
+interface ResizerStateProps {
+  resizeDebounce: number;
 }
+
+interface ResizerDispatchProps {
+  updateParentDimensions(dimension: Dimensions): void;
+}
+
+type ResizerProps = ResizerStateProps & ResizerDispatchProps;
+
 class Resizer extends React.Component<ResizerProps> {
   private initialResizeComplete = false;
   private containerRef: RefObject<HTMLDivElement>;
@@ -22,10 +33,12 @@ class Resizer extends React.Component<ResizerProps> {
   }
 
   componentDidMount() {
-    this.onResizeDebounced = debounce(this.onResize, this.props.chartStore!.resizeDebounce);
+    this.onResizeDebounced = debounce(this.onResize, this.props.resizeDebounce);
     if (this.containerRef.current) {
-      this.ro.observe(this.containerRef.current as Element);
+      const { clientWidth, clientHeight } = this.containerRef.current;
+      this.props.updateParentDimensions({ width: clientWidth, height: clientHeight, top: 0, left: 0 });
     }
+    this.ro.observe(this.containerRef.current as Element);
   }
 
   componentWillUnmount() {
@@ -44,7 +57,7 @@ class Resizer extends React.Component<ResizerProps> {
     }
     const { width, height } = entries[0].contentRect;
     this.animationFrameID = window.requestAnimationFrame(() => {
-      this.props.chartStore!.updateParentDimensions(width, height, 0, 0);
+      this.props.updateParentDimensions({ width, height, top: 0, left: 0 });
     });
   };
 
@@ -62,4 +75,24 @@ class Resizer extends React.Component<ResizerProps> {
   };
 }
 
-export const ChartResizer = inject('chartStore')(observer(Resizer));
+const mapDispatchToProps = (dispatch: Dispatch): ResizerDispatchProps =>
+  bindActionCreators(
+    {
+      updateParentDimensions,
+    },
+    dispatch,
+  );
+
+const mapStateToProps = (state: GlobalChartState): ResizerStateProps => {
+  const settings = getSettingsSpecSelector(state);
+  const resizeDebounce =
+    settings.resizeDebounce === undefined || settings.resizeDebounce === null ? 200 : settings.resizeDebounce;
+  return {
+    resizeDebounce,
+  };
+};
+
+export const ChartResizer = connect(
+  mapStateToProps,
+  mapDispatchToProps,
+)(Resizer);
diff --git a/src/components/chart_status.tsx b/src/components/chart_status.tsx
new file mode 100644
index 0000000000..14624a3421
--- /dev/null
+++ b/src/components/chart_status.tsx
@@ -0,0 +1,39 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { GlobalChartState } from '../state/chart_state';
+import { getSettingsSpecSelector } from '../state/selectors/get_settings_specs';
+import { RenderChangeListener } from '../specs';
+
+interface ChartStatusStateProps {
+  rendered: boolean;
+  renderedCount: number;
+  onRenderChange?: RenderChangeListener;
+}
+class ChartStatusComponent extends React.Component<ChartStatusStateProps> {
+  componentDidMount() {
+    this.dispatchRenderChange();
+  }
+  componentDidUpdate() {
+    this.dispatchRenderChange();
+  }
+  dispatchRenderChange = () => {
+    const { onRenderChange, rendered } = this.props;
+    if (onRenderChange) {
+      onRenderChange(rendered);
+    }
+  };
+  render() {
+    const { rendered, renderedCount } = this.props;
+    return <div className="echChartStatus" data-ech-render-complete={rendered} data-ech-render-count={renderedCount} />;
+  }
+}
+
+const mapStateToProps = (state: GlobalChartState): ChartStatusStateProps => {
+  return {
+    rendered: state.chartRendered,
+    renderedCount: state.chartRenderedCount,
+    onRenderChange: getSettingsSpecSelector(state).onRenderChange,
+  };
+};
+
+export const ChartStatus = connect(mapStateToProps)(ChartStatusComponent);
diff --git a/src/components/crosshair.tsx b/src/components/crosshair.tsx
deleted file mode 100644
index 3d28e2f228..0000000000
--- a/src/components/crosshair.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import { inject, observer } from 'mobx-react';
-import React, { CSSProperties } from 'react';
-import { TooltipType } from '../chart_types/xy_chart/utils/interactions';
-import { ChartStore } from '../chart_types/xy_chart/store/chart_state';
-import { isHorizontalRotation } from '../chart_types/xy_chart/store/utils';
-
-interface CrosshairProps {
-  chartStore?: ChartStore;
-}
-
-function canRenderBand(type: TooltipType, visible: boolean) {
-  return visible && (type === TooltipType.Crosshairs || type === TooltipType.VerticalCursor);
-}
-function canRenderHelpLine(type: TooltipType, visible: boolean) {
-  return visible && type === TooltipType.Crosshairs;
-}
-
-class CrosshairComponent extends React.Component<CrosshairProps> {
-  static displayName = 'Crosshair';
-
-  render() {
-    const { isCrosshairVisible } = this.props.chartStore!;
-    if (!isCrosshairVisible.get()) {
-      return <div className="echCrosshair" />;
-    }
-    return (
-      <div className="echCrosshair">
-        {this.renderBand()}
-        {this.renderLine()}
-      </div>
-    );
-  }
-
-  renderBand() {
-    const {
-      chartTheme: {
-        crosshair: { band },
-      },
-      cursorBandPosition: { top, left, width, height, visible },
-      tooltipType,
-    } = this.props.chartStore!;
-    if (!visible || !canRenderBand(tooltipType.get(), band.visible)) {
-      return null;
-    }
-
-    const style: CSSProperties = {
-      top,
-      left,
-      width,
-      height,
-      background: band.fill,
-    };
-
-    return <div className="echCrosshair__band" style={style} />;
-  }
-
-  renderLine() {
-    const {
-      chartTheme: {
-        crosshair: { line },
-      },
-      cursorLinePosition,
-      tooltipType,
-      chartRotation,
-    } = this.props.chartStore!;
-
-    if (!canRenderHelpLine(tooltipType.get(), line.visible)) {
-      return null;
-    }
-    const isHorizontalRotated = isHorizontalRotation(chartRotation);
-    let style: CSSProperties;
-    if (isHorizontalRotated) {
-      style = {
-        ...cursorLinePosition,
-        borderTopWidth: line.strokeWidth,
-        borderTopColor: line.stroke,
-        borderTopStyle: line.dash ? 'dashed' : 'solid',
-      };
-    } else {
-      style = {
-        ...cursorLinePosition,
-        borderLeftWidth: line.strokeWidth,
-        borderLeftColor: line.stroke,
-        borderLeftStyle: line.dash ? 'dashed' : 'solid',
-      };
-    }
-    return <div className="echCrosshair__line" style={style} />;
-  }
-}
-
-export const Crosshair = inject('chartStore')(observer(CrosshairComponent));
diff --git a/src/components/highlighter.tsx b/src/components/highlighter.tsx
deleted file mode 100644
index d19b8997aa..0000000000
--- a/src/components/highlighter.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import { inject, observer } from 'mobx-react';
-import React from 'react';
-import { isPointGeometry } from '../chart_types/xy_chart/rendering/rendering';
-import { ChartStore } from '../chart_types/xy_chart/store/chart_state';
-
-interface HighlighterProps {
-  chartStore?: ChartStore;
-}
-
-class HighlighterComponent extends React.Component<HighlighterProps> {
-  static displayName = 'Highlighter';
-
-  render() {
-    const { highlightedGeometries, chartTransform, chartDimensions, chartRotation } = this.props.chartStore!;
-    const left = chartDimensions.left + chartTransform.x;
-    const top = chartDimensions.top + chartTransform.y;
-    const clipWidth = [90, -90].includes(chartRotation) ? chartDimensions.height : chartDimensions.width;
-    const clipHeight = [90, -90].includes(chartRotation) ? chartDimensions.width : chartDimensions.height;
-    return (
-      <svg className="echHighlighter">
-        <defs>
-          <clipPath id="echHighlighterClipPath">
-            <rect x="0" y="0" width={clipWidth} height={clipHeight} />
-          </clipPath>
-        </defs>
-        <g transform={`translate(${left}, ${top}) rotate(${chartRotation})`}>
-          {highlightedGeometries.map((geom, i) => {
-            const { color, x, y } = geom;
-            if (isPointGeometry(geom)) {
-              return (
-                <circle
-                  key={i}
-                  cx={x + geom.transform.x}
-                  cy={y}
-                  r={geom.radius}
-                  stroke={color}
-                  strokeWidth={4}
-                  fill="transparent"
-                />
-              );
-            }
-            return (
-              <rect
-                key={i}
-                x={x}
-                y={y}
-                width={geom.width}
-                height={geom.height}
-                className="echHighlighter__rect"
-                clipPath="url(#echHighlighterClipPath)"
-              />
-            );
-          })}
-        </g>
-      </svg>
-    );
-  }
-}
-
-export const Highlighter = inject('chartStore')(observer(HighlighterComponent));
diff --git a/src/components/icons/assets/dot.tsx b/src/components/icons/assets/dot.tsx
index 58921040ba..c50af6dcce 100644
--- a/src/components/icons/assets/dot.tsx
+++ b/src/components/icons/assets/dot.tsx
@@ -1,15 +1,17 @@
 import React from 'react';
 import { Props } from '../icon';
 
-export function DotIcon(extraProps: Props) {
-  return (
-    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" {...extraProps}>
-      <defs>
-        <circle id="dot-a" cx="8" cy="8" r="4" />
-      </defs>
-      <g>
-        <use xlinkHref="#dot-a" />
-      </g>
-    </svg>
-  );
+export class DotIcon extends React.PureComponent<Props> {
+  render() {
+    return (
+      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" {...this.props}>
+        <defs>
+          <circle id="dot-a" cx="8" cy="8" r="4" />
+        </defs>
+        <g>
+          <use xlinkHref="#dot-a" />
+        </g>
+      </svg>
+    );
+  }
 }
diff --git a/src/components/icons/icon.tsx b/src/components/icons/icon.tsx
index 66b2686bc0..3d7de41eea 100644
--- a/src/components/icons/icon.tsx
+++ b/src/components/icons/icon.tsx
@@ -31,25 +31,27 @@ export interface IconProps {
 
 export type Props = Omit<SVGAttributes<SVGElement>, 'color' | 'type'> & IconProps;
 
-export const Icon = (props: Props) => {
-  const { type, color, className, tabIndex, ...rest } = props;
-  let optionalCustomStyles = null;
+export class Icon extends React.PureComponent<Props> {
+  render() {
+    const { type, color, className, tabIndex, ...rest } = this.props;
+    let optionalCustomStyles = null;
 
-  if (color) {
-    optionalCustomStyles = { color };
-  }
+    if (color) {
+      optionalCustomStyles = { color };
+    }
 
-  const classes = classNames('echIcon', className);
+    const classes = classNames('echIcon', className);
 
-  const Svg = (type && typeToIconMap[type]) || EmptyIcon;
+    const Svg = (type && typeToIconMap[type]) || EmptyIcon;
 
-  // This is a fix for IE and Edge, which ignores tabindex="-1" on an SVG, but respects
-  // focusable="false".
-  //   - If there's no tab index specified, we'll default the icon to not be focusable,
-  //     which is how SVGs behave in Chrome, Safari, and FF.
-  //   - If tab index is -1, then the consumer wants the icon to not be focusable.
-  //   - For all other values, the consumer wants the icon to be focusable.
-  const focusable = tabIndex == null || tabIndex === -1 ? 'false' : 'true';
+    // This is a fix for IE and Edge, which ignores tabindex="-1" on an SVG, but respects
+    // focusable="false".
+    //   - If there's no tab index specified, we'll default the icon to not be focusable,
+    //     which is how SVGs behave in Chrome, Safari, and FF.
+    //   - If tab index is -1, then the consumer wants the icon to not be focusable.
+    //   - For all other values, the consumer wants the icon to be focusable.
+    const focusable = tabIndex == null || tabIndex === -1 ? 'false' : 'true';
 
-  return <Svg className={classes} {...optionalCustomStyles} tabIndex={tabIndex} focusable={focusable} {...rest} />;
-};
+    return <Svg className={classes} {...optionalCustomStyles} tabIndex={tabIndex} focusable={focusable} {...rest} />;
+  }
+}
diff --git a/src/components/legend/legend.test.tsx b/src/components/legend/legend.test.tsx
new file mode 100644
index 0000000000..348596e722
--- /dev/null
+++ b/src/components/legend/legend.test.tsx
@@ -0,0 +1,124 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { Chart } from '../chart';
+import { Settings, BarSeries } from '../../specs';
+import { ScaleType } from '../../utils/scales/scales';
+import { DataGenerator } from '../../utils/data_generators/data_generator';
+import { Legend } from './legend';
+import { LegendListItem } from './legend_item';
+
+describe('Legend', () => {
+  it('shall render the all the series names', () => {
+    const wrapper = mount(
+      <Chart>
+        <Settings showLegend />
+        <BarSeries
+          id="areas"
+          name="area"
+          xScaleType={ScaleType.Linear}
+          yScaleType={ScaleType.Linear}
+          xAccessor={0}
+          yAccessors={[1]}
+          splitSeriesAccessors={[2]}
+          data={[[0, 123, 'group0'], [0, 123, 'group1'], [0, 123, 'group2'], [0, 123, 'group3']]}
+        />
+      </Chart>,
+    );
+    const legendWrapper = wrapper.find(Legend);
+    expect(legendWrapper.exists).toBeTruthy();
+    const legendItems = legendWrapper.find(LegendListItem);
+    expect(legendItems.exists).toBeTruthy();
+    expect(legendItems).toHaveLength(4);
+    legendItems.forEach((legendItem, i) => {
+      // the legend item shows also the value as default parameter
+      expect(legendItem.text()).toBe(`group${i}123`);
+    });
+  });
+  it('shall render the all the series names without the data value', () => {
+    const wrapper = mount(
+      <Chart>
+        <Settings showLegend showLegendDisplayValue={false} />
+        <BarSeries
+          id="areas"
+          name="area"
+          xScaleType={ScaleType.Linear}
+          yScaleType={ScaleType.Linear}
+          xAccessor={0}
+          yAccessors={[1]}
+          splitSeriesAccessors={[2]}
+          data={[[0, 123, 'group0'], [0, 123, 'group1'], [0, 123, 'group2'], [0, 123, 'group3']]}
+        />
+      </Chart>,
+    );
+    const legendWrapper = wrapper.find(Legend);
+    expect(legendWrapper.exists).toBeTruthy();
+    const legendItems = legendWrapper.find(LegendListItem);
+    expect(legendItems.exists).toBeTruthy();
+    expect(legendItems).toHaveLength(4);
+    legendItems.forEach((legendItem, i) => {
+      // the legend item shows also the value as default parameter
+      expect(legendItem.text()).toBe(`group${i}`);
+    });
+  });
+  it('shall call the over and out listeners for every list item', () => {
+    const onLegendItemOver = jest.fn();
+    const onLegendItemOut = jest.fn();
+    const dg = new DataGenerator();
+    const numberOfSeries = 4;
+    const data = dg.generateGroupedSeries(10, numberOfSeries, 'split');
+    const wrapper = mount(
+      <Chart>
+        <Settings showLegend onLegendItemOver={onLegendItemOver} onLegendItemOut={onLegendItemOut} />
+        <BarSeries
+          id="areas"
+          xScaleType={ScaleType.Linear}
+          yScaleType={ScaleType.Linear}
+          xAccessor={'x'}
+          yAccessors={['y']}
+          splitSeriesAccessors={['g']}
+          data={data}
+        />
+      </Chart>,
+    );
+    const legendWrapper = wrapper.find(Legend);
+    expect(legendWrapper.exists).toBeTruthy();
+    const legendItems = legendWrapper.find(LegendListItem);
+    expect(legendItems.exists).toBeTruthy();
+    legendItems.forEach((legendItem, i) => {
+      legendItem.simulate('mouseenter');
+      expect(onLegendItemOver).toBeCalledTimes(i + 1);
+      legendItem.simulate('mouseleave');
+      expect(onLegendItemOut).toBeCalledTimes(i + 1);
+    });
+  });
+  it('shall call click listener for every list item', () => {
+    const onLegendItemClick = jest.fn();
+    const dg = new DataGenerator();
+    const numberOfSeries = 4;
+    const data = dg.generateGroupedSeries(10, numberOfSeries, 'split');
+    const wrapper = mount(
+      <Chart>
+        <Settings showLegend onLegendItemClick={onLegendItemClick} />
+        <BarSeries
+          id="areas"
+          xScaleType={ScaleType.Linear}
+          yScaleType={ScaleType.Linear}
+          xAccessor={'x'}
+          yAccessors={['y']}
+          splitSeriesAccessors={['g']}
+          data={data}
+        />
+      </Chart>,
+    );
+    const legendWrapper = wrapper.find(Legend);
+    expect(legendWrapper.exists).toBeTruthy();
+    const legendItems = legendWrapper.find(LegendListItem);
+    expect(legendItems.exists).toBeTruthy();
+    expect(legendItems).toHaveLength(4);
+    legendItems.forEach((legendItem, i) => {
+      // the click is only enabled on the title
+      legendItem.find('.echLegendItem__title').simulate('click');
+      expect(onLegendItemClick).toBeCalledTimes(i + 1);
+    });
+  });
+});
diff --git a/src/components/legend/legend.tsx b/src/components/legend/legend.tsx
index 93afc1409c..015aa46691 100644
--- a/src/components/legend/legend.tsx
+++ b/src/components/legend/legend.tsx
@@ -1,28 +1,54 @@
 import React, { createRef } from 'react';
-import { inject, observer } from 'mobx-react';
 import classNames from 'classnames';
-
 import { isVerticalAxis, isHorizontalAxis } from '../../chart_types/xy_chart/utils/axis_utils';
-import { LegendItem as SeriesLegendItem } from '../../chart_types/xy_chart/legend/legend';
-import { ChartStore } from '../../chart_types/xy_chart/store/chart_state';
+import { connect } from 'react-redux';
 import { Position } from '../../chart_types/xy_chart/utils/specs';
-import { LegendItem } from './legend_item';
+import { GlobalChartState } from '../../state/chart_state';
+import { getLegendItemsSelector } from '../../state/selectors/get_legend_items';
+import { getSettingsSpecSelector } from '../../state/selectors/get_settings_specs';
+import { getChartThemeSelector } from '../../state/selectors/get_chart_theme';
+import { getLegendItemsValuesSelector } from '../../state/selectors/get_legend_items_values';
+import { getLegendSizeSelector } from '../../state/selectors/get_legend_size';
+import { onToggleLegend } from '../../state/actions/legend';
+import { Dispatch, bindActionCreators } from 'redux';
+import { LIGHT_THEME } from '../../utils/themes/light_theme';
+import { LegendListItem } from './legend_item';
 import { Theme } from '../../utils/themes/theme';
 import { TooltipLegendValue } from '../../chart_types/xy_chart/tooltip/tooltip';
-import { AccessorType } from '../../chart_types/xy_chart/rendering/rendering';
-
-interface LegendProps {
-  chartStore?: ChartStore; // FIX until we find a better way on ts mobx
+import { AccessorType } from '../../utils/geometry';
+import { LegendItem, getItemLabel } from '../../chart_types/xy_chart/legend/legend';
+import { BBox } from '../../utils/bbox/bbox_calculator';
+import {
+  onToggleDeselectSeriesAction,
+  onLegendItemOutAction,
+  onLegendItemOverAction,
+} from '../../state/actions/legend';
+import { SettingsSpec } from '../../specs';
+
+interface LegendStateProps {
+  legendItems: Map<string, LegendItem>;
+  legendPosition: Position;
+  legendItemTooltipValues: Map<string, TooltipLegendValue>;
+  showLegend: boolean;
+  legendCollapsed: boolean;
+  debug: boolean;
+  chartTheme: Theme;
+  legendSize: BBox;
+  settings?: SettingsSpec;
 }
-
-interface LegendState {
-  width?: number;
+interface LegendDispatchProps {
+  onToggleLegend: typeof onToggleLegend;
+  onLegendItemOutAction: typeof onLegendItemOutAction;
+  onLegendItemOverAction: typeof onLegendItemOverAction;
+  onToggleDeselectSeriesAction: typeof onToggleDeselectSeriesAction;
 }
+type LegendProps = LegendStateProps & LegendDispatchProps;
 
 interface LegendStyle {
   maxHeight?: string;
   maxWidth?: string;
   width?: string;
+  height?: string;
 }
 
 interface LegendListStyle {
@@ -33,41 +59,21 @@ interface LegendListStyle {
   gridTemplateColumns?: string;
 }
 
-class LegendComponent extends React.Component<LegendProps, LegendState> {
+class LegendComponent extends React.Component<LegendProps> {
   static displayName = 'Legend';
   legendItemCount = 0;
 
-  state = {
-    width: undefined,
-  };
-
   private echLegend = createRef<HTMLDivElement>();
 
-  componentDidUpdate() {
-    this.tryLegendResize();
-  }
-
   render() {
-    const {
-      legendInitialized,
-      chartInitialized,
-      legendItems,
-      legendPosition,
-      showLegend,
-      debug,
-      chartTheme,
-    } = this.props.chartStore!;
-    const position = legendPosition.get();
-
-    if (!showLegend.get() || !legendInitialized.get() || legendItems.size === 0) {
+    const { legendItems, legendPosition, legendSize, showLegend, debug, chartTheme } = this.props;
+    if (!showLegend || legendItems.size === 0) {
       return null;
     }
-
-    const legendContainerStyle = this.getLegendStyle(position, chartTheme);
-    const legendListStyle = this.getLegendListStyle(position, chartTheme);
-    const legendClasses = classNames('echLegend', `echLegend--${position}`, {
+    const legendContainerStyle = this.getLegendStyle(legendPosition, legendSize);
+    const legendListStyle = this.getLegendListStyle(legendPosition, chartTheme);
+    const legendClasses = classNames('echLegend', `echLegend--${legendPosition}`, {
       'echLegend--debug': debug,
-      invisible: !chartInitialized.get(),
     });
 
     return (
@@ -81,35 +87,6 @@ class LegendComponent extends React.Component<LegendProps, LegendState> {
     );
   }
 
-  tryLegendResize = () => {
-    const { chartInitialized, chartTheme, legendPosition, legendItems } = this.props.chartStore!;
-    const { width } = this.state;
-
-    if (
-      this.echLegend.current &&
-      isVerticalAxis(legendPosition.get()) &&
-      !chartInitialized.get() &&
-      width === undefined &&
-      this.echLegend.current.offsetWidth > 0
-    ) {
-      const buffer = chartTheme.legend.spacingBuffer;
-      this.legendItemCount = legendItems.size;
-
-      return this.setState({
-        width: this.echLegend.current.offsetWidth + buffer,
-      });
-    }
-
-    // Need to reset width to enable downsizing of width
-    if (width !== undefined && legendItems.size !== this.legendItemCount) {
-      this.legendItemCount = legendItems.size;
-
-      this.setState({
-        width: undefined,
-      });
-    }
-  };
-
   getLegendListStyle = (position: Position, { chartMargins, legend }: Theme): LegendListStyle => {
     const { top: paddingTop, bottom: paddingBottom, left: paddingLeft, right: paddingRight } = chartMargins;
 
@@ -127,36 +104,21 @@ class LegendComponent extends React.Component<LegendProps, LegendState> {
     };
   };
 
-  getLegendStyle = (position: Position, { legend }: Theme): LegendStyle => {
+  getLegendStyle = (position: Position, size: BBox): LegendStyle => {
     if (isVerticalAxis(position)) {
-      if (this.state.width !== undefined) {
-        const threshold = Math.min(this.state.width!, legend.verticalWidth);
-        const width = `${threshold}px`;
-
-        return {
-          width,
-          maxWidth: width,
-        };
-      }
-
+      const width = `${size.width}px`;
       return {
-        maxWidth: `${legend.verticalWidth}px`,
+        width,
+        maxWidth: width,
       };
     }
-
+    const height = `${size.height}px`;
     return {
-      maxHeight: `${legend.horizontalHeight}px`,
+      height,
+      maxHeight: height,
     };
   };
 
-  onLegendItemMouseover = (legendItemKey: string) => () => {
-    this.props.chartStore!.onLegendItemOver(legendItemKey);
-  };
-
-  onLegendItemMouseout = () => {
-    this.props.chartStore!.onLegendItemOut();
-  };
-
   private getLegendValues(
     tooltipValues: Map<string, TooltipLegendValue> | undefined,
     key: string,
@@ -171,39 +133,89 @@ class LegendComponent extends React.Component<LegendProps, LegendState> {
     return banded ? [y1, y0] : [y1];
   }
 
-  private getItemLabel(
-    { banded, label, y1AccessorFormat, y0AccessorFormat }: SeriesLegendItem,
-    yAccessor: AccessorType,
-  ) {
-    if (!banded) {
-      return label;
+  private renderLegendElement = (item: LegendItem) => {
+    if (!this.props.settings) {
+      return null;
     }
-
-    return yAccessor === AccessorType.Y1 ? `${label}${y1AccessorFormat}` : `${label}${y0AccessorFormat}`;
-  }
-
-  private renderLegendElement = (item: SeriesLegendItem) => {
     const { key, displayValue, banded } = item;
-    const { legendPosition, legendItemTooltipValues, isCursorOnChart } = this.props.chartStore!;
-    const tooltipValues = legendItemTooltipValues.get();
-    const legendValues = this.getLegendValues(tooltipValues, key, banded);
-
+    const { legendItemTooltipValues, settings } = this.props;
+    const { showLegendDisplayValue, legendPosition } = settings;
+    const legendValues = this.getLegendValues(legendItemTooltipValues, key, banded);
     return legendValues.map((value, index) => {
       const yAccessor: AccessorType = index === 0 ? AccessorType.Y1 : AccessorType.Y0;
       return (
-        <LegendItem
+        <LegendListItem
           {...item}
-          label={this.getItemLabel(item, yAccessor)}
+          label={getItemLabel(item, yAccessor)}
           key={`${key}-${yAccessor}`}
-          legendItemKey={key}
-          legendPosition={legendPosition.get()}
-          displayValue={isCursorOnChart.get() ? value : displayValue.formatted[yAccessor]}
-          onMouseEnter={this.onLegendItemMouseover(key)}
-          onMouseLeave={this.onLegendItemMouseout}
+          legendItem={item}
+          displayValue={value !== '' ? value : displayValue.formatted[yAccessor]}
+          showLegendDisplayValue={showLegendDisplayValue}
+          legendPosition={legendPosition}
+          toggleDeselectSeriesAction={this.props.onToggleDeselectSeriesAction}
+          legendItemOutAction={this.props.onLegendItemOutAction}
+          legendItemOverAction={this.props.onLegendItemOverAction}
+          onLegendItemOverListener={settings.onLegendItemOver}
+          onLegendItemOutListener={settings.onLegendItemOut}
+          onLegendItemClickListener={settings.onLegendItemClick}
         />
       );
     });
   };
 }
 
-export const Legend = inject('chartStore')(observer(LegendComponent));
+const mapDispatchToProps = (dispatch: Dispatch): LegendDispatchProps =>
+  bindActionCreators(
+    {
+      onToggleLegend,
+      onToggleDeselectSeriesAction,
+      onLegendItemOutAction,
+      onLegendItemOverAction,
+    },
+    dispatch,
+  );
+
+const mapStateToProps = (state: GlobalChartState): LegendStateProps => {
+  if (!state.specsInitialized) {
+    return {
+      legendItems: new Map(),
+      legendPosition: Position.Right,
+      showLegend: false,
+      legendCollapsed: false,
+      legendItemTooltipValues: new Map(),
+      debug: false,
+      chartTheme: LIGHT_THEME,
+      legendSize: { width: 0, height: 0 },
+    };
+  }
+  const { legendPosition, showLegend, debug } = getSettingsSpecSelector(state);
+  if (!showLegend) {
+    return {
+      legendItems: new Map(),
+      legendPosition: Position.Right,
+      showLegend: false,
+      legendCollapsed: false,
+      legendItemTooltipValues: new Map(),
+      debug: false,
+      chartTheme: LIGHT_THEME,
+      legendSize: { width: 0, height: 0 },
+    };
+  }
+  const legendItems = getLegendItemsSelector(state);
+  return {
+    legendItems,
+    legendPosition,
+    showLegend,
+    legendCollapsed: state.interactions.legendCollapsed,
+    legendItemTooltipValues: getLegendItemsValuesSelector(state),
+    debug,
+    chartTheme: getChartThemeSelector(state),
+    legendSize: getLegendSizeSelector(state),
+    settings: getSettingsSpecSelector(state),
+  };
+};
+
+export const Legend = connect(
+  mapStateToProps,
+  mapDispatchToProps,
+)(LegendComponent);
diff --git a/src/components/legend/legend_item.tsx b/src/components/legend/legend_item.tsx
index dfa1ebd403..7e279fba1d 100644
--- a/src/components/legend/legend_item.tsx
+++ b/src/components/legend/legend_item.tsx
@@ -1,185 +1,151 @@
 import classNames from 'classnames';
-import { inject, observer } from 'mobx-react';
 import React from 'react';
 import { Icon } from '../icons/icon';
-
-import { ChartStore } from '../../chart_types/xy_chart/store/chart_state';
+import { LegendItemListener, BasicListener } from '../../specs/settings';
+import { isEqualSeriesKey } from '../../chart_types/xy_chart/utils/series_utils';
+import { DataSeriesColorsValues } from '../../chart_types/xy_chart/utils/series';
+import { LegendItem } from '../../chart_types/xy_chart/legend/legend';
+import { onLegendItemOutAction, onLegendItemOverAction } from '../../state/actions/legend';
 import { Position } from '../../chart_types/xy_chart/utils/specs';
 
 interface LegendItemProps {
-  chartStore?: ChartStore; // FIX until we find a better way on ts mobx
-  legendItemKey: string;
-  legendPosition: Position;
-  color: string | undefined;
-  label: string | undefined;
-  isSeriesVisible?: boolean;
-  isLegendItemVisible?: boolean;
+  selectedLegendItem?: LegendItem | null;
+  legendItem: LegendItem;
   displayValue: string;
-  onMouseEnter: (event: React.MouseEvent) => void;
-  onMouseLeave: () => void;
+  label?: string;
+  legendPosition: Position;
+  showLegendDisplayValue: boolean;
+  onLegendItemClickListener?: LegendItemListener;
+  onLegendItemOutListener?: BasicListener;
+  onLegendItemOverListener?: LegendItemListener;
+  legendItemOutAction: typeof onLegendItemOutAction;
+  legendItemOverAction: typeof onLegendItemOverAction;
+  toggleDeselectSeriesAction: (legendItemId: DataSeriesColorsValues) => void;
 }
 
 interface LegendItemState {
   isColorPickerOpen: boolean;
 }
 
-class LegendItemComponent extends React.Component<LegendItemProps, LegendItemState> {
-  static displayName = 'LegendItem';
+/**
+ * Create a div for the the displayed value
+ * @param displayValue
+ * @param isSeriesVisible
+ */
+function renderDisplayValue(displayValue: string, isSeriesVisible: boolean | undefined) {
+  const displayValueClassNames = classNames('echLegendItem__displayValue', {
+    ['echLegendItem__displayValue--hidden']: !isSeriesVisible,
+  });
+  return (
+    <div className={displayValueClassNames} title={displayValue}>
+      {displayValue}
+    </div>
+  );
+}
 
-  constructor(props: LegendItemProps) {
-    super(props);
-    this.state = {
-      isColorPickerOpen: false,
-    };
-  }
+/**
+ * Create a div for the title
+ * @param title
+ * @param onTitleClick
+ * @param hasTitleClickListener
+ * @param isSelected
+ * @param showLegendDisplayValue
+ */
+function renderTitle(
+  title: string,
+  onTitleClick: (event: React.MouseEvent<Element, MouseEvent>) => void,
+  hasTitleClickListener: boolean,
+  isSelected: boolean,
+  showLegendDisplayValue: boolean,
+) {
+  // TODO add contextual menu panel on click
+  const titleClassNames = classNames('echLegendItem__title', {
+    ['echLegendItem__title--hasClickListener']: hasTitleClickListener,
+    ['echLegendItem__title--selected']: isSelected,
+    ['echLegendItem__title--hasDisplayValue']: showLegendDisplayValue,
+  });
+  return (
+    <div className={titleClassNames} title={title} onClick={onTitleClick}>
+      {title}
+    </div>
+  );
+}
 
-  closeColorPicker = () => {
-    this.setState({
-      isColorPickerOpen: false,
-    });
-  };
+/**
+ * Create a div for the color/eye icon
+ * @param color
+ * @param isSeriesVisible
+ */
+function renderColor(color: string, isSeriesVisible = true) {
+  // TODO add color picker
+  if (isSeriesVisible) {
+    return (
+      <div className="echLegendItem__color" aria-label="series color" title="series color">
+        <Icon type="dot" color={color} />
+      </div>
+    );
+  }
+  // changing the default viewBox for the eyeClosed icon to keep the same dimensions
+  return (
+    <div className="echLegendItem__color" aria-label="series hidden" title="series hidden">
+      <Icon type="eyeClosed" viewBox="-3 -3 22 22" />
+    </div>
+  );
+}
 
-  toggleColorPicker = () => {
-    this.setState({
-      isColorPickerOpen: !this.state.isColorPickerOpen,
-    });
-  };
+export class LegendListItem extends React.PureComponent<LegendItemProps, LegendItemState> {
+  static displayName = 'LegendItem';
 
   render() {
-    const {
-      legendItemKey,
-      legendPosition,
-      chartStore,
-      color,
-      label,
-      isSeriesVisible,
-      isLegendItemVisible,
-      displayValue,
-      onMouseEnter,
-      onMouseLeave,
-    } = this.props;
-    const onTitleClick = this.onVisibilityClick(legendItemKey);
-    const showLegendDisplayValue = chartStore!.showLegendDisplayValue.get();
-    const isSelected = legendItemKey === chartStore!.selectedLegendItemKey.get();
-    const hasDisplayValue = chartStore!.showLegendDisplayValue.get();
-    const hasTitleClickListener = Boolean(chartStore!.onLegendItemClickListener);
-
+    const { displayValue, legendItem, legendPosition, label } = this.props;
+    const { color, isSeriesVisible, value, isLegendItemVisible } = legendItem;
+    const onTitleClick = this.onVisibilityClick(legendItem.value);
+
+    const { showLegendDisplayValue, selectedLegendItem, onLegendItemClickListener } = this.props;
+    const isSelected =
+      selectedLegendItem == null
+        ? false
+        : isEqualSeriesKey(value.colorValues, selectedLegendItem.value.colorValues) &&
+          value.specId === selectedLegendItem.value.specId;
+    const hasTitleClickListener = Boolean(onLegendItemClickListener);
     const itemClasses = classNames('echLegendItem', `echLegendItem--${legendPosition}`, {
-      'echLegendItem--hidden': !isSeriesVisible,
+      'echLegendItem-isHidden': !isSeriesVisible,
       'echLegendItem__displayValue--hidden': !isLegendItemVisible,
     });
 
     return (
-      <div className={itemClasses} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
-        {this.renderColor(this.toggleColorPicker, color, isSeriesVisible)}
-        {this.renderTitle(label, onTitleClick, hasTitleClickListener, isSelected, hasDisplayValue)}
-        {this.renderDisplayValue(displayValue, showLegendDisplayValue, isSeriesVisible)}
-      </div>
-    );
-  }
-  renderColor(colorClickAction: () => void, color?: string, isSeriesVisible = true) {
-    if (!color) {
-      return null;
-    }
-    // TODO add color picker
-    const iconType = isSeriesVisible ? 'dot' : 'eyeClosed';
-    const iconColor = isSeriesVisible ? color : undefined;
-    const title = isSeriesVisible ? 'series color' : 'series hidden';
-    const viewBox = isSeriesVisible ? undefined : '-3 -3 22 22';
-    return (
-      <div className="echLegendItem__color" aria-label={title} title={title}>
-        <Icon type={iconType} color={iconColor} onClick={colorClickAction} viewBox={viewBox} />
+      <div className={itemClasses} onMouseEnter={this.onLegendItemMouseOver} onMouseLeave={this.onLegendItemMouseOut}>
+        {color && renderColor(color, isSeriesVisible)}
+        {label && renderTitle(label, onTitleClick, hasTitleClickListener, isSelected, showLegendDisplayValue)}
+        {showLegendDisplayValue && renderDisplayValue(displayValue, isSeriesVisible)}
       </div>
     );
   }
 
-  renderVisibilityButton = (legendItemKey: string, isSeriesVisible = true) => {
-    const iconType = isSeriesVisible ? 'eye' : 'eyeClosed';
-    return (
-      <div className="echLegendItem__visibility">
-        <Icon type={iconType} aria-label="toggle visibility" onClick={this.onVisibilityClick(legendItemKey)} />
-      </div>
-    );
-  };
-
-  renderTitle(
-    title: string | undefined,
-    onTitleClick: (event: React.MouseEvent<Element, MouseEvent>) => void,
-    hasTitleClickListener: boolean,
-    isSelected: boolean,
-    hasDisplayValue: boolean,
-  ) {
-    // TODO add contextual menu panel on click
-    if (!title) {
-      return null;
+  onLegendItemMouseOver = () => {
+    const { onLegendItemOverListener, legendItemOverAction, legendItem } = this.props;
+    // call the settings listener directly if available
+    if (onLegendItemOverListener) {
+      onLegendItemOverListener(legendItem.value);
     }
-    const titleClassNames = classNames('echLegendItem__title', {
-      ['echLegendItem__title--hasClickListener']: hasTitleClickListener,
-      ['echLegendItem__title--selected']: isSelected,
-      ['echLegendItem__title--hasDisplayValue']: hasDisplayValue,
-    });
-    return (
-      <div className={titleClassNames} title={title} onClick={onTitleClick}>
-        {title}
-      </div>
-    );
-  }
+    legendItemOverAction(legendItem.key);
+  };
 
-  renderDisplayValue(displayValue: string, show: boolean, isSeriesVisible: boolean | undefined) {
-    if (!show) {
-      return;
+  onLegendItemMouseOut = () => {
+    const { onLegendItemOutListener, legendItemOutAction } = this.props;
+    // call the settings listener directly if available
+    if (onLegendItemOutListener) {
+      onLegendItemOutListener();
     }
-    const displayValueClassNames = classNames('echLegendItem__displayValue', {
-      ['echLegendItem__displayValue--hidden']: !isSeriesVisible,
-    });
-    return (
-      <div className={displayValueClassNames} title={displayValue}>
-        {displayValue}
-      </div>
-    );
-  }
-
-  onLegendTitleClick = (legendItemKey: string) => () => {
-    this.props.chartStore!.onLegendItemClick(legendItemKey);
+    legendItemOutAction();
   };
 
-  // Keeping these as reference when we have a contextual panel
-  // private onLegendItemPanelClose = () => {
-  //   // tslint:disable-next-line:no-console
-  //   console.log('close');
-  // }
-
-  // private onColorPickerChange = (legendItemKey: string) => (color: string) => {
-  //   this.props.chartStore!.setSeriesColor(legendItemKey, color);
-  // }
-
-  // private renderPlusButton = () => {
-  //   return (
-  //     <EuiButtonIcon
-  //       onClick={this.props.chartStore!.onLegendItemPlusClick}
-  //       iconType="plusInCircle"
-  //       aria-label="minus"
-  //     />
-  //   );
-  // }
-
-  // private renderMinusButton = () => {
-  //   return (
-  //     <EuiButtonIcon
-  //       onClick={this.props.chartStore!.onLegendItemMinusClick}
-  //       iconType="minusInCircle"
-  //       aria-label="minus"
-  //     />
-  //   );
-  // }
-
-  private onVisibilityClick = (legendItemKey: string) => (event: React.MouseEvent) => {
-    if (event.shiftKey) {
-      this.props.chartStore!.toggleSingleSeries(legendItemKey);
-    } else {
-      this.props.chartStore!.toggleSeriesVisibility(legendItemKey);
+  // TODO handle shift key
+  onVisibilityClick = (legendItemId: DataSeriesColorsValues) => () => {
+    const { onLegendItemClickListener, toggleDeselectSeriesAction } = this.props;
+    if (onLegendItemClickListener) {
+      onLegendItemClickListener(legendItemId);
     }
+    toggleDeselectSeriesAction(legendItemId);
   };
 }
-
-export const LegendItem = inject('chartStore')(observer(LegendItemComponent));
diff --git a/src/components/react_canvas/bar_values.tsx b/src/components/react_canvas/bar_values.tsx
deleted file mode 100644
index 327efb529e..0000000000
--- a/src/components/react_canvas/bar_values.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import React from 'react';
-import { Group, Rect, Text } from 'react-konva';
-import { BarGeometry } from '../../chart_types/xy_chart/rendering/rendering';
-import { Rotation } from '../../chart_types/xy_chart/utils/specs';
-import { DisplayValueStyle } from '../../utils/themes/theme';
-import { Dimensions } from '../../utils/dimensions';
-import { buildBarValueProps } from './utils/rendering_props_utils';
-
-interface BarValuesProps {
-  chartDimensions: Dimensions;
-  chartRotation: Rotation;
-  debug: boolean;
-  bars: BarGeometry[];
-  displayValueStyle: DisplayValueStyle;
-}
-
-export class BarValues extends React.PureComponent<BarValuesProps> {
-  render() {
-    const { chartDimensions } = this.props;
-
-    return (
-      <Group x={chartDimensions.left} y={chartDimensions.top}>
-        {this.renderBarValues()}
-      </Group>
-    );
-  }
-
-  private renderBarValues = () => {
-    const { bars, displayValueStyle, debug, chartRotation, chartDimensions } = this.props;
-    return bars.map((bar, index) => {
-      const { displayValue, x, y, height, width } = bar;
-      if (!displayValue) {
-        return;
-      }
-
-      const key = `bar-value-${index}`;
-      const displayValueProps = buildBarValueProps({
-        x,
-        y,
-        barHeight: height,
-        barWidth: width,
-        displayValueStyle,
-        displayValue,
-        chartRotation,
-        chartDimensions,
-      });
-
-      const debugProps = {
-        ...displayValueProps,
-        stroke: 'violet',
-        strokeWidth: 1,
-        fill: 'transparent',
-      };
-
-      return (
-        <Group key={key}>
-          {debug && <Rect {...debugProps} />}
-          {displayValue && <Text {...displayValueProps} />}
-        </Group>
-      );
-    });
-  };
-}
diff --git a/src/components/react_canvas/chart_container.tsx b/src/components/react_canvas/chart_container.tsx
deleted file mode 100644
index c455eb89b8..0000000000
--- a/src/components/react_canvas/chart_container.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import React from 'react';
-import { inject, observer } from 'mobx-react';
-import { ChartStore } from '../../chart_types/xy_chart/store/chart_state';
-import { ReactiveChart } from './reactive_chart';
-import { Stage } from 'react-konva';
-interface ReactiveChartProps {
-  chartStore?: ChartStore; // FIX until we find a better way on ts mobx
-  forwardRef: React.RefObject<Stage>;
-}
-
-class ChartContainerComponent extends React.Component<ReactiveChartProps> {
-  static displayName = 'ChartContainer';
-
-  render() {
-    const { chartInitialized } = this.props.chartStore!;
-    if (!chartInitialized.get()) {
-      return null;
-    }
-    const { setCursorPosition, isChartEmpty } = this.props.chartStore!;
-    return (
-      <div
-        className="echChartCursorContainer"
-        style={{
-          cursor: this.props.chartStore!.chartCursor.get(),
-        }}
-        onMouseMove={({ nativeEvent: { offsetX, offsetY } }) => {
-          if (!isChartEmpty.get()) {
-            setCursorPosition(offsetX, offsetY);
-          }
-        }}
-        onMouseLeave={() => {
-          setCursorPosition(-1, -1);
-        }}
-        onMouseUp={() => {
-          if (this.props.chartStore!.isBrushing.get()) {
-            return;
-          }
-          this.props.chartStore!.handleChartClick();
-        }}
-      >
-        <ReactiveChart forwardRef={this.props.forwardRef} />
-      </div>
-    );
-  }
-}
-
-export const ChartContainer = inject('chartStore')(observer(ChartContainerComponent));
diff --git a/src/components/react_canvas/reactive_chart.tsx b/src/components/react_canvas/reactive_chart.tsx
deleted file mode 100644
index 83ee14327b..0000000000
--- a/src/components/react_canvas/reactive_chart.tsx
+++ /dev/null
@@ -1,473 +0,0 @@
-import React from 'react';
-import { inject, observer } from 'mobx-react';
-import { Layer, Rect, Stage } from 'react-konva';
-
-import { AnnotationId } from '../../utils/ids';
-import { isLineAnnotation, isRectAnnotation, AxisSpec } from '../../chart_types/xy_chart/utils/specs';
-import { LineAnnotationStyle, RectAnnotationStyle, mergeGridLineConfigs } from '../../utils/themes/theme';
-import {
-  AnnotationDimensions,
-  AnnotationLineProps,
-  AnnotationRectProps,
-} from '../../chart_types/xy_chart/annotations/annotation_utils';
-import { ChartStore, Point } from '../../chart_types/xy_chart/store/chart_state';
-import { BrushExtent } from '../../chart_types/xy_chart/store/utils';
-import { AreaGeometries } from './area_geometries';
-import { Axis } from './axis';
-import { BarGeometries } from './bar_geometries';
-import { BarValues } from './bar_values';
-import { Grid } from './grid';
-import { LineAnnotation } from './line_annotation';
-import { LineGeometries } from './line_geometries';
-import { RectAnnotation } from './rect_annotation';
-import { AxisTick, AxisTicksDimensions, isVerticalGrid } from '../../chart_types/xy_chart/utils/axis_utils';
-import { Dimensions } from '../../utils/dimensions';
-import { Clippings } from './utils/rendering_props_utils';
-
-interface ReactiveChartProps {
-  chartStore?: ChartStore; // FIX until we find a better way on ts mobx
-  forwardRef: React.RefObject<Stage>;
-}
-interface ReactiveChartState {
-  brushing: boolean;
-  brushStart: Point;
-  brushEnd: Point;
-  bbox: {
-    left: number;
-    top: number;
-  };
-}
-
-interface AxisProps {
-  key: string;
-  axisSpec: AxisSpec;
-  axisTicksDimensions: AxisTicksDimensions;
-  axisPosition: Dimensions;
-  ticks: AxisTick[];
-}
-
-interface ReactiveChartElementIndex {
-  element: JSX.Element;
-  zIndex: number;
-}
-
-function limitPoint(value: number, min: number, max: number) {
-  if (value > max) {
-    return max;
-  } else if (value < min) {
-    return min;
-  } else {
-    return value;
-  }
-}
-function getPoint(event: MouseEvent, extent: BrushExtent): Point {
-  const point = {
-    x: limitPoint(event.offsetX, extent.minX, extent.maxX),
-    y: limitPoint(event.offsetY, extent.minY, extent.maxY),
-  };
-  return point;
-}
-class Chart extends React.Component<ReactiveChartProps, ReactiveChartState> {
-  static displayName = 'ReactiveChart';
-  firstRender = true;
-  state = {
-    brushing: false,
-    brushStart: {
-      x: 0,
-      y: 0,
-    },
-    brushEnd: {
-      x: 0,
-      y: 0,
-    },
-    bbox: {
-      left: 0,
-      top: 0,
-    },
-  };
-
-  componentWillUnmount() {
-    window.removeEventListener('mouseup', this.onEndBrushing);
-  }
-
-  renderBarSeries = (clippings: Clippings): ReactiveChartElementIndex[] => {
-    const { geometries, canDataBeAnimated, chartTheme } = this.props.chartStore!;
-    if (!geometries) {
-      return [];
-    }
-    const highlightedLegendItem = this.getHighlightedLegendItem();
-    const element = (
-      <BarGeometries
-        key={'bar-geometries'}
-        animated={canDataBeAnimated}
-        bars={geometries.bars}
-        sharedStyle={chartTheme.sharedStyle}
-        highlightedLegendItem={highlightedLegendItem}
-        clippings={clippings}
-      />
-    );
-
-    return [
-      {
-        element,
-        zIndex: 0,
-      },
-    ];
-  };
-  renderLineSeries = (clippings: Clippings): ReactiveChartElementIndex[] => {
-    const { geometries, canDataBeAnimated, chartTheme } = this.props.chartStore!;
-    if (!geometries) {
-      return [];
-    }
-
-    const highlightedLegendItem = this.getHighlightedLegendItem();
-
-    const element = (
-      <LineGeometries
-        key={'line-geometries'}
-        animated={canDataBeAnimated}
-        lines={geometries.lines}
-        sharedStyle={chartTheme.sharedStyle}
-        highlightedLegendItem={highlightedLegendItem}
-        clippings={clippings}
-      />
-    );
-
-    return [
-      {
-        element,
-        zIndex: 0,
-      },
-    ];
-  };
-  renderAreaSeries = (clippings: Clippings): ReactiveChartElementIndex[] => {
-    const { geometries, canDataBeAnimated, chartTheme } = this.props.chartStore!;
-    if (!geometries) {
-      return [];
-    }
-
-    const highlightedLegendItem = this.getHighlightedLegendItem();
-
-    const element = (
-      <AreaGeometries
-        key={'area-geometries'}
-        animated={canDataBeAnimated}
-        areas={geometries.areas}
-        sharedStyle={chartTheme.sharedStyle}
-        highlightedLegendItem={highlightedLegendItem}
-        clippings={clippings}
-      />
-    );
-
-    return [
-      {
-        element,
-        zIndex: 0,
-      },
-    ];
-  };
-
-  getAxes = (): AxisProps[] => {
-    const { axesVisibleTicks, axesSpecs, axesTicksDimensions, axesPositions } = this.props.chartStore!;
-    const ids = [...axesVisibleTicks.keys()];
-
-    return ids
-      .map((id) => ({
-        key: `axis-${id}`,
-        ticks: axesVisibleTicks.get(id),
-        axisSpec: axesSpecs.get(id),
-        axisTicksDimensions: axesTicksDimensions.get(id),
-        axisPosition: axesPositions.get(id),
-      }))
-      .filter(
-        (config: Partial<AxisProps>): config is AxisProps => {
-          const { ticks, axisSpec, axisTicksDimensions, axisPosition } = config;
-
-          return Boolean(ticks && axisSpec && axisTicksDimensions && axisPosition);
-        },
-      );
-  };
-
-  renderAxes = (): JSX.Element[] => {
-    const { chartTheme, debug, chartDimensions } = this.props.chartStore!;
-    const axes = this.getAxes();
-
-    return axes.map(({ key, ...axisProps }) => (
-      <Axis {...axisProps} key={key} chartTheme={chartTheme} debug={debug} chartDimensions={chartDimensions} />
-    ));
-  };
-
-  renderGrids = () => {
-    const { axesGridLinesPositions, axesSpecs, chartDimensions, chartTheme, debug } = this.props.chartStore!;
-
-    const gridComponents: JSX.Element[] = [];
-    axesGridLinesPositions.forEach((axisGridLinesPositions, axisId) => {
-      const axisSpec = axesSpecs.get(axisId);
-
-      if (axisSpec && axisGridLinesPositions.length > 0) {
-        const themeConfig = isVerticalGrid(axisSpec.position)
-          ? chartTheme.axes.gridLineStyle.vertical
-          : chartTheme.axes.gridLineStyle.horizontal;
-
-        const axisSpecConfig = axisSpec.gridLineStyle;
-        const gridLineStyle = axisSpecConfig ? mergeGridLineConfigs(axisSpecConfig, themeConfig) : themeConfig;
-        gridComponents.push(
-          <Grid
-            key={`axis-grid-${axisId}`}
-            chartDimensions={chartDimensions}
-            debug={debug}
-            gridLineStyle={gridLineStyle}
-            linesPositions={axisGridLinesPositions}
-          />,
-        );
-      }
-    });
-    return gridComponents;
-  };
-
-  renderAnnotations = (): ReactiveChartElementIndex[] => {
-    const { annotationDimensions, annotationSpecs, chartDimensions, debug } = this.props.chartStore!;
-
-    const annotationElements: ReactiveChartElementIndex[] = [];
-    annotationDimensions.forEach((annotation: AnnotationDimensions, id: AnnotationId) => {
-      const spec = annotationSpecs.get(id);
-
-      if (!spec) {
-        return;
-      }
-
-      const zIndex = spec.zIndex || 0;
-      let element;
-      if (isLineAnnotation(spec)) {
-        const lineStyle = spec.style as LineAnnotationStyle;
-
-        element = (
-          <LineAnnotation
-            key={`annotation-${id}`}
-            chartDimensions={chartDimensions}
-            debug={debug}
-            lines={annotation as AnnotationLineProps[]}
-            lineStyle={lineStyle}
-          />
-        );
-      } else if (isRectAnnotation(spec)) {
-        const rectStyle = spec.style as RectAnnotationStyle;
-        element = (
-          <RectAnnotation
-            key={`annotation-${id}`}
-            chartDimensions={chartDimensions}
-            debug={debug}
-            rects={annotation as AnnotationRectProps[]}
-            rectStyle={rectStyle}
-          />
-        );
-      }
-
-      if (element) {
-        annotationElements.push({
-          element,
-          zIndex,
-        });
-      }
-    });
-    return annotationElements;
-  };
-
-  renderBarValues = () => {
-    const { debug, chartDimensions, geometries, chartTheme, chartRotation } = this.props.chartStore!;
-    if (!geometries) {
-      return;
-    }
-    const props = {
-      debug,
-      chartDimensions,
-      chartRotation,
-      bars: geometries.bars,
-      // displayValue is guaranteed on style as part of the merged theme
-      displayValueStyle: chartTheme.barSeriesStyle.displayValue!,
-    };
-    return <BarValues {...props} />;
-  };
-
-  renderBrushTool = () => {
-    const { brushing, brushStart, brushEnd } = this.state;
-    const { chartDimensions, chartRotation, chartTransform } = this.props.chartStore!;
-    if (!brushing) {
-      return null;
-    }
-    let x = 0;
-    let y = 0;
-    let width = 0;
-    let height = 0;
-    if (chartRotation === 0 || chartRotation === 180) {
-      x = brushStart.x;
-      y = chartDimensions.top + chartTransform.y;
-      width = brushEnd.x - brushStart.x;
-      height = chartDimensions.height;
-    } else {
-      x = chartDimensions.left + chartTransform.x;
-      y = brushStart.y;
-      width = chartDimensions.width;
-      height = brushEnd.y - brushStart.y;
-    }
-    return <Rect x={x} y={y} width={width} height={height} fill="gray" opacity={0.6} />;
-  };
-  onStartBrusing = (event: { evt: MouseEvent }) => {
-    window.addEventListener('mouseup', this.onEndBrushing);
-    const { brushExtent } = this.props.chartStore!;
-    const point = getPoint(event.evt, brushExtent);
-    this.setState(() => ({
-      brushing: true,
-      brushStart: point,
-      brushEnd: point,
-    }));
-  };
-  onEndBrushing = () => {
-    window.removeEventListener('mouseup', this.onEndBrushing);
-    const { brushStart, brushEnd } = this.state;
-
-    this.setState(
-      () => ({
-        brushing: false,
-        brushStart: { x: 0, y: 0 },
-        brushEnd: { x: 0, y: 0 },
-      }),
-      () => {
-        this.props.chartStore!.onBrushEnd(brushStart, brushEnd);
-      },
-    );
-  };
-  onBrushing = (event: { evt: MouseEvent }) => {
-    if (!this.state.brushing) {
-      return;
-    }
-    if (!this.props.chartStore!.isBrushing.get()) {
-      this.props.chartStore!.onBrushStart();
-    }
-    const { brushExtent } = this.props.chartStore!;
-    const point = getPoint(event.evt, brushExtent);
-    this.setState(() => ({
-      brushEnd: point,
-    }));
-  };
-
-  sortAndRenderElements() {
-    const { chartRotation, chartDimensions } = this.props.chartStore!;
-    const { height, width } = chartDimensions;
-    const clippings = {
-      clipX: 0,
-      clipY: 0,
-      clipWidth: [90, -90].includes(chartRotation) ? height : width,
-      clipHeight: [90, -90].includes(chartRotation) ? width : height,
-    };
-
-    const bars = this.renderBarSeries(clippings);
-    const areas = this.renderAreaSeries(clippings);
-    const lines = this.renderLineSeries(clippings);
-    const annotations = this.renderAnnotations();
-
-    return [...bars, ...areas, ...lines, ...annotations]
-      .sort((elemIdxA, elemIdxB) => elemIdxA.zIndex - elemIdxB.zIndex)
-      .map((elemIdx) => elemIdx.element);
-  }
-
-  render() {
-    const { chartInitialized } = this.props.chartStore!;
-    if (!chartInitialized.get()) {
-      return null;
-    }
-
-    const {
-      parentDimensions,
-      chartDimensions,
-      chartRotation,
-      chartTransform,
-      debug,
-      isChartEmpty,
-    } = this.props.chartStore!;
-
-    if (isChartEmpty.get()) {
-      return (
-        <div className="echReactiveChart_unavailable">
-          <p>No data to display</p>
-        </div>
-      );
-    }
-
-    let brushProps = {};
-    const isBrushEnabled = this.props.chartStore!.isBrushEnabled();
-    if (isBrushEnabled) {
-      brushProps = {
-        onMouseDown: this.onStartBrusing,
-        onMouseMove: this.onBrushing,
-      };
-    }
-
-    return (
-      <Stage
-        width={parentDimensions.width}
-        height={parentDimensions.height}
-        style={{
-          width: '100%',
-          height: '100%',
-        }}
-        {...brushProps}
-        ref={this.props.forwardRef}
-      >
-        <Layer hitGraphEnabled={false} listening={false}>
-          {this.renderGrids()}
-        </Layer>
-        <Layer hitGraphEnabled={false} listening={false}>
-          {this.renderAxes()}
-        </Layer>
-
-        <Layer
-          x={chartDimensions.left + chartTransform.x}
-          y={chartDimensions.top + chartTransform.y}
-          rotation={chartRotation}
-          hitGraphEnabled={false}
-          listening={false}
-        >
-          {this.sortAndRenderElements()}
-        </Layer>
-
-        {debug && (
-          <Layer hitGraphEnabled={false} listening={false}>
-            {this.renderDebugChartBorders()}
-          </Layer>
-        )}
-        {isBrushEnabled && (
-          <Layer hitGraphEnabled={false} listening={false}>
-            {this.renderBrushTool()}
-          </Layer>
-        )}
-
-        <Layer hitGraphEnabled={false} listening={false}>
-          {this.renderBarValues()}
-        </Layer>
-      </Stage>
-    );
-  }
-
-  private renderDebugChartBorders = () => {
-    const { chartDimensions } = this.props.chartStore!;
-    return (
-      <Rect
-        x={chartDimensions.left}
-        y={chartDimensions.top}
-        width={chartDimensions.width}
-        height={chartDimensions.height}
-        stroke="red"
-        strokeWidth={4}
-        listening={false}
-        dash={[4, 4]}
-      />
-    );
-  };
-
-  private getHighlightedLegendItem = () => {
-    return this.props.chartStore!.highlightedLegendItem.get();
-  };
-}
-
-export const ReactiveChart = inject('chartStore')(observer(Chart));
diff --git a/src/components/react_canvas/rect_annotation.tsx b/src/components/react_canvas/rect_annotation.tsx
deleted file mode 100644
index 13f984e075..0000000000
--- a/src/components/react_canvas/rect_annotation.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react';
-import { Group, Rect } from 'react-konva';
-import { RectAnnotationStyle } from '../../utils/themes/theme';
-import { Dimensions } from '../../utils/dimensions';
-import { AnnotationRectProps } from '../../chart_types/xy_chart/annotations/annotation_utils';
-
-interface RectAnnotationProps {
-  chartDimensions: Dimensions;
-  debug: boolean;
-  rects: AnnotationRectProps[];
-  rectStyle: RectAnnotationStyle;
-}
-
-export class RectAnnotation extends React.PureComponent<RectAnnotationProps> {
-  render() {
-    return this.renderAnnotation();
-  }
-  private renderAnnotationRect = (props: AnnotationRectProps, i: number) => {
-    const { x, y, width, height } = props.rect;
-    const rectProps = {
-      ...this.props.rectStyle,
-      x,
-      y,
-      width,
-      height,
-    };
-
-    return <Rect {...rectProps} key={`rect-${i}`} />;
-  };
-
-  private renderAnnotation = () => {
-    const { rects } = this.props;
-
-    return <Group>{rects.map(this.renderAnnotationRect)}</Group>;
-  };
-}
diff --git a/src/index.ts b/src/index.ts
index 2a0ac16032..e231d32cda 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,10 +1,8 @@
 export * from './specs';
 export { Chart } from './components/chart';
 export { ChartSize, ChartSizeArray, ChartSizeObject } from './utils/chart_size';
-export { TooltipType, TooltipValue, TooltipValueFormatter } from './chart_types/xy_chart/utils/interactions';
 export { SpecId, GroupId, AxisId, AnnotationId, getAxisId, getGroupId, getSpecId, getAnnotationId } from './utils/ids';
 export { ScaleType } from './utils/scales/scales';
-export { Position, Rendering, Rotation, TickFormatter } from './chart_types/xy_chart/utils/specs';
 export * from './utils/themes/theme';
 export { LIGHT_THEME } from './utils/themes/light_theme';
 export { DARK_THEME } from './utils/themes/dark_theme';
@@ -13,6 +11,9 @@ export { RecursivePartial } from './utils/commons';
 export { CurveType } from './utils/curves';
 export { timeFormatter, niceTimeFormatter, niceTimeFormatByDay } from './utils/data/formatters';
 export { DataGenerator } from './utils/data_generators/data_generator';
+export { ChartTypes } from './chart_types';
+export { Position, Rendering, Rotation, TickFormatter } from './chart_types/xy_chart/utils/specs';
+export { TooltipType, TooltipValue, TooltipValueFormatter } from './chart_types/xy_chart/utils/interactions';
 export { DataSeriesColorsValues } from './chart_types/xy_chart/utils/series';
 export {
   AnnotationDomainType,
@@ -24,16 +25,8 @@ export {
   LineAnnotationSpec,
   RectAnnotationDatum,
   RectAnnotationSpec,
+  SeriesTypes,
+  SpecTypes,
 } from './chart_types/xy_chart/utils/specs';
-export { GeometryValue } from './chart_types/xy_chart/rendering/rendering';
 export { AnnotationTooltipFormatter } from './chart_types/xy_chart/annotations/annotation_utils';
-export { SettingSpecProps } from './specs/settings';
-export {
-  BrushEndListener,
-  ElementClickListener,
-  ElementOverListener,
-  LegendItemListener,
-  CursorUpdateListener,
-  RenderChangeListener,
-  BasicListener,
-} from './chart_types/xy_chart/store/chart_state';
+export { GeometryValue } from './utils/geometry';
diff --git a/src/mocks/scale/scale.ts b/src/mocks/scale/scale.ts
index 53384e29f1..386988db6a 100644
--- a/src/mocks/scale/scale.ts
+++ b/src/mocks/scale/scale.ts
@@ -6,6 +6,7 @@ export class MockScale {
     scale: jest.fn().mockImplementation((x) => x),
     type: ScaleType.Linear,
     bandwidth: 0,
+    bandwidthPadding: 0,
     minInterval: 0,
     barsPadding: 0,
     range: [0, 100],
diff --git a/src/mocks/specs/specs.ts b/src/mocks/specs/specs.ts
index c889979131..0a831adfec 100644
--- a/src/mocks/specs/specs.ts
+++ b/src/mocks/specs/specs.ts
@@ -8,14 +8,19 @@ import {
   HistogramBarSeriesSpec,
   LineSeriesSpec,
   BasicSeriesSpec,
+  SpecTypes,
+  SeriesTypes,
 } from '../../chart_types/xy_chart/utils/specs';
-import { getSpecId, getGroupId, SpecId } from '../../utils/ids';
+import { getSpecId, getGroupId } from '../../utils/ids';
 import { ScaleType } from '../../utils/scales/scales';
+import { ChartTypes } from '../../chart_types';
 
 export class MockSeriesSpec {
   private static readonly barBase: BarSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: getSpecId('spec1'),
-    seriesType: 'bar',
+    seriesType: SeriesTypes.Bar,
     groupId: getGroupId(DEFAULT_GLOBAL_ID),
     xScaleType: ScaleType.Ordinal,
     yScaleType: ScaleType.Linear,
@@ -25,12 +30,14 @@ export class MockSeriesSpec {
     hideInLegend: false,
     enableHistogramMode: false,
     stackAsPercentage: false,
-    data: [],
+    data: [] as any[],
   };
 
   private static readonly histogramBarBase: HistogramBarSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: getSpecId('spec1'),
-    seriesType: 'bar',
+    seriesType: SeriesTypes.Bar,
     groupId: getGroupId(DEFAULT_GLOBAL_ID),
     xScaleType: ScaleType.Ordinal,
     yScaleType: ScaleType.Linear,
@@ -43,8 +50,10 @@ export class MockSeriesSpec {
   };
 
   private static readonly areaBase: AreaSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: getSpecId('spec1'),
-    seriesType: 'area',
+    seriesType: SeriesTypes.Area,
     groupId: getGroupId(DEFAULT_GLOBAL_ID),
     xScaleType: ScaleType.Ordinal,
     yScaleType: ScaleType.Linear,
@@ -57,8 +66,10 @@ export class MockSeriesSpec {
   };
 
   private static readonly lineBase: LineSeriesSpec = {
+    chartType: ChartTypes.XYAxis,
+    specType: SpecTypes.Series,
     id: getSpecId('spec1'),
-    seriesType: 'line',
+    seriesType: SeriesTypes.Line,
     groupId: getGroupId(DEFAULT_GLOBAL_ID),
     xScaleType: ScaleType.Ordinal,
     yScaleType: ScaleType.Linear,
@@ -91,11 +102,10 @@ export class MockSeriesSpec {
 
 export class MockSeriesSpecs {
   static fromSpecs(specs: BasicSeriesSpec[]): SeriesSpecs {
-    const specsMap: [SpecId, BasicSeriesSpec][] = specs.map((spec) => [spec.id, spec]);
-    return new Map(specsMap);
+    return specs;
   }
 
   static empty(): SeriesSpecs {
-    return new Map();
+    return [];
   }
 }
diff --git a/src/specs/index.ts b/src/specs/index.ts
index aed77a90a9..29bbf5feaf 100644
--- a/src/specs/index.ts
+++ b/src/specs/index.ts
@@ -1,3 +1,13 @@
-export { Settings, CursorEvent } from './settings';
-// XY chart specs
-export * from '../chart_types/xy_chart/specs';
+import { ChartTypes } from '../chart_types';
+
+export interface Spec {
+  /** unique Spec identifier */
+  id: string;
+  /** Chart type define the type of chart that use this spec */
+  chartType: ChartTypes;
+  /** The type of spec, can be series, axis, annotation, settings etc*/
+  specType: string;
+}
+export * from './settings';
+
+export * from '../chart_types/specs';
diff --git a/src/specs/settings.test.tsx b/src/specs/settings.test.tsx
index caa6cde14c..e3f43a4627 100644
--- a/src/specs/settings.test.tsx
+++ b/src/specs/settings.test.tsx
@@ -3,115 +3,105 @@ import * as React from 'react';
 import { Position, Rendering, Rotation } from '../chart_types/xy_chart/utils/specs';
 import { DARK_THEME } from '../utils/themes/dark_theme';
 import { TooltipType } from '../chart_types/xy_chart/utils/interactions';
-import { ChartStore } from '../chart_types/xy_chart/store/chart_state';
-import { DEFAULT_TOOLTIP_SNAP, DEFAULT_TOOLTIP_TYPE, SettingsComponent, SettingSpecProps } from './settings';
+import { Settings, SettingsSpec } from './settings';
 import { PartialTheme } from '../utils/themes/theme';
 import { LIGHT_THEME } from '../utils/themes/light_theme';
-
+import { chartStoreReducer, GlobalChartState } from '../state/chart_state';
+import { createStore, Store } from 'redux';
+import { SpecsParser } from './specs_parser';
+import { Provider } from 'react-redux';
+import { getSettingsSpecSelector } from '../state/selectors/get_settings_specs';
+import { getChartThemeSelector } from '../state/selectors/get_chart_theme';
+
+const getProxy = (chartStore: Store<GlobalChartState>) => {
+  return function SettingsProxy({ settings }: { settings?: Partial<SettingsSpec> }) {
+    return (
+      <Provider store={chartStore}>
+        <SpecsParser>
+          <Settings {...settings} />
+        </SpecsParser>
+      </Provider>
+    );
+  };
+};
 describe('Settings spec component', () => {
+  let chartStore: Store<GlobalChartState>;
+  let SettingsProxy: ({ settings }: { settings?: Partial<SettingsSpec> }) => JSX.Element;
+  beforeEach(() => {
+    const storeReducer = chartStoreReducer('chart_id');
+    chartStore = createStore(storeReducer);
+    expect(chartStore.getState().specsInitialized).toBe(false);
+    SettingsProxy = getProxy(chartStore);
+  });
   test('should update store on mount if spec has a chart store', () => {
-    const chartStore = new ChartStore();
-
-    // component without store
-    mount(<SettingsComponent rotation={90} />);
-    expect(chartStore.chartRotation).toBe(0);
-
-    mount(<SettingsComponent rotation={90} chartStore={chartStore} />);
-    expect(chartStore.chartRotation).toBe(90);
+    mount(
+      <Provider store={chartStore}>
+        <SpecsParser />
+      </Provider>,
+    );
+    expect(getSettingsSpecSelector(chartStore.getState()).rotation).toBe(0);
+
+    mount(
+      <Provider store={chartStore}>
+        <SpecsParser>
+          <Settings rotation={90} />
+        </SpecsParser>
+      </Provider>,
+    );
+    expect(getSettingsSpecSelector(chartStore.getState()).rotation).toBe(90);
   });
 
   test('should update store on component update', () => {
-    const chartStore = new ChartStore();
-
-    const component = mount(<SettingsComponent chartStore={chartStore} />);
+    const component = mount(<SettingsProxy />);
+    let settingSpec = getSettingsSpecSelector(chartStore.getState());
+    expect(settingSpec.theme).toEqual(LIGHT_THEME);
+    expect(settingSpec.rotation).toBe(0);
     component.setProps({
-      theme: DARK_THEME,
-      rotation: 90 as Rotation,
-      rendering: 'svg' as Rendering,
-      animateData: true,
-      showLegend: true,
-      tooltip: {
-        type: TooltipType.None,
-        snap: false,
+      settings: {
+        theme: DARK_THEME,
+        rotation: 90 as Rotation,
+        rendering: 'svg' as Rendering,
+        animateData: true,
+        showLegend: true,
+        tooltip: {
+          type: TooltipType.None,
+          snap: false,
+        },
+        legendPosition: Position.Bottom,
+        showLegendDisplayValue: false,
+        debug: true,
+        xDomain: { min: 0, max: 10 },
       },
-      legendPosition: Position.Bottom,
-      showLegendDisplayValue: false,
-      debug: true,
-      xDomain: { min: 0, max: 10 },
     });
-
-    expect(chartStore.chartTheme).toEqual(DARK_THEME);
-    expect(chartStore.chartRotation).toBe(90);
-    expect(chartStore.chartRendering).toBe('svg');
-    expect(chartStore.animateData).toBe(true);
-    expect(chartStore.showLegend.get()).toEqual(true);
-    expect(chartStore.tooltipType.get()).toEqual(TooltipType.None);
-    expect(chartStore.tooltipSnap.get()).toEqual(false);
-    expect(chartStore.legendPosition.get()).toBe(Position.Bottom);
-    expect(chartStore.showLegendDisplayValue.get()).toEqual(false);
-    expect(chartStore.debug).toBe(true);
-    expect(chartStore.customXDomain).toEqual({ min: 0, max: 10 });
-  });
-
-  test('should set chart properties on chart store', () => {
-    const chartStore = new ChartStore();
-
-    expect(chartStore.chartTheme).toEqual(LIGHT_THEME);
-    expect(chartStore.chartRotation).toBe(0);
-    expect(chartStore.chartRendering).toBe('canvas');
-    expect(chartStore.animateData).toBe(false);
-    expect(chartStore.showLegend.get()).toEqual(false);
-    expect(chartStore.tooltipType.get()).toEqual(DEFAULT_TOOLTIP_TYPE);
-    expect(chartStore.tooltipSnap.get()).toEqual(DEFAULT_TOOLTIP_SNAP);
-    expect(chartStore.showLegendDisplayValue.get()).toEqual(true);
-    expect(chartStore.legendPosition.get()).toBe(Position.Right);
-    expect(chartStore.debug).toBe(false);
-    expect(chartStore.customXDomain).toBeUndefined();
-
-    const updatedProps: SettingSpecProps = {
-      theme: DARK_THEME,
-      rotation: 90 as Rotation,
-      rendering: 'svg' as Rendering,
-      animateData: true,
-      showLegend: true,
-      tooltip: {
-        type: TooltipType.None,
-        snap: false,
-      },
-      legendPosition: Position.Bottom,
-      hideDuplicateAxes: false,
-      showLegendDisplayValue: false,
-      debug: true,
-      xDomain: { min: 0, max: 10 },
-    };
-
-    mount(<SettingsComponent chartStore={chartStore} {...updatedProps} />);
-
-    expect(chartStore.chartTheme).toEqual(DARK_THEME);
-    expect(chartStore.chartRotation).toBe(90);
-    expect(chartStore.chartRendering).toBe('svg');
-    expect(chartStore.animateData).toBe(true);
-    expect(chartStore.showLegend.get()).toEqual(true);
-    expect(chartStore.tooltipType.get()).toEqual(TooltipType.None);
-    expect(chartStore.tooltipSnap.get()).toEqual(false);
-    expect(chartStore.legendPosition.get()).toBe(Position.Bottom);
-    expect(chartStore.showLegendDisplayValue.get()).toEqual(false);
-    expect(chartStore.debug).toBe(true);
-    expect(chartStore.customXDomain).toEqual({ min: 0, max: 10 });
+    settingSpec = getSettingsSpecSelector(chartStore.getState());
+    expect(settingSpec.theme).toEqual(DARK_THEME);
+    expect(settingSpec.rotation).toBe(90);
+    expect(settingSpec.rendering).toBe('svg');
+    expect(settingSpec.animateData).toBe(true);
+    expect(settingSpec.showLegend).toEqual(true);
+    expect(settingSpec.tooltip).toEqual({
+      type: TooltipType.None,
+      snap: false,
+    });
+    expect(settingSpec.legendPosition).toBe(Position.Bottom);
+    expect(settingSpec.showLegendDisplayValue).toEqual(false);
+    expect(settingSpec.debug).toBe(true);
+    expect(settingSpec.xDomain).toEqual({ min: 0, max: 10 });
   });
 
   test('should set event listeners on chart store', () => {
-    const chartStore = new ChartStore();
-
-    expect(chartStore.onElementClickListener).toBeUndefined();
-    expect(chartStore.onElementOverListener).toBeUndefined();
-    expect(chartStore.onElementOutListener).toBeUndefined();
-    expect(chartStore.onBrushEndListener).toBeUndefined();
-    expect(chartStore.onLegendItemOverListener).toBeUndefined();
-    expect(chartStore.onLegendItemOutListener).toBeUndefined();
-    expect(chartStore.onLegendItemClickListener).toBeUndefined();
-    expect(chartStore.onLegendItemPlusClickListener).toBeUndefined();
-    expect(chartStore.onLegendItemMinusClickListener).toBeUndefined();
+    mount(<SettingsProxy />);
+    let settingSpec = getSettingsSpecSelector(chartStore.getState());
+
+    expect(settingSpec.onElementClick).toBeUndefined();
+    expect(settingSpec.onElementOver).toBeUndefined();
+    expect(settingSpec.onElementOut).toBeUndefined();
+    expect(settingSpec.onBrushEnd).toBeUndefined();
+    expect(settingSpec.onLegendItemOver).toBeUndefined();
+    expect(settingSpec.onLegendItemOut).toBeUndefined();
+    expect(settingSpec.onLegendItemClick).toBeUndefined();
+    expect(settingSpec.onLegendItemPlusClick).toBeUndefined();
+    expect(settingSpec.onLegendItemMinusClick).toBeUndefined();
 
     const onElementClick = (): void => {
       return;
@@ -133,7 +123,7 @@ describe('Settings spec component', () => {
       return;
     };
 
-    const chartStoreListeners = {
+    const updatedProps: Partial<SettingsSpec> = {
       onElementClick,
       onElementOver,
       onElementOut: onOut,
@@ -147,31 +137,34 @@ describe('Settings spec component', () => {
       onRenderChange: onRenderChangeEvent,
     };
 
-    mount(<SettingsComponent chartStore={chartStore} {...chartStoreListeners} />);
-    expect(chartStore.onElementClickListener).toEqual(onElementClick);
-    expect(chartStore.onElementOverListener).toEqual(onElementOver);
-    expect(chartStore.onElementOutListener).toEqual(onOut);
-    expect(chartStore.onBrushEndListener).toEqual(onBrushEnd);
-    expect(chartStore.onLegendItemOverListener).toEqual(onLegendEvent);
-    expect(chartStore.onLegendItemOutListener).toEqual(onOut);
-    expect(chartStore.onLegendItemClickListener).toEqual(onLegendEvent);
-    expect(chartStore.onLegendItemPlusClickListener).toEqual(onLegendEvent);
-    expect(chartStore.onLegendItemMinusClickListener).toEqual(onLegendEvent);
-    expect(chartStore.onCursorUpdateListener).toEqual(onCursorUpdateEvent);
-    expect(chartStore.onRenderChangeListener).toEqual(onRenderChangeEvent);
+    mount(<SettingsProxy settings={updatedProps} />);
+    settingSpec = getSettingsSpecSelector(chartStore.getState());
+
+    expect(settingSpec.onElementClick).toEqual(onElementClick);
+    expect(settingSpec.onElementOver).toEqual(onElementOver);
+    expect(settingSpec.onElementOut).toEqual(onOut);
+    expect(settingSpec.onBrushEnd).toEqual(onBrushEnd);
+    expect(settingSpec.onLegendItemOver).toEqual(onLegendEvent);
+    expect(settingSpec.onLegendItemOut).toEqual(onOut);
+    expect(settingSpec.onLegendItemClick).toEqual(onLegendEvent);
+    expect(settingSpec.onLegendItemPlusClick).toEqual(onLegendEvent);
+    expect(settingSpec.onLegendItemMinusClick).toEqual(onLegendEvent);
+    expect(settingSpec.onCursorUpdate).toEqual(onCursorUpdateEvent);
+    expect(settingSpec.onRenderChange).toEqual(onRenderChangeEvent);
   });
 
   test('should allow partial theme', () => {
-    const chartStore = new ChartStore();
+    mount(<SettingsProxy />);
+    let settingSpec = getSettingsSpecSelector(chartStore.getState());
+    expect(settingSpec.theme).toEqual(LIGHT_THEME);
+
     const partialTheme: PartialTheme = {
       colors: {
         defaultVizColor: 'aquamarine',
       },
     };
 
-    expect(chartStore.chartTheme).toEqual(LIGHT_THEME);
-
-    const updatedProps: SettingSpecProps = {
+    const updatedProps: Partial<SettingsSpec> = {
       theme: partialTheme,
       baseTheme: DARK_THEME,
       rotation: 90 as Rotation,
@@ -189,9 +182,13 @@ describe('Settings spec component', () => {
       xDomain: { min: 0, max: 10 },
     };
 
-    mount(<SettingsComponent chartStore={chartStore} {...updatedProps} />);
+    mount(<SettingsProxy settings={updatedProps} />);
 
-    expect(chartStore.chartTheme).toEqual({
+    settingSpec = getSettingsSpecSelector(chartStore.getState());
+    // the theme is no longer stored into the setting spec.
+    // it's final theme object is computed through selectors
+    const theme = getChartThemeSelector(chartStore.getState());
+    expect(theme).toEqual({
       ...DARK_THEME,
       colors: {
         ...DARK_THEME.colors,
diff --git a/src/specs/settings.tsx b/src/specs/settings.tsx
index e3e9f1ab41..1d44143991 100644
--- a/src/specs/settings.tsx
+++ b/src/specs/settings.tsx
@@ -1,31 +1,27 @@
-import { PureComponent } from 'react';
-import { inject } from 'mobx-react';
-
-import { DomainRange, Position, Rendering, Rotation } from '../chart_types/xy_chart/utils/specs';
-import { mergeWithDefaultTheme, PartialTheme, Theme } from '../utils/themes/theme';
+import { DomainRange, Position, Rendering, Rotation, SpecTypes } from '../chart_types/xy_chart/utils/specs';
+import { PartialTheme, Theme } from '../utils/themes/theme';
 import { Domain } from '../utils/domain';
 import { TooltipType, TooltipValueFormatter } from '../chart_types/xy_chart/utils/interactions';
-import {
-  BrushEndListener,
-  ChartStore,
-  ElementClickListener,
-  ElementOverListener,
-  LegendItemListener,
-  CursorUpdateListener,
-  RenderChangeListener,
-} from '../chart_types/xy_chart/store/chart_state';
 import { ScaleTypes } from '../utils/scales/scales';
+import { getConnect, specComponentFactory } from '../state/spec_factory';
+import { Spec } from '.';
 import { LIGHT_THEME } from '../utils/themes/light_theme';
-
-export const DEFAULT_TOOLTIP_TYPE = TooltipType.VerticalCursor;
-export const DEFAULT_TOOLTIP_SNAP = true;
-
-interface TooltipProps {
-  type?: TooltipType;
-  snap?: boolean;
-  headerFormatter?: TooltipValueFormatter;
-}
-
+import { ChartTypes } from '../chart_types';
+import { GeometryValue } from '../utils/geometry';
+import { DataSeriesColorsValues } from '../chart_types/xy_chart/utils/series';
+
+export type ElementClickListener = (values: GeometryValue[]) => void;
+export type ElementOverListener = (values: GeometryValue[]) => void;
+export type BrushEndListener = (min: number, max: number) => void;
+export type LegendItemListener = (dataSeriesIdentifiers: DataSeriesColorsValues | null) => void;
+export type CursorUpdateListener = (event?: CursorEvent) => void;
+/**
+ * Listener to be called when chart render state changes
+ *
+ * `isRendered` value is `true` when rendering is complete and `false` otherwise
+ */
+export type RenderChangeListener = (isRendered: boolean) => void;
+export type BasicListener = () => undefined | void;
 /**
  * Event used to syncronize cursors between Charts.
  *
@@ -42,16 +38,14 @@ export interface CursorEvent {
   value: number | string;
 }
 
-function isTooltipProps(config: TooltipType | TooltipProps): config is TooltipProps {
-  return typeof config === 'object';
-}
-
-function isTooltipType(config: TooltipType | TooltipProps): config is TooltipType {
-  return typeof config === 'string';
+interface TooltipProps {
+  type?: TooltipType;
+  snap?: boolean;
+  headerFormatter?: TooltipValueFormatter;
+  unit?: string;
 }
 
-export interface SettingSpecProps {
-  chartStore?: ChartStore;
+export interface SettingsSpec extends Spec {
   /**
    * Partial theme to be merged with base
    *
@@ -74,9 +68,9 @@ export interface SettingSpecProps {
   animateData: boolean;
   showLegend: boolean;
   /** Either a TooltipType or an object with configuration of type, snap, and/or headerFormatter */
-  tooltip?: TooltipType | TooltipProps;
+  tooltip: TooltipType | TooltipProps;
   debug: boolean;
-  legendPosition?: Position;
+  legendPosition: Position;
   showLegendDisplayValue: boolean;
   /**
    * Removes duplicate axes
@@ -86,10 +80,10 @@ export interface SettingSpecProps {
   hideDuplicateAxes: boolean;
   onElementClick?: ElementClickListener;
   onElementOver?: ElementOverListener;
-  onElementOut?: () => undefined | void;
+  onElementOut?: BasicListener;
   onBrushEnd?: BrushEndListener;
   onLegendItemOver?: LegendItemListener;
-  onLegendItemOut?: () => undefined | void;
+  onLegendItemOut?: BasicListener;
   onLegendItemClick?: LegendItemListener;
   onLegendItemPlusClick?: LegendItemListener;
   onLegendItemMinusClick?: LegendItemListener;
@@ -99,135 +93,48 @@ export interface SettingSpecProps {
   resizeDebounce?: number;
 }
 
-function getTheme(baseTheme?: Theme, theme?: PartialTheme | PartialTheme[]): Theme {
-  const base = baseTheme ? baseTheme : LIGHT_THEME;
-
-  if (Array.isArray(theme)) {
-    const [firstTheme, ...axillaryThemes] = theme;
-    return mergeWithDefaultTheme(firstTheme, base, axillaryThemes);
-  }
-
-  return theme ? mergeWithDefaultTheme(theme, base) : base;
-}
-
-function updateChartStore(props: SettingSpecProps) {
-  const {
-    chartStore,
-    theme,
-    baseTheme,
-    rotation,
-    rendering,
-    animateData,
-    showLegend,
-    tooltip,
-    legendPosition,
-    showLegendDisplayValue,
-    onElementClick,
-    onElementOver,
-    onElementOut,
-    onBrushEnd,
-    onLegendItemOver,
-    onLegendItemOut,
-    onLegendItemClick,
-    onLegendItemMinusClick,
-    onLegendItemPlusClick,
-    onRenderChange,
-    onCursorUpdate,
-    debug,
-    xDomain,
-    resizeDebounce,
-    hideDuplicateAxes,
-  } = props;
-
-  if (!chartStore) {
-    return;
-  }
-
-  chartStore.chartTheme = getTheme(baseTheme, theme);
-  chartStore.chartRotation = rotation;
-  chartStore.chartRendering = rendering;
-  chartStore.animateData = animateData;
-  chartStore.debug = debug;
-  chartStore.resizeDebounce = resizeDebounce!;
-  chartStore.hideDuplicateAxes = hideDuplicateAxes;
-
-  if (tooltip && isTooltipProps(tooltip)) {
-    const { type, snap, headerFormatter } = tooltip;
-    chartStore.tooltipType.set(type!);
-    chartStore.tooltipSnap.set(snap!);
-    chartStore.tooltipHeaderFormatter = headerFormatter;
-  } else if (tooltip && isTooltipType(tooltip)) {
-    chartStore.tooltipType.set(tooltip);
-  }
-
-  chartStore.setShowLegend(showLegend);
-
-  if (legendPosition) {
-    chartStore.legendPosition.set(legendPosition);
-  }
-  chartStore.showLegendDisplayValue.set(showLegendDisplayValue);
-  chartStore.customXDomain = xDomain;
-
-  if (onElementOver) {
-    chartStore.setOnElementOverListener(onElementOver);
-  }
-  if (onElementClick) {
-    chartStore.setOnElementClickListener(onElementClick);
-  }
-  if (onElementOut) {
-    chartStore.setOnElementOutListener(onElementOut);
-  }
-  if (onBrushEnd) {
-    chartStore.setOnBrushEndListener(onBrushEnd);
-  }
-  if (onLegendItemOver) {
-    chartStore.setOnLegendItemOverListener(onLegendItemOver);
-  }
-  if (onLegendItemOut) {
-    chartStore.setOnLegendItemOutListener(onLegendItemOut);
-  }
-  if (onLegendItemClick) {
-    chartStore.setOnLegendItemClickListener(onLegendItemClick);
-  }
-  if (onLegendItemPlusClick) {
-    chartStore.setOnLegendItemPlusClickListener(onLegendItemPlusClick);
-  }
-  if (onLegendItemMinusClick) {
-    chartStore.setOnLegendItemMinusClickListener(onLegendItemMinusClick);
-  }
-  if (onCursorUpdate) {
-    chartStore.setOnCursorUpdateListener(onCursorUpdate);
-  }
-  if (onRenderChange) {
-    chartStore.setOnRenderChangeListener(onRenderChange);
-  }
-}
-
-export class SettingsComponent extends PureComponent<SettingSpecProps> {
-  static defaultProps: Partial<SettingSpecProps> = {
-    rendering: 'canvas',
-    rotation: 0,
-    animateData: true,
-    showLegend: false,
-    resizeDebounce: 10,
-    debug: false,
-    hideDuplicateAxes: false,
-    tooltip: {
-      type: DEFAULT_TOOLTIP_TYPE,
-      snap: DEFAULT_TOOLTIP_SNAP,
-    },
-    showLegendDisplayValue: true,
-  };
+export type DefaultSettingsProps =
+  | 'id'
+  | 'chartType'
+  | 'specType'
+  | 'rendering'
+  | 'rotation'
+  | 'resizeDebounce'
+  | 'animateData'
+  | 'showLegend'
+  | 'debug'
+  | 'tooltip'
+  | 'showLegendDisplayValue'
+  | 'theme'
+  | 'legendPosition'
+  | 'hideDuplicateAxes';
 
-  componentDidMount() {
-    updateChartStore(this.props);
-  }
-  componentDidUpdate() {
-    updateChartStore(this.props);
-  }
-  render() {
-    return null;
-  }
-}
+export const DEFAULT_TOOLTIP_TYPE = TooltipType.VerticalCursor;
+export const DEFAULT_TOOLTIP_SNAP = true;
 
-export const Settings = inject('chartStore')(SettingsComponent);
+export const DEFAULT_SETTINGS_SPEC = {
+  id: '__global__settings___',
+  chartType: ChartTypes.Global,
+  specType: SpecTypes.Settings,
+  rendering: 'canvas' as 'canvas',
+  rotation: 0 as 0,
+  animateData: true,
+  showLegend: false,
+  resizeDebounce: 10,
+  debug: false,
+  tooltip: {
+    type: DEFAULT_TOOLTIP_TYPE,
+    snap: DEFAULT_TOOLTIP_SNAP,
+    value: '',
+  },
+  legendPosition: Position.Right,
+  showLegendDisplayValue: true,
+  hideDuplicateAxes: false,
+  theme: LIGHT_THEME,
+};
+
+type SpecProps = Partial<Omit<SettingsSpec, 'chartType' | 'specType' | 'id'>>;
+
+export const Settings: React.FunctionComponent<SpecProps> = getConnect()(
+  specComponentFactory<SettingsSpec, DefaultSettingsProps>(DEFAULT_SETTINGS_SPEC),
+);
diff --git a/src/specs/specs_parser.test.tsx b/src/specs/specs_parser.test.tsx
index c68e8bdd1d..44a4c7a316 100644
--- a/src/specs/specs_parser.test.tsx
+++ b/src/specs/specs_parser.test.tsx
@@ -1,36 +1,81 @@
 import { mount } from 'enzyme';
 import * as React from 'react';
-import { ChartStore } from '../chart_types/xy_chart/store/chart_state';
-import { SpecsSpecRootComponent } from './specs_parser';
+import { createStore } from 'redux';
+import { Provider } from 'react-redux';
+import { SpecsParser } from './specs_parser';
+import { chartStoreReducer } from '../state/chart_state';
+import { BarSeries } from '../';
+import { DEFAULT_SETTINGS_SPEC } from './settings';
+import { BarSeriesSpec } from '../chart_types/xy_chart/utils/specs';
 
 describe('Specs parser', () => {
-  test('Mount and parse specs', () => {
-    const chartStore = new ChartStore();
-    expect(chartStore.specsInitialized.get()).toBe(false);
-    const component = <SpecsSpecRootComponent chartStore={chartStore} />;
+  test('can mount the spec parser', () => {
+    const storeReducer = chartStoreReducer('chart_id');
+    const chartStore = createStore(storeReducer);
+
+    expect(chartStore.getState().specsInitialized).toBe(false);
+    const component = (
+      <Provider store={chartStore}>
+        <SpecsParser />
+      </Provider>
+    );
+    mount(component);
+    expect(chartStore.getState().specsInitialized).toBe(true);
+  });
+  test('can parse few components', () => {
+    const storeReducer = chartStoreReducer('chart_id');
+    const chartStore = createStore(storeReducer);
+
+    expect(chartStore.getState().specsInitialized).toBe(false);
+    const component = (
+      <Provider store={chartStore}>
+        <SpecsParser>
+          <BarSeries id={'bars'} xAccessor={0} yAccessors={[1]} data={[[0, 1], [1, 2]]} />
+          <BarSeries id={'bars'} xAccessor={0} yAccessors={[1]} data={[[0, 1], [1, 2]]} />
+          <BarSeries id={'bars2'} xAccessor={0} yAccessors={[1]} data={[[0, 1], [1, 2]]} />
+        </SpecsParser>
+      </Provider>
+    );
     mount(component);
-    expect(chartStore.specsInitialized.get()).toBe(true);
+    const state = chartStore.getState();
+    expect(state.specsInitialized).toBe(true);
+    expect(Object.keys(state.specs)).toEqual([DEFAULT_SETTINGS_SPEC.id, 'bars', 'bars2']);
+    expect(state.specs['bars']).toBeDefined();
+    expect(state.specs['bars2']).toBeDefined();
   });
-  test('chart store initialized and computeChart on component update', () => {
-    const chartStore = new ChartStore();
-    const computeChart = jest.fn(
-      (): void => {
-        return;
-      },
+  test('can update a component', () => {
+    const storeReducer = chartStoreReducer('chart_id');
+    const chartStore = createStore(storeReducer);
+
+    expect(chartStore.getState().specsInitialized).toBe(false);
+    const component = (
+      <Provider store={chartStore}>
+        <SpecsParser>
+          <BarSeries id={'bars'} xAccessor={0} yAccessors={[1]} data={[[0, 1], [1, 2]]} />
+        </SpecsParser>
+      </Provider>
     );
-    chartStore.computeChart = computeChart;
+    const wrapper = mount(component);
 
-    const component = mount(<SpecsSpecRootComponent chartStore={chartStore} />);
-    component.update();
-    component.setState({ foo: 'bar' });
-    expect(chartStore.specsInitialized.get()).toBe(true);
-    expect(computeChart).toBeCalled();
+    wrapper.setProps({
+      children: (
+        <SpecsParser>
+          <BarSeries id={'bars'} xAccessor={1} yAccessors={[1]} data={[[0, 1], [1, 2]]} />
+        </SpecsParser>
+      ),
+    });
+    const state = chartStore.getState();
+    expect((state.specs['bars'] as BarSeriesSpec).xAccessor).toBe(1);
   });
-  test('updates initialization state on unmount', () => {
-    const chartStore = new ChartStore();
-    chartStore.chartInitialized.set(true);
-    const component = mount(<SpecsSpecRootComponent chartStore={chartStore} />);
+  test('set initialization to false on unmount', () => {
+    const storeReducer = chartStoreReducer('chart_id');
+    const chartStore = createStore(storeReducer);
+    const component = mount(
+      <Provider store={chartStore}>
+        <SpecsParser />
+      </Provider>,
+    );
     component.unmount();
-    expect(chartStore.chartInitialized.get()).toBe(false);
+    expect(chartStore.getState().specsInitialized).toBe(false);
   });
 });
diff --git a/src/specs/specs_parser.tsx b/src/specs/specs_parser.tsx
index aaa827e891..7fe38ede6b 100644
--- a/src/specs/specs_parser.tsx
+++ b/src/specs/specs_parser.tsx
@@ -1,26 +1,37 @@
-import { inject } from 'mobx-react';
-import { PureComponent } from 'react';
-import { ChartStore } from '../chart_types/xy_chart/store/chart_state';
+import React, { useEffect } from 'react';
+import { bindActionCreators, Dispatch } from 'redux';
+import { connect } from 'react-redux';
+import { specParsed, specUnmounted } from '../state/actions/specs';
 
-export interface SpecProps {
-  chartStore?: ChartStore; // FIX
-}
+export const SpecsParserComponent: React.FunctionComponent<{}> = (props) => {
+  const injected = props as DispatchProps;
+  useEffect(() => {
+    injected.specParsed();
+  });
+  useEffect(
+    () => () => {
+      injected.specUnmounted();
+    },
+    [],
+  );
+  return props.children ? (props.children as React.ReactElement) : null;
+};
 
-export class SpecsSpecRootComponent extends PureComponent<SpecProps> {
-  componentDidMount() {
-    this.props.chartStore!.specsInitialized.set(true);
-    this.props.chartStore!.computeChart();
-  }
-  componentDidUpdate() {
-    this.props.chartStore!.specsInitialized.set(true);
-    this.props.chartStore!.computeChart();
-  }
-  componentWillUnmount() {
-    this.props.chartStore!.chartInitialized.set(false);
-  }
-  render() {
-    return this.props.children || null;
-  }
+interface DispatchProps {
+  specParsed: () => void;
+  specUnmounted: () => void;
 }
 
-export const SpecsParser = inject('chartStore')(SpecsSpecRootComponent);
+const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
+  bindActionCreators(
+    {
+      specParsed,
+      specUnmounted,
+    },
+    dispatch,
+  );
+
+export const SpecsParser = connect(
+  null,
+  mapDispatchToProps,
+)(SpecsParserComponent);
diff --git a/src/state/actions/chart.ts b/src/state/actions/chart.ts
new file mode 100644
index 0000000000..763f94f113
--- /dev/null
+++ b/src/state/actions/chart.ts
@@ -0,0 +1,11 @@
+export const CHART_RENDERED = 'CHART_RENDERED';
+
+interface ChartRenderedAction {
+  type: typeof CHART_RENDERED;
+}
+
+export function onChartRendered(): ChartRenderedAction {
+  return { type: CHART_RENDERED };
+}
+
+export type ChartActions = ChartRenderedAction;
diff --git a/src/state/actions/chart_settings.ts b/src/state/actions/chart_settings.ts
new file mode 100644
index 0000000000..e8bbfd7a69
--- /dev/null
+++ b/src/state/actions/chart_settings.ts
@@ -0,0 +1,14 @@
+import { Dimensions } from '../../utils/dimensions';
+
+export const UPDATE_PARENT_DIMENSION = 'UPDATE_PARENT_DIMENSION';
+
+interface UpdateParentDimensionAction {
+  type: typeof UPDATE_PARENT_DIMENSION;
+  dimensions: Dimensions;
+}
+
+export function updateParentDimensions(dimensions: Dimensions): UpdateParentDimensionAction {
+  return { type: UPDATE_PARENT_DIMENSION, dimensions };
+}
+
+export type ChartSettingsActions = UpdateParentDimensionAction;
diff --git a/src/state/actions/events.ts b/src/state/actions/events.ts
new file mode 100644
index 0000000000..c51133b84d
--- /dev/null
+++ b/src/state/actions/events.ts
@@ -0,0 +1,14 @@
+import { CursorEvent } from '../../specs/settings';
+
+export const EXTERNAL_POINTER_EVENT = 'EXTERNAL_POINTER_EVENT';
+
+interface ExternalPointerEvent {
+  type: typeof EXTERNAL_POINTER_EVENT;
+  event?: CursorEvent;
+}
+
+export function onExternalPointerEvent(event?: CursorEvent): ExternalPointerEvent {
+  return { type: EXTERNAL_POINTER_EVENT, event };
+}
+
+export type EventsActions = ExternalPointerEvent;
diff --git a/src/state/actions/index.ts b/src/state/actions/index.ts
new file mode 100644
index 0000000000..7044bba8b6
--- /dev/null
+++ b/src/state/actions/index.ts
@@ -0,0 +1,14 @@
+import { SpecActions } from './specs';
+import { ChartActions } from './chart';
+import { ChartSettingsActions } from './chart_settings';
+import { LegendActions } from './legend';
+import { EventsActions } from './events';
+import { MouseActions } from './mouse';
+
+export type StateActions =
+  | SpecActions
+  | ChartActions
+  | ChartSettingsActions
+  | LegendActions
+  | EventsActions
+  | MouseActions;
diff --git a/src/state/actions/legend.ts b/src/state/actions/legend.ts
new file mode 100644
index 0000000000..9884bda069
--- /dev/null
+++ b/src/state/actions/legend.ts
@@ -0,0 +1,44 @@
+import { DataSeriesColorsValues } from '../../chart_types/xy_chart/utils/series';
+
+export const ON_TOGGLE_LEGEND = 'ON_TOGGLE_LEGEND';
+export const ON_LEGEND_ITEM_OVER = 'ON_LEGEND_ITEM_OVER';
+export const ON_LEGEND_ITEM_OUT = 'ON_LEGEND_ITEM_OUT';
+export const ON_TOGGLE_DESELECT_SERIES = 'ON_TOGGLE_DESELECT_SERIES';
+
+interface ToggleLegendAction {
+  type: typeof ON_TOGGLE_LEGEND;
+}
+interface LegendItemOverAction {
+  type: typeof ON_LEGEND_ITEM_OVER;
+  legendItemKey: string | null;
+}
+interface LegendItemOutAction {
+  type: typeof ON_LEGEND_ITEM_OUT;
+}
+
+interface ToggleDeselectSeriesAction {
+  type: typeof ON_TOGGLE_DESELECT_SERIES;
+  legendItemId: DataSeriesColorsValues;
+}
+
+export function onToggleLegend(): ToggleLegendAction {
+  return { type: ON_TOGGLE_LEGEND };
+}
+
+export function onLegendItemOverAction(legendItemKey: string | null): LegendItemOverAction {
+  return { type: ON_LEGEND_ITEM_OVER, legendItemKey };
+}
+
+export function onLegendItemOutAction(): LegendItemOutAction {
+  return { type: ON_LEGEND_ITEM_OUT };
+}
+
+export function onToggleDeselectSeriesAction(legendItemId: DataSeriesColorsValues): ToggleDeselectSeriesAction {
+  return { type: ON_TOGGLE_DESELECT_SERIES, legendItemId };
+}
+
+export type LegendActions =
+  | ToggleLegendAction
+  | LegendItemOverAction
+  | LegendItemOutAction
+  | ToggleDeselectSeriesAction;
diff --git a/src/state/actions/mouse.ts b/src/state/actions/mouse.ts
new file mode 100644
index 0000000000..ab1f45c740
--- /dev/null
+++ b/src/state/actions/mouse.ts
@@ -0,0 +1,51 @@
+import { Point } from '../../utils/point';
+
+export const ON_POINTER_MOVE = 'ON_POINTER_MOVE';
+export const ON_MOUSE_DOWN = 'ON_MOUSE_DOWN';
+export const ON_MOUSE_UP = 'ON_MOUSE_UP';
+
+interface MouseDownAction {
+  type: typeof ON_MOUSE_DOWN;
+  position: Point;
+  time: number;
+}
+interface MouseUpAction {
+  type: typeof ON_MOUSE_UP;
+  position: Point;
+  time: number;
+}
+
+interface PointerMoveAction {
+  type: typeof ON_POINTER_MOVE;
+  position: Point;
+  time: number;
+}
+
+/**
+ * Action called on mouse button down event
+ * @param position the x and y position (native event offsetX, offsetY)
+ * @param time the timestamp of the event (native event timeStamp)
+ */
+export function onMouseDown(position: Point, time: number): MouseDownAction {
+  return { type: ON_MOUSE_DOWN, position, time };
+}
+
+/**
+ * Action called on mouse button up event
+ * @param position the x and y position (native event offsetX, offsetY)
+ * @param time the timestamp of the event (native event timeStamp)
+ */
+export function onMouseUp(position: Point, time: number): MouseUpAction {
+  return { type: ON_MOUSE_UP, position, time };
+}
+
+/**
+ * Action called with the mouse coordinates relatives to the chart container (exclude the legend)
+ * @param position the x and y position (native event offsetX, offsetY)
+ * @param time the timestamp of the event (native event timeStamp)
+ */
+export function onPointerMove(position: Point, time: number): PointerMoveAction {
+  return { type: ON_POINTER_MOVE, position, time };
+}
+
+export type MouseActions = MouseDownAction | MouseUpAction | PointerMoveAction;
diff --git a/src/state/actions/specs.ts b/src/state/actions/specs.ts
new file mode 100644
index 0000000000..0bf622a9ea
--- /dev/null
+++ b/src/state/actions/specs.ts
@@ -0,0 +1,42 @@
+import { Spec } from '../../specs';
+
+export const UPSERT_SPEC = 'UPSERT_SPEC';
+export const REMOVE_SPEC = 'REMOVE_SPEC';
+export const SPEC_PARSED = 'SPEC_PARSED';
+export const SPEC_UNMOUNTED = 'SPEC_UNMOUNTED';
+
+interface SpecParsedAction {
+  type: typeof SPEC_PARSED;
+}
+
+interface SpecUnmountedAction {
+  type: typeof SPEC_UNMOUNTED;
+}
+
+interface UpsertSpecAction {
+  type: typeof UPSERT_SPEC;
+  spec: Spec;
+}
+
+interface RemoveSpecAction {
+  type: typeof REMOVE_SPEC;
+  id: string;
+}
+
+export function upsertSpec(spec: Spec): UpsertSpecAction {
+  return { type: UPSERT_SPEC, spec };
+}
+
+export function removeSpec(id: string): RemoveSpecAction {
+  return { type: REMOVE_SPEC, id };
+}
+
+export function specParsed(): SpecParsedAction {
+  return { type: SPEC_PARSED };
+}
+
+export function specUnmounted(): SpecUnmountedAction {
+  return { type: SPEC_UNMOUNTED };
+}
+
+export type SpecActions = SpecParsedAction | SpecUnmountedAction | UpsertSpecAction | RemoveSpecAction;
diff --git a/src/state/chart_state.ts b/src/state/chart_state.ts
new file mode 100644
index 0000000000..ec3a6ac4f1
--- /dev/null
+++ b/src/state/chart_state.ts
@@ -0,0 +1,271 @@
+import { SPEC_PARSED, SPEC_UNMOUNTED, UPSERT_SPEC, REMOVE_SPEC } from './actions/specs';
+import { interactionsReducer } from './reducers/interactions';
+import { ChartTypes } from '../chart_types';
+import { XYAxisChartState } from '../chart_types/xy_chart/state/chart_state';
+import { DataSeriesColorsValues } from '../chart_types/xy_chart/utils/series';
+import { Spec } from '../specs';
+import { DEFAULT_SETTINGS_SPEC, CursorEvent } from '../specs/settings';
+import { Dimensions } from '../utils/dimensions';
+import { Point } from '../utils/point';
+import { LegendItem } from '../chart_types/xy_chart/legend/legend';
+import { TooltipLegendValue } from '../chart_types/xy_chart/tooltip/tooltip';
+import { StateActions } from './actions';
+import { CHART_RENDERED } from './actions/chart';
+import { UPDATE_PARENT_DIMENSION } from './actions/chart_settings';
+import { EXTERNAL_POINTER_EVENT } from './actions/events';
+import { RefObject } from 'react';
+import { Stage } from 'react-konva';
+
+export type BackwardRef = () => React.RefObject<HTMLDivElement>;
+
+/**
+ * A set of chart-type-dependant functions that are required and called
+ * globally by the <ChartContainer> and
+ */
+export interface InternalChartState {
+  // the chart type
+  chartType: ChartTypes;
+  // returns a JSX element with the chart rendered (lenged excluded)
+  chartRenderer(containerRef: BackwardRef, forwardStageRef: RefObject<Stage>): JSX.Element | null;
+  // true if the brush is available for this chart type
+  isBrushAvailable(globalState: GlobalChartState): boolean;
+  // true if the chart is empty (no data displayed)
+  isChartEmpty(globalState: GlobalChartState): boolean;
+  // return the list of legend items
+  getLegendItems(globalState: GlobalChartState): Map<string, LegendItem>;
+  // return the list of values for each legend item
+  getLegendItemsValues(globalState: GlobalChartState): Map<string, TooltipLegendValue>;
+  // return the CSS pointer cursor depending on the internal chart state
+  getPointerCursor(globalState: GlobalChartState): string;
+}
+
+export interface SpecList {
+  [specId: string]: Spec;
+}
+
+export interface PointerState {
+  position: Point;
+  time: number;
+}
+export interface DragState {
+  start: PointerState;
+  end: PointerState;
+}
+export interface PointerStates {
+  dragging: boolean;
+  current: PointerState;
+  down: PointerState | null;
+  up: PointerState | null;
+  lastDrag: DragState | null;
+  lastClick: PointerState | null;
+}
+
+export interface InteractionsState {
+  pointer: PointerStates;
+  highlightedLegendItemKey: string | null;
+  legendCollapsed: boolean;
+  invertDeselect: boolean;
+  deselectedDataSeries: DataSeriesColorsValues[];
+}
+
+export interface ExternalEventsState {
+  pointer: CursorEvent | null;
+}
+
+export interface GlobalChartState {
+  // an unique ID for each chart used by re-reselect to memoize selector per chart
+  chartId: string;
+  // true when all all the specs are parsed ad stored into the specs object
+  specsInitialized: boolean;
+  // true if the chart is rendered on dom
+  chartRendered: boolean;
+  // incremental count of the chart rendering
+  chartRenderedCount: number;
+  // the map of parsed specs
+  specs: SpecList;
+  // the chart type depending on the used specs
+  chartType: ChartTypes | null;
+  // a chart-type-dependant class that is used to render and share chart-type dependant functions
+  internalChartState: InternalChartState | null;
+  // the dimensions of the parent container, including the legend
+  parentDimensions: Dimensions;
+  // the state of the interactions
+  interactions: InteractionsState;
+  // external event state
+  externalEvents: ExternalEventsState;
+}
+
+export const getInitialState = (chartId: string): GlobalChartState => ({
+  chartId,
+  specsInitialized: false,
+  chartRendered: false,
+  chartRenderedCount: 0,
+  specs: {
+    [DEFAULT_SETTINGS_SPEC.id]: DEFAULT_SETTINGS_SPEC,
+  },
+  chartType: null,
+  internalChartState: null,
+  interactions: {
+    pointer: {
+      dragging: false,
+      current: {
+        position: {
+          x: -1,
+          y: -1,
+        },
+        time: 0,
+      },
+      down: null,
+      up: null,
+      lastDrag: null,
+      lastClick: null,
+    },
+    legendCollapsed: false,
+    highlightedLegendItemKey: null,
+    deselectedDataSeries: [],
+    invertDeselect: false,
+  },
+  externalEvents: {
+    pointer: null,
+  },
+  parentDimensions: {
+    height: 0,
+    width: 0,
+    left: 0,
+    top: 0,
+  },
+});
+
+export const chartStoreReducer = (chartId: string) => {
+  const initialState = getInitialState(chartId);
+  return (state = initialState, action: StateActions): GlobalChartState => {
+    switch (action.type) {
+      case SPEC_PARSED:
+        const chartType = findMainChartType(state.specs);
+
+        if (isChartTypeChanged(state, chartType)) {
+          const internalChartState = initInternalChartState(chartType);
+          return {
+            ...state,
+            specsInitialized: true,
+            chartRendered: false,
+            chartType,
+            internalChartState,
+          };
+        } else {
+          return {
+            ...state,
+            specsInitialized: true,
+            chartRendered: false,
+            chartType,
+          };
+        }
+      case SPEC_UNMOUNTED:
+        return {
+          ...state,
+          specsInitialized: false,
+          chartRendered: false,
+        };
+      case UPSERT_SPEC:
+        return {
+          ...state,
+          specsInitialized: false,
+          chartRendered: false,
+          specs: {
+            ...state.specs,
+            [action.spec.id]: action.spec,
+          },
+        };
+      case REMOVE_SPEC:
+        const { [action.id]: specToRemove, ...rest } = state.specs;
+        return {
+          ...state,
+          specsInitialized: false,
+          chartRendered: false,
+          specs: {
+            ...rest,
+          },
+        };
+      case CHART_RENDERED:
+        const count = state.chartRendered ? state.chartRenderedCount : state.chartRenderedCount + 1;
+        return {
+          ...state,
+          chartRendered: true,
+          chartRenderedCount: count,
+        };
+      case UPDATE_PARENT_DIMENSION:
+        return {
+          ...state,
+          parentDimensions: {
+            ...action.dimensions,
+          },
+        };
+      case EXTERNAL_POINTER_EVENT:
+        // discard events from self if any
+        if (!action.event || action.event.chartId === state.chartId) {
+          return {
+            ...state,
+            externalEvents: {
+              ...state.externalEvents,
+              pointer: null,
+            },
+          };
+        }
+        return {
+          ...state,
+          externalEvents: {
+            ...state.externalEvents,
+            pointer: {
+              ...action.event,
+            },
+          },
+        };
+      default:
+        return {
+          ...state,
+          interactions: interactionsReducer(state.interactions, action),
+        };
+    }
+  };
+};
+
+function findMainChartType(specs: SpecList): ChartTypes | null {
+  const types: Partial<Record<ChartTypes, number>> = Object.keys(specs).reduce<Partial<Record<ChartTypes, number>>>(
+    (acc, specId) => {
+      const { chartType } = specs[specId];
+      let accumulator = acc[chartType];
+      if (accumulator === undefined) {
+        accumulator = 0;
+      } else {
+        accumulator += 1;
+      }
+      acc[chartType] = accumulator;
+      return acc;
+    },
+    {},
+  );
+  // https://stackoverflow.com/questions/55012174/why-doesnt-object-keys-return-a-keyof-type-in-typescript
+  const chartTypes = Object.keys(types).filter((type) => type !== ChartTypes.Global);
+  if (chartTypes.length > 1) {
+    // eslint-disable-next-line no-console
+    console.warn('Multiple chart type on the same configuration');
+    return null;
+  } else {
+    return chartTypes[0] as ChartTypes;
+  }
+}
+
+function initInternalChartState(chartType: ChartTypes | null): InternalChartState | null {
+  switch (chartType) {
+    case ChartTypes.Pie:
+      return null; // TODO add pie chart state
+    case ChartTypes.XYAxis:
+      return new XYAxisChartState();
+    default:
+      return null;
+  }
+}
+
+function isChartTypeChanged(state: GlobalChartState, newChartType: ChartTypes | null) {
+  return state.chartType !== newChartType;
+}
diff --git a/src/state/reducers/interactions.ts b/src/state/reducers/interactions.ts
new file mode 100644
index 0000000000..64b1542737
--- /dev/null
+++ b/src/state/reducers/interactions.ts
@@ -0,0 +1,120 @@
+import { InteractionsState } from '../chart_state';
+import {
+  ON_TOGGLE_LEGEND,
+  ON_LEGEND_ITEM_OUT,
+  ON_LEGEND_ITEM_OVER,
+  ON_TOGGLE_DESELECT_SERIES,
+  LegendActions,
+} from '../actions/legend';
+import { ON_MOUSE_DOWN, ON_MOUSE_UP, ON_POINTER_MOVE, MouseActions } from '../actions/mouse';
+import { DataSeriesColorsValues, findDataSeriesByColorValues } from '../../chart_types/xy_chart/utils/series';
+
+export function interactionsReducer(state: InteractionsState, action: LegendActions | MouseActions): InteractionsState {
+  switch (action.type) {
+    case ON_POINTER_MOVE:
+      return {
+        ...state,
+        pointer: {
+          ...state.pointer,
+          dragging: state.pointer.down && state.pointer.down.time < action.time ? true : false,
+          current: {
+            position: {
+              ...action.position,
+            },
+            time: action.time,
+          },
+        },
+      };
+    case ON_MOUSE_DOWN:
+      return {
+        ...state,
+        pointer: {
+          ...state.pointer,
+          dragging: false,
+          up: null,
+          down: {
+            position: {
+              ...action.position,
+            },
+            time: action.time,
+          },
+        },
+      };
+    case ON_MOUSE_UP: {
+      return {
+        ...state,
+        pointer: {
+          ...state.pointer,
+          lastDrag:
+            state.pointer.down && state.pointer.dragging
+              ? {
+                  start: {
+                    position: {
+                      ...state.pointer.down.position,
+                    },
+                    time: state.pointer.down.time,
+                  },
+                  end: {
+                    position: {
+                      ...action.position,
+                    },
+                    time: action.time,
+                  },
+                }
+              : null,
+          lastClick:
+            state.pointer.down && !state.pointer.dragging
+              ? {
+                  position: {
+                    ...action.position,
+                  },
+                  time: action.time,
+                }
+              : null,
+          dragging: false,
+          down: null,
+          up: {
+            position: {
+              ...action.position,
+            },
+            time: action.time,
+          },
+        },
+      };
+    }
+    case ON_TOGGLE_LEGEND:
+      return {
+        ...state,
+        legendCollapsed: !state.legendCollapsed,
+      };
+    case ON_LEGEND_ITEM_OUT:
+      return {
+        ...state,
+        highlightedLegendItemKey: null,
+      };
+    case ON_LEGEND_ITEM_OVER:
+      return {
+        ...state,
+        highlightedLegendItemKey: action.legendItemKey,
+      };
+    case ON_TOGGLE_DESELECT_SERIES:
+      return {
+        ...state,
+        deselectedDataSeries: toggleDeselectedDataSeries(action.legendItemId, state.deselectedDataSeries),
+      };
+    default:
+      return state;
+  }
+}
+
+function toggleDeselectedDataSeries(
+  legendItem: DataSeriesColorsValues,
+  deselectedDataSeries: DataSeriesColorsValues[],
+) {
+  const index = findDataSeriesByColorValues(deselectedDataSeries, legendItem);
+  if (index > -1) {
+    return [...deselectedDataSeries.slice(0, index), ...deselectedDataSeries.slice(index + 1)];
+  } else {
+    return [...deselectedDataSeries, legendItem];
+  }
+}
diff --git a/src/state/selectors/get_chart_container_dimensions.ts b/src/state/selectors/get_chart_container_dimensions.ts
new file mode 100644
index 0000000000..29288e7055
--- /dev/null
+++ b/src/state/selectors/get_chart_container_dimensions.ts
@@ -0,0 +1,33 @@
+import createCachedSelector from 're-reselect';
+import { getSettingsSpecSelector } from './get_settings_specs';
+import { getLegendSizeSelector } from './get_legend_size';
+import { GlobalChartState } from '../chart_state';
+import { Dimensions } from '../../utils/dimensions';
+import { isVerticalAxis } from '../../chart_types/xy_chart/utils/axis_utils';
+import { getChartIdSelector } from './get_chart_id';
+
+const getParentDimension = (state: GlobalChartState) => state.parentDimensions;
+
+export const getChartContainerDimensionsSelector = createCachedSelector(
+  [getSettingsSpecSelector, getLegendSizeSelector, getParentDimension],
+  (settings, legendSize, parentDimensions): Dimensions => {
+    if (!settings.showLegend) {
+      return parentDimensions;
+    }
+    if (isVerticalAxis(settings.legendPosition)) {
+      return {
+        left: 0,
+        top: 0,
+        width: parentDimensions.width - legendSize.width,
+        height: parentDimensions.height,
+      };
+    } else {
+      return {
+        left: 0,
+        top: 0,
+        width: parentDimensions.width,
+        height: parentDimensions.height - legendSize.height,
+      };
+    }
+  },
+)(getChartIdSelector);
diff --git a/src/state/selectors/get_chart_id.ts b/src/state/selectors/get_chart_id.ts
new file mode 100644
index 0000000000..e0177ae7b4
--- /dev/null
+++ b/src/state/selectors/get_chart_id.ts
@@ -0,0 +1,3 @@
+import { GlobalChartState } from '../chart_state';
+
+export const getChartIdSelector = (state: GlobalChartState) => state.chartId;
diff --git a/src/state/selectors/get_chart_rotation.ts b/src/state/selectors/get_chart_rotation.ts
new file mode 100644
index 0000000000..219d72e48c
--- /dev/null
+++ b/src/state/selectors/get_chart_rotation.ts
@@ -0,0 +1,12 @@
+import createCachedSelector from 're-reselect';
+import { getSettingsSpecSelector } from './get_settings_specs';
+
+import { Rotation } from '../../chart_types/xy_chart/utils/specs';
+import { getChartIdSelector } from './get_chart_id';
+
+export const getChartRotationSelector = createCachedSelector(
+  [getSettingsSpecSelector],
+  (settingsSpec): Rotation => {
+    return settingsSpec.rotation;
+  },
+)(getChartIdSelector);
diff --git a/src/state/selectors/get_chart_theme.ts b/src/state/selectors/get_chart_theme.ts
new file mode 100644
index 0000000000..9a4b739452
--- /dev/null
+++ b/src/state/selectors/get_chart_theme.ts
@@ -0,0 +1,23 @@
+import createCachedSelector from 're-reselect';
+import { getSettingsSpecSelector } from './get_settings_specs';
+import { PartialTheme, Theme, mergeWithDefaultTheme } from '../../utils/themes/theme';
+import { LIGHT_THEME } from '../../utils/themes/light_theme';
+import { getChartIdSelector } from './get_chart_id';
+
+export const getChartThemeSelector = createCachedSelector(
+  [getSettingsSpecSelector],
+  (settingsSpec): Theme => {
+    return getTheme(settingsSpec.baseTheme, settingsSpec.theme);
+  },
+)(getChartIdSelector);
+
+function getTheme(baseTheme?: Theme, theme?: PartialTheme | PartialTheme[]): Theme {
+  const base = baseTheme ? baseTheme : LIGHT_THEME;
+
+  if (Array.isArray(theme)) {
+    const [firstTheme, ...axillaryThemes] = theme;
+    return mergeWithDefaultTheme(firstTheme, base, axillaryThemes);
+  }
+
+  return theme ? mergeWithDefaultTheme(theme, base) : base;
+}
diff --git a/src/state/selectors/get_chart_type_components.ts b/src/state/selectors/get_chart_type_components.ts
new file mode 100644
index 0000000000..0f87771481
--- /dev/null
+++ b/src/state/selectors/get_chart_type_components.ts
@@ -0,0 +1,12 @@
+import { GlobalChartState, BackwardRef } from '../chart_state';
+import { Stage } from 'react-konva';
+
+type ChartRendererFn = (containerRef: BackwardRef, forwardStageRef: React.RefObject<Stage>) => JSX.Element | null;
+
+export const getInternalChartRendererSelector = (state: GlobalChartState): ChartRendererFn => {
+  if (state.internalChartState) {
+    return state.internalChartState.chartRenderer;
+  } else {
+    return () => null;
+  }
+};
diff --git a/src/state/selectors/get_internal_cursor_pointer.ts b/src/state/selectors/get_internal_cursor_pointer.ts
new file mode 100644
index 0000000000..21f43ef9bd
--- /dev/null
+++ b/src/state/selectors/get_internal_cursor_pointer.ts
@@ -0,0 +1,9 @@
+import { GlobalChartState } from '../chart_state';
+
+export const getInternalPointerCursor = (state: GlobalChartState): string => {
+  if (state.internalChartState) {
+    return state.internalChartState.getPointerCursor(state);
+  } else {
+    return 'default';
+  }
+};
diff --git a/src/state/selectors/get_internal_is_brushing_available.ts b/src/state/selectors/get_internal_is_brushing_available.ts
new file mode 100644
index 0000000000..34fcdc4e19
--- /dev/null
+++ b/src/state/selectors/get_internal_is_brushing_available.ts
@@ -0,0 +1,9 @@
+import { GlobalChartState } from '../chart_state';
+
+export const getInternalIsBrushingAvailableSelector = (state: GlobalChartState): boolean => {
+  if (state.internalChartState) {
+    return state.internalChartState.isBrushAvailable(state);
+  } else {
+    return false;
+  }
+};
diff --git a/src/state/selectors/get_legend_items.ts b/src/state/selectors/get_legend_items.ts
new file mode 100644
index 0000000000..d3e1888e4c
--- /dev/null
+++ b/src/state/selectors/get_legend_items.ts
@@ -0,0 +1,11 @@
+import { GlobalChartState } from '../chart_state';
+import { LegendItem } from '../../chart_types/xy_chart/legend/legend';
+
+const EMPTY_LEGEND_LIST = new Map<string, LegendItem>();
+export const getLegendItemsSelector = (state: GlobalChartState): Map<string, LegendItem> => {
+  if (state.internalChartState) {
+    return state.internalChartState.getLegendItems(state);
+  } else {
+    return EMPTY_LEGEND_LIST;
+  }
+};
diff --git a/src/state/selectors/get_legend_items_values.ts b/src/state/selectors/get_legend_items_values.ts
new file mode 100644
index 0000000000..9a41a4f8be
--- /dev/null
+++ b/src/state/selectors/get_legend_items_values.ts
@@ -0,0 +1,11 @@
+import { TooltipLegendValue } from '../../chart_types/xy_chart/tooltip/tooltip';
+import { GlobalChartState } from '../chart_state';
+
+const EMPTY_ITEM_LIST = new Map<string, TooltipLegendValue>();
+export const getLegendItemsValuesSelector = (state: GlobalChartState): Map<string, TooltipLegendValue> => {
+  if (state.internalChartState) {
+    return state.internalChartState.getLegendItemsValues(state);
+  } else {
+    return EMPTY_ITEM_LIST;
+  }
+};
diff --git a/src/state/selectors/get_legend_size.ts b/src/state/selectors/get_legend_size.ts
new file mode 100644
index 0000000000..18dd4b534e
--- /dev/null
+++ b/src/state/selectors/get_legend_size.ts
@@ -0,0 +1,94 @@
+import createCachedSelector from 're-reselect';
+import { getLegendItemsSelector } from './get_legend_items';
+import { CanvasTextBBoxCalculator } from '../../utils/bbox/canvas_text_bbox_calculator';
+import { BBox } from '../../utils/bbox/bbox_calculator';
+import { getSettingsSpecSelector } from './get_settings_specs';
+import { isVerticalAxis } from '../../chart_types/xy_chart/utils/axis_utils';
+import { getChartThemeSelector } from './get_chart_theme';
+import { GlobalChartState } from '../chart_state';
+import { getItemLabel } from '../../chart_types/xy_chart/legend/legend';
+import { getChartIdSelector } from './get_chart_id';
+
+const getParentDimensionSelector = (state: GlobalChartState) => state.parentDimensions;
+
+const legendItemLabelsSelector = createCachedSelector(
+  [getSettingsSpecSelector, getLegendItemsSelector],
+  (settings, legendItems): string[] => {
+    const labels: string[] = [];
+    const { showLegendDisplayValue } = settings;
+    legendItems.forEach((item) => {
+      const labelY1 = getItemLabel(item, 'y1');
+      if (item.displayValue.formatted.y1 !== null) {
+        labels.push(`${labelY1}${showLegendDisplayValue ? item.displayValue.formatted.y1 : ''}`);
+      } else {
+        labels.push(labelY1);
+      }
+      if (item.banded) {
+        const labelY0 = getItemLabel(item, 'y0');
+        if (item.displayValue.formatted.y0 !== null) {
+          labels.push(`${labelY0}${showLegendDisplayValue ? item.displayValue.formatted.y0 : ''}`);
+        } else {
+          labels.push(labelY0);
+        }
+      }
+    });
+    return labels;
+  },
+)(getChartIdSelector);
+
+const MARKER_WIDTH = 16;
+// const MARKER_HEIGHT = 16;
+const MARKER_LEFT_MARGIN = 4;
+const VALUE_LEFT_MARGIN = 4;
+const VERTICAL_PADDING = 4;
+
+export const getLegendSizeSelector = createCachedSelector(
+  [getSettingsSpecSelector, getChartThemeSelector, getParentDimensionSelector, legendItemLabelsSelector],
+  (settings, theme, parentDimensions, labels): BBox => {
+    const bboxCalculator = new CanvasTextBBoxCalculator();
+    const bbox = labels.reduce(
+      (acc, label) => {
+        const bbox = bboxCalculator.compute(
+          label,
+          1,
+          12,
+          '"Inter UI", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"',
+          1.5,
+          400,
+        );
+        if (acc.height < bbox.height) {
+          acc.height = bbox.height;
+        }
+        if (acc.width < bbox.width) {
+          acc.width = bbox.width;
+        }
+        return acc;
+      },
+      { width: 0, height: 0 },
+    );
+
+    bboxCalculator.destroy();
+    const { showLegend, showLegendDisplayValue, legendPosition } = settings;
+    const {
+      legend: { verticalWidth, spacingBuffer },
+    } = theme;
+    if (!showLegend) {
+      return { width: 0, height: 0 };
+    }
+    const legendItemWidth =
+      MARKER_WIDTH + MARKER_LEFT_MARGIN + bbox.width + (showLegendDisplayValue ? VALUE_LEFT_MARGIN : 0);
+    if (isVerticalAxis(legendPosition)) {
+      const legendItemHeight = bbox.height + VERTICAL_PADDING * 2;
+      return {
+        width: Math.floor(Math.min(legendItemWidth + spacingBuffer, verticalWidth)),
+        height: legendItemHeight,
+      };
+    } else {
+      const isSingleLine = (parentDimensions.width - 20) / 200 > labels.length;
+      return {
+        height: isSingleLine ? bbox.height + 16 : bbox.height * 2 + 24,
+        width: Math.floor(Math.min(legendItemWidth + spacingBuffer, verticalWidth)),
+      };
+    }
+  },
+)(getChartIdSelector);
diff --git a/src/state/selectors/get_settings_specs.test.ts b/src/state/selectors/get_settings_specs.test.ts
new file mode 100644
index 0000000000..270c0abc35
--- /dev/null
+++ b/src/state/selectors/get_settings_specs.test.ts
@@ -0,0 +1,37 @@
+import { getSettingsSpecSelector } from './get_settings_specs';
+import { getInitialState } from '../chart_state';
+import { DEFAULT_SETTINGS_SPEC } from '../../specs';
+describe('selectors - getSettingsSpecSelector', () => {
+  const state = getInitialState('chartId1');
+  it('shall return the same reference', () => {
+    const settings = getSettingsSpecSelector(state);
+    expect(settings).toBe(DEFAULT_SETTINGS_SPEC);
+  });
+  it('shall avoid recomputations', () => {
+    getSettingsSpecSelector(state);
+    expect(getSettingsSpecSelector.recomputations()).toBe(1);
+    getSettingsSpecSelector(state);
+    expect(getSettingsSpecSelector.recomputations()).toBe(1);
+    getSettingsSpecSelector({ ...state, specsInitialized: true });
+    expect(getSettingsSpecSelector.recomputations()).toBe(1);
+    getSettingsSpecSelector({ ...state, parentDimensions: { width: 100, height: 100, top: 100, left: 100 } });
+    expect(getSettingsSpecSelector.recomputations()).toBe(1);
+  });
+  it('shall return new settings if settings changed', () => {
+    const updatedSettings = {
+      ...DEFAULT_SETTINGS_SPEC,
+      rotation: 90,
+    };
+    const updatedState = {
+      ...state,
+      specs: {
+        [DEFAULT_SETTINGS_SPEC.id]: updatedSettings,
+      },
+    };
+    const settingsSpecToCheck = getSettingsSpecSelector(updatedState);
+    expect(settingsSpecToCheck).toBe(updatedSettings);
+    expect(getSettingsSpecSelector.recomputations()).toBe(2);
+    getSettingsSpecSelector(updatedState);
+    expect(getSettingsSpecSelector.recomputations()).toBe(2);
+  });
+});
diff --git a/src/state/selectors/get_settings_specs.ts b/src/state/selectors/get_settings_specs.ts
new file mode 100644
index 0000000000..942c96551f
--- /dev/null
+++ b/src/state/selectors/get_settings_specs.ts
@@ -0,0 +1,20 @@
+import createCachedSelector from 're-reselect';
+import { GlobalChartState } from '../chart_state';
+import { ChartTypes } from '../../chart_types';
+import { getSpecsFromStore } from '../utils';
+import { SettingsSpec } from '../../specs/settings';
+import { getChartIdSelector } from './get_chart_id';
+import { SpecTypes } from '../../chart_types/xy_chart/utils/specs';
+
+const getSpecs = (state: GlobalChartState) => state.specs;
+
+export const getSettingsSpecSelector = createCachedSelector(
+  [getSpecs],
+  (specs): SettingsSpec => {
+    const settingsSpecs = getSpecsFromStore<SettingsSpec>(specs, ChartTypes.Global, SpecTypes.Settings);
+    if (settingsSpecs.length > 1) {
+      throw new Error('Multiple settings specs are configured on the same chart');
+    }
+    return settingsSpecs[0];
+  },
+)(getChartIdSelector);
diff --git a/src/state/selectors/is_chart_empty.ts b/src/state/selectors/is_chart_empty.ts
new file mode 100644
index 0000000000..2113a64d40
--- /dev/null
+++ b/src/state/selectors/is_chart_empty.ts
@@ -0,0 +1,9 @@
+import { GlobalChartState } from '../chart_state';
+
+export const isInternalChartEmptySelector = (state: GlobalChartState): boolean | undefined => {
+  if (state.internalChartState) {
+    return state.internalChartState.isChartEmpty(state);
+  } else {
+    return undefined;
+  }
+};
diff --git a/src/state/selectors/is_initialized.ts b/src/state/selectors/is_initialized.ts
new file mode 100644
index 0000000000..97f943ad2f
--- /dev/null
+++ b/src/state/selectors/is_initialized.ts
@@ -0,0 +1,3 @@
+import { GlobalChartState } from '../chart_state';
+
+export const isInitialized = (state: GlobalChartState) => state.specsInitialized;
diff --git a/src/state/spec_factory.ts b/src/state/spec_factory.ts
new file mode 100644
index 0000000000..3cda252391
--- /dev/null
+++ b/src/state/spec_factory.ts
@@ -0,0 +1,58 @@
+import { useEffect, useRef } from 'react';
+import { Dispatch, bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+import { upsertSpec, removeSpec } from './actions/specs';
+import { Spec } from '../specs';
+
+export interface DispatchProps {
+  upsertSpec: (spec: Spec) => void;
+  removeSpec: (id: string) => void;
+}
+
+function usePrevious(value: string) {
+  const ref = useRef<string>();
+  useEffect(() => {
+    ref.current = value;
+  });
+  return ref.current;
+}
+
+export function specComponentFactory<U extends Spec, D extends keyof U>(
+  defaultProps: Pick<U, D | 'chartType' | 'specType'>,
+) {
+  const spec = (props: U & DispatchProps) => {
+    const prevId = usePrevious(props.id);
+    const { removeSpec, upsertSpec, ...spec } = props;
+    useEffect(() => {
+      if (prevId && prevId !== props.id) {
+        removeSpec(prevId);
+      }
+      upsertSpec(spec);
+    });
+    useEffect(
+      () => () => {
+        removeSpec(props.id);
+      },
+      [],
+    );
+    return null;
+  };
+  spec.defaultProps = defaultProps;
+  return spec;
+}
+
+const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
+  bindActionCreators(
+    {
+      upsertSpec,
+      removeSpec,
+    },
+    dispatch,
+  );
+
+export function getConnect() {
+  return connect(
+    null,
+    mapDispatchToProps,
+  );
+}
diff --git a/src/state/utils.test.ts b/src/state/utils.test.ts
new file mode 100644
index 0000000000..678d8c43ed
--- /dev/null
+++ b/src/state/utils.test.ts
@@ -0,0 +1,11 @@
+import { getSpecsFromStore } from './utils';
+import { ChartTypes } from '../chart_types';
+import { SpecTypes } from '../chart_types/xy_chart/utils/specs';
+
+describe('State utils', () => {
+  it('getSpecsFromStore shall return always the same object reference excluding the array', () => {
+    const spec1 = { id: 'id1', chartType: ChartTypes.XYAxis, specType: SpecTypes.Series };
+    const specs = getSpecsFromStore({ id1: spec1 }, ChartTypes.XYAxis, SpecTypes.Series);
+    expect(specs[0]).toBe(spec1);
+  });
+});
diff --git a/src/state/utils.ts b/src/state/utils.ts
new file mode 100644
index 0000000000..ee20f9bb10
--- /dev/null
+++ b/src/state/utils.ts
@@ -0,0 +1,18 @@
+import { SpecList } from './chart_state';
+import { Spec } from '../specs';
+import { ChartTypes } from '../chart_types';
+
+export function getSpecsFromStore<U extends Spec>(specs: SpecList, chartType: ChartTypes, specType?: string): U[] {
+  return Object.keys(specs)
+    .filter((specId) => {
+      const currentSpec = specs[specId];
+      if (specType) {
+        return currentSpec.specType === specType && currentSpec.chartType === chartType;
+      } else {
+        return currentSpec.chartType === chartType;
+      }
+    })
+    .map((specId) => {
+      return specs[specId] as U;
+    });
+}
diff --git a/src/utils/bbox/bbox_calculator.ts b/src/utils/bbox/bbox_calculator.ts
index dd172cdeec..3a33551b2d 100644
--- a/src/utils/bbox/bbox_calculator.ts
+++ b/src/utils/bbox/bbox_calculator.ts
@@ -1,11 +1,14 @@
-import { Option } from 'fp-ts/lib/Option';
-
 export interface BBox {
   width: number;
   height: number;
 }
 
+export const DEFAULT_EMPTY_BBOX = {
+  width: 0,
+  height: 0,
+};
+
 export interface BBoxCalculator {
-  compute(text: string, padding: number, fontSize?: number, fontFamily?: string): Option<BBox>;
+  compute(text: string, padding: number, fontSize?: number, fontFamily?: string): BBox;
   destroy(): void;
 }
diff --git a/src/utils/bbox/canvas_text_bbox_calculator.test.ts b/src/utils/bbox/canvas_text_bbox_calculator.test.ts
index eb726dca78..25e0306c71 100644
--- a/src/utils/bbox/canvas_text_bbox_calculator.test.ts
+++ b/src/utils/bbox/canvas_text_bbox_calculator.test.ts
@@ -1,62 +1,9 @@
-import { none } from 'fp-ts/lib/Option';
 import { CanvasTextBBoxCalculator } from './canvas_text_bbox_calculator';
 
 describe('CanvasTextBBoxCalculator', () => {
   test('can create a canvas for computing text measurement values', () => {
     const canvasBboxCalculator = new CanvasTextBBoxCalculator();
-    const bbox = canvasBboxCalculator.compute('foo', 0).getOrElse({
-      width: 0,
-      height: 0,
-    });
-    expect(Math.abs(bbox.width - 23.2)).toBeLessThanOrEqual(2);
-    expect(bbox.height).toBe(16);
-
-    canvasBboxCalculator.context = null;
-    expect(canvasBboxCalculator.compute('foo', 0)).toBe(none);
-  });
-  test('can compute near the same width for the same text independently of the scale factor', () => {
-    let canvasBboxCalculator = new CanvasTextBBoxCalculator(undefined, 5);
-
-    let bbox = canvasBboxCalculator.compute('foo', 0).getOrElse({
-      width: 0,
-      height: 0,
-    });
-    expect(Math.abs(bbox.width - 23.2)).toBeLessThanOrEqual(2);
-    expect(bbox.height).toBe(16);
-
-    canvasBboxCalculator = new CanvasTextBBoxCalculator(undefined, 10);
-
-    bbox = canvasBboxCalculator.compute('foo', 0).getOrElse({
-      width: 0,
-      height: 0,
-    });
-    expect(Math.abs(bbox.width - 23.2)).toBeLessThanOrEqual(2);
-    expect(bbox.height).toBe(16);
-
-    canvasBboxCalculator = new CanvasTextBBoxCalculator(undefined, 50);
-
-    bbox = canvasBboxCalculator.compute('foo', 0).getOrElse({
-      width: 0,
-      height: 0,
-    });
-    expect(Math.abs(bbox.width - 23.2)).toBeLessThanOrEqual(2);
-    expect(bbox.height).toBe(16);
-
-    canvasBboxCalculator = new CanvasTextBBoxCalculator(undefined, 100);
-
-    bbox = canvasBboxCalculator.compute('foo', 0).getOrElse({
-      width: 0,
-      height: 0,
-    });
-    expect(Math.abs(bbox.width - 23.2)).toBeLessThanOrEqual(2);
-    expect(bbox.height).toBe(16);
-
-    canvasBboxCalculator = new CanvasTextBBoxCalculator(undefined, 1000);
-
-    bbox = canvasBboxCalculator.compute('foo', 0).getOrElse({
-      width: 0,
-      height: 0,
-    });
+    const bbox = canvasBboxCalculator.compute('foo', 0);
     expect(Math.abs(bbox.width - 23.2)).toBeLessThanOrEqual(2);
     expect(bbox.height).toBe(16);
   });
diff --git a/src/utils/bbox/canvas_text_bbox_calculator.ts b/src/utils/bbox/canvas_text_bbox_calculator.ts
index 78408cf7fd..0fa168e0df 100644
--- a/src/utils/bbox/canvas_text_bbox_calculator.ts
+++ b/src/utils/bbox/canvas_text_bbox_calculator.ts
@@ -1,42 +1,34 @@
-import { none, Option, some } from 'fp-ts/lib/Option';
-import { BBox, BBoxCalculator } from './bbox_calculator';
+import { BBox, BBoxCalculator, DEFAULT_EMPTY_BBOX } from './bbox_calculator';
 
 export class CanvasTextBBoxCalculator implements BBoxCalculator {
-  context: CanvasRenderingContext2D | null;
   private attachedRoot: HTMLElement;
   private offscreenCanvas: HTMLCanvasElement;
-  private scaledFontSize: number;
+  private context: CanvasRenderingContext2D | null;
 
-  constructor(rootElement?: HTMLElement, scaledFontSize = 100) {
+  constructor(rootElement?: HTMLElement) {
     this.offscreenCanvas = document.createElement('canvas');
     this.offscreenCanvas.style.position = 'absolute';
-    this.offscreenCanvas.style.top = '-9999px';
-
+    this.offscreenCanvas.style.top = '-99999px';
+    this.offscreenCanvas.style.left = '-99999px';
     this.context = this.offscreenCanvas.getContext('2d');
     this.attachedRoot = rootElement || document.documentElement;
     this.attachedRoot.appendChild(this.offscreenCanvas);
-    this.scaledFontSize = scaledFontSize;
   }
-  compute(text: string, padding: number, fontSize = 16, fontFamily = 'Arial'): Option<BBox> {
+  compute(text: string, padding: number, fontSize = 16, fontFamily = 'Arial', lineHeight = 1, fontWeight = 400): BBox {
     if (!this.context) {
-      return none;
+      return DEFAULT_EMPTY_BBOX;
     }
-
     // Padding should be at least one to avoid browser measureText inconsistencies
     if (padding < 1) {
       padding = 1;
     }
-
-    // We scale the text up to get a more accurate computation of the width of the text
-    // because `measureText` can vary a lot between browsers.
-    const scalingFactor = this.scaledFontSize / fontSize;
-    this.context.font = `${this.scaledFontSize}px ${fontFamily}`;
+    this.context.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
     const measure = this.context.measureText(text);
 
-    return some({
-      width: measure.width / scalingFactor + padding,
-      height: fontSize,
-    });
+    return {
+      width: measure.width + padding,
+      height: fontSize * lineHeight,
+    };
   }
   destroy(): void {
     this.attachedRoot.removeChild(this.offscreenCanvas);
diff --git a/src/utils/bbox/dom_text_bbox_calculator.ts b/src/utils/bbox/dom_text_bbox_calculator.ts
new file mode 100644
index 0000000000..57a5286022
--- /dev/null
+++ b/src/utils/bbox/dom_text_bbox_calculator.ts
@@ -0,0 +1,31 @@
+import { BBox, BBoxCalculator } from './bbox_calculator';
+
+export class DOMTextBBoxCalculator implements BBoxCalculator {
+  private attachedRoot: HTMLElement;
+  private offscreenCanvas: HTMLSpanElement;
+
+  constructor(rootElement?: HTMLElement) {
+    this.offscreenCanvas = document.createElement('span');
+    this.offscreenCanvas.style.position = 'absolute';
+    this.offscreenCanvas.style.top = '-9999px';
+    this.offscreenCanvas.style.left = '-9999px';
+
+    this.attachedRoot = rootElement || document.documentElement;
+    this.attachedRoot.appendChild(this.offscreenCanvas);
+  }
+  compute(text: string, padding: number, fontSize = 16, fontFamily = 'Arial', lineHeight = 1, fontWeight = 400): BBox {
+    this.offscreenCanvas.style.fontSize = `${fontSize}px`;
+    this.offscreenCanvas.style.fontFamily = fontFamily;
+    this.offscreenCanvas.style.fontWeight = `${fontWeight}`;
+    this.offscreenCanvas.style.lineHeight = `${lineHeight}px`;
+    this.offscreenCanvas.innerHTML = text;
+
+    return {
+      width: Math.ceil(this.offscreenCanvas.clientWidth + padding),
+      height: Math.ceil(this.offscreenCanvas.clientHeight),
+    };
+  }
+  destroy(): void {
+    this.attachedRoot.removeChild(this.offscreenCanvas);
+  }
+}
diff --git a/src/utils/bbox/svg_text_bbox_calculator.ts b/src/utils/bbox/svg_text_bbox_calculator.ts
index b2a874b3e2..fbc1507140 100644
--- a/src/utils/bbox/svg_text_bbox_calculator.ts
+++ b/src/utils/bbox/svg_text_bbox_calculator.ts
@@ -1,4 +1,3 @@
-import { Option, some } from 'fp-ts/lib/Option';
 import { BBox, BBoxCalculator } from './bbox_calculator';
 
 // not sure where to specify this, required for tests
@@ -26,13 +25,13 @@ export class SvgTextBBoxCalculator implements BBoxCalculator {
     this.attachedRoot = rootElement || document.documentElement;
     this.attachedRoot.appendChild(this.svgElem);
   }
-  compute(text: string): Option<BBox> {
+  compute(text: string): BBox {
     this.textNode.textContent = text;
     const rect = this.textElem.getBoundingClientRect();
-    return some({
+    return {
       width: rect.width,
       height: rect.height,
-    });
+    };
   }
   destroy(): void {
     this.attachedRoot.removeChild(this.svgElem);
diff --git a/src/utils/events.ts b/src/utils/events.ts
new file mode 100644
index 0000000000..9b607705f0
--- /dev/null
+++ b/src/utils/events.ts
@@ -0,0 +1,6 @@
+import { CursorEvent } from '../specs';
+import { Scale } from './scales/scales';
+
+export function isValidExternalPointerEvent(event: CursorEvent, mainScale: Scale): boolean {
+  return event.unit === undefined || event.unit === mainScale.unit;
+}
diff --git a/src/utils/geometry.ts b/src/utils/geometry.ts
new file mode 100644
index 0000000000..149322f197
--- /dev/null
+++ b/src/utils/geometry.ts
@@ -0,0 +1,120 @@
+import { $Values } from 'utility-types';
+import { SpecId } from './ids';
+import { BarSeriesStyle, PointStyle, AreaStyle, LineStyle, ArcStyle } from './themes/theme';
+
+export interface GeometryId {
+  specId: SpecId;
+  seriesKey: any[];
+}
+
+/**
+ * The accessor type
+ */
+export const AccessorType = Object.freeze({
+  Y0: 'y0' as 'y0',
+  Y1: 'y1' as 'y1',
+});
+
+export type AccessorType = $Values<typeof AccessorType>;
+
+export interface GeometryValue {
+  y: any;
+  x: any;
+  accessor: AccessorType;
+}
+
+export type IndexedGeometry = PointGeometry | BarGeometry;
+
+/**
+ * Array of **range** clippings [x1, x2] to be excluded during rendering
+ *
+ * Note: Must be scaled **range** values (i.e. pixel coordinates) **NOT** domain values
+ */
+export type ClippedRanges = [number, number][];
+
+export interface PointGeometry {
+  x: number;
+  y: number;
+  radius: number;
+  color: string;
+  transform: {
+    x: number;
+    y: number;
+  };
+  geometryId: GeometryId;
+  value: GeometryValue;
+  styleOverrides?: Partial<PointStyle>;
+}
+export interface BarGeometry {
+  x: number;
+  y: number;
+  width: number;
+  height: number;
+  color: string;
+  displayValue?: {
+    text: any;
+    width: number;
+    height: number;
+    hideClippedValue?: boolean;
+    isValueContainedInElement?: boolean;
+  };
+  geometryId: GeometryId;
+  value: GeometryValue;
+  seriesStyle: BarSeriesStyle;
+}
+
+export interface LineGeometry {
+  line: string;
+  points: PointGeometry[];
+  color: string;
+  transform: {
+    x: number;
+    y: number;
+  };
+  geometryId: GeometryId;
+  seriesLineStyle: LineStyle;
+  seriesPointStyle: PointStyle;
+  /**
+   * Ranges of `[x0, x1]` pairs to clip from series
+   */
+  clippedRanges: ClippedRanges;
+}
+
+export interface AreaGeometry {
+  area: string;
+  lines: string[];
+  points: PointGeometry[];
+  color: string;
+  transform: {
+    x: number;
+    y: number;
+  };
+  geometryId: GeometryId;
+  seriesAreaStyle: AreaStyle;
+  seriesAreaLineStyle: LineStyle;
+  seriesPointStyle: PointStyle;
+  isStacked: boolean;
+  /**
+   * Ranges of `[x0, x1]` pairs to clip from series
+   */
+  clippedRanges: ClippedRanges;
+}
+
+export interface ArcGeometry {
+  arc: string;
+  color: string;
+  geometryId: GeometryId;
+  seriesArcStyle: ArcStyle;
+  transform: {
+    x: number;
+    y: number;
+  };
+}
+
+export function isPointGeometry(ig: IndexedGeometry): ig is PointGeometry {
+  return ig.hasOwnProperty('radius');
+}
+
+export function isBarGeometry(ig: IndexedGeometry): ig is BarGeometry {
+  return ig.hasOwnProperty('width') && ig.hasOwnProperty('height');
+}
diff --git a/src/utils/ids.ts b/src/utils/ids.ts
index d8e88bdc71..e86a47c69d 100644
--- a/src/utils/ids.ts
+++ b/src/utils/ids.ts
@@ -1,25 +1,17 @@
-/* eslint @typescript-eslint/no-empty-interface: off */
-import { iso, Newtype } from 'newtype-ts';
-
-export interface GroupId extends Newtype<{ readonly GroupId: unique symbol }, string> {}
-export interface AxisId extends Newtype<{ readonly AxisId: unique symbol }, string> {}
-export interface SpecId extends Newtype<{ readonly SpecId: unique symbol }, string> {}
-export interface AnnotationId extends Newtype<{ readonly AnnotationId: unique symbol }, string> {}
-
-const groupIdIso = iso<GroupId>();
-const axisIdIso = iso<AxisId>();
-const specIdIso = iso<SpecId>();
-const annotationIdIso = iso<AnnotationId>();
-
-export function getGroupId(id: string): GroupId {
-  return groupIdIso.wrap(id);
+export function getGroupId(id: string): string {
+  return id;
 }
-export function getAxisId(id: string): AxisId {
-  return axisIdIso.wrap(id);
+export function getAxisId(id: string): string {
+  return id;
 }
-export function getSpecId(id: string): SpecId {
-  return specIdIso.wrap(id);
+export function getSpecId(id: string): string {
+  return id;
 }
-export function getAnnotationId(id: string): AnnotationId {
-  return annotationIdIso.wrap(id);
+export function getAnnotationId(id: string): string {
+  return id;
 }
+
+export type GroupId = string;
+export type AxisId = string;
+export type SpecId = string;
+export type AnnotationId = string;
diff --git a/src/utils/point.ts b/src/utils/point.ts
new file mode 100644
index 0000000000..79d639a89f
--- /dev/null
+++ b/src/utils/point.ts
@@ -0,0 +1,4 @@
+export interface Point {
+  x: number;
+  y: number;
+}
diff --git a/src/utils/scales/scale_band.ts b/src/utils/scales/scale_band.ts
index c869149bec..e8cf04f696 100644
--- a/src/utils/scales/scale_band.ts
+++ b/src/utils/scales/scale_band.ts
@@ -4,6 +4,7 @@ import { ScaleType, Scale } from './scales';
 
 export class ScaleBand implements Scale {
   readonly bandwidth: number;
+  readonly bandwidthPadding: number;
   readonly step: number;
   readonly type: ScaleType;
   readonly domain: any[];
@@ -34,13 +35,13 @@ export class ScaleBand implements Scale {
     this.d3Scale.paddingInner(safeBarPadding);
     this.d3Scale.paddingOuter(safeBarPadding / 2);
     this.bandwidth = this.d3Scale.bandwidth() || 0;
-
     this.step = this.d3Scale.step();
     this.domain = this.d3Scale.domain();
     this.range = range.slice();
     if (overrideBandwidth) {
       this.bandwidth = overrideBandwidth * (1 - safeBarPadding);
     }
+    this.bandwidthPadding = this.bandwidth;
     // TO FIX: we are assiming that it's ordered
     this.isInverted = this.domain[0] > this.domain[1];
     this.invertedScale = scaleQuantize()
@@ -75,7 +76,3 @@ export class ScaleBand implements Scale {
     return this.domain.includes(value);
   }
 }
-
-export function isOrdinalScale(scale: Scale): scale is ScaleBand {
-  return scale.type === ScaleType.Ordinal;
-}
diff --git a/src/utils/scales/scale_continuous.ts b/src/utils/scales/scale_continuous.ts
index 93e83742ec..0508a6d15e 100644
--- a/src/utils/scales/scale_continuous.ts
+++ b/src/utils/scales/scale_continuous.ts
@@ -31,12 +31,6 @@ const SCALES = {
   [ScaleType.Time]: scaleUtc,
 };
 
-export function limitToMin(value: number, positive: boolean) {
-  if (value === 0) {
-    return positive ? 1 : -1;
-  }
-  return value;
-}
 /**
  * As log(0) = -Infinite, a log scale domain must be strictly-positive
  * or strictly-negative; the domain must not include or cross zero value.
@@ -250,9 +244,12 @@ export class ScaleContinuous implements Scale {
     value: number,
     data: number[],
   ): {
-    value: any;
+    value: number;
     withinBandwidth: boolean;
-  } {
+  } | null {
+    if (data.length === 0) {
+      return null;
+    }
     const invertedValue = this.invert(value);
     const bisectValue = this.bandwidth === 0 ? invertedValue + this.minInterval / 2 : invertedValue;
     const leftIndex = bisectLeft(data, bisectValue);
@@ -308,10 +305,6 @@ export class ScaleContinuous implements Scale {
   }
 }
 
-export function isContinuousScale(scale: Scale): scale is ScaleContinuous {
-  return scale.type !== ScaleType.Ordinal;
-}
-
 export function isLogarithmicScale(scale: Scale) {
   return scale.type === ScaleType.Log;
 }
diff --git a/src/utils/scales/scales.ts b/src/utils/scales/scales.ts
index 587906b10e..f78c4cd8f7 100644
--- a/src/utils/scales/scales.ts
+++ b/src/utils/scales/scales.ts
@@ -13,11 +13,12 @@ export interface Scale {
   ) => {
     value: any;
     withinBandwidth: boolean;
-  };
+  } | null;
   isSingleValue: () => boolean;
   /** Check if the passed value is within the scale domain */
   isValueInDomain: (value: any) => boolean;
   bandwidth: number;
+  bandwidthPadding: number;
   minInterval: number;
   type: ScaleType;
   /**
diff --git a/src/utils/themes/dark_theme.ts b/src/utils/themes/dark_theme.ts
index c3e17b8c4e..920d39bf1e 100644
--- a/src/utils/themes/dark_theme.ts
+++ b/src/utils/themes/dark_theme.ts
@@ -61,6 +61,14 @@ export const DARK_THEME: Theme = {
       offsetY: 0,
     },
   },
+  arcSeriesStyle: {
+    arc: {
+      visible: true,
+      stroke: 'white',
+      strokeWidth: 1,
+      opacity: 1,
+    },
+  },
   sharedStyle: DEFAULT_GEOMETRY_STYLES,
   scales: {
     barsPadding: 0.25,
diff --git a/src/utils/themes/light_theme.ts b/src/utils/themes/light_theme.ts
index 5af9972261..bfc55d6993 100644
--- a/src/utils/themes/light_theme.ts
+++ b/src/utils/themes/light_theme.ts
@@ -60,6 +60,14 @@ export const LIGHT_THEME: Theme = {
       offsetY: 0,
     },
   },
+  arcSeriesStyle: {
+    arc: {
+      visible: true,
+      stroke: 'black',
+      strokeWidth: 1,
+      opacity: 1,
+    },
+  },
   sharedStyle: DEFAULT_GEOMETRY_STYLES,
   scales: {
     barsPadding: 0.25,
diff --git a/src/utils/themes/theme.ts b/src/utils/themes/theme.ts
index 29704d59e6..6efc793d5b 100644
--- a/src/utils/themes/theme.ts
+++ b/src/utils/themes/theme.ts
@@ -13,11 +13,15 @@ export interface TextStyle {
   fill: string;
   padding: number;
 }
+
+/** Shared style properties for varies geometries */
 export interface GeometryStyle {
-  stroke: string;
-  strokeWidth: number;
-  fill?: string;
-  opacity?: number;
+  /**
+   * Opacity multiplier
+   *
+   * if set to `0.5` all given opacities will be halfed
+   */
+  opacity: number;
 }
 
 /** Shared style properties for varies geometries */
@@ -146,6 +150,7 @@ export interface Theme {
    * You may use `CustomSeriesColorsMap` to assign colors to a given series or replace the `theme.colors.vizColors` colors to your desired colors.
    */
   barSeriesStyle: BarSeriesStyle;
+  arcSeriesStyle: ArcSeriesStyle;
   sharedStyle: SharedGeometryStateStyle;
   axes: AxisConfig;
   scales: ScalesConfig;
@@ -196,6 +201,19 @@ export interface AreaStyle {
   opacity: number;
 }
 
+export interface ArcStyle {
+  /** is the arc is visible or hidden ? */
+  visible: boolean;
+  /** a static fill color if defined, if not it will use the color of the series */
+  fill?: string;
+  /** a static stroke color if defined, if not it will use the color of the series */
+  stroke?: string;
+  /** the stroke width of the line */
+  strokeWidth: number;
+  /** the opacity of each arc on the theme/series */
+  opacity: number;
+}
+
 export interface RectStyle {
   /** a static fill color if defined, if not it will use the color of the series */
   fill?: string;
@@ -238,6 +256,10 @@ export interface AreaSeriesStyle {
   point: PointStyle;
 }
 
+export interface ArcSeriesStyle {
+  arc: ArcStyle;
+}
+
 export interface CrosshairStyle {
   band: FillStyle & Visible;
   line: StrokeStyle & Visible & Partial<StrokeDashArray>;
diff --git a/stories/annotations.tsx b/stories/annotations.tsx
index 2dc5271850..5a38813f7e 100644
--- a/stories/annotations.tsx
+++ b/stories/annotations.tsx
@@ -21,8 +21,8 @@ import {
 } from '../src';
 import { Icon } from '../src/components/icons/icon';
 import { KIBANA_METRICS } from '../src/utils/data_samples/test_dataset_kibana';
-import { AccessorType } from '../src/chart_types/xy_chart/rendering/rendering';
 import { getChartRotationKnob } from './common';
+import { AccessorType } from '../src/utils/geometry';
 
 const dateFormatter = timeFormatter('HH:mm:ss');
 
@@ -65,7 +65,7 @@ storiesOf('Annotations', module)
       <Chart className={'story-chart'}>
         <Settings showLegend debug={boolean('debug', false)} rotation={getChartRotationKnob()} />
         <LineAnnotation
-          annotationId={getAnnotationId('anno_1')}
+          id={getAnnotationId('anno_1')}
           domainType={AnnotationDomainTypes.XDomain}
           dataValues={dataValues}
           style={style}
@@ -91,7 +91,7 @@ storiesOf('Annotations', module)
       <Chart className={'story-chart'}>
         <Settings debug={boolean('debug', false)} rotation={getChartRotationKnob()} />
         <LineAnnotation
-          annotationId={getAnnotationId('anno_1')}
+          id={'anno_1'}
           domainType={AnnotationDomainTypes.XDomain}
           dataValues={dataValues}
           marker={<Icon type="alert" />}
@@ -122,7 +122,7 @@ storiesOf('Annotations', module)
       <Chart className={'story-chart'}>
         <Settings debug={boolean('debug', false)} rotation={getChartRotationKnob()} />
         <LineAnnotation
-          annotationId={getAnnotationId('anno_')}
+          id={'anno_'}
           domainType={AnnotationDomainTypes.YDomain}
           dataValues={dataValues}
           marker={<Icon type="alert" />}
@@ -153,7 +153,7 @@ storiesOf('Annotations', module)
       <Chart className={'story-chart'}>
         <Settings debug={boolean('debug', false)} rotation={getChartRotationKnob()} />
         <LineAnnotation
-          annotationId={getAnnotationId('anno_1')}
+          id={'anno_1'}
           domainType={AnnotationDomainTypes.XDomain}
           dataValues={dataValues}
           marker={<Icon type="alert" />}
@@ -211,7 +211,7 @@ storiesOf('Annotations', module)
       <Chart className={'story-chart'}>
         <Settings debug={boolean('debug', false)} rotation={getChartRotationKnob()} />
         <LineAnnotation
-          annotationId={getAnnotationId('anno_1')}
+          id={'anno_1'}
           domainType={AnnotationDomainTypes.XDomain}
           dataValues={dataValues}
           style={style}
@@ -241,13 +241,14 @@ storiesOf('Annotations', module)
           y0: 0,
           y1: 7,
         },
+        details: 'details about this annotation',
       },
     ];
 
     return (
       <Chart className={'story-chart'}>
         <Settings debug={boolean('debug', false)} rotation={getChartRotationKnob()} />
-        <RectAnnotation dataValues={dataValues} annotationId={getAnnotationId('rect')} />
+        <RectAnnotation dataValues={dataValues} id={'rect'} />
         <Axis id={getAxisId('bottom')} position={Position.Bottom} title={'x-domain axis'} />
         <Axis id={getAxisId('left')} title={'y-domain axis'} position={Position.Left} />
         <BarSeries
@@ -275,7 +276,7 @@ storiesOf('Annotations', module)
     return (
       <Chart className={'story-chart'}>
         <Settings debug={boolean('debug', false)} rotation={getChartRotationKnob()} />
-        <RectAnnotation dataValues={dataValues} annotationId={getAnnotationId('rect')} />
+        <RectAnnotation dataValues={dataValues} id={'rect'} />
         <Axis id={getAxisId('bottom')} position={Position.Bottom} title={'x-domain axis'} />
         <Axis id={getAxisId('left')} title={'y-domain axis'} position={Position.Left} />
         <BarSeries
@@ -342,7 +343,7 @@ storiesOf('Annotations', module)
     return (
       <Chart className={'story-chart'}>
         <Settings debug={boolean('debug', false)} rotation={getChartRotationKnob()} />
-        <RectAnnotation dataValues={dataValues} annotationId={getAnnotationId('rect')} />
+        <RectAnnotation dataValues={dataValues} id={'rect'} />
         <Axis id={getAxisId('bottom')} position={xAxisPosition} title={xAxisTitle} />
         <Axis id={getAxisId('left')} title={yAxisTitle} position={yAxisPosition} />
         <LineSeries
@@ -433,7 +434,7 @@ storiesOf('Annotations', module)
         <Settings debug={boolean('debug', false)} rotation={getChartRotationKnob()} />
         <RectAnnotation
           dataValues={dataValues}
-          annotationId={getAnnotationId('rect')}
+          id={'rect'}
           style={style}
           renderTooltip={renderTooltip}
           zIndex={zIndex}
@@ -482,7 +483,7 @@ storiesOf('Annotations', module)
       <Chart className={'story-chart'}>
         <Settings debug={boolean('debug', false)} rotation={getChartRotationKnob()} xDomain={xDomain} />
         <LineAnnotation
-          annotationId={getAnnotationId('anno_1')}
+          id={'anno_1'}
           domainType={AnnotationDomainTypes.XDomain}
           dataValues={dataValues}
           style={style}
@@ -540,7 +541,7 @@ storiesOf('Annotations', module)
       <Chart className={'story-chart'}>
         <RectAnnotation
           dataValues={dataValues}
-          annotationId={getAnnotationId('rect')}
+          id={'rect'}
           renderTooltip={isCustomTooltip ? tooltipFormatter : undefined}
         />
         <Axis id={getAxisId('bottom')} position={Position.Bottom} title={'x-domain axis'} />
diff --git a/stories/area_chart.tsx b/stories/area_chart.tsx
index d30a3e761b..6bf938e2b5 100644
--- a/stories/area_chart.tsx
+++ b/stories/area_chart.tsx
@@ -175,6 +175,7 @@ storiesOf('Area Chart', module)
           tickFormat={dateFormatter}
         />
         <Axis
+          id={'left'}
           title={KIBANA_METRICS.metrics.kibana_os_load[0].metric.title}
           position={Position.Left}
           tickFormat={(d) => Number(d).toFixed(2)}
@@ -213,6 +214,7 @@ storiesOf('Area Chart', module)
           tickFormat={dateFormatter}
         />
         <Axis
+          id={'left'}
           title={KIBANA_METRICS.metrics.kibana_os_load[0].metric.title}
           position={Position.Left}
           tickFormat={(d) => Number(d).toFixed(2)}
@@ -278,6 +280,7 @@ storiesOf('Area Chart', module)
           tickFormat={dateFormatter}
         />
         <Axis
+          id={'left'}
           title={KIBANA_METRICS.metrics.kibana_os_load[0].metric.title}
           position={Position.Left}
           tickFormat={(d) => Number(d).toFixed(2)}
@@ -327,6 +330,7 @@ storiesOf('Area Chart', module)
           tickFormat={dateFormatter}
         />
         <Axis
+          id={'left'}
           title={KIBANA_METRICS.metrics.kibana_os_load[0].metric.title}
           position={Position.Left}
           tickFormat={(d) => Number(d).toFixed(2)}
diff --git a/stories/bar_chart.tsx b/stories/bar_chart.tsx
index 2ebb1bab7f..b9c67f1581 100644
--- a/stories/bar_chart.tsx
+++ b/stories/bar_chart.tsx
@@ -10,7 +10,6 @@ import {
   BarSeries,
   Chart,
   DARK_THEME,
-  getAnnotationId,
   getAxisId,
   getGroupId,
   getSpecId,
@@ -1437,7 +1436,7 @@ storiesOf('Bar Chart', module)
       <Chart className={'story-chart'}>
         <Settings rotation={getChartRotationKnob()} theme={theme} debug={boolean('debug', true)} />
         <LineAnnotation
-          annotationId={getAnnotationId('line-annotation')}
+          id={'line-annotation'}
           domainType={AnnotationDomainTypes.XDomain}
           dataValues={[{ dataValue: 2 }, { dataValue: 2.5 }, { dataValue: 3.5 }]}
           style={lineAnnotationStyle}
@@ -1458,7 +1457,7 @@ storiesOf('Bar Chart', module)
               details: 'rect annotation',
             },
           ]}
-          annotationId={getAnnotationId('rect')}
+          id={'rect'}
         />
         <Axis id={getAxisId('discover-histogram-left-axis')} position={Position.Left} title={'left axis'} />
         <Axis id={getAxisId('discover-histogram-bottom-axis')} position={Position.Bottom} title={'bottom axis'} />
diff --git a/stories/interactions.tsx b/stories/interactions.tsx
index 688dc4272d..f94caac636 100644
--- a/stories/interactions.tsx
+++ b/stories/interactions.tsx
@@ -21,6 +21,7 @@ import {
   TooltipType,
   TooltipValue,
   TooltipValueFormatter,
+  HistogramBarSeries,
 } from '../src/';
 
 import { array, boolean, number, select, button } from '@storybook/addon-knobs';
@@ -470,6 +471,62 @@ storiesOf('Interactions', module)
           yScaleType={ScaleType.Linear}
           xAccessor="x"
           yAccessors={['y']}
+          timeZone={'Europe/Rome'}
+          data={[
+            { x: now, y: 2 },
+            { x: now + oneDay, y: 7 },
+            { x: now + oneDay * 2, y: 3 },
+            { x: now + oneDay * 5, y: 6 },
+          ]}
+        />
+        <LineSeries
+          id={getSpecId('baras')}
+          xScaleType={ScaleType.Time}
+          yScaleType={ScaleType.Linear}
+          xAccessor="x"
+          yAccessors={['y']}
+          timeZone={'Europe/Rome'}
+          data={[
+            { x: now, y: 2 },
+            { x: now + oneDay, y: 7 },
+            { x: now + oneDay * 2, y: 3 },
+            { x: now + oneDay * 5, y: 6 },
+          ]}
+        />
+      </Chart>
+    );
+  })
+  .add('brush selection tool on histogram time charts', () => {
+    const now = DateTime.fromISO('2019-01-11T00:00:00.000')
+      .setZone('utc+1')
+      .toMillis();
+    const oneDay = 1000 * 60 * 60 * 24;
+    const formatter = niceTimeFormatter([now, now + oneDay * 5]);
+    return (
+      <Chart className={'story-chart'}>
+        <Settings
+          debug={boolean('debug', false)}
+          onBrushEnd={(start, end) => {
+            action('onBrushEnd')(formatter(start), formatter(end));
+          }}
+          onElementClick={action('onElementClick')}
+        />
+        <Axis
+          id={getAxisId('bottom')}
+          position={Position.Bottom}
+          title={'bottom'}
+          showOverlappingTicks={true}
+          tickFormat={formatter}
+        />
+        <Axis id={getAxisId('left')} title={'left'} position={Position.Left} tickFormat={(d) => Number(d).toFixed(2)} />
+
+        <HistogramBarSeries
+          id={getSpecId('bars')}
+          xScaleType={ScaleType.Time}
+          yScaleType={ScaleType.Linear}
+          xAccessor="x"
+          yAccessors={['y']}
+          timeZone={'Europe/Rome'}
           data={[
             { x: now, y: 2 },
             { x: now + oneDay, y: 7 },
diff --git a/stories/mixed.tsx b/stories/mixed.tsx
index 47619d757b..73a4557f19 100644
--- a/stories/mixed.tsx
+++ b/stories/mixed.tsx
@@ -17,7 +17,7 @@ import {
   Settings,
 } from '../src/';
 import { timeFormatter } from '../src/utils/data/formatters';
-import { Fit } from '../src/chart_types/xy_chart/utils/specs';
+import { Fit, SeriesTypes } from '../src/chart_types/xy_chart/utils/specs';
 
 storiesOf('Mixed Charts', module)
   .add('bar and lines', () => {
@@ -290,10 +290,10 @@ storiesOf('Mixed Charts', module)
     const seriesType = select<string>(
       'seriesType',
       {
-        Area: 'area',
-        Line: 'line',
+        Area: SeriesTypes.Area,
+        Line: SeriesTypes.Line,
       },
-      'area',
+      SeriesTypes.Area,
     );
     const dataKey = select<string>(
       'dataset',
@@ -365,7 +365,7 @@ storiesOf('Mixed Charts', module)
         />
         <Axis id={getAxisId('bottom')} position={Position.Bottom} title={'Bottom axis'} showOverlappingTicks={true} />
         <Axis id={getAxisId('left')} title={'Left axis'} position={Position.Left} />
-        {seriesType === 'area' ? (
+        {seriesType === SeriesTypes.Area ? (
           <AreaSeries
             id={getSpecId('test')}
             xScaleType={xScaleType}
diff --git a/stories/scales.tsx b/stories/scales.tsx
index 28d8adfdd2..e1f73a1f30 100644
--- a/stories/scales.tsx
+++ b/stories/scales.tsx
@@ -39,9 +39,6 @@ storiesOf('Scales', module)
 
     let data;
     switch (datasetSelected) {
-      case 'utc':
-        data = UTC_DATASET;
-        break;
       case 'local':
         data = CURRENT_TIMEZONE_DATASET;
         break;
@@ -51,6 +48,10 @@ storiesOf('Scales', module)
       case 'utc-8':
         data = OTHER_MINUS8_TIMEZONE_DATASET;
         break;
+      case 'utc':
+      default:
+        data = UTC_DATASET;
+        break;
     }
     let tooltipFn: (d: number) => string;
     switch (tooltipSelected) {
diff --git a/tsconfig.jest.json b/tsconfig.jest.json
index f407711d1d..8d80e97a08 100644
--- a/tsconfig.jest.json
+++ b/tsconfig.jest.json
@@ -1,8 +1,4 @@
 {
   "extends": "./tsconfig.json",
-  "include": [
-    "src/**/*",
-    "scripts/setup_enzyme.ts",
-    "scripts/custom_matchers.ts"
-  ]
+  "include": ["src/**/*", "scripts/setup_enzyme.ts", "scripts/custom_matchers.ts"]
 }
diff --git a/wiki/overview.md b/wiki/overview.md
index e1b016f75f..797858c5fd 100644
--- a/wiki/overview.md
+++ b/wiki/overview.md
@@ -125,7 +125,7 @@ export interface SeriesSpec {
   /** An array of data */
   data: Datum[];
   /** The type of series you are looking to render */
-  seriesType: 'bar' | 'line' | 'area';
+  seriesType: SeriesTypes;
   /** Custom colors for series */
   customSeriesColors?: CustomSeriesColorsMap;
   /** If the series should appear in the legend
@@ -183,7 +183,7 @@ A `BarSeriesSpec` for example is the following intersection type:
 export type BarSeriesSpec = SeriesSpec &
   SeriesAccessors &
   SeriesScales & {
-    seriesType: 'bar';
+    seriesType: SeriesTypes.Bar;
   };
 ```
 
diff --git a/yarn.lock b/yarn.lock
index 596bce006d..510171d21a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,52 +2,25 @@
 # yarn lockfile v1
 
 
-"@babel/code-frame@7.0.0":
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8"
-  integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==
-  dependencies:
-    "@babel/highlight" "^7.0.0"
-
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5":
+"@babel/code-frame@7.5.5", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5":
   version "7.5.5"
   resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
   integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==
   dependencies:
     "@babel/highlight" "^7.0.0"
 
-"@babel/core@7.4.3":
-  version "7.4.3"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.3.tgz#198d6d3af4567be3989550d97e068de94503074f"
-  integrity sha512-oDpASqKFlbspQfzAE7yaeTmdljSH2ADIvBlb0RwbStltTuWa0+7CCI1fYVINNv9saHPa1W7oaKeuNuKj+RQCvA==
-  dependencies:
-    "@babel/code-frame" "^7.0.0"
-    "@babel/generator" "^7.4.0"
-    "@babel/helpers" "^7.4.3"
-    "@babel/parser" "^7.4.3"
-    "@babel/template" "^7.4.0"
-    "@babel/traverse" "^7.4.3"
-    "@babel/types" "^7.4.0"
-    convert-source-map "^1.1.0"
-    debug "^4.1.0"
-    json5 "^2.1.0"
-    lodash "^4.17.11"
-    resolve "^1.3.2"
-    semver "^5.4.1"
-    source-map "^0.5.0"
-
-"@babel/core@^7.0.0":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30"
-  integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==
+"@babel/core@7.6.0":
+  version "7.6.0"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48"
+  integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==
   dependencies:
     "@babel/code-frame" "^7.5.5"
-    "@babel/generator" "^7.5.5"
-    "@babel/helpers" "^7.5.5"
-    "@babel/parser" "^7.5.5"
-    "@babel/template" "^7.4.4"
-    "@babel/traverse" "^7.5.5"
-    "@babel/types" "^7.5.5"
+    "@babel/generator" "^7.6.0"
+    "@babel/helpers" "^7.6.0"
+    "@babel/parser" "^7.6.0"
+    "@babel/template" "^7.6.0"
+    "@babel/traverse" "^7.6.0"
+    "@babel/types" "^7.6.0"
     convert-source-map "^1.1.0"
     debug "^4.1.0"
     json5 "^2.1.0"
@@ -56,18 +29,18 @@
     semver "^5.4.1"
     source-map "^0.5.0"
 
-"@babel/core@^7.1.0":
-  version "7.6.2"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.2.tgz#069a776e8d5e9eefff76236bc8845566bd31dd91"
-  integrity sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ==
+"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.3.4", "@babel/core@^7.4.5":
+  version "7.6.4"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.4.tgz#6ebd9fe00925f6c3e177bb726a188b5f578088ff"
+  integrity sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ==
   dependencies:
     "@babel/code-frame" "^7.5.5"
-    "@babel/generator" "^7.6.2"
+    "@babel/generator" "^7.6.4"
     "@babel/helpers" "^7.6.2"
-    "@babel/parser" "^7.6.2"
+    "@babel/parser" "^7.6.4"
     "@babel/template" "^7.6.0"
-    "@babel/traverse" "^7.6.2"
-    "@babel/types" "^7.6.0"
+    "@babel/traverse" "^7.6.3"
+    "@babel/types" "^7.6.3"
     convert-source-map "^1.1.0"
     debug "^4.1.0"
     json5 "^2.1.0"
@@ -76,47 +49,16 @@
     semver "^5.4.1"
     source-map "^0.5.0"
 
-"@babel/core@^7.3.4", "@babel/core@^7.4.3":
-  version "7.4.5"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.5.tgz#081f97e8ffca65a9b4b0fdc7e274e703f000c06a"
-  integrity sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==
+"@babel/generator@^7.4.0", "@babel/generator@^7.6.0", "@babel/generator@^7.6.3", "@babel/generator@^7.6.4":
+  version "7.6.4"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.4.tgz#a4f8437287bf9671b07f483b76e3bb731bc97671"
+  integrity sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==
   dependencies:
-    "@babel/code-frame" "^7.0.0"
-    "@babel/generator" "^7.4.4"
-    "@babel/helpers" "^7.4.4"
-    "@babel/parser" "^7.4.5"
-    "@babel/template" "^7.4.4"
-    "@babel/traverse" "^7.4.5"
-    "@babel/types" "^7.4.4"
-    convert-source-map "^1.1.0"
-    debug "^4.1.0"
-    json5 "^2.1.0"
-    lodash "^4.17.11"
-    resolve "^1.3.2"
-    semver "^5.4.1"
-    source-map "^0.5.0"
-
-"@babel/generator@^7.4.0", "@babel/generator@^7.4.4", "@babel/generator@^7.6.2":
-  version "7.6.2"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.2.tgz#dac8a3c2df118334c2a29ff3446da1636a8f8c03"
-  integrity sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==
-  dependencies:
-    "@babel/types" "^7.6.0"
+    "@babel/types" "^7.6.3"
     jsesc "^2.5.1"
     lodash "^4.17.13"
     source-map "^0.5.0"
 
-"@babel/generator@^7.5.5":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf"
-  integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==
-  dependencies:
-    "@babel/types" "^7.5.5"
-    jsesc "^2.5.1"
-    lodash "^4.17.13"
-    source-map "^0.5.0"
-    trim-right "^1.0.1"
-
 "@babel/helper-annotate-as-pure@^7.0.0":
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32"
@@ -149,10 +91,10 @@
     "@babel/traverse" "^7.4.4"
     "@babel/types" "^7.4.4"
 
-"@babel/helper-create-class-features-plugin@^7.4.0", "@babel/helper-create-class-features-plugin@^7.5.5":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4"
-  integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg==
+"@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.6.0":
+  version "7.6.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz#769711acca889be371e9bc2eb68641d55218021f"
+  integrity sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng==
   dependencies:
     "@babel/helper-function-name" "^7.1.0"
     "@babel/helper-member-expression-to-functions" "^7.5.5"
@@ -161,7 +103,7 @@
     "@babel/helper-replace-supers" "^7.5.5"
     "@babel/helper-split-export-declaration" "^7.4.4"
 
-"@babel/helper-define-map@^7.4.0", "@babel/helper-define-map@^7.5.5":
+"@babel/helper-define-map@^7.5.5":
   version "7.5.5"
   resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369"
   integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==
@@ -170,15 +112,6 @@
     "@babel/types" "^7.5.5"
     lodash "^4.17.13"
 
-"@babel/helper-define-map@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz#6969d1f570b46bdc900d1eba8e5d59c48ba2c12a"
-  integrity sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==
-  dependencies:
-    "@babel/helper-function-name" "^7.1.0"
-    "@babel/types" "^7.4.4"
-    lodash "^4.17.11"
-
 "@babel/helper-explode-assignable-expression@^7.1.0":
   version "7.1.0"
   resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6"
@@ -210,13 +143,6 @@
   dependencies:
     "@babel/types" "^7.4.4"
 
-"@babel/helper-member-expression-to-functions@^7.0.0":
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f"
-  integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==
-  dependencies:
-    "@babel/types" "^7.0.0"
-
 "@babel/helper-member-expression-to-functions@^7.5.5":
   version "7.5.5"
   resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590"
@@ -232,16 +158,16 @@
     "@babel/types" "^7.0.0"
 
 "@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz#96115ea42a2f139e619e98ed46df6019b94414b8"
-  integrity sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==
+  version "7.5.5"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a"
+  integrity sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==
   dependencies:
     "@babel/helper-module-imports" "^7.0.0"
     "@babel/helper-simple-access" "^7.1.0"
     "@babel/helper-split-export-declaration" "^7.4.4"
     "@babel/template" "^7.4.4"
-    "@babel/types" "^7.4.4"
-    lodash "^4.17.11"
+    "@babel/types" "^7.5.5"
+    lodash "^4.17.13"
 
 "@babel/helper-optimise-call-expression@^7.0.0":
   version "7.0.0"
@@ -256,11 +182,11 @@
   integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==
 
 "@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.4.4.tgz#a47e02bc91fb259d2e6727c2a30013e3ac13c4a2"
-  integrity sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==
+  version "7.5.5"
+  resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351"
+  integrity sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==
   dependencies:
-    lodash "^4.17.11"
+    lodash "^4.17.13"
 
 "@babel/helper-remap-async-to-generator@^7.1.0":
   version "7.1.0"
@@ -273,17 +199,7 @@
     "@babel/traverse" "^7.1.0"
     "@babel/types" "^7.0.0"
 
-"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz#aee41783ebe4f2d3ab3ae775e1cc6f1a90cefa27"
-  integrity sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==
-  dependencies:
-    "@babel/helper-member-expression-to-functions" "^7.0.0"
-    "@babel/helper-optimise-call-expression" "^7.0.0"
-    "@babel/traverse" "^7.4.4"
-    "@babel/types" "^7.4.4"
-
-"@babel/helper-replace-supers@^7.4.0", "@babel/helper-replace-supers@^7.5.5":
+"@babel/helper-replace-supers@^7.5.5":
   version "7.5.5"
   resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2"
   integrity sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==
@@ -301,7 +217,7 @@
     "@babel/template" "^7.1.0"
     "@babel/types" "^7.0.0"
 
-"@babel/helper-split-export-declaration@^7.4.0", "@babel/helper-split-export-declaration@^7.4.4":
+"@babel/helper-split-export-declaration@^7.4.4":
   version "7.4.4"
   resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677"
   integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==
@@ -318,16 +234,7 @@
     "@babel/traverse" "^7.1.0"
     "@babel/types" "^7.2.0"
 
-"@babel/helpers@^7.4.3", "@babel/helpers@^7.5.5":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e"
-  integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==
-  dependencies:
-    "@babel/template" "^7.4.4"
-    "@babel/traverse" "^7.5.5"
-    "@babel/types" "^7.5.5"
-
-"@babel/helpers@^7.4.4", "@babel/helpers@^7.6.2":
+"@babel/helpers@^7.6.0", "@babel/helpers@^7.6.2":
   version "7.6.2"
   resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.2.tgz#681ffe489ea4dcc55f23ce469e58e59c1c045153"
   integrity sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==
@@ -345,15 +252,10 @@
     esutils "^2.0.2"
     js-tokens "^4.0.0"
 
-"@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.5", "@babel/parser@^7.6.0", "@babel/parser@^7.6.2":
-  version "7.6.2"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.2.tgz#205e9c95e16ba3b8b96090677a67c9d6075b70a1"
-  integrity sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==
-
-"@babel/parser@^7.5.5":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b"
-  integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==
+"@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0", "@babel/parser@^7.6.3", "@babel/parser@^7.6.4":
+  version "7.6.4"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.4.tgz#cb9b36a7482110282d5cb6dd424ec9262b473d81"
+  integrity sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==
 
 "@babel/plugin-proposal-async-generator-functions@^7.2.0":
   version "7.2.0"
@@ -364,15 +266,7 @@
     "@babel/helper-remap-async-to-generator" "^7.1.0"
     "@babel/plugin-syntax-async-generators" "^7.2.0"
 
-"@babel/plugin-proposal-class-properties@7.4.0":
-  version "7.4.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.0.tgz#d70db61a2f1fd79de927eea91f6411c964e084b8"
-  integrity sha512-t2ECPNOXsIeK1JxJNKmgbzQtoG27KIlVE61vTqX0DKR9E9sZlVVxWUtEW9D5FlZ8b8j7SBNCHY47GgPKCKlpPg==
-  dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.4.0"
-    "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-proposal-class-properties@^7.3.3":
+"@babel/plugin-proposal-class-properties@7.5.5", "@babel/plugin-proposal-class-properties@^7.3.3":
   version "7.5.5"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4"
   integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A==
@@ -380,12 +274,12 @@
     "@babel/helper-create-class-features-plugin" "^7.5.5"
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-proposal-decorators@7.4.0":
-  version "7.4.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.4.0.tgz#8e1bfd83efa54a5f662033afcc2b8e701f4bb3a9"
-  integrity sha512-d08TLmXeK/XbgCo7ZeZ+JaeZDtDai/2ctapTRsWWkkmy7G/cqz8DQN/HlWG7RR4YmfXxmExsbU3SuCjlM7AtUg==
+"@babel/plugin-proposal-decorators@7.6.0":
+  version "7.6.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.6.0.tgz#6659d2572a17d70abd68123e89a12a43d90aa30c"
+  integrity sha512-ZSyYw9trQI50sES6YxREXKu+4b7MAg6Qx2cvyDDYjP2Hpzd3FleOUwC9cqn1+za8d0A2ZU8SHujxFao956efUg==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.4.0"
+    "@babel/helper-create-class-features-plugin" "^7.6.0"
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-decorators" "^7.2.0"
 
@@ -405,15 +299,7 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-json-strings" "^7.2.0"
 
-"@babel/plugin-proposal-object-rest-spread@7.4.3":
-  version "7.4.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.3.tgz#be27cd416eceeba84141305b93c282f5de23bbb4"
-  integrity sha512-xC//6DNSSHVjq8O2ge0dyYlhshsH4T7XdCVoxbi5HzLYWfsC5ooFlJjrXk8RcAT+hjHAK9UjBXdylzSoDK3t4g==
-  dependencies:
-    "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
-
-"@babel/plugin-proposal-object-rest-spread@^7.3.2", "@babel/plugin-proposal-object-rest-spread@^7.4.3", "@babel/plugin-proposal-object-rest-spread@^7.5.5":
+"@babel/plugin-proposal-object-rest-spread@7.5.5":
   version "7.5.5"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58"
   integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==
@@ -421,10 +307,10 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
 
-"@babel/plugin-proposal-object-rest-spread@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz#1ef173fcf24b3e2df92a678f027673b55e7e3005"
-  integrity sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==
+"@babel/plugin-proposal-object-rest-spread@^7.3.2", "@babel/plugin-proposal-object-rest-spread@^7.5.5", "@babel/plugin-proposal-object-rest-spread@^7.6.2":
+  version "7.6.2"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz#8ffccc8f3a6545e9f78988b6bf4fe881b88e8096"
+  integrity sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
@@ -437,14 +323,14 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
 
-"@babel/plugin-proposal-unicode-property-regex@^7.4.0", "@babel/plugin-proposal-unicode-property-regex@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78"
-  integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==
+"@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.6.2":
+  version "7.6.2"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.6.2.tgz#05413762894f41bfe42b9a5e80919bd575dcc802"
+  integrity sha512-NxHETdmpeSCtiatMRYWVJo7266rrvAC3DTeG5exQBIH/fMIUK7ejDNznBbn3HQl/o9peymRRg7Yqkx6PdUXmMw==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/helper-regex" "^7.4.4"
-    regexpu-core "^4.5.4"
+    regexpu-core "^4.6.0"
 
 "@babel/plugin-syntax-async-generators@^7.2.0":
   version "7.2.0"
@@ -516,7 +402,7 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-async-to-generator@^7.4.0", "@babel/plugin-transform-async-to-generator@^7.5.0":
+"@babel/plugin-transform-async-to-generator@^7.5.0":
   version "7.5.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e"
   integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==
@@ -525,15 +411,6 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/helper-remap-async-to-generator" "^7.1.0"
 
-"@babel/plugin-transform-async-to-generator@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz#a3f1d01f2f21cadab20b33a82133116f14fb5894"
-  integrity sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==
-  dependencies:
-    "@babel/helper-module-imports" "^7.0.0"
-    "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/helper-remap-async-to-generator" "^7.1.0"
-
 "@babel/plugin-transform-block-scoped-functions@^7.2.0":
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190"
@@ -541,37 +418,15 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-block-scoping@^7.4.0", "@babel/plugin-transform-block-scoping@^7.5.5":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce"
-  integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==
+"@babel/plugin-transform-block-scoping@^7.6.0", "@babel/plugin-transform-block-scoping@^7.6.3":
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz#6e854e51fbbaa84351b15d4ddafe342f3a5d542a"
+  integrity sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     lodash "^4.17.13"
 
-"@babel/plugin-transform-block-scoping@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz#c13279fabf6b916661531841a23c4b7dae29646d"
-  integrity sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==
-  dependencies:
-    "@babel/helper-plugin-utils" "^7.0.0"
-    lodash "^4.17.11"
-
-"@babel/plugin-transform-classes@7.4.3":
-  version "7.4.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.3.tgz#adc7a1137ab4287a555d429cc56ecde8f40c062c"
-  integrity sha512-PUaIKyFUDtG6jF5DUJOfkBdwAS/kFFV3XFk7Nn0a6vR7ZT8jYw5cGtIlat77wcnd0C6ViGqo/wyNf4ZHytF/nQ==
-  dependencies:
-    "@babel/helper-annotate-as-pure" "^7.0.0"
-    "@babel/helper-define-map" "^7.4.0"
-    "@babel/helper-function-name" "^7.1.0"
-    "@babel/helper-optimise-call-expression" "^7.0.0"
-    "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/helper-replace-supers" "^7.4.0"
-    "@babel/helper-split-export-declaration" "^7.4.0"
-    globals "^11.1.0"
-
-"@babel/plugin-transform-classes@^7.4.3", "@babel/plugin-transform-classes@^7.5.5":
+"@babel/plugin-transform-classes@^7.5.5":
   version "7.5.5"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9"
   integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==
@@ -585,20 +440,6 @@
     "@babel/helper-split-export-declaration" "^7.4.4"
     globals "^11.1.0"
 
-"@babel/plugin-transform-classes@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz#0ce4094cdafd709721076d3b9c38ad31ca715eb6"
-  integrity sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==
-  dependencies:
-    "@babel/helper-annotate-as-pure" "^7.0.0"
-    "@babel/helper-define-map" "^7.4.4"
-    "@babel/helper-function-name" "^7.1.0"
-    "@babel/helper-optimise-call-expression" "^7.0.0"
-    "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/helper-replace-supers" "^7.4.4"
-    "@babel/helper-split-export-declaration" "^7.4.4"
-    globals "^11.1.0"
-
 "@babel/plugin-transform-computed-properties@^7.2.0":
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da"
@@ -606,42 +447,21 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-destructuring@7.4.3":
-  version "7.4.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.3.tgz#1a95f5ca2bf2f91ef0648d5de38a8d472da4350f"
-  integrity sha512-rVTLLZpydDFDyN4qnXdzwoVpk1oaXHIvPEOkOLyr88o7oHxVc/LyrnDx+amuBWGOwUb7D1s/uLsKBNTx08htZg==
-  dependencies:
-    "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-destructuring@^7.4.3", "@babel/plugin-transform-destructuring@^7.5.0":
-  version "7.5.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a"
-  integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==
-  dependencies:
-    "@babel/helper-plugin-utils" "^7.0.0"
-
-"@babel/plugin-transform-destructuring@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz#9d964717829cc9e4b601fc82a26a71a4d8faf20f"
-  integrity sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==
+"@babel/plugin-transform-destructuring@7.6.0", "@babel/plugin-transform-destructuring@^7.6.0":
+  version "7.6.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz#44bbe08b57f4480094d57d9ffbcd96d309075ba6"
+  integrity sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-dotall-regex@^7.4.3", "@babel/plugin-transform-dotall-regex@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3"
-  integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==
+"@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.6.2":
+  version "7.6.2"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.6.2.tgz#44abb948b88f0199a627024e1508acaf8dc9b2f9"
+  integrity sha512-KGKT9aqKV+9YMZSkowzYoYEiHqgaDhGmPNZlZxX6UeHC4z30nC1J9IrZuGqbYFB1jaIGdv91ujpze0exiVK8bA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/helper-regex" "^7.4.4"
-    regexpu-core "^4.5.4"
-
-"@babel/plugin-transform-duplicate-keys@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3"
-  integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==
-  dependencies:
-    "@babel/helper-plugin-utils" "^7.0.0"
+    regexpu-core "^4.6.0"
 
 "@babel/plugin-transform-duplicate-keys@^7.5.0":
   version "7.5.0"
@@ -658,30 +478,30 @@
     "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0"
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-flow-strip-types@7.4.0":
-  version "7.4.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.0.tgz#f3c59eecff68c99b9c96eaafe4fe9d1fa8947138"
-  integrity sha512-C4ZVNejHnfB22vI2TYN4RUp2oCmq6cSEAg4RygSvYZUECRqUu9O4PMEMNJ4wsemaRGg27BbgYctG4BZh+AgIHw==
+"@babel/plugin-transform-flow-strip-types@7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.4.tgz#d267a081f49a8705fc9146de0768c6b58dccd8f7"
+  integrity sha512-WyVedfeEIILYEaWGAUWzVNyqG4sfsNooMhXWsu/YzOvVGcsnPb5PguysjJqI3t3qiaYj0BR8T2f5njdjTGe44Q==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-flow" "^7.2.0"
 
 "@babel/plugin-transform-flow-strip-types@^7.0.0":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.4.tgz#d267a081f49a8705fc9146de0768c6b58dccd8f7"
-  integrity sha512-WyVedfeEIILYEaWGAUWzVNyqG4sfsNooMhXWsu/YzOvVGcsnPb5PguysjJqI3t3qiaYj0BR8T2f5njdjTGe44Q==
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.6.3.tgz#8110f153e7360cfd5996eee68706cfad92d85256"
+  integrity sha512-l0ETkyEofkqFJ9LS6HChNIKtVJw2ylKbhYMlJ5C6df+ldxxaLIyXY4yOdDQQspfFpV8/vDiaWoJlvflstlYNxg==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-flow" "^7.2.0"
 
-"@babel/plugin-transform-for-of@^7.4.3", "@babel/plugin-transform-for-of@^7.4.4":
+"@babel/plugin-transform-for-of@^7.4.4":
   version "7.4.4"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556"
   integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-function-name@^7.4.3", "@babel/plugin-transform-function-name@^7.4.4":
+"@babel/plugin-transform-function-name@^7.4.4":
   version "7.4.4"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad"
   integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==
@@ -703,14 +523,6 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-modules-amd@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6"
-  integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==
-  dependencies:
-    "@babel/helper-module-transforms" "^7.1.0"
-    "@babel/helper-plugin-utils" "^7.0.0"
-
 "@babel/plugin-transform-modules-amd@^7.5.0":
   version "7.5.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91"
@@ -720,26 +532,17 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     babel-plugin-dynamic-import-node "^2.3.0"
 
-"@babel/plugin-transform-modules-commonjs@^7.4.3", "@babel/plugin-transform-modules-commonjs@^7.5.0":
-  version "7.5.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74"
-  integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==
+"@babel/plugin-transform-modules-commonjs@^7.6.0":
+  version "7.6.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz#39dfe957de4420445f1fcf88b68a2e4aa4515486"
+  integrity sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g==
   dependencies:
     "@babel/helper-module-transforms" "^7.4.4"
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/helper-simple-access" "^7.1.0"
     babel-plugin-dynamic-import-node "^2.3.0"
 
-"@babel/plugin-transform-modules-commonjs@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz#0bef4713d30f1d78c2e59b3d6db40e60192cac1e"
-  integrity sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==
-  dependencies:
-    "@babel/helper-module-transforms" "^7.4.4"
-    "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/helper-simple-access" "^7.1.0"
-
-"@babel/plugin-transform-modules-systemjs@^7.4.0", "@babel/plugin-transform-modules-systemjs@^7.5.0":
+"@babel/plugin-transform-modules-systemjs@^7.5.0":
   version "7.5.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249"
   integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==
@@ -748,14 +551,6 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     babel-plugin-dynamic-import-node "^2.3.0"
 
-"@babel/plugin-transform-modules-systemjs@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz#dc83c5665b07d6c2a7b224c00ac63659ea36a405"
-  integrity sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==
-  dependencies:
-    "@babel/helper-hoist-variables" "^7.4.4"
-    "@babel/helper-plugin-utils" "^7.0.0"
-
 "@babel/plugin-transform-modules-umd@^7.2.0":
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae"
@@ -764,28 +559,20 @@
     "@babel/helper-module-transforms" "^7.1.0"
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-named-capturing-groups-regex@^7.4.2", "@babel/plugin-transform-named-capturing-groups-regex@^7.4.5":
-  version "7.4.5"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106"
-  integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==
+"@babel/plugin-transform-named-capturing-groups-regex@^7.6.0", "@babel/plugin-transform-named-capturing-groups-regex@^7.6.3":
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.3.tgz#aaa6e409dd4fb2e50b6e2a91f7e3a3149dbce0cf"
+  integrity sha512-jTkk7/uE6H2s5w6VlMHeWuH+Pcy2lmdwFoeWCVnvIrDUnB5gQqTVI8WfmEAhF2CDEarGrknZcmSFg1+bkfCoSw==
   dependencies:
-    regexp-tree "^0.1.6"
+    regexpu-core "^4.6.0"
 
-"@babel/plugin-transform-new-target@^7.4.0", "@babel/plugin-transform-new-target@^7.4.4":
+"@babel/plugin-transform-new-target@^7.4.4":
   version "7.4.4"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5"
   integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-object-super@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598"
-  integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==
-  dependencies:
-    "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/helper-replace-supers" "^7.1.0"
-
 "@babel/plugin-transform-object-super@^7.5.5":
   version "7.5.5"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9"
@@ -794,7 +581,7 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/helper-replace-supers" "^7.5.5"
 
-"@babel/plugin-transform-parameters@^7.4.3", "@babel/plugin-transform-parameters@^7.4.4":
+"@babel/plugin-transform-parameters@^7.4.4":
   version "7.4.4"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16"
   integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==
@@ -810,10 +597,10 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-react-constant-elements@7.2.0", "@babel/plugin-transform-react-constant-elements@^7.0.0", "@babel/plugin-transform-react-constant-elements@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.2.0.tgz#ed602dc2d8bff2f0cb1a5ce29263dbdec40779f7"
-  integrity sha512-YYQFg6giRFMsZPKUM9v+VcHOdfSQdz9jHCx3akAi3UYgyjndmdYGSXylQ/V+HswQt4fL8IklchD9HTsaOCrWQQ==
+"@babel/plugin-transform-react-constant-elements@^7.0.0", "@babel/plugin-transform-react-constant-elements@^7.2.0":
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.6.3.tgz#9fc9ea060b983c7c035acbe481cbe1fb1245bfff"
+  integrity sha512-1/YogSSU7Tby9rq2VCmhuRg+6pxsHy2rI7w/oo8RKoBt6uBUFG+mk6x13kK+FY1/ggN92HAfg7ADd1v1+NCOKg==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
@@ -834,9 +621,9 @@
     "@babel/plugin-syntax-jsx" "^7.2.0"
 
 "@babel/plugin-transform-react-jsx-source@^7.0.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz#20c8c60f0140f5dd3cd63418d452801cf3f7180f"
-  integrity sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==
+  version "7.5.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz#583b10c49cf057e237085bcbd8cc960bd83bd96b"
+  integrity sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-jsx" "^7.2.0"
@@ -850,7 +637,7 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-jsx" "^7.2.0"
 
-"@babel/plugin-transform-regenerator@^7.4.3", "@babel/plugin-transform-regenerator@^7.4.5":
+"@babel/plugin-transform-regenerator@^7.4.5":
   version "7.4.5"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f"
   integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==
@@ -864,10 +651,10 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-runtime@7.4.3":
-  version "7.4.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.4.3.tgz#4d6691690ecdc9f5cb8c3ab170a1576c1f556371"
-  integrity sha512-7Q61bU+uEI7bCUFReT1NKn7/X6sDQsZ7wL1sJ9IYMAO7cI+eg6x9re1cEw2fCRMbbTVyoeUKWSV1M6azEfKCfg==
+"@babel/plugin-transform-runtime@7.6.0":
+  version "7.6.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.0.tgz#85a3cce402b28586138e368fce20ab3019b9713e"
+  integrity sha512-Da8tMf7uClzwUm/pnJ1S93m/aRXmoYNDD7TkHua8xBDdaAs54uZpTWvEt6NGwmoVMb9mZbntfTqmG2oSzN/7Vg==
   dependencies:
     "@babel/helper-module-imports" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
@@ -881,10 +668,10 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-spread@^7.2.0":
-  version "7.2.2"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406"
-  integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==
+"@babel/plugin-transform-spread@^7.2.0", "@babel/plugin-transform-spread@^7.6.2":
+  version "7.6.2"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz#fc77cf798b24b10c46e1b51b1b88c2bf661bb8dd"
+  integrity sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
@@ -896,7 +683,7 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/helper-regex" "^7.0.0"
 
-"@babel/plugin-transform-template-literals@^7.2.0", "@babel/plugin-transform-template-literals@^7.4.4":
+"@babel/plugin-transform-template-literals@^7.4.4":
   version "7.4.4"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0"
   integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==
@@ -911,123 +698,71 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-typescript@^7.3.2":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8"
-  integrity sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w==
+"@babel/plugin-transform-typescript@^7.6.0":
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.3.tgz#dddb50cf3b8b2ef70b22e5326e9a91f05a1db13b"
+  integrity sha512-aiWINBrPMSC3xTXRNM/dfmyYuPNKY/aexYqBgh0HBI5Y+WO5oRAqW/oROYeYHrF4Zw12r9rK4fMk/ZlAmqx/FQ==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.5.5"
+    "@babel/helper-create-class-features-plugin" "^7.6.0"
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-typescript" "^7.2.0"
 
-"@babel/plugin-transform-unicode-regex@^7.4.3", "@babel/plugin-transform-unicode-regex@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f"
-  integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==
+"@babel/plugin-transform-unicode-regex@^7.4.4", "@babel/plugin-transform-unicode-regex@^7.6.2":
+  version "7.6.2"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.6.2.tgz#b692aad888a7e8d8b1b214be6b9dc03d5031f698"
+  integrity sha512-orZI6cWlR3nk2YmYdb0gImrgCUwb5cBUwjf6Ks6dvNVvXERkwtJWOQaEOjPiu0Gu1Tq6Yq/hruCZZOOi9F34Dw==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/helper-regex" "^7.4.4"
-    regexpu-core "^4.5.4"
+    regexpu-core "^4.6.0"
 
 "@babel/polyfill@^7.4.4":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.4.4.tgz#78801cf3dbe657844eeabf31c1cae3828051e893"
-  integrity sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==
+  version "7.6.0"
+  resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.6.0.tgz#6d89203f8b6cd323e8d946e47774ea35dc0619cc"
+  integrity sha512-q5BZJI0n/B10VaQQvln1IlDK3BTBJFbADx7tv+oXDPIDZuTo37H5Adb9jhlXm/fEN4Y7/64qD9mnrJJG7rmaTw==
   dependencies:
     core-js "^2.6.5"
     regenerator-runtime "^0.13.2"
 
-"@babel/preset-env@7.4.3":
-  version "7.4.3"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.3.tgz#e71e16e123dc0fbf65a52cbcbcefd072fbd02880"
-  integrity sha512-FYbZdV12yHdJU5Z70cEg0f6lvtpZ8jFSDakTm7WXeJbLXh4R0ztGEu/SW7G1nJ2ZvKwDhz8YrbA84eYyprmGqw==
-  dependencies:
-    "@babel/helper-module-imports" "^7.0.0"
-    "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/plugin-proposal-async-generator-functions" "^7.2.0"
-    "@babel/plugin-proposal-json-strings" "^7.2.0"
-    "@babel/plugin-proposal-object-rest-spread" "^7.4.3"
-    "@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
-    "@babel/plugin-proposal-unicode-property-regex" "^7.4.0"
-    "@babel/plugin-syntax-async-generators" "^7.2.0"
-    "@babel/plugin-syntax-json-strings" "^7.2.0"
-    "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
-    "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
-    "@babel/plugin-transform-arrow-functions" "^7.2.0"
-    "@babel/plugin-transform-async-to-generator" "^7.4.0"
-    "@babel/plugin-transform-block-scoped-functions" "^7.2.0"
-    "@babel/plugin-transform-block-scoping" "^7.4.0"
-    "@babel/plugin-transform-classes" "^7.4.3"
-    "@babel/plugin-transform-computed-properties" "^7.2.0"
-    "@babel/plugin-transform-destructuring" "^7.4.3"
-    "@babel/plugin-transform-dotall-regex" "^7.4.3"
-    "@babel/plugin-transform-duplicate-keys" "^7.2.0"
-    "@babel/plugin-transform-exponentiation-operator" "^7.2.0"
-    "@babel/plugin-transform-for-of" "^7.4.3"
-    "@babel/plugin-transform-function-name" "^7.4.3"
-    "@babel/plugin-transform-literals" "^7.2.0"
-    "@babel/plugin-transform-member-expression-literals" "^7.2.0"
-    "@babel/plugin-transform-modules-amd" "^7.2.0"
-    "@babel/plugin-transform-modules-commonjs" "^7.4.3"
-    "@babel/plugin-transform-modules-systemjs" "^7.4.0"
-    "@babel/plugin-transform-modules-umd" "^7.2.0"
-    "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.2"
-    "@babel/plugin-transform-new-target" "^7.4.0"
-    "@babel/plugin-transform-object-super" "^7.2.0"
-    "@babel/plugin-transform-parameters" "^7.4.3"
-    "@babel/plugin-transform-property-literals" "^7.2.0"
-    "@babel/plugin-transform-regenerator" "^7.4.3"
-    "@babel/plugin-transform-reserved-words" "^7.2.0"
-    "@babel/plugin-transform-shorthand-properties" "^7.2.0"
-    "@babel/plugin-transform-spread" "^7.2.0"
-    "@babel/plugin-transform-sticky-regex" "^7.2.0"
-    "@babel/plugin-transform-template-literals" "^7.2.0"
-    "@babel/plugin-transform-typeof-symbol" "^7.2.0"
-    "@babel/plugin-transform-unicode-regex" "^7.4.3"
-    "@babel/types" "^7.4.0"
-    browserslist "^4.5.2"
-    core-js-compat "^3.0.0"
-    invariant "^2.2.2"
-    js-levenshtein "^1.1.3"
-    semver "^5.5.0"
-
-"@babel/preset-env@^7.4.3":
-  version "7.4.5"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.5.tgz#2fad7f62983d5af563b5f3139242755884998a58"
-  integrity sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w==
+"@babel/preset-env@7.6.0":
+  version "7.6.0"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.0.tgz#aae4141c506100bb2bfaa4ac2a5c12b395619e50"
+  integrity sha512-1efzxFv/TcPsNXlRhMzRnkBFMeIqBBgzwmZwlFDw5Ubj0AGLeufxugirwZmkkX/ayi3owsSqoQ4fw8LkfK9SYg==
   dependencies:
     "@babel/helper-module-imports" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-proposal-async-generator-functions" "^7.2.0"
+    "@babel/plugin-proposal-dynamic-import" "^7.5.0"
     "@babel/plugin-proposal-json-strings" "^7.2.0"
-    "@babel/plugin-proposal-object-rest-spread" "^7.4.4"
+    "@babel/plugin-proposal-object-rest-spread" "^7.5.5"
     "@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
     "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
     "@babel/plugin-syntax-async-generators" "^7.2.0"
+    "@babel/plugin-syntax-dynamic-import" "^7.2.0"
     "@babel/plugin-syntax-json-strings" "^7.2.0"
     "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
     "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
     "@babel/plugin-transform-arrow-functions" "^7.2.0"
-    "@babel/plugin-transform-async-to-generator" "^7.4.4"
+    "@babel/plugin-transform-async-to-generator" "^7.5.0"
     "@babel/plugin-transform-block-scoped-functions" "^7.2.0"
-    "@babel/plugin-transform-block-scoping" "^7.4.4"
-    "@babel/plugin-transform-classes" "^7.4.4"
+    "@babel/plugin-transform-block-scoping" "^7.6.0"
+    "@babel/plugin-transform-classes" "^7.5.5"
     "@babel/plugin-transform-computed-properties" "^7.2.0"
-    "@babel/plugin-transform-destructuring" "^7.4.4"
+    "@babel/plugin-transform-destructuring" "^7.6.0"
     "@babel/plugin-transform-dotall-regex" "^7.4.4"
-    "@babel/plugin-transform-duplicate-keys" "^7.2.0"
+    "@babel/plugin-transform-duplicate-keys" "^7.5.0"
     "@babel/plugin-transform-exponentiation-operator" "^7.2.0"
     "@babel/plugin-transform-for-of" "^7.4.4"
     "@babel/plugin-transform-function-name" "^7.4.4"
     "@babel/plugin-transform-literals" "^7.2.0"
     "@babel/plugin-transform-member-expression-literals" "^7.2.0"
-    "@babel/plugin-transform-modules-amd" "^7.2.0"
-    "@babel/plugin-transform-modules-commonjs" "^7.4.4"
-    "@babel/plugin-transform-modules-systemjs" "^7.4.4"
+    "@babel/plugin-transform-modules-amd" "^7.5.0"
+    "@babel/plugin-transform-modules-commonjs" "^7.6.0"
+    "@babel/plugin-transform-modules-systemjs" "^7.5.0"
     "@babel/plugin-transform-modules-umd" "^7.2.0"
-    "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5"
+    "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.0"
     "@babel/plugin-transform-new-target" "^7.4.4"
-    "@babel/plugin-transform-object-super" "^7.2.0"
+    "@babel/plugin-transform-object-super" "^7.5.5"
     "@babel/plugin-transform-parameters" "^7.4.4"
     "@babel/plugin-transform-property-literals" "^7.2.0"
     "@babel/plugin-transform-regenerator" "^7.4.5"
@@ -1038,7 +773,7 @@
     "@babel/plugin-transform-template-literals" "^7.4.4"
     "@babel/plugin-transform-typeof-symbol" "^7.2.0"
     "@babel/plugin-transform-unicode-regex" "^7.4.4"
-    "@babel/types" "^7.4.4"
+    "@babel/types" "^7.6.0"
     browserslist "^4.6.0"
     core-js-compat "^3.1.1"
     invariant "^2.2.2"
@@ -1046,18 +781,18 @@
     semver "^5.5.0"
 
 "@babel/preset-env@^7.4.5":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a"
-  integrity sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.3.tgz#9e1bf05a2e2d687036d24c40e4639dc46cef2271"
+  integrity sha512-CWQkn7EVnwzlOdR5NOm2+pfgSNEZmvGjOhlCHBDq0J8/EStr+G+FvPEiz9B56dR6MoiUFjXhfE4hjLoAKKJtIQ==
   dependencies:
     "@babel/helper-module-imports" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-proposal-async-generator-functions" "^7.2.0"
     "@babel/plugin-proposal-dynamic-import" "^7.5.0"
     "@babel/plugin-proposal-json-strings" "^7.2.0"
-    "@babel/plugin-proposal-object-rest-spread" "^7.5.5"
+    "@babel/plugin-proposal-object-rest-spread" "^7.6.2"
     "@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
-    "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
+    "@babel/plugin-proposal-unicode-property-regex" "^7.6.2"
     "@babel/plugin-syntax-async-generators" "^7.2.0"
     "@babel/plugin-syntax-dynamic-import" "^7.2.0"
     "@babel/plugin-syntax-json-strings" "^7.2.0"
@@ -1066,11 +801,11 @@
     "@babel/plugin-transform-arrow-functions" "^7.2.0"
     "@babel/plugin-transform-async-to-generator" "^7.5.0"
     "@babel/plugin-transform-block-scoped-functions" "^7.2.0"
-    "@babel/plugin-transform-block-scoping" "^7.5.5"
+    "@babel/plugin-transform-block-scoping" "^7.6.3"
     "@babel/plugin-transform-classes" "^7.5.5"
     "@babel/plugin-transform-computed-properties" "^7.2.0"
-    "@babel/plugin-transform-destructuring" "^7.5.0"
-    "@babel/plugin-transform-dotall-regex" "^7.4.4"
+    "@babel/plugin-transform-destructuring" "^7.6.0"
+    "@babel/plugin-transform-dotall-regex" "^7.6.2"
     "@babel/plugin-transform-duplicate-keys" "^7.5.0"
     "@babel/plugin-transform-exponentiation-operator" "^7.2.0"
     "@babel/plugin-transform-for-of" "^7.4.4"
@@ -1078,10 +813,10 @@
     "@babel/plugin-transform-literals" "^7.2.0"
     "@babel/plugin-transform-member-expression-literals" "^7.2.0"
     "@babel/plugin-transform-modules-amd" "^7.5.0"
-    "@babel/plugin-transform-modules-commonjs" "^7.5.0"
+    "@babel/plugin-transform-modules-commonjs" "^7.6.0"
     "@babel/plugin-transform-modules-systemjs" "^7.5.0"
     "@babel/plugin-transform-modules-umd" "^7.2.0"
-    "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5"
+    "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.3"
     "@babel/plugin-transform-new-target" "^7.4.4"
     "@babel/plugin-transform-object-super" "^7.5.5"
     "@babel/plugin-transform-parameters" "^7.4.4"
@@ -1089,12 +824,12 @@
     "@babel/plugin-transform-regenerator" "^7.4.5"
     "@babel/plugin-transform-reserved-words" "^7.2.0"
     "@babel/plugin-transform-shorthand-properties" "^7.2.0"
-    "@babel/plugin-transform-spread" "^7.2.0"
+    "@babel/plugin-transform-spread" "^7.6.2"
     "@babel/plugin-transform-sticky-regex" "^7.2.0"
     "@babel/plugin-transform-template-literals" "^7.4.4"
     "@babel/plugin-transform-typeof-symbol" "^7.2.0"
-    "@babel/plugin-transform-unicode-regex" "^7.4.4"
-    "@babel/types" "^7.5.5"
+    "@babel/plugin-transform-unicode-regex" "^7.6.2"
+    "@babel/types" "^7.6.3"
     browserslist "^4.6.0"
     core-js-compat "^3.1.1"
     invariant "^2.2.2"
@@ -1109,7 +844,7 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-transform-flow-strip-types" "^7.0.0"
 
-"@babel/preset-react@7.0.0", "@babel/preset-react@^7.0.0":
+"@babel/preset-react@7.0.0":
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0.tgz#e86b4b3d99433c7b3e9e91747e2653958bc6b3c0"
   integrity sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==
@@ -1120,18 +855,29 @@
     "@babel/plugin-transform-react-jsx-self" "^7.0.0"
     "@babel/plugin-transform-react-jsx-source" "^7.0.0"
 
-"@babel/preset-typescript@7.3.3":
-  version "7.3.3"
-  resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.3.3.tgz#88669911053fa16b2b276ea2ede2ca603b3f307a"
-  integrity sha512-mzMVuIP4lqtn4du2ynEfdO0+RYcslwrZiJHXu4MGaC1ctJiW2fyaeDrtjJGs7R/KebZ1sgowcIoWf4uRpEfKEg==
+"@babel/preset-react@^7.0.0":
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.6.3.tgz#d5242c828322520205ae4eda5d4f4f618964e2f6"
+  integrity sha512-07yQhmkZmRAfwREYIQgW0HEwMY9GBJVuPY4Q12UC72AbfaawuupVWa8zQs2tlL+yun45Nv/1KreII/0PLfEsgA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/plugin-transform-typescript" "^7.3.2"
+    "@babel/plugin-transform-react-display-name" "^7.0.0"
+    "@babel/plugin-transform-react-jsx" "^7.0.0"
+    "@babel/plugin-transform-react-jsx-self" "^7.0.0"
+    "@babel/plugin-transform-react-jsx-source" "^7.0.0"
+
+"@babel/preset-typescript@7.6.0":
+  version "7.6.0"
+  resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.6.0.tgz#25768cb8830280baf47c45ab1a519a9977498c98"
+  integrity sha512-4xKw3tTcCm0qApyT6PqM9qniseCE79xGHiUnNdKGdxNsGUc2X7WwZybqIpnTmoukg3nhPceI5KPNzNqLNeIJww==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/plugin-transform-typescript" "^7.6.0"
 
 "@babel/runtime-corejs2@^7.4.2":
-  version "7.4.5"
-  resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.4.5.tgz#3d892f0560df21bafb384dd7727e33853e95d3c9"
-  integrity sha512-5yLuwzvIDecKwYMzJtiarky4Fb5643H3Ao5jwX0HrMR5oM5mn2iHH9wSZonxwNK0oAjAFUQAiOd4jT7/9Y2jMQ==
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.6.3.tgz#de3f446b3fb688b98cbd220474d1a7cad909bcb8"
+  integrity sha512-nuA2o+rgX2+PrNTZ063ehncVcg7sn+tU71BB81SaWRVUbGwCOlb0+yQA1e0QqmzOfRSYOxfvf8cosYqFbJEiwQ==
   dependencies:
     core-js "^2.6.5"
     regenerator-runtime "^0.13.2"
@@ -1143,24 +889,17 @@
   dependencies:
     regenerator-runtime "^0.12.0"
 
-"@babel/runtime@7.4.3":
-  version "7.4.3"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.3.tgz#79888e452034223ad9609187a0ad1fe0d2ad4bdc"
-  integrity sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==
-  dependencies:
-    regenerator-runtime "^0.13.2"
-
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.2":
-  version "7.4.5"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12"
-  integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==
+"@babel/runtime@7.6.0":
+  version "7.6.0"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205"
+  integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==
   dependencies:
     regenerator-runtime "^0.13.2"
 
-"@babel/runtime@^7.4.3", "@babel/runtime@^7.4.5":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
-  integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3":
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.3.tgz#935122c74c73d2240cafd32ddb5fc2a6cd35cf1f"
+  integrity sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==
   dependencies:
     regenerator-runtime "^0.13.2"
 
@@ -1173,62 +912,34 @@
     "@babel/parser" "^7.6.0"
     "@babel/types" "^7.6.0"
 
-"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.6.2":
-  version "7.6.2"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.2.tgz#b0e2bfd401d339ce0e6c05690206d1e11502ce2c"
-  integrity sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==
+"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0", "@babel/traverse@^7.6.2", "@babel/traverse@^7.6.3":
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.3.tgz#66d7dba146b086703c0fb10dd588b7364cec47f9"
+  integrity sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==
   dependencies:
     "@babel/code-frame" "^7.5.5"
-    "@babel/generator" "^7.6.2"
+    "@babel/generator" "^7.6.3"
     "@babel/helper-function-name" "^7.1.0"
     "@babel/helper-split-export-declaration" "^7.4.4"
-    "@babel/parser" "^7.6.2"
-    "@babel/types" "^7.6.0"
+    "@babel/parser" "^7.6.3"
+    "@babel/types" "^7.6.3"
     debug "^4.1.0"
     globals "^11.1.0"
     lodash "^4.17.13"
 
-"@babel/traverse@^7.5.5":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb"
-  integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==
-  dependencies:
-    "@babel/code-frame" "^7.5.5"
-    "@babel/generator" "^7.5.5"
-    "@babel/helper-function-name" "^7.1.0"
-    "@babel/helper-split-export-declaration" "^7.4.4"
-    "@babel/parser" "^7.5.5"
-    "@babel/types" "^7.5.5"
-    debug "^4.1.0"
-    globals "^11.1.0"
-    lodash "^4.17.13"
-
-"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.6.0":
-  version "7.6.1"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648"
-  integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==
+"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0", "@babel/types@^7.6.3":
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.3.tgz#3f07d96f854f98e2fbd45c64b0cb942d11e8ba09"
+  integrity sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==
   dependencies:
     esutils "^2.0.2"
     lodash "^4.17.13"
     to-fast-properties "^2.0.0"
 
-"@babel/types@^7.2.0":
-  version "7.4.4"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0"
-  integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==
-  dependencies:
-    esutils "^2.0.2"
-    lodash "^4.17.11"
-    to-fast-properties "^2.0.0"
-
-"@babel/types@^7.5.5":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a"
-  integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==
-  dependencies:
-    esutils "^2.0.2"
-    lodash "^4.17.13"
-    to-fast-properties "^2.0.0"
+"@base2/pretty-print-object@^1.0.0":
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.0.tgz#860ce718b0b73f4009e153541faff2cb6b85d047"
+  integrity sha512-4Th98KlMHr5+JkxfcoDT//6vY8vM+iSPrLNpHhRyLx2CFYi8e2RfqPLdpbnpo0Q5lQC5hNB79yes07zb02fvCw==
 
 "@cnakazawa/watch@^1.0.3":
   version "1.0.3"
@@ -1239,16 +950,16 @@
     minimist "^1.2.0"
 
 "@commitlint/cli@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-8.1.0.tgz#a3d4236c0ac961d7026a53d728b179c696d6a045"
-  integrity sha512-83K5C2nIAgoZlzMegf0/MEBjX+ampUyc/u79RxgX9ZYjzos+RQtNyO7I43dztVxPXSwAnX9XRgoOfkGWA4nbig==
-  dependencies:
-    "@commitlint/format" "^8.1.0"
-    "@commitlint/lint" "^8.1.0"
-    "@commitlint/load" "^8.1.0"
-    "@commitlint/read" "^8.1.0"
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-8.2.0.tgz#fbf9969e04e2162d985eaa644fdad6ce807aadb6"
+  integrity sha512-8fJ5pmytc38yw2QWbTTJmXLfSiWPwMkHH4govo9zJ/+ERPBF2jvlxD/dQvk24ezcizjKc6LFka2edYC4OQ+Dgw==
+  dependencies:
+    "@commitlint/format" "^8.2.0"
+    "@commitlint/lint" "^8.2.0"
+    "@commitlint/load" "^8.2.0"
+    "@commitlint/read" "^8.2.0"
     babel-polyfill "6.26.0"
-    chalk "2.3.1"
+    chalk "2.4.2"
     get-stdin "7.0.0"
     lodash "4.17.14"
     meow "5.0.0"
@@ -1256,89 +967,89 @@
     resolve-global "1.0.0"
 
 "@commitlint/config-conventional@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-8.1.0.tgz#ba61fbf0ad4df52da2b5ee3034470371a2cbf039"
-  integrity sha512-/JY+FNBnrT91qzDVIoV1Buiigvj7Le7ezFw+oRqu0nYREX03k7xnaG/7t7rUSvm7hM6dnLSOlaUsevjgMI9AEw==
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-8.2.0.tgz#886a5538e3708e017ec2871e0cbce00f635d3102"
+  integrity sha512-HuwlHQ3DyVhpK9GHgTMhJXD8Zp8PGIQVpQGYh/iTrEU6TVxdRC61BxIDZvfWatCaiG617Z/U8maRAFrqFM4TqA==
 
-"@commitlint/ensure@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-8.1.0.tgz#6c669f85c3005ed15c8141d83cf5312c43001613"
-  integrity sha512-dBU4CcjN0vJSDNOeSpaHNgQ1ra444u4USvI6PTaHVAS4aeDpZ5Cds1rxkZNsocu48WNycUu0jP84+zjcw2pPLQ==
+"@commitlint/ensure@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-8.2.0.tgz#fad0c81c3d3bd09aa5fbcbcc483ae1f39bc8af8f"
+  integrity sha512-XZZih/kcRrqK7lEORbSYCfqQw6byfsFbLygRGVdJMlCPGu9E2MjpwCtoj5z7y/lKfUB3MJaBhzn2muJqS1gC6A==
   dependencies:
     lodash "4.17.14"
 
-"@commitlint/execute-rule@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-8.1.0.tgz#e8386bd0836b3dcdd41ebb9d5904bbeb447e4715"
-  integrity sha512-+vpH3RFuO6ypuCqhP2rSqTjFTQ7ClzXtUvXphpROv9v9+7zH4L+Ex+wZLVkL8Xj2cxefSLn/5Kcqa9XyJTn3kg==
+"@commitlint/execute-rule@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-8.2.0.tgz#aefb3744e22613660adefb7ebcccaa60bd24e78d"
+  integrity sha512-9MBRthHaulbWTa8ReG2Oii2qc117NuvzhZdnkuKuYLhker7sUXGFcVhLanuWUKGyfyI2o9zVr/NHsNbCCsTzAA==
 
-"@commitlint/format@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-8.1.0.tgz#c3f3ca78bb74cbc1cce1368c0974b0cb8f31b98e"
-  integrity sha512-D0cmabUTQIKdABgt08d9JAvO9+lMRAmkcsZx8TMScY502R67HCw77JhzRDcw1RmqX5rN8JO6ZjDHO92Pbwlt+Q==
+"@commitlint/format@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-8.2.0.tgz#0a2447fadac7c0421ce8a8d7e27dfa2172c737d4"
+  integrity sha512-sA77agkDEMsEMrlGhrLtAg8vRexkOofEEv/CZX+4xlANyAz2kNwJvMg33lcL65CBhqKEnRRJRxfZ1ZqcujdKcQ==
   dependencies:
     chalk "^2.0.1"
 
-"@commitlint/is-ignored@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-8.1.0.tgz#c0583fa3c641b2d4898be1443e70e9c467429de2"
-  integrity sha512-HUSxx6kuLbqrQ8jb5QRzo+yR+CIXgA9HNcIcZ1qWrb+O9GOixt3mlW8li1IcfIgfODlaWoxIz0jYCxR08IoQLg==
+"@commitlint/is-ignored@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-8.2.0.tgz#b6409ab28bf5a80f25e14da17da3916adb230a89"
+  integrity sha512-ADaGnKfbfV6KD1pETp0Qf7XAyc75xTy3WJlbvPbwZ4oPdBMsXF0oXEEGMis6qABfU2IXan5/KAJgAFX3vdd0jA==
   dependencies:
     "@types/semver" "^6.0.1"
-    semver "6.1.1"
+    semver "6.2.0"
 
-"@commitlint/lint@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-8.1.0.tgz#ad10f4885c06f14c71de11dcd6bf2ca54a395141"
-  integrity sha512-WYjbUgtqvnlVH3S3XPZMAa+N7KO0yQ+GuUG20Qra+EtER6SRYawykmEs4wAyrmY8VcFXUnKgSlIQUsqmGKwNZQ==
+"@commitlint/lint@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-8.2.0.tgz#aadc606379f3550eb877f16d4f5b103639cbf92a"
+  integrity sha512-ch9JN8aR37ufdjoWv50jLfvFz9rWMgLW5HEkMGLsM/51gjekmQYS5NJg8S2+6F5+jmralAO7VkUMI6FukXKX0A==
   dependencies:
-    "@commitlint/is-ignored" "^8.1.0"
-    "@commitlint/parse" "^8.1.0"
-    "@commitlint/rules" "^8.1.0"
+    "@commitlint/is-ignored" "^8.2.0"
+    "@commitlint/parse" "^8.2.0"
+    "@commitlint/rules" "^8.2.0"
     babel-runtime "^6.23.0"
     lodash "4.17.14"
 
-"@commitlint/load@>6.1.1", "@commitlint/load@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-8.1.0.tgz#63b72ae5bb9152b8fa5b17c5428053032a9a49c8"
-  integrity sha512-ra02Dvmd7Gp1+uFLzTY3yGOpHjPzl5T9wYg/xrtPJNiOWXvQ0Mw7THw+ucd1M5iLUWjvdavv2N87YDRc428wHg==
+"@commitlint/load@>6.1.1", "@commitlint/load@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-8.2.0.tgz#9ca53a0c795e4f63d796b4d42279e856549add1a"
+  integrity sha512-EV6PfAY/p83QynNd1llHxJiNxKmp43g8+7dZbyfHFbsGOdokrCnoelAVZ+WGgktXwLN/uXyfkcIAxwac015UYw==
   dependencies:
-    "@commitlint/execute-rule" "^8.1.0"
-    "@commitlint/resolve-extends" "^8.1.0"
+    "@commitlint/execute-rule" "^8.2.0"
+    "@commitlint/resolve-extends" "^8.2.0"
     babel-runtime "^6.23.0"
     chalk "2.4.2"
     cosmiconfig "^5.2.0"
     lodash "4.17.14"
     resolve-from "^5.0.0"
 
-"@commitlint/message@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-8.1.0.tgz#8fb8046ddaa7e5c846a79da7cdbd15cf1a7770ae"
-  integrity sha512-AjHq022G8jQQ/3YrBOjwVBD4xF75hvC3vcvFoBIb7cC8vad1QWq+1w+aks0KlEK5IW+/+7ORZXIH+oyW7h3+8A==
+"@commitlint/message@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-8.2.0.tgz#bdc0388183f6bc6006c7e7e197a721683011907a"
+  integrity sha512-LNsSwDLIFgE3nb/Sb1PIluYNy4Q8igdf4tpJCdv5JJDf7CZCZt3ZTglj0YutZZorpRRuHJsVIB2+dI4bVH3bFw==
 
-"@commitlint/parse@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-8.1.0.tgz#833243c6d848e7a7e775a283b38697166ed2fd22"
-  integrity sha512-n4fEbZ5kdK5HChvne7Mj8rGGkKMfA4H11IuWiWmmMzgmZTNb/B04LPrzdUm4lm3f10XzM2JMM7PLXqofQJOGvA==
+"@commitlint/parse@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-8.2.0.tgz#de80137e89ee5a2d3029656c9b33e90c88c6f56c"
+  integrity sha512-vzouqroTXG6QXApkrps0gbeSYW6w5drpUk7QAeZIcaCSPsQXDM8eqqt98ZzlzLJHo5oPNXPX1AAVSTrssvHemA==
   dependencies:
     conventional-changelog-angular "^1.3.3"
     conventional-commits-parser "^2.1.0"
     lodash "^4.17.11"
 
-"@commitlint/read@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-8.1.0.tgz#effe07c965ba1735a5f7f8b7b19ac4d98c887507"
-  integrity sha512-PKsGMQFEr2sX/+orI71b82iyi8xFqb7F4cTvsLxzB5x6/QutxPVM3rg+tEVdi6rBKIDuqRIp2puDZQuREZs3vg==
+"@commitlint/read@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-8.2.0.tgz#54c6549723d532c74434ee0d74e0459032dc9159"
+  integrity sha512-1tBai1VuSQmsOTsvJr3Fi/GZqX3zdxRqYe/yN4i3cLA5S2Y4QGJ5I3l6nGZlKgm/sSelTCVKHltrfWU8s5H7SA==
   dependencies:
-    "@commitlint/top-level" "^8.1.0"
+    "@commitlint/top-level" "^8.2.0"
     "@marionebl/sander" "^0.6.0"
     babel-runtime "^6.23.0"
     git-raw-commits "^1.3.0"
 
-"@commitlint/resolve-extends@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-8.1.0.tgz#ed67f2ee484160ac8e0078bae52f172625157472"
-  integrity sha512-r/y+CeKW72Oa9BUctS1+I/MFCDiI3lfhwfQ65Tpfn6eZ4CuBYKzrCRi++GTHeAFKE3y8q1epJq5Rl/1GBejtBw==
+"@commitlint/resolve-extends@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-8.2.0.tgz#b7f2f0c71c10f24b98a199ed11d2c14cfd7a318f"
+  integrity sha512-cwi0HUsDcD502HBP8huXfTkVuWmeo1Fiz3GKxNwMBBsJV4+bKa7QrtxbNpXhVuarX7QjWfNTvmW6KmFS7YK9uw==
   dependencies:
     "@types/node" "^12.0.2"
     import-fresh "^3.0.0"
@@ -1346,32 +1057,32 @@
     resolve-from "^5.0.0"
     resolve-global "^1.0.0"
 
-"@commitlint/rules@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-8.1.0.tgz#009c64a8a23feb4647e5a25057997be62a272c8a"
-  integrity sha512-hlM8VfNjsOkbvMteFyqn0c3akiUjqG09Iid28MBLrXl/d+8BR3eTzwJ4wMta4oz/iqGyrIywvg1FpHrV977MPA==
+"@commitlint/rules@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-8.2.0.tgz#4cd6a323ca1a3f3d33ae6dc723f8c88f3dcde347"
+  integrity sha512-FlqSBBP2Gxt5Ibw+bxdYpzqYR6HI8NIBpaTBhAjSEAduQtdWFMOhF0zsgkwH7lHN7opaLcnY2fXxAhbzTmJQQA==
   dependencies:
-    "@commitlint/ensure" "^8.1.0"
-    "@commitlint/message" "^8.1.0"
-    "@commitlint/to-lines" "^8.1.0"
+    "@commitlint/ensure" "^8.2.0"
+    "@commitlint/message" "^8.2.0"
+    "@commitlint/to-lines" "^8.2.0"
     babel-runtime "^6.23.0"
 
-"@commitlint/to-lines@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-8.1.0.tgz#5bf2597f46acacec4b1b3dba832ac8934798b22a"
-  integrity sha512-Lh4OH1bInI8GME/7FggS0/XkIMEJdTObMbXRyPRGaPcWH5S7zpB6y+b4qjzBHXAbEv2O46QAAMjZ+ywPQCpmYQ==
+"@commitlint/to-lines@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-8.2.0.tgz#dddb5916a457e1a79e437115a9b8eac7bf9ad52a"
+  integrity sha512-LXTYG3sMenlN5qwyTZ6czOULVcx46uMy+MEVqpvCgptqr/MZcV/C2J+S2o1DGwj1gOEFMpqrZaE3/1R2Q+N8ng==
 
-"@commitlint/top-level@^8.1.0":
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-8.1.0.tgz#f1950de73a1f76ef5c9e753a6b77402e0755d677"
-  integrity sha512-EvQuofuA/+0l1w9pkG/PRyIwACmZdIh9qxyax7w7mR8qqmSHscqf2jARIylh1TOx0uI9egO8MuPLiwC1RwyREA==
+"@commitlint/top-level@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-8.2.0.tgz#206e7cbc54dbe9494190677f887dd60943fed5b0"
+  integrity sha512-Yaw4KmYNy31/HhRUuZ+fupFcDalnfpdu4JGBgGAqS9aBHdMSSWdWqtAaDaxdtWjTZeN3O0sA2gOhXwvKwiDwvw==
   dependencies:
     find-up "^4.0.0"
 
 "@elastic/eui@^13.1.0":
-  version "13.1.0"
-  resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-13.1.0.tgz#a3100bb37d6317b493d0ba0b8723f622e7628406"
-  integrity sha512-Z0Xqduomk2rBvKDZuLww/U11J/nHwiqkpNMnrMPJ96mBi3UlwA9QucA1/Edu30aCGvGcwKq08RUALO4owz6OWQ==
+  version "13.8.2"
+  resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-13.8.2.tgz#4509fb319f0c8b16fbc91d208c7c70d6d565d11f"
+  integrity sha512-lwnBcFFFuo9dQA+ir72G4+tT2stoddQj6jt0MDDDGwwFST9rrasYyu174nmbGeC0UoaxX/lE0skn5gaXnhYmvg==
   dependencies:
     "@types/lodash" "^4.14.116"
     "@types/numeral" "^0.0.25"
@@ -1405,25 +1116,25 @@
     find-root "^1.1.0"
     source-map "^0.7.2"
 
-"@emotion/cache@^10.0.14":
-  version "10.0.14"
-  resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.14.tgz#56093cff025c04b0330bdd92afe8335ed326dd18"
-  integrity sha512-HNGEwWnPlNyy/WPXBXzbjzkzeZFV657Z99/xq2xs5yinJHbMfi3ioCvBJ6Y8Zc8DQzO9F5jDmVXJB41Ytx3QMw==
+"@emotion/cache@^10.0.17":
+  version "10.0.19"
+  resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.19.tgz#d258d94d9c707dcadaf1558def968b86bb87ad71"
+  integrity sha512-BoiLlk4vEsGBg2dAqGSJu0vJl/PgVtCYLBFJaEO8RmQzPugXewQCXZJNXTDFaRlfCs0W+quesayav4fvaif5WQ==
   dependencies:
     "@emotion/sheet" "0.9.3"
     "@emotion/stylis" "0.8.4"
     "@emotion/utils" "0.11.2"
-    "@emotion/weak-memoize" "0.2.3"
+    "@emotion/weak-memoize" "0.2.4"
 
 "@emotion/core@^10.0.9":
-  version "10.0.14"
-  resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.14.tgz#cac5c334b278d5b7688cfff39e460a5b50abb71c"
-  integrity sha512-G9FbyxLm3lSnPfLDcag8fcOQBKui/ueXmWOhV+LuEQg9HrqExuWnWaO6gm6S5rNe+AMcqLXVljf8pYgAdFLNSg==
+  version "10.0.21"
+  resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.21.tgz#2e8398d2b92fd90d4ed6ac4d0b66214971de3458"
+  integrity sha512-U9zbc7ovZ2ceIwbLXYZPJy6wPgnOdTNT4jENZ31ee6v2lojetV5bTbCVk6ciT8G3wQRyVaTTfUCH9WCrMzpRIw==
   dependencies:
-    "@babel/runtime" "^7.4.3"
-    "@emotion/cache" "^10.0.14"
+    "@babel/runtime" "^7.5.5"
+    "@emotion/cache" "^10.0.17"
     "@emotion/css" "^10.0.14"
-    "@emotion/serialize" "^0.11.8"
+    "@emotion/serialize" "^0.11.10"
     "@emotion/sheet" "0.9.3"
     "@emotion/utils" "0.11.2"
 
@@ -1436,40 +1147,40 @@
     "@emotion/utils" "0.11.2"
     babel-plugin-emotion "^10.0.14"
 
-"@emotion/hash@0.7.2":
-  version "0.7.2"
-  resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.2.tgz#53211e564604beb9befa7a4400ebf8147473eeef"
-  integrity sha512-RMtr1i6E8MXaBWwhXL3yeOU8JXRnz8GNxHvaUfVvwxokvayUY0zoBeWbKw1S9XkufmGEEdQd228pSZXFkAln8Q==
+"@emotion/hash@0.7.3":
+  version "0.7.3"
+  resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.3.tgz#a166882c81c0c6040975dd30df24fae8549bd96f"
+  integrity sha512-14ZVlsB9akwvydAdaEnVnvqu6J2P6ySv39hYyl/aoB6w/V+bXX0tay8cF6paqbgZsN2n5Xh15uF4pE+GvE+itw==
 
 "@emotion/hash@^0.6.2", "@emotion/hash@^0.6.6":
   version "0.6.6"
   resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.6.6.tgz#62266c5f0eac6941fece302abad69f2ee7e25e44"
   integrity sha512-ojhgxzUHZ7am3D2jHkMzPpsBAiB005GF5YU4ea+8DNPybMk01JJUM9V9YRlF/GE95tcOm8DxQvWA2jq19bGalQ==
 
-"@emotion/is-prop-valid@0.8.2":
-  version "0.8.2"
-  resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.2.tgz#b9692080da79041683021fcc32f96b40c54c59dc"
-  integrity sha512-ZQIMAA2kLUWiUeMZNJDTeCwYRx1l8SQL0kHktze4COT22occKpDML1GDUXP5/sxhOMrZO8vZw773ni4H5Snrsg==
+"@emotion/is-prop-valid@0.8.3":
+  version "0.8.3"
+  resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.3.tgz#cbe62ddbea08aa022cdf72da3971570a33190d29"
+  integrity sha512-We7VBiltAJ70KQA0dWkdPMXnYoizlxOXpvtjmu5/MBnExd+u0PGgV27WCYanmLAbCwAU30Le/xA0CQs/F/Otig==
   dependencies:
-    "@emotion/memoize" "0.7.2"
+    "@emotion/memoize" "0.7.3"
 
-"@emotion/memoize@0.7.2":
-  version "0.7.2"
-  resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.2.tgz#7f4c71b7654068dfcccad29553520f984cc66b30"
-  integrity sha512-hnHhwQzvPCW1QjBWFyBtsETdllOM92BfrKWbUTmh9aeOlcVOiXvlPsK4104xH8NsaKfg86PTFsWkueQeUfMA/w==
+"@emotion/memoize@0.7.3":
+  version "0.7.3"
+  resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.3.tgz#5b6b1c11d6a6dddf1f2fc996f74cf3b219644d78"
+  integrity sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow==
 
 "@emotion/memoize@^0.6.1", "@emotion/memoize@^0.6.6":
   version "0.6.6"
   resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.6.6.tgz#004b98298d04c7ca3b4f50ca2035d4f60d2eed1b"
   integrity sha512-h4t4jFjtm1YV7UirAFuSuFGyLa+NNxjdkq6DpFLANNQY5rHueFZHVY+8Cu1HYVP6DrheB0kv4m5xPjo7eKT7yQ==
 
-"@emotion/serialize@^0.11.8":
-  version "0.11.8"
-  resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.8.tgz#e41dcf7029e45286a3e0cf922933e670fe05402c"
-  integrity sha512-Qb6Us2Yk1ZW8SOYH6s5z7qzXXb2iHwVeqc6FjXtac0vvxC416ki0eTtHNw4Q5smoyxdyZh3519NKGrQvvvrZ/Q==
+"@emotion/serialize@^0.11.10", "@emotion/serialize@^0.11.11", "@emotion/serialize@^0.11.8":
+  version "0.11.11"
+  resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.11.tgz#c92a5e5b358070a7242d10508143306524e842a4"
+  integrity sha512-YG8wdCqoWtuoMxhHZCTA+egL0RSGdHEc+YCsmiSBPBEDNuVeMWtjEWtGrhUterSChxzwnWBXvzSxIFQI/3sHLw==
   dependencies:
-    "@emotion/hash" "0.7.2"
-    "@emotion/memoize" "0.7.2"
+    "@emotion/hash" "0.7.3"
+    "@emotion/memoize" "0.7.3"
     "@emotion/unitless" "0.7.4"
     "@emotion/utils" "0.11.2"
     csstype "^2.5.7"
@@ -1489,23 +1200,23 @@
   resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.3.tgz#689f135ecf87d3c650ed0c4f5ddcbe579883564a"
   integrity sha512-c3Q6V7Df7jfwSq5AzQWbXHa5soeE4F5cbqi40xn0CzXxWW9/6Mxq48WJEtqfWzbZtW9odZdnRAkwCQwN12ob4A==
 
-"@emotion/styled-base@^10.0.14":
-  version "10.0.14"
-  resolved "https://registry.yarnpkg.com/@emotion/styled-base/-/styled-base-10.0.14.tgz#1b78a93e067ea852b2069339fcfd72c32ec91e4d"
-  integrity sha512-1nC5iO/Rk0DY47M5wXCyWpbo/woiwXWfVbNKDM3QRi7CKq8CwC++PQ5HgiYflFrAt1vjzIVZqnzrIn3idUoQgg==
+"@emotion/styled-base@^10.0.17":
+  version "10.0.19"
+  resolved "https://registry.yarnpkg.com/@emotion/styled-base/-/styled-base-10.0.19.tgz#53655274797194d86453354fdb2c947b46032db6"
+  integrity sha512-Sz6GBHTbOZoeZQKvkE9gQPzaJ6/qtoQ/OPvyG2Z/6NILlYk60Es1cEcTgTkm26H8y7A0GSgp4UmXl+srvsnFPg==
   dependencies:
-    "@babel/runtime" "^7.4.3"
-    "@emotion/is-prop-valid" "0.8.2"
-    "@emotion/serialize" "^0.11.8"
+    "@babel/runtime" "^7.5.5"
+    "@emotion/is-prop-valid" "0.8.3"
+    "@emotion/serialize" "^0.11.11"
     "@emotion/utils" "0.11.2"
 
 "@emotion/styled@^10.0.7":
-  version "10.0.14"
-  resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.14.tgz#538bcf0d67bf8f6de946bcfbee53dc7d0187b346"
-  integrity sha512-Ae8d5N/FmjvZKXjqWcjfhZhjCdkvxZSqD95Q72BYDNQnsOKLHIA4vWlMolLXDNkw1dIxV3l2pp82Z87HXj6eYQ==
+  version "10.0.17"
+  resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.17.tgz#0cd38b8b36259541f2c6717fc22607a120623654"
+  integrity sha512-zHMgWjHDMNjD+ux64POtDnjLAObniu3znxFBLSdV/RiEhSLjHIowfvSbbd/C33/3uwtI6Uzs2KXnRZtka/PpAQ==
   dependencies:
-    "@emotion/styled-base" "^10.0.14"
-    babel-plugin-emotion "^10.0.14"
+    "@emotion/styled-base" "^10.0.17"
+    babel-plugin-emotion "^10.0.17"
 
 "@emotion/stylis@0.8.4":
   version "0.8.4"
@@ -1537,10 +1248,10 @@
   resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.8.2.tgz#576ff7fb1230185b619a75d258cbc98f0867a8dc"
   integrity sha512-rLu3wcBWH4P5q1CGoSSH/i9hrXs7SlbRLkoq9IGuoPYNGQvDJ3pt/wmOM+XgYjIDRMVIdkUWt0RsfzF50JfnCw==
 
-"@emotion/weak-memoize@0.2.3":
-  version "0.2.3"
-  resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.3.tgz#dfa0c92efe44a1d1a7974fb49ffeb40ef2da5a27"
-  integrity sha512-zVgvPwGK7c1aVdUVc9Qv7SqepOGRDrqCw7KZPSZziWGxSlbII3gmvGLPzLX4d0n0BMbamBacUrN22zOMyFFEkQ==
+"@emotion/weak-memoize@0.2.4":
+  version "0.2.4"
+  resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.4.tgz#622a72bebd1e3f48d921563b4b60a762295a81fc"
+  integrity sha512-6PYY5DVdAY1ifaQW6XYTnOMihmBVT27elqSjEoodchsGjzYlEsTQMcEhSud99kVawatyTZRTiVkJ/c6lwbQ7nA==
 
 "@hapi/address@2.x.x":
   version "2.1.2"
@@ -1553,9 +1264,9 @@
   integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==
 
 "@hapi/hoek@8.x.x":
-  version "8.2.4"
-  resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.4.tgz#684a14f4ca35d46f44abc87dfc696e5e4fe8a020"
-  integrity sha512-Ze5SDNt325yZvNO7s5C4fXDscjJ6dcqLFXJQ/M7dZRQCewuDj2iDUuBi6jLQt+APbW9RjjVEvLr35FXuOEqjow==
+  version "8.3.0"
+  resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.3.0.tgz#2b9db1cd00f3891005c77b3a8d608b88a6d0aa4d"
+  integrity sha512-C0QL9bmgUXTSuf8nDeGrpMjtJG7tPUr8wG6/wxPbP62tGwCwQtdMSJYfESowmY4P3Hn593f+8OzNY5bckcu/LQ==
 
 "@hapi/joi@^15.0.3":
   version "15.1.1"
@@ -1568,9 +1279,9 @@
     "@hapi/topo" "3.x.x"
 
 "@hapi/topo@3.x.x":
-  version "3.1.4"
-  resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.4.tgz#42e2fe36f593d90ad258a08b582be128c141c45d"
-  integrity sha512-aVWQTOI9wBD6zawmOr6f+tdEIxQC8JXfQVLTjgGe8YEStAWGn/GNNVTobKJhbWKveQj2RyYF3oYbO9SC8/eOCA==
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.5.tgz#3baea17e456530edad69a75c3fc7cde97dd6d331"
+  integrity sha512-bi9m1jrui9LlvtVdLaHv0DqeOoe+I8dep+nEcTgW6XxJHL3xArQcilYz3tIp0cRC4gWlsVtABK7vNKg4jzEmAA==
   dependencies:
     "@hapi/hoek" "8.x.x"
 
@@ -1632,7 +1343,7 @@
     "@jest/types" "^24.9.0"
     jest-mock "^24.9.0"
 
-"@jest/fake-timers@^24", "@jest/fake-timers@^24.8.0", "@jest/fake-timers@^24.9.0":
+"@jest/fake-timers@^24", "@jest/fake-timers@^24.9.0":
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93"
   integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==
@@ -1677,7 +1388,7 @@
     graceful-fs "^4.1.15"
     source-map "^0.6.0"
 
-"@jest/test-result@^24.8.0", "@jest/test-result@^24.9.0":
+"@jest/test-result@^24.9.0":
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca"
   integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==
@@ -1718,7 +1429,7 @@
     source-map "^0.6.1"
     write-file-atomic "2.4.1"
 
-"@jest/types@^24", "@jest/types@^24.8.0", "@jest/types@^24.9.0":
+"@jest/types@^24", "@jest/types@^24.9.0":
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59"
   integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==
@@ -1744,67 +1455,52 @@
     call-me-maybe "^1.0.1"
     glob-to-regexp "^0.3.0"
 
-"@nodelib/fs.scandir@2.1.1":
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz#7fa8fed654939e1a39753d286b48b4836d00e0eb"
-  integrity sha512-NT/skIZjgotDSiXs0WqYhgcuBKhUMgfekCmCGtkUAiLqZdOnrdjmZr9wRl3ll64J9NF79uZ4fk16Dx0yMc/Xbg==
+"@nodelib/fs.scandir@2.1.3":
+  version "2.1.3"
+  resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"
+  integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==
   dependencies:
-    "@nodelib/fs.stat" "2.0.1"
+    "@nodelib/fs.stat" "2.0.3"
     run-parallel "^1.1.9"
 
-"@nodelib/fs.stat@2.0.1", "@nodelib/fs.stat@^2.0.1":
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz#814f71b1167390cfcb6a6b3d9cdeb0951a192c14"
-  integrity sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw==
+"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2":
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3"
+  integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==
 
 "@nodelib/fs.stat@^1.1.2":
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
   integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
 
-"@nodelib/fs.walk@^1.2.1":
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.2.tgz#6a6450c5e17012abd81450eb74949a4d970d2807"
-  integrity sha512-J/DR3+W12uCzAJkw7niXDcqcKBg6+5G5Q/ZpThpGNzAUz70eOR6RV4XnnSN01qHZiVl0eavoxJsBypQoKsV2QQ==
+"@nodelib/fs.walk@^1.2.3":
+  version "1.2.4"
+  resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976"
+  integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==
   dependencies:
-    "@nodelib/fs.scandir" "2.1.1"
+    "@nodelib/fs.scandir" "2.1.3"
     fastq "^1.6.0"
 
 "@octokit/endpoint@^5.1.0":
-  version "5.1.2"
-  resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-5.1.2.tgz#45fd879e33a25ee10fa4cffc4d098ee04135afe6"
-  integrity sha512-bBGGmcRFq1x0jrB29G/9KjYmO3cdHfk3476B2JOHRvLsNw1Pn3l+ZvbiqtcO9qAS4Ti+zFedLB84ziHZRZclQA==
+  version "5.4.0"
+  resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-5.4.0.tgz#5b44b3e8e92d88765daf127e1501174ecbca7bce"
+  integrity sha512-DWTNgEKg5KXzvNjKTzcFTnkZiL7te6pQxxumvxPjyjDpcY5V3xzywnNu1WVqySY3Ct1flF/kAoyDdZos6acq3Q==
   dependencies:
-    deepmerge "3.2.0"
     is-plain-object "^3.0.0"
-    universal-user-agent "^2.1.0"
-    url-template "^2.0.8"
+    universal-user-agent "^4.0.0"
 
 "@octokit/request-error@^1.0.1", "@octokit/request-error@^1.0.2":
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-1.0.2.tgz#e6dbc5be13be1041ef8eca9225520982add574cf"
-  integrity sha512-T9swMS/Vc4QlfWrvyeSyp/GjhXtYaBzCcibjGywV4k4D2qVrQKfEMPy8OxMDEj7zkIIdpHwqdpVbKCvnUPqkXw==
-  dependencies:
-    deprecation "^2.0.0"
-    once "^1.4.0"
-
-"@octokit/request@^4.0.1":
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/@octokit/request/-/request-4.1.0.tgz#e85dc377113baf2fe24433af8feb20e8a32e21b0"
-  integrity sha512-RvpQAba4i+BNH0z8i0gPRc1ShlHidj4puQjI/Tno6s+Q3/Mzb0XRSHJiOhpeFrZ22V7Mwjq1E7QS27P5CgpWYA==
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-1.0.4.tgz#15e1dc22123ba4a9a4391914d80ec1e5303a23be"
+  integrity sha512-L4JaJDXn8SGT+5G0uX79rZLv0MNJmfGa4vb4vy1NnpjSnWDLJRy6m90udGwvMmavwsStgbv2QNkPzzTCMmL+ig==
   dependencies:
-    "@octokit/endpoint" "^5.1.0"
-    "@octokit/request-error" "^1.0.1"
     deprecation "^2.0.0"
-    is-plain-object "^3.0.0"
-    node-fetch "^2.3.0"
     once "^1.4.0"
-    universal-user-agent "^2.1.0"
 
 "@octokit/request@^5.0.0":
-  version "5.0.2"
-  resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.0.2.tgz#59a920451f24811c016ddc507adcc41aafb2dca5"
-  integrity sha512-z1BQr43g4kOL4ZrIVBMHwi68Yg9VbkRUyuAgqCp1rU3vbYa69+2gIld/+gHclw15bJWQnhqqyEb7h5a5EqgZ0A==
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.1.0.tgz#5609dcc7b5323e529f29d535214383d9eaf0c05c"
+  integrity sha512-I15T9PwjFs4tbWyhtFU2Kq7WDPidYMvRB7spmxoQRZfxSmiqullG+Nz+KbSmpkfnlvHwTr1e31R5WReFRKMXjg==
   dependencies:
     "@octokit/endpoint" "^5.1.0"
     "@octokit/request-error" "^1.0.1"
@@ -1812,31 +1508,12 @@
     is-plain-object "^3.0.0"
     node-fetch "^2.3.0"
     once "^1.4.0"
-    universal-user-agent "^3.0.0"
-
-"@octokit/rest@^16.13.1":
-  version "16.26.0"
-  resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.26.0.tgz#5c12b28763219045e1c9a15182e8dfaed10004e8"
-  integrity sha512-NBpzre44ZAQWZhlH+zUYTgqI0pHN+c9rNj4d+pCydGEiKTGc1HKmoTghEUyr9GxazDyoAvmpx9nL0I7QS1Olvg==
-  dependencies:
-    "@octokit/request" "^4.0.1"
-    "@octokit/request-error" "^1.0.2"
-    atob-lite "^2.0.0"
-    before-after-hook "^1.4.0"
-    btoa-lite "^1.0.0"
-    deprecation "^2.0.0"
-    lodash.get "^4.4.2"
-    lodash.set "^4.3.2"
-    lodash.uniq "^4.5.0"
-    octokit-pagination-methods "^1.1.0"
-    once "^1.4.0"
-    universal-user-agent "^2.0.0"
-    url-template "^2.0.8"
+    universal-user-agent "^4.0.0"
 
 "@octokit/rest@^16.27.0":
-  version "16.28.7"
-  resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.28.7.tgz#a2c2db5b318da84144beba82d19c1a9dbdb1a1fa"
-  integrity sha512-cznFSLEhh22XD3XeqJw51OLSfyL2fcFKUO+v2Ep9MTAFfFLS1cK1Zwd1yEgQJmJoDnj4/vv3+fGGZweG+xsbIA==
+  version "16.33.0"
+  resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.33.0.tgz#13c1404b24c9871419eb31029de177e82f3eb851"
+  integrity sha512-t4jMR+odsfooQwmHiREoTQixVTX2DfdbSaO+lKrW9R5XBuk0DW+5T/JdfwtxAGUAHgvDDpWY/NVVDfEPTzxD6g==
   dependencies:
     "@octokit/request" "^5.0.0"
     "@octokit/request-error" "^1.0.2"
@@ -1849,8 +1526,7 @@
     lodash.uniq "^4.5.0"
     octokit-pagination-methods "^1.1.0"
     once "^1.4.0"
-    universal-user-agent "^3.0.0"
-    url-template "^2.0.8"
+    universal-user-agent "^4.0.0"
 
 "@reach/router@^1.2.1":
   version "1.2.1"
@@ -1873,22 +1549,10 @@
     fs-extra "^8.0.0"
     lodash "^4.17.4"
 
-"@semantic-release/commit-analyzer@^6.1.0":
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-6.1.0.tgz#32bbe3c23da86e23edf072fbb276fa2f383fcb17"
-  integrity sha512-2lb+t6muGenI86mYGpZYOgITx9L3oZYF697tJoqXeQEk0uw0fm+OkkOuDTBA3Oax9ftoNIrCKv9bwgYvxrbM6w==
-  dependencies:
-    conventional-changelog-angular "^5.0.0"
-    conventional-commits-filter "^2.0.0"
-    conventional-commits-parser "^3.0.0"
-    debug "^4.0.0"
-    import-from "^2.1.0"
-    lodash "^4.17.4"
-
-"@semantic-release/commit-analyzer@^6.2.0":
-  version "6.2.0"
-  resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-6.2.0.tgz#5cd25ce67ba9ba5b46e47457505e63629e186695"
-  integrity sha512-oUtPydYcbtJsEY6WCPi4wynTgRecK5zCkKaGmHi+9Xl7d6jGf7LomnJCg++6dNF1tyavrbGMSdXTCPH6Dx9LbA==
+"@semantic-release/commit-analyzer@^6.1.0", "@semantic-release/commit-analyzer@^6.2.0":
+  version "6.3.0"
+  resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-6.3.0.tgz#e0fb2f6af7be2321ad9401d8ae25be0cc1005d83"
+  integrity sha512-sh51MVlV8VyrvGIemcvzueDADX/8qGbAgce1F0CtQv8hNKYyhdaJeHzfiM1rNXwCynDmcQj+Yq9rrWt71tBd/Q==
   dependencies:
     conventional-changelog-angular "^5.0.0"
     conventional-commits-filter "^2.0.0"
@@ -1918,33 +1582,10 @@
     micromatch "^4.0.0"
     p-reduce "^2.0.0"
 
-"@semantic-release/github@^5.1.0":
-  version "5.2.10"
-  resolved "https://registry.yarnpkg.com/@semantic-release/github/-/github-5.2.10.tgz#bf325f11685d59b864c8946d7d30fcb749d89e37"
-  integrity sha512-z/UwIxKb+EMiJDIy/57MBzJ80ar5H9GJQRyML/ILQ8dlrPwXs7cTyTvC7AesrF7t1mJZtg3ht9Qf9RdtR/LGzw==
-  dependencies:
-    "@octokit/rest" "^16.13.1"
-    "@semantic-release/error" "^2.2.0"
-    aggregate-error "^2.0.0"
-    bottleneck "^2.0.1"
-    debug "^4.0.0"
-    dir-glob "^2.0.0"
-    fs-extra "^7.0.0"
-    globby "^9.0.0"
-    http-proxy-agent "^2.1.0"
-    https-proxy-agent "^2.2.1"
-    issue-parser "^3.0.0"
-    lodash "^4.17.4"
-    mime "^2.0.3"
-    p-filter "^1.0.0"
-    p-retry "^3.0.0"
-    parse-github-url "^1.0.1"
-    url-join "^4.0.0"
-
-"@semantic-release/github@^5.4.2":
-  version "5.4.2"
-  resolved "https://registry.yarnpkg.com/@semantic-release/github/-/github-5.4.2.tgz#1dbde876228c03ff9a000893a18aff5c6ab2cd61"
-  integrity sha512-8gkOa5tED/+sjAPwZRYsLaGr6VuAGLZinSvLsuF9/l4qLeYV8gvj7fhjFJepGu6y31t7PR2J9SWzmsqsBAyyKQ==
+"@semantic-release/github@^5.1.0", "@semantic-release/github@^5.4.2":
+  version "5.5.3"
+  resolved "https://registry.yarnpkg.com/@semantic-release/github/-/github-5.5.3.tgz#280f5c3d1cbcd469005b0858867d8ceb41c7bc8f"
+  integrity sha512-7Fl6LRYA20Wn440gPWB+uZ3A1slokKS47Kd4uxQnXt4t4lXYTMrg1tpzkY1FUQgsWqq8PFgoJ3lCPoo8JOQwKg==
   dependencies:
     "@octokit/rest" "^16.27.0"
     "@semantic-release/error" "^2.2.0"
@@ -1955,8 +1596,8 @@
     fs-extra "^8.0.0"
     globby "^10.0.0"
     http-proxy-agent "^2.1.0"
-    https-proxy-agent "^2.2.1"
-    issue-parser "^4.0.0"
+    https-proxy-agent "^3.0.0"
+    issue-parser "^5.0.0"
     lodash "^4.17.4"
     mime "^2.4.3"
     p-filter "^2.0.0"
@@ -1964,59 +1605,27 @@
     parse-github-url "^1.0.1"
     url-join "^4.0.0"
 
-"@semantic-release/npm@^5.0.5":
-  version "5.1.7"
-  resolved "https://registry.yarnpkg.com/@semantic-release/npm/-/npm-5.1.7.tgz#ed3bac977d46294bfd11df7621bb5a9b6d5523be"
-  integrity sha512-4THiFGp9APX1a+EJJsOYurJCR8TrRUgNCU9u46AkZekWfvtyzacfIBKCrmEljpYG8qDDnHLZwHSqyW4ID4iteA==
-  dependencies:
-    "@semantic-release/error" "^2.2.0"
-    aggregate-error "^3.0.0"
-    execa "^1.0.0"
-    fs-extra "^7.0.0"
-    lodash "^4.17.4"
-    nerf-dart "^1.0.0"
-    normalize-url "^4.0.0"
-    npm "^6.8.0"
-    rc "^1.2.8"
-    read-pkg "^5.0.0"
-    registry-auth-token "^3.3.1"
-
-"@semantic-release/npm@^5.1.13":
-  version "5.1.13"
-  resolved "https://registry.yarnpkg.com/@semantic-release/npm/-/npm-5.1.13.tgz#7b06d62b4d9c8336ae5a5c85eede26fb89f19e3b"
-  integrity sha512-pONvpoEtGH1nd6Wj3SryACNJ/YXXsvSSekE9Pdk6mnaRv7lGhXdaeJJr6Lr4L8WK98oZv4aJOr68vTac2Oc+dA==
+"@semantic-release/npm@^5.0.5", "@semantic-release/npm@^5.1.13":
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/@semantic-release/npm/-/npm-5.2.0.tgz#e5643c43ca5f3eb7db3d403fe12e44c187c5f9c6"
+  integrity sha512-+WUoFNTVn4saPLbIBd+fCXL9nP6c49iOyvjLqWNq4lh2/sLZg993MMTBVvTxHRaojxb42R2RjePsO5AaFM3Lzw==
   dependencies:
     "@semantic-release/error" "^2.2.0"
     aggregate-error "^3.0.0"
-    execa "^1.0.0"
+    execa "^2.0.2"
     fs-extra "^8.0.0"
-    lodash "^4.17.4"
+    lodash "^4.17.15"
     nerf-dart "^1.0.0"
     normalize-url "^4.0.0"
-    npm "^6.8.0"
+    npm "^6.10.3"
     rc "^1.2.8"
     read-pkg "^5.0.0"
     registry-auth-token "^4.0.0"
 
-"@semantic-release/release-notes-generator@^7.1.2":
-  version "7.1.4"
-  resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-7.1.4.tgz#8f4f752c5a8385abdaac1256127cef05988bc2ad"
-  integrity sha512-pWPouZujddgb6t61t9iA9G3yIfp3TeQ7bPbV1ixYSeP6L7gI1+Du82fY/OHfEwyifpymLUQW0XnIKgKct5IMMw==
-  dependencies:
-    conventional-changelog-angular "^5.0.0"
-    conventional-changelog-writer "^4.0.0"
-    conventional-commits-filter "^2.0.0"
-    conventional-commits-parser "^3.0.0"
-    debug "^4.0.0"
-    get-stream "^4.0.0"
-    import-from "^2.1.0"
-    into-stream "^4.0.0"
-    lodash "^4.17.4"
-
-"@semantic-release/release-notes-generator@^7.2.1":
-  version "7.2.1"
-  resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-7.2.1.tgz#2c0c340e7be2a3d27c28cb869b6737a70f2862fe"
-  integrity sha512-TdlYgYH6amhE80i9L9HPcTwYzk4Rma7qM1g7XJEEfip7dNXWgmrBeibN4DJmTg/qrUFDd4GD86lFDcYXNZDNow==
+"@semantic-release/release-notes-generator@^7.1.2", "@semantic-release/release-notes-generator@^7.2.1":
+  version "7.3.0"
+  resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-7.3.0.tgz#b94f3d84d7071eb8e921b53a9729ca48722e7c0f"
+  integrity sha512-6ozBLHM9XZR6Z8PFSKssLtwBYc5l1WOnxj034F8051QOo3TMKDDPKwdj2Niyc+e7ru7tGa3Ftq7nfN0YnD6//A==
   dependencies:
     conventional-changelog-angular "^5.0.0"
     conventional-changelog-writer "^4.0.0"
@@ -2399,10 +2008,10 @@
   resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz#310ec0775de808a6a2e4fd4268c245fd734c1165"
   integrity sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w==
 
-"@svgr/babel-plugin-svg-dynamic-title@^4.2.0":
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.2.0.tgz#43f0f689a5347a894160eb51b39a109889a4df20"
-  integrity sha512-gH2qItapwCUp6CCqbxvzBbc4dh4OyxdYKsW3EOkYexr0XUmQL0ScbdNh6DexkZ01T+sdClniIbnCObsXcnx3sQ==
+"@svgr/babel-plugin-svg-dynamic-title@^4.3.3":
+  version "4.3.3"
+  resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.3.tgz#2cdedd747e5b1b29ed4c241e46256aac8110dd93"
+  integrity sha512-w3Be6xUNdwgParsvxkkeZb545VhXEwjGMwExMVBIdPQJeyMQHqm9Msnb2a1teHBqUYL66qtwfhNkbj1iarCG7w==
 
 "@svgr/babel-plugin-svg-em-dimensions@^4.2.0":
   version "4.2.0"
@@ -2419,69 +2028,67 @@
   resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz#5f1e2f886b2c85c67e76da42f0f6be1b1767b697"
   integrity sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw==
 
-"@svgr/babel-preset@^4.2.0":
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-4.2.0.tgz#c9fc236445a02a8cd4e750085e51c181de00d6c5"
-  integrity sha512-iLetHpRCQXfK47voAs5/uxd736cCyocEdorisjAveZo8ShxJ/ivSZgstBmucI1c8HyMF5tOrilJLoFbhpkPiKw==
+"@svgr/babel-preset@^4.3.3":
+  version "4.3.3"
+  resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-4.3.3.tgz#a75d8c2f202ac0e5774e6bfc165d028b39a1316c"
+  integrity sha512-6PG80tdz4eAlYUN3g5GZiUjg2FMcp+Wn6rtnz5WJG9ITGEF1pmFdzq02597Hn0OmnQuCVaBYQE1OVFAnwOl+0A==
   dependencies:
     "@svgr/babel-plugin-add-jsx-attribute" "^4.2.0"
     "@svgr/babel-plugin-remove-jsx-attribute" "^4.2.0"
     "@svgr/babel-plugin-remove-jsx-empty-expression" "^4.2.0"
     "@svgr/babel-plugin-replace-jsx-attribute-value" "^4.2.0"
-    "@svgr/babel-plugin-svg-dynamic-title" "^4.2.0"
+    "@svgr/babel-plugin-svg-dynamic-title" "^4.3.3"
     "@svgr/babel-plugin-svg-em-dimensions" "^4.2.0"
     "@svgr/babel-plugin-transform-react-native-svg" "^4.2.0"
     "@svgr/babel-plugin-transform-svg-component" "^4.2.0"
 
-"@svgr/core@^4.2.0":
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.2.0.tgz#f32ef8b9d05312aaa775896ec30ae46a6521e248"
-  integrity sha512-nvzXaf2VavqjMCTTfsZfjL4o9035KedALkMzk82qOlHOwBb8JT+9+zYDgBl0oOunbVF94WTLnvGunEg0csNP3Q==
+"@svgr/core@^4.3.3":
+  version "4.3.3"
+  resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.3.tgz#b37b89d5b757dc66e8c74156d00c368338d24293"
+  integrity sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w==
   dependencies:
-    "@svgr/plugin-jsx" "^4.2.0"
+    "@svgr/plugin-jsx" "^4.3.3"
     camelcase "^5.3.1"
-    cosmiconfig "^5.2.0"
+    cosmiconfig "^5.2.1"
 
-"@svgr/hast-util-to-babel-ast@^4.2.0":
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.2.0.tgz#dd743435a5f3a8e84a1da067f27b5fae3d7b6b63"
-  integrity sha512-IvAeb7gqrGB5TH9EGyBsPrMRH/QCzIuAkLySKvH2TLfLb2uqk98qtJamordRQTpHH3e6TORfBXoTo7L7Opo/Ow==
+"@svgr/hast-util-to-babel-ast@^4.3.2":
+  version "4.3.2"
+  resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.2.tgz#1d5a082f7b929ef8f1f578950238f630e14532b8"
+  integrity sha512-JioXclZGhFIDL3ddn4Kiq8qEqYM2PyDKV0aYno8+IXTLuYt6TOgHUbUAAFvqtb0Xn37NwP0BTHglejFoYr8RZg==
   dependencies:
-    "@babel/types" "^7.4.0"
+    "@babel/types" "^7.4.4"
 
-"@svgr/plugin-jsx@^4.2.0":
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.2.0.tgz#15a91562c9b5f90640ea0bdcb2ad59d692ee7ae9"
-  integrity sha512-AM1YokmZITgveY9bulLVquqNmwiFo2Px2HL+IlnTCR01YvWDfRL5QKdnF7VjRaS5MNP938mmqvL0/8oz3zQMkg==
+"@svgr/plugin-jsx@^4.3.3":
+  version "4.3.3"
+  resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.3.tgz#e2ba913dbdfbe85252a34db101abc7ebd50992fa"
+  integrity sha512-cLOCSpNWQnDB1/v+SUENHH7a0XY09bfuMKdq9+gYvtuwzC2rU4I0wKGFEp1i24holdQdwodCtDQdFtJiTCWc+w==
   dependencies:
-    "@babel/core" "^7.4.3"
-    "@svgr/babel-preset" "^4.2.0"
-    "@svgr/hast-util-to-babel-ast" "^4.2.0"
-    rehype-parse "^6.0.0"
-    unified "^7.1.0"
-    vfile "^4.0.0"
+    "@babel/core" "^7.4.5"
+    "@svgr/babel-preset" "^4.3.3"
+    "@svgr/hast-util-to-babel-ast" "^4.3.2"
+    svg-parser "^2.0.0"
 
-"@svgr/plugin-svgo@^4.2.0":
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-4.2.0.tgz#2a594a2d3312955e75fd87dc77ae51f377c809f3"
-  integrity sha512-zUEKgkT172YzHh3mb2B2q92xCnOAMVjRx+o0waZ1U50XqKLrVQ/8dDqTAtnmapdLsGurv8PSwenjLCUpj6hcvw==
+"@svgr/plugin-svgo@^4.3.1":
+  version "4.3.1"
+  resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz#daac0a3d872e3f55935c6588dd370336865e9e32"
+  integrity sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w==
   dependencies:
-    cosmiconfig "^5.2.0"
+    cosmiconfig "^5.2.1"
     merge-deep "^3.0.2"
-    svgo "^1.2.1"
+    svgo "^1.2.2"
 
 "@svgr/webpack@^4.0.3":
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-4.2.0.tgz#b7cdef42ae671a27ed4cfe118a0f2da7f4e9ebed"
-  integrity sha512-sm3UUJHmRlqEg8w8bjUT+FAMf5lkgCydxotEapinpd10kzrpQP++Qd+bmuepE3hsIUU68BO24vgQALQ92qBZEw==
+  version "4.3.3"
+  resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-4.3.3.tgz#13cc2423bf3dff2d494f16b17eb7eacb86895017"
+  integrity sha512-bjnWolZ6KVsHhgyCoYRFmbd26p8XVbulCzSG53BDQqAr+JOAderYK7CuYrB3bDjHJuF6LJ7Wrr42+goLRV9qIg==
   dependencies:
-    "@babel/core" "^7.4.3"
+    "@babel/core" "^7.4.5"
     "@babel/plugin-transform-react-constant-elements" "^7.0.0"
-    "@babel/preset-env" "^7.4.3"
+    "@babel/preset-env" "^7.4.5"
     "@babel/preset-react" "^7.0.0"
-    "@svgr/core" "^4.2.0"
-    "@svgr/plugin-jsx" "^4.2.0"
-    "@svgr/plugin-svgo" "^4.2.0"
+    "@svgr/core" "^4.3.3"
+    "@svgr/plugin-jsx" "^4.3.3"
+    "@svgr/plugin-svgo" "^4.3.1"
     loader-utils "^1.2.3"
 
 "@types/babel__core@^7.1.0":
@@ -2518,16 +2125,16 @@
     "@babel/types" "^7.3.0"
 
 "@types/cheerio@*":
-  version "0.22.11"
-  resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.11.tgz#61c0facf9636d14ba5f77fc65ed8913aa845d717"
-  integrity sha512-x0X3kPbholdJZng9wDMhb2swvUi3UYRNAuWAmIPIWlfgAJZp//cql/qblE7181Mg7SjWVwq6ldCPCLn5AY/e7w==
+  version "0.22.13"
+  resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.13.tgz#5eecda091a24514185dcba99eda77e62bf6523e6"
+  integrity sha512-OZd7dCUOUkiTorf97vJKwZnSja/DmHfuBAroe1kREZZTCf/tlFecwHhsOos3uVHxeKGZDwzolIrCUApClkdLuA==
   dependencies:
     "@types/node" "*"
 
 "@types/classnames@^2.2.7":
-  version "2.2.7"
-  resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.7.tgz#fb68cc9be8487e6ea5b13700e759bfbab7e0fefd"
-  integrity sha512-rzOhiQ55WzAiFgXRtitP/ZUT8iVNyllEpylJ5zHzR4vArUvMB39GTk+Zon/uAM0JxEFAWnwsxC2gH8s+tZ3Myg==
+  version "2.2.9"
+  resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.9.tgz#d868b6febb02666330410fe7f58f3c4b8258be7b"
+  integrity sha512-MNl+rT5UmZeilaPxAVs6YaPC2m6aA8rofviZbhbxpPpl61uKodfdQVsBtgJGTqGizEf02oW3tsVe7FYB8kK14A==
 
 "@types/d3-array@^1.2.6":
   version "1.2.7"
@@ -2576,9 +2183,9 @@
     "@types/enzyme" "*"
 
 "@types/enzyme@*", "@types/enzyme@^3.9.0":
-  version "3.9.2"
-  resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.9.2.tgz#bfbbc5f89cf3092d01712d843ffade2bf5578c24"
-  integrity sha512-f8lXku9JIa6vReljhHmHqMvaRcabdJzuOOVoLGjQvoL4ikQu0aQaHMI4uR/BCStYcpSbktTov5GpL2iruHaykA==
+  version "3.10.3"
+  resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.3.tgz#02b6c5ac7d0472005944a652e79045e2f6c66804"
+  integrity sha512-f/Kcb84sZOSZiBPCkr4He9/cpuSLcKRyQaEE20Q30Prx0Dn6wcyMAWI0yofL6yvd9Ht9G7EVkQeRqK0n5w8ILw==
   dependencies:
     "@types/cheerio" "*"
     "@types/react" "*"
@@ -2594,9 +2201,9 @@
   integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
 
 "@types/expect-puppeteer@^3.3.1":
-  version "3.3.1"
-  resolved "https://registry.yarnpkg.com/@types/expect-puppeteer/-/expect-puppeteer-3.3.1.tgz#46e5944bf425b86ea13a563c7c8b86901414988d"
-  integrity sha512-3raSnf28NelDtv0ksvQPZs410taJZ4d70vA8sVzmbRPV04fpmQm9/BOxUCloETD/ZI1EXRpv0pzOQKhPTbm4jg==
+  version "3.3.2"
+  resolved "https://registry.yarnpkg.com/@types/expect-puppeteer/-/expect-puppeteer-3.3.2.tgz#246f91e5907ddcfabc2f146408a1f99c8d24c3b5"
+  integrity sha512-WRxRC9kn+ItWL+Ar/oRHwkdjM50ujJbyhrYknwZu2vetE28Eh9RqurAgn1jtyFpfi9bL3pXDUQSrXtDENmda2w==
   dependencies:
     "@types/jest" "*"
     "@types/puppeteer" "*"
@@ -2610,6 +2217,14 @@
     "@types/minimatch" "*"
     "@types/node" "*"
 
+"@types/hoist-non-react-statics@^3.3.0":
+  version "3.3.1"
+  resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
+  integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
+  dependencies:
+    "@types/react" "*"
+    hoist-non-react-statics "^3.3.0"
+
 "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
@@ -2665,20 +2280,15 @@
   resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636"
   integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==
 
-"@types/lodash@^4.14.116":
-  version "4.14.132"
-  resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.132.tgz#8ce45ca8745ff2e004fac0de0ab46f61e390ffa0"
-  integrity sha512-RNUU1rrh85NgUJcjOOr96YXr+RHwInGbaQCZmlitqOaCKXffj8bh+Zxwuq5rjDy5OgzFldDVoqk4pyLEDiwxIw==
-
-"@types/lodash@^4.14.121":
-  version "4.14.130"
-  resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.130.tgz#04b3a690d5f4fc34579963c99adae067b8c8eb5a"
-  integrity sha512-H++wk0tbneBsRVfLkgAAd0IIpmpVr2Bj4T0HncoOsQf3/xrJexRYQK2Tqo0Ej3pFslM8GkMgdis9bu6xIb1ycw==
+"@types/lodash@^4.14.116", "@types/lodash@^4.14.121":
+  version "4.14.144"
+  resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.144.tgz#12e57fc99064bce45e5ab3c8bc4783feb75eab8e"
+  integrity sha512-ogI4g9W5qIQQUhXAclq6zhqgqNUr7UlFaqDHbch7WLSLeeM/7d3CRaw7GLajxvyFvhJqw4Rpcz5bhoaYtIx6Tg==
 
 "@types/luxon@^1.11.1":
-  version "1.13.0"
-  resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-1.13.0.tgz#e92338702d0b1b96e8d5ea6fe39d9938891aacd0"
-  integrity sha512-XmDiRVoJWgVdqX9x1a/GU4p9bSgZY7q8SOyMLs3fx1AdQcxLYAPIt/jfZm2e+PBVRWuEx1FqYNJ37kBZ53TMqA==
+  version "1.15.2"
+  resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-1.15.2.tgz#528f11f7d6dc08cec0445d4bea8065a5bb6989b2"
+  integrity sha512-zHPoyVrLvNaiMRYdhmh88Rn489ZgAgbc6iLxR5Yi0VCNfeNYHcszbhJV2vDHLNrVGy35BPtWBRn4OP2F9BBvFw==
 
 "@types/minimatch@*", "@types/minimatch@^3.0.3":
   version "3.0.3"
@@ -2693,9 +2303,9 @@
     moment ">=2.14.0"
 
 "@types/node@*":
-  version "12.0.2"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.2.tgz#3452a24edf9fea138b48fad4a0a028a683da1e40"
-  integrity sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==
+  version "12.12.7"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
+  integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
 
 "@types/node@^12.0.2":
   version "12.6.8"
@@ -2713,14 +2323,14 @@
   integrity sha512-ShHzHkYD+Ldw3eyttptCpUhF1/mkInWwasQkCNXZHOsJMJ/UMa8wXrxSrTJaVk0r4pLK/VnESVM0wFsfQzNEKQ==
 
 "@types/prop-types@*":
-  version "15.7.1"
-  resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6"
-  integrity sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==
+  version "15.7.3"
+  resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
+  integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
 
 "@types/puppeteer@*", "@types/puppeteer@^1.19.1":
-  version "1.19.1"
-  resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-1.19.1.tgz#942ca62288953a0f5fbbc25c103b5f2ba28b60ab"
-  integrity sha512-ReWZvoEfMiJIA3AG+eM+nCx5GKrU2ANVYY5TC0nbpeiTCtnJbcqnmBbR8TkXMBTvLBYcuTOAELbTcuX73siDNQ==
+  version "1.20.1"
+  resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-1.20.1.tgz#0aba5ae3d290daa91cd3ba9f66ba5e9fba3499cc"
+  integrity sha512-F91CqYDHETg3pQfIPNBNZKmi7R1xS1y4yycOYX7o6Xk16KF+IV+9LqTmVuG+FIxw/53/JEy94zKjjGjg92V6bg==
   dependencies:
     "@types/node" "*"
 
@@ -2730,23 +2340,33 @@
   integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
 
 "@types/react-beautiful-dnd@^10.1.0":
-  version "10.1.2"
-  resolved "https://registry.yarnpkg.com/@types/react-beautiful-dnd/-/react-beautiful-dnd-10.1.2.tgz#74069f7b1d0cb67b7af99a2584b30e496e545d8b"
-  integrity sha512-76M5VRbhduUarM9wyMWQm3tLKCVMKTlhG0+W67dteg/HBE+kueIwuyLWzE0m5fmuilvrDXoM5NL890KLnHETZw==
+  version "10.1.3"
+  resolved "https://registry.yarnpkg.com/@types/react-beautiful-dnd/-/react-beautiful-dnd-10.1.3.tgz#a558eba3f807582a2e1d2db1bcca975525e7c331"
+  integrity sha512-VTbrLV4vIBgTRl6AIpY4vvZGHb6vEQypNAdmCG8+OZ0uvwEmPccRY5a4Qxvn4EgKi7wE4dBdCeWYrniuJ75R0A==
   dependencies:
     "@types/react" "*"
 
 "@types/react-dom@^16.8.2":
-  version "16.8.4"
-  resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.8.4.tgz#7fb7ba368857c7aa0f4e4511c4710ca2c5a12a88"
-  integrity sha512-eIRpEW73DCzPIMaNBDP5pPIpK1KXyZwNgfxiVagb5iGiz6da+9A5hslSX6GAQKdO7SayVCS/Fr2kjqprgAvkfA==
+  version "16.9.1"
+  resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.1.tgz#79206237cba9532a9f870b1cd5428bef6b66378c"
+  integrity sha512-1S/akvkKr63qIUWVu5IKYou2P9fHLb/P2VAwyxVV85JGaGZTcUniMiTuIqM3lXFB25ej6h+CYEQ27ERVwi6eGA==
+  dependencies:
+    "@types/react" "*"
+
+"@types/react-redux@^7.1.1":
+  version "7.1.4"
+  resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.4.tgz#e0d02a073e730b8b58a6341bddca2ea692ff0bce"
+  integrity sha512-SUV/7d+4L7C1Db/D4pqASgN1V1U2HnDEhEol9lYpPSguS76xFboZzf5ha2hTz6v31cUewyC7WksMh1q8JxhebQ==
   dependencies:
+    "@types/hoist-non-react-statics" "^3.3.0"
     "@types/react" "*"
+    hoist-non-react-statics "^3.3.0"
+    redux "^4.0.0"
 
 "@types/react@*", "@types/react@^16.8.5":
-  version "16.8.18"
-  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.18.tgz#fe66fb748b0b6ca9709d38b87b2d1356d960a511"
-  integrity sha512-lUXdKzRqWR4FebR5tGHkLCqnvQJS4fdXKCBrNGGbglqZg2gpU+J82pMONevQODUotATs9fc9k66bx3/St8vReg==
+  version "16.9.5"
+  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.5.tgz#079dabd918b19b32118c25fd00a786bb6d0d5e51"
+  integrity sha512-jQ12VMiFOWYlp+j66dghOWcmDDwhca0bnlcTxS4Qz/fh5gi6wpaZDthPEu/Gc/YlAuO87vbiUXL8qKstFvuOaA==
   dependencies:
     "@types/prop-types" "*"
     csstype "^2.2.0"
@@ -2762,9 +2382,9 @@
   integrity sha512-SMA+fUwULwK7sd/ZJicUztiPs8F1yCPwF3O23Z9uQ32ME5Ha0NmDK9+QTsYE4O2tHXChzXomSWWeIhCnoN1LqA==
 
 "@types/semver@^6.0.1":
-  version "6.0.1"
-  resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.0.1.tgz#a984b405c702fa5a7ec6abc56b37f2ba35ef5af6"
-  integrity sha512-ffCdcrEE5h8DqVxinQjo+2d1q+FV5z7iNtPofw3JsrltSoSVlOGaW0rY8XxtO9XukdTn8TaCGWmk2VFGhI70mg==
+  version "6.0.2"
+  resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.0.2.tgz#5e8b09f0e4af53034b1d0fb9977a277847836205"
+  integrity sha512-G1Ggy7/9Nsa1Jt2yiBR2riEuyK2DFNnqow6R7cromXPMNynackRY1vqFTLz/gwnef1LHokbXThcPhqMRjUbkpQ==
 
 "@types/stack-utils@^1.0.1":
   version "1.0.1"
@@ -2784,23 +2404,15 @@
     "@types/react" "*"
     "@types/storybook__react" "*"
 
-"@types/storybook__addon-knobs@^5.0.3":
-  version "5.0.3"
-  resolved "https://registry.yarnpkg.com/@types/storybook__addon-knobs/-/storybook__addon-knobs-5.0.3.tgz#a6366877d7b21f9fa2cc9eb23650304388393350"
-  integrity sha512-NnSOu4ajk4kL1e1eRe9zzyspIghgFu8B9ELyrAl1jF/nJE26YK2oDTi7qr+k/+X33rNaYFo6e7+lsEqeI3MLXg==
+"@types/storybook__addon-knobs@5.0.4":
+  version "5.0.4"
+  resolved "https://registry.yarnpkg.com/@types/storybook__addon-knobs/-/storybook__addon-knobs-5.0.4.tgz#8d29b295459279a7a8e91cf2fffc99a3727258ea"
+  integrity sha512-B43R3SWGjQe/dyGpzjjCLloMBcxhHUtLOYv1EwIEiCBaZrz8h4ItdHA3yMX3GO6L6MyH9BVhNUUc9QzdfnyyjQ==
   dependencies:
     "@types/react" "*"
     "@types/storybook__react" "*"
 
-"@types/storybook__react@*":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@types/storybook__react/-/storybook__react-4.0.1.tgz#b6320c9d027b8ee7ef1445fef8b4cba196d48ace"
-  integrity sha512-knkZErqv8Iy2QbebqBa5tsy2itIMKdO6bcQ7C19nmgTc+j1pnQhXCGcVyARzAQ1/NAuSYudSWQAKG+plgK7hyQ==
-  dependencies:
-    "@types/react" "*"
-    "@types/webpack-env" "*"
-
-"@types/storybook__react@^4.0.2":
+"@types/storybook__react@*", "@types/storybook__react@^4.0.2":
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/@types/storybook__react/-/storybook__react-4.0.2.tgz#f36fb399574c662e79c1a0cf6e429b6ff730da40"
   integrity sha512-U/+J5qccRdKFryvHkk1a0IeZaSIZLCmTwAQhTSDGeC3SPNIYPus+EtunBqP49r870l8czbfxtjeC3IL9P66ngQ==
@@ -2808,44 +2420,22 @@
     "@types/react" "*"
     "@types/webpack-env" "*"
 
-"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2":
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
-  integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
-
 "@types/url-parse@^1.4.3":
   version "1.4.3"
   resolved "https://registry.yarnpkg.com/@types/url-parse/-/url-parse-1.4.3.tgz#fba49d90f834951cb000a674efee3d6f20968329"
   integrity sha512-4kHAkbV/OfW2kb5BLVUuUMoumB3CP8rHqlw48aHvFy5tf9ER0AfOonBlX29l/DD68G70DmyhRlSYfQPSYpC5Vw==
 
 "@types/uuid@^3.4.4":
-  version "3.4.4"
-  resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.4.tgz#7af69360fa65ef0decb41fd150bf4ca5c0cefdf5"
-  integrity sha512-tPIgT0GUmdJQNSHxp0X2jnpQfBSTfGxUMc/2CXBU2mnyTFVYVa2ojpoQ74w0U2yn2vw3jnC640+77lkFFpdVDw==
-  dependencies:
-    "@types/node" "*"
-
-"@types/vfile-message@*":
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/@types/vfile-message/-/vfile-message-1.0.1.tgz#e1e9895cc6b36c462d4244e64e6d0b6eaf65355a"
-  integrity sha512-mlGER3Aqmq7bqR1tTTIVHq8KSAFFRyGbrxuM8C/H82g6k7r2fS+IMEkIu3D7JHzG10NvPdR8DNx0jr0pwpp4dA==
-  dependencies:
-    "@types/node" "*"
-    "@types/unist" "*"
-
-"@types/vfile@^3.0.0":
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/@types/vfile/-/vfile-3.0.2.tgz#19c18cd232df11ce6fa6ad80259bc86c366b09b9"
-  integrity sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==
+  version "3.4.5"
+  resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.5.tgz#d4dc10785b497a1474eae0ba7f0cb09c0ddfd6eb"
+  integrity sha512-MNL15wC3EKyw1VLF+RoVO4hJJdk9t/Hlv3rt1OL65Qvuadm4BYo6g9ZJQqoq7X8NBFSsQXgAujWciovh2lpVjA==
   dependencies:
     "@types/node" "*"
-    "@types/unist" "*"
-    "@types/vfile-message" "*"
 
 "@types/webpack-env@*":
-  version "1.13.9"
-  resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.9.tgz#a67287861c928ebf4159a908d1fb1a2a34d4097a"
-  integrity sha512-p8zp5xqkly3g4cCmo2mKOHI9+Z/kObmDj0BmjbDDJQlgDTiEGTbm17MEwTAusV6XceCy+bNw9q/ZHXHyKo3zkg==
+  version "1.14.0"
+  resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.14.0.tgz#8edfc5f8e6eae20eeed3ca0d02974ed4ee5e4efc"
+  integrity sha512-Fv+0gYJzE/czLoRKq+gnXWr4yBpPM3tO3C8pDLFwqVKlMICQUq5OsxwwFZYDaVr7+L6mgNDp16iOcJHEz3J5RQ==
 
 "@types/yargs-parser@*":
   version "13.1.0"
@@ -2860,39 +2450,56 @@
     "@types/yargs-parser" "*"
 
 "@typescript-eslint/eslint-plugin@^2.3.2":
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.3.2.tgz#7e112ca0bb29044d915baf10163a8199a20f7c69"
-  integrity sha512-tcnpksq1bXzcIRbYLeXkgp6l+ggEMXXUcl1wsSvL807fRtmvVQKygElwEUf4hBA76dNag3VAK1q2m3vd7qJaZA==
+  version "2.3.3"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.3.3.tgz#71e06c6887650301e02105c99b4c8f67454157e3"
+  integrity sha512-12cCbwu5PbQudkq2xCIS/QhB7hCMrsNPXK+vJtqy/zFqtzVkPRGy12O5Yy0gUK086f3VHV/P4a4R4CjMW853pA==
   dependencies:
-    "@typescript-eslint/experimental-utils" "2.3.2"
+    "@typescript-eslint/experimental-utils" "2.3.3"
     eslint-utils "^1.4.2"
     functional-red-black-tree "^1.0.1"
     regexpp "^2.0.1"
     tsutils "^3.17.1"
 
-"@typescript-eslint/experimental-utils@2.3.2":
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.3.2.tgz#e50f31264507e6fec7b33840bb6af260c24f4ea8"
-  integrity sha512-t+JGdTT6dRbmvKDlhlVkEueoZa0fhJNfG6z2cpnRPLwm3VwYr2BjR//acJGC1Yza0I9ZNcDfRY7ubQEvvfG6Jg==
+"@typescript-eslint/experimental-utils@2.3.3":
+  version "2.3.3"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.3.3.tgz#0685613063ff397cfa9209be2e6e81c0382a9b11"
+  integrity sha512-MQ4jKPMTU1ty4TigJCRKFPye2qyQdH8jzIIkceaHgecKFmkNS1hXPqKiZ+mOehkz6+HcN5Nuvwm+frmWZR9tdg==
   dependencies:
     "@types/json-schema" "^7.0.3"
-    "@typescript-eslint/typescript-estree" "2.3.2"
+    "@typescript-eslint/typescript-estree" "2.3.3"
     eslint-scope "^5.0.0"
 
+"@typescript-eslint/experimental-utils@^1.13.0":
+  version "1.13.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz#b08c60d780c0067de2fb44b04b432f540138301e"
+  integrity sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==
+  dependencies:
+    "@types/json-schema" "^7.0.3"
+    "@typescript-eslint/typescript-estree" "1.13.0"
+    eslint-scope "^4.0.0"
+
 "@typescript-eslint/parser@^2.3.2":
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.3.2.tgz#e9b742e191cd1209930da469cde379591ad0af5b"
-  integrity sha512-nq1UQeNGdKdqdgF6Ww+Ov2OidWgiL96+JYdXXZ2rkP/OWyc6KMNSbs6MpRCpI8q+PmDa7hBnHNQIo7w/drYccA==
+  version "2.3.3"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.3.3.tgz#af519d6572bdee3e9610e21c8362766858976bc1"
+  integrity sha512-+cV53HuYFeeyrNW8x/rgPmbVrzzp/rpRmwbJnNtwn4K8mroL1BdjxwQh7X9cUHp9rm4BBiEWmD3cSBjKG7d5mw==
   dependencies:
     "@types/eslint-visitor-keys" "^1.0.0"
-    "@typescript-eslint/experimental-utils" "2.3.2"
-    "@typescript-eslint/typescript-estree" "2.3.2"
+    "@typescript-eslint/experimental-utils" "2.3.3"
+    "@typescript-eslint/typescript-estree" "2.3.3"
     eslint-visitor-keys "^1.1.0"
 
-"@typescript-eslint/typescript-estree@2.3.2":
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.3.2.tgz#107414aa04e689fe6f7251eb63fb500217f2b7f4"
-  integrity sha512-eZNEAai16nwyhIVIEaWQlaUgAU3S9CkQ58qvK0+3IuSdLJD3W1PNuehQFMIhW/mTP1oFR9GNoTcLg7gtXz6lzA==
+"@typescript-eslint/typescript-estree@1.13.0":
+  version "1.13.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz#8140f17d0f60c03619798f1d628b8434913dc32e"
+  integrity sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==
+  dependencies:
+    lodash.unescape "4.0.1"
+    semver "5.5.0"
+
+"@typescript-eslint/typescript-estree@2.3.3":
+  version "2.3.3"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.3.3.tgz#be802220876bedfb80384cde1d46fe57ae7abf71"
+  integrity sha512-GkACs12Xp8d/STunNv/iSMYJFQrkrax9vuPZySlgSzoJJtw1cp6tbEw4qsLskQv6vloLrkFJHcTJ0a/yCB5cIA==
   dependencies:
     glob "^7.1.4"
     is-glob "^4.0.1"
@@ -3093,12 +2700,7 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
     mime-types "~2.1.24"
     negotiator "0.6.2"
 
-acorn-dynamic-import@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948"
-  integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==
-
-acorn-globals@^4.1.0:
+acorn-globals@^4.1.0, acorn-globals@^4.3.0:
   version "4.3.4"
   resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7"
   integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==
@@ -3106,18 +2708,10 @@ acorn-globals@^4.1.0:
     acorn "^6.0.1"
     acorn-walk "^6.0.1"
 
-acorn-globals@^4.3.0:
-  version "4.3.2"
-  resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.2.tgz#4e2c2313a597fd589720395f6354b41cd5ec8006"
-  integrity sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==
-  dependencies:
-    acorn "^6.0.1"
-    acorn-walk "^6.0.1"
-
 acorn-jsx@^5.0.0:
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e"
-  integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==
+  version "5.0.2"
+  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f"
+  integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==
 
 acorn-walk@^6.0.1:
   version "6.2.0"
@@ -3129,32 +2723,24 @@ acorn@^5.5.3:
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
   integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
 
-acorn@^6.0.1:
+acorn@^6.0.1, acorn@^6.0.4, acorn@^6.0.7, acorn@^6.2.1:
   version "6.3.0"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e"
   integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==
 
-acorn@^6.0.4, acorn@^6.0.5, acorn@^6.0.7:
-  version "6.1.1"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f"
-  integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==
-
-acorn@^6.2.0:
-  version "6.2.1"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51"
-  integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==
-
-address@1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9"
-  integrity sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==
+address@1.1.2, address@^1.0.1:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
+  integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==
 
-address@^1.0.1:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/address/-/address-1.1.0.tgz#ef8e047847fcd2c5b6f50c16965f924fd99fe709"
-  integrity sha512-4diPfzWbLEIElVG4AnqP+00SULlPzNuyJFNnmMrLgyaxG6tZXJ1sn7mjBu4fHrJE+Yp/jgylOweJn2xsLMFggQ==
+agent-base@4, agent-base@^4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
+  integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
+  dependencies:
+    es6-promisify "^5.0.0"
 
-agent-base@4, agent-base@^4.1.0, agent-base@~4.2.1:
+agent-base@~4.2.1:
   version "4.2.1"
   resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
   integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
@@ -3168,21 +2754,13 @@ agentkeepalive@^3.4.1:
   dependencies:
     humanize-ms "^1.2.1"
 
-aggregate-error@^2.0.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-2.2.0.tgz#f54b464db18cc77c907ae084451f39134707134a"
-  integrity sha512-E5n+IZkhh22/pFdUvHUU/o9z752lc+7tgHt+FXS/g6BjlbE9249dGmuS/SxIWMPhTljZJkFN+7OXE0+O5+WT8w==
-  dependencies:
-    clean-stack "^2.0.0"
-    indent-string "^3.0.0"
-
 aggregate-error@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.0.tgz#5b5a3c95e9095f311c9ab16c19fb4f3527cd3f79"
-  integrity sha512-yKD9kEoJIR+2IFqhMwayIBgheLYbB3PS2OBhWae1L/ODTd/JF/30cW0bc9TqzRL3k4U41Dieu3BF4I29p8xesA==
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0"
+  integrity sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==
   dependencies:
     clean-stack "^2.0.0"
-    indent-string "^3.2.0"
+    indent-string "^4.0.0"
 
 "airbnb-js-shims@^1 || ^2":
   version "2.2.0"
@@ -3208,12 +2786,12 @@ aggregate-error@^3.0.0:
     symbol.prototype.description "^1.0.0"
 
 airbnb-prop-types@^2.13.2:
-  version "2.13.2"
-  resolved "https://registry.yarnpkg.com/airbnb-prop-types/-/airbnb-prop-types-2.13.2.tgz#43147a5062dd2a4a5600e748a47b64004cc5f7fc"
-  integrity sha512-2FN6DlHr6JCSxPPi25EnqGaXC4OC3/B3k1lCd6MMYrZ51/Gf/1qDfaR+JElzWa+Tl7cY2aYOlsYJGFeQyVHIeQ==
+  version "2.15.0"
+  resolved "https://registry.yarnpkg.com/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz#5287820043af1eb469f5b0af0d6f70da6c52aaef"
+  integrity sha512-jUh2/hfKsRjNFC4XONQrxo/n/3GG4Tn6Hl0WlFQN5PY9OMC9loSCoAYKnZsWaP8wEfd5xcrPloK0Zg6iS1xwVA==
   dependencies:
-    array.prototype.find "^2.0.4"
-    function.prototype.name "^1.1.0"
+    array.prototype.find "^2.1.0"
+    function.prototype.name "^1.1.1"
     has "^1.0.3"
     is-regex "^1.0.4"
     object-is "^1.0.1"
@@ -3221,29 +2799,19 @@ airbnb-prop-types@^2.13.2:
     object.entries "^1.1.0"
     prop-types "^15.7.2"
     prop-types-exact "^1.2.0"
-    react-is "^16.8.6"
+    react-is "^16.9.0"
 
 ajv-errors@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
   integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==
 
-ajv-keywords@^3.1.0:
-  version "3.4.0"
-  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.0.tgz#4b831e7b531415a7cc518cd404e73f6193c6349d"
-  integrity sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==
-
-ajv@^6.1.0, ajv@^6.1.1, ajv@^6.9.1:
-  version "6.10.0"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
-  integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==
-  dependencies:
-    fast-deep-equal "^2.0.1"
-    fast-json-stable-stringify "^2.0.0"
-    json-schema-traverse "^0.4.1"
-    uri-js "^4.2.2"
+ajv-keywords@^3.1.0, ajv-keywords@^3.4.1:
+  version "3.4.1"
+  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da"
+  integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==
 
-ajv@^6.5.5:
+ajv@^6.1.0, ajv@^6.1.1, ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1:
   version "6.10.2"
   resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52"
   integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==
@@ -3402,11 +2970,6 @@ array-filter@^1.0.0:
   resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83"
   integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=
 
-array-filter@~0.0.0:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
-  integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw=
-
 array-find-index@^1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
@@ -3435,16 +2998,6 @@ array-includes@^3.0.3:
     define-properties "^1.1.2"
     es-abstract "^1.7.0"
 
-array-map@~0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
-  integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=
-
-array-reduce@~0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
-  integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=
-
 array-union@^1.0.1, array-union@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
@@ -3472,13 +3025,13 @@ array-unique@^0.3.2:
   resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
   integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
 
-array.prototype.find@^2.0.4:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90"
-  integrity sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=
+array.prototype.find@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.1.0.tgz#630f2eaf70a39e608ac3573e45cf8ccd0ede9ad7"
+  integrity sha512-Wn41+K1yuO5p7wRZDl7890c3xvv5UBrfVXTVIe28rSQb6LS0fZMDrQB6PAcxQFRFy6vJTLDc3A2+3CjQdzVKRg==
   dependencies:
-    define-properties "^1.1.2"
-    es-abstract "^1.7.0"
+    define-properties "^1.1.3"
+    es-abstract "^1.13.0"
 
 array.prototype.flat@^1.2.1:
   version "1.2.1"
@@ -3577,17 +3130,12 @@ async-limiter@~1.0.0:
   resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
   integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
 
-async@^1.5.2:
-  version "1.5.2"
-  resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
-  integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
-
-async@^2.1.4:
-  version "2.6.2"
-  resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381"
-  integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==
+async@^2.1.4, async@^2.6.2:
+  version "2.6.3"
+  resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
+  integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
   dependencies:
-    lodash "^4.17.11"
+    lodash "^4.17.14"
 
 asynckit@^0.4.0:
   version "0.4.0"
@@ -3605,17 +3153,17 @@ atob@^2.1.1:
   integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
 
 autoprefixer@^9.4.9, autoprefixer@^9.6.1:
-  version "9.6.1"
-  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.1.tgz#51967a02d2d2300bb01866c1611ec8348d355a47"
-  integrity sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw==
+  version "9.6.4"
+  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.4.tgz#e6453be47af316b2923eaeaed87860f52ad4b7eb"
+  integrity sha512-Koz2cJU9dKOxG8P1f8uVaBntOv9lP4yz9ffWvWaicv9gHBPhpQB22nGijwd8gqW9CNT+UdkbQOQNLVI8jN1ZfQ==
   dependencies:
-    browserslist "^4.6.3"
-    caniuse-lite "^1.0.30000980"
+    browserslist "^4.7.0"
+    caniuse-lite "^1.0.30000998"
     chalk "^2.4.2"
     normalize-range "^0.1.2"
     num2fraction "^1.2.2"
-    postcss "^7.0.17"
-    postcss-value-parser "^4.0.0"
+    postcss "^7.0.18"
+    postcss-value-parser "^4.0.2"
 
 aws-sign2@~0.7.0:
   version "0.7.0"
@@ -3699,29 +3247,22 @@ babel-plugin-add-react-displayname@^0.0.5:
   resolved "https://registry.yarnpkg.com/babel-plugin-add-react-displayname/-/babel-plugin-add-react-displayname-0.0.5.tgz#339d4cddb7b65fd62d1df9db9fe04de134122bd5"
   integrity sha1-M51M3be2X9YtHfnbn+BN4TQSK9U=
 
-babel-plugin-dynamic-import-node@2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.2.0.tgz#c0adfb07d95f4a4495e9aaac6ec386c4d7c2524e"
-  integrity sha512-fP899ELUnTaBcIzmrW7nniyqqdYWrWuJUyPWHxFa/c7r7hS6KC8FscNfLlBNIoPSc55kYMGEEKjPjJGCLbE1qA==
-  dependencies:
-    object.assign "^4.1.0"
-
-babel-plugin-dynamic-import-node@^2.3.0:
+babel-plugin-dynamic-import-node@2.3.0, babel-plugin-dynamic-import-node@^2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f"
   integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==
   dependencies:
     object.assign "^4.1.0"
 
-babel-plugin-emotion@^10.0.14, babel-plugin-emotion@^10.0.9:
-  version "10.0.14"
-  resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.14.tgz#c1d0e4621e303507ea7da57daa3cd771939d6df4"
-  integrity sha512-T7hdxJ4xXkKW3OXcizK0pnUJlBeNj/emjQZPDIZvGOuwl2adIgicQWRNkz6BuwKdDTrqaXQn1vayaL6aL8QW5A==
+babel-plugin-emotion@^10.0.14, babel-plugin-emotion@^10.0.17, babel-plugin-emotion@^10.0.9:
+  version "10.0.21"
+  resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.21.tgz#9ebeb12edeea3e60a5476b0e07c9868605e65968"
+  integrity sha512-03o+T6sfVAJhNDcSdLapgv4IeewcFPzxlvBUVdSf7o5PI57ZSxoDvmy+ZulVWSu+rOWAWkEejNcsb29TuzJHbg==
   dependencies:
     "@babel/helper-module-imports" "^7.0.0"
-    "@emotion/hash" "0.7.2"
-    "@emotion/memoize" "0.7.2"
-    "@emotion/serialize" "^0.11.8"
+    "@emotion/hash" "0.7.3"
+    "@emotion/memoize" "0.7.3"
+    "@emotion/serialize" "^0.11.11"
     babel-plugin-macros "^2.0.0"
     babel-plugin-syntax-jsx "^6.18.0"
     convert-source-map "^1.5.0"
@@ -3764,16 +3305,7 @@ babel-plugin-jest-hoist@^24.9.0:
   dependencies:
     "@types/babel__traverse" "^7.0.6"
 
-babel-plugin-macros@2.5.1:
-  version "2.5.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.5.1.tgz#4a119ac2c2e19b458c259b9accd7ee34fd57ec6f"
-  integrity sha512-xN3KhAxPzsJ6OQTktCanNpIFnnMsCV+t8OloKxIL72D6+SUZYFn9qfklPgef5HyyDtzYZqqb+fs1S12+gQY82Q==
-  dependencies:
-    "@babel/runtime" "^7.4.2"
-    cosmiconfig "^5.2.0"
-    resolve "^1.10.0"
-
-babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.4.5:
+babel-plugin-macros@2.6.1, babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.4.5:
   version "2.6.1"
   resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.6.1.tgz#41f7ead616fc36f6a93180e89697f69f51671181"
   integrity sha512-6W2nwiXme6j1n2erPOnmRiWfObUhWH7Qw1LMi9XZy8cj+KtESu3T6asZvtk5bMQQjX8te35o7CFueiSdL/2NmQ==
@@ -3794,15 +3326,15 @@ babel-plugin-minify-constant-folding@^0.5.0:
   dependencies:
     babel-helper-evaluate-path "^0.5.0"
 
-babel-plugin-minify-dead-code-elimination@^0.5.0:
-  version "0.5.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.5.0.tgz#d23ef5445238ad06e8addf5c1cf6aec835bcda87"
-  integrity sha512-XQteBGXlgEoAKc/BhO6oafUdT4LBa7ARi55mxoyhLHNuA+RlzRmeMAfc31pb/UqU01wBzRc36YqHQzopnkd/6Q==
+babel-plugin-minify-dead-code-elimination@^0.5.1:
+  version "0.5.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.5.1.tgz#1a0c68e44be30de4976ca69ffc535e08be13683f"
+  integrity sha512-x8OJOZIrRmQBcSqxBcLbMIK8uPmTvNWPXH2bh5MDCW1latEqYiRMuUkPImKcfpo59pTUB2FT7HfcgtG8ZlR5Qg==
   dependencies:
     babel-helper-evaluate-path "^0.5.0"
     babel-helper-mark-eval-scopes "^0.4.3"
     babel-helper-remove-or-void "^0.4.3"
-    lodash.some "^4.6.0"
+    lodash "^4.17.11"
 
 babel-plugin-minify-flip-comparisons@^0.4.3:
   version "0.4.3"
@@ -3811,11 +3343,12 @@ babel-plugin-minify-flip-comparisons@^0.4.3:
   dependencies:
     babel-helper-is-void-0 "^0.4.3"
 
-babel-plugin-minify-guarded-expressions@^0.4.3:
-  version "0.4.3"
-  resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.3.tgz#cc709b4453fd21b1f302877444c89f88427ce397"
-  integrity sha1-zHCbRFP9IbHzAod0RMifiEJ845c=
+babel-plugin-minify-guarded-expressions@^0.4.4:
+  version "0.4.4"
+  resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.4.tgz#818960f64cc08aee9d6c75bec6da974c4d621135"
+  integrity sha512-RMv0tM72YuPPfLT9QLr3ix9nwUIq+sHT6z8Iu3sLbqldzC1Dls8DPCywzUIzkTx9Zh1hWX4q/m9BPoPed9GOfA==
   dependencies:
+    babel-helper-evaluate-path "^0.5.0"
     babel-helper-flip-expressions "^0.4.3"
 
 babel-plugin-minify-infinity@^0.4.3:
@@ -3840,11 +3373,12 @@ babel-plugin-minify-replace@^0.5.0:
   resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.5.0.tgz#d3e2c9946c9096c070efc96761ce288ec5c3f71c"
   integrity sha512-aXZiaqWDNUbyNNNpWs/8NyST+oU7QTpK7J9zFEFSA0eOmtUNMU3fczlTTTlnCxHmq/jYNFEmkkSG3DDBtW3Y4Q==
 
-babel-plugin-minify-simplify@^0.5.0:
-  version "0.5.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.5.0.tgz#1f090018afb90d8b54d3d027fd8a4927f243da6f"
-  integrity sha512-TM01J/YcKZ8XIQd1Z3nF2AdWHoDsarjtZ5fWPDksYZNsoOjQ2UO2EWm824Ym6sp127m44gPlLFiO5KFxU8pA5Q==
+babel-plugin-minify-simplify@^0.5.1:
+  version "0.5.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.5.1.tgz#f21613c8b95af3450a2ca71502fdbd91793c8d6a"
+  integrity sha512-OSYDSnoCxP2cYDMk9gxNAed6uJDiDz65zgL6h8d3tm8qXIagWGMLWhqysT6DY3Vs7Fgq7YUDcjOomhVUb+xX6A==
   dependencies:
+    babel-helper-evaluate-path "^0.5.0"
     babel-helper-flip-expressions "^0.4.3"
     babel-helper-is-nodes-equiv "^0.0.1"
     babel-helper-to-multiple-sequence-expressions "^0.5.0"
@@ -3857,9 +3391,9 @@ babel-plugin-minify-type-constructors@^0.4.3:
     babel-helper-is-void-0 "^0.4.3"
 
 babel-plugin-named-asset-import@^0.3.1:
-  version "0.3.2"
-  resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.2.tgz#20978ed446b8e1bf4a2f42d0a94c0ece85f75f4f"
-  integrity sha512-CxwvxrZ9OirpXQ201Ec57OmGhmI8/ui/GwTDy0hSp6CmRvgRC0pSair6Z04Ck+JStA0sMPZzSJ3uE4n17EXpPQ==
+  version "0.3.4"
+  resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.4.tgz#4a8fc30e9a3e2b1f5ed36883386ab2d84e1089bd"
+  integrity sha512-S6d+tEzc5Af1tKIMbsf2QirCcPdQ+mKUCY2H1nJj1DyA1ShwpsoxEOAwbWsG5gcXNV/olpvQd9vrUWRx4bnhpw==
 
 babel-plugin-react-docgen@^3.0.0:
   version "3.1.0"
@@ -3957,20 +3491,20 @@ babel-preset-jest@^24.9.0:
     babel-plugin-jest-hoist "^24.9.0"
 
 "babel-preset-minify@^0.5.0 || 0.6.0-alpha.5":
-  version "0.5.0"
-  resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.5.0.tgz#e25bb8d3590087af02b650967159a77c19bfb96b"
-  integrity sha512-xj1s9Mon+RFubH569vrGCayA9Fm2GMsCgDRm1Jb8SgctOB7KFcrVc2o8K3YHUyMz+SWP8aea75BoS8YfsXXuiA==
+  version "0.5.1"
+  resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.5.1.tgz#25f5d0bce36ec818be80338d0e594106e21eaa9f"
+  integrity sha512-1IajDumYOAPYImkHbrKeiN5AKKP9iOmRoO2IPbIuVp0j2iuCcj0n7P260z38siKMZZ+85d3mJZdtW8IgOv+Tzg==
   dependencies:
     babel-plugin-minify-builtins "^0.5.0"
     babel-plugin-minify-constant-folding "^0.5.0"
-    babel-plugin-minify-dead-code-elimination "^0.5.0"
+    babel-plugin-minify-dead-code-elimination "^0.5.1"
     babel-plugin-minify-flip-comparisons "^0.4.3"
-    babel-plugin-minify-guarded-expressions "^0.4.3"
+    babel-plugin-minify-guarded-expressions "^0.4.4"
     babel-plugin-minify-infinity "^0.4.3"
     babel-plugin-minify-mangle-names "^0.5.0"
     babel-plugin-minify-numeric-literals "^0.4.3"
     babel-plugin-minify-replace "^0.5.0"
-    babel-plugin-minify-simplify "^0.5.0"
+    babel-plugin-minify-simplify "^0.5.1"
     babel-plugin-minify-type-constructors "^0.4.3"
     babel-plugin-transform-inline-consecutive-adds "^0.4.3"
     babel-plugin-transform-member-expression-literals "^6.9.4"
@@ -3983,30 +3517,28 @@ babel-preset-jest@^24.9.0:
     babel-plugin-transform-remove-undefined "^0.5.0"
     babel-plugin-transform-simplify-comparison-operators "^6.9.4"
     babel-plugin-transform-undefined-to-void "^6.9.4"
-    lodash.isplainobject "^4.0.6"
+    lodash "^4.17.11"
 
 babel-preset-react-app@^9.0.0:
-  version "9.0.0"
-  resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-9.0.0.tgz#703108142bc9dd7173bde6a1a0138a762abc76f9"
-  integrity sha512-YVsDA8HpAKklhFLJtl9+AgaxrDaor8gGvDFlsg1ByOS0IPGUovumdv4/gJiAnLcDmZmKlH6+9sVOz4NVW7emAg==
-  dependencies:
-    "@babel/core" "7.4.3"
-    "@babel/plugin-proposal-class-properties" "7.4.0"
-    "@babel/plugin-proposal-decorators" "7.4.0"
-    "@babel/plugin-proposal-object-rest-spread" "7.4.3"
+  version "9.0.2"
+  resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-9.0.2.tgz#247d37e883d6d6f4b4691e5f23711bb2dd80567d"
+  integrity sha512-aXD+CTH8Chn8sNJr4tO/trWKqe5sSE4hdO76j9fhVezJSzmpWYWUSc5JoPmdSxADwef5kQFNGKXd433vvkd2VQ==
+  dependencies:
+    "@babel/core" "7.6.0"
+    "@babel/plugin-proposal-class-properties" "7.5.5"
+    "@babel/plugin-proposal-decorators" "7.6.0"
+    "@babel/plugin-proposal-object-rest-spread" "7.5.5"
     "@babel/plugin-syntax-dynamic-import" "7.2.0"
-    "@babel/plugin-transform-classes" "7.4.3"
-    "@babel/plugin-transform-destructuring" "7.4.3"
-    "@babel/plugin-transform-flow-strip-types" "7.4.0"
-    "@babel/plugin-transform-react-constant-elements" "7.2.0"
+    "@babel/plugin-transform-destructuring" "7.6.0"
+    "@babel/plugin-transform-flow-strip-types" "7.4.4"
     "@babel/plugin-transform-react-display-name" "7.2.0"
-    "@babel/plugin-transform-runtime" "7.4.3"
-    "@babel/preset-env" "7.4.3"
+    "@babel/plugin-transform-runtime" "7.6.0"
+    "@babel/preset-env" "7.6.0"
     "@babel/preset-react" "7.0.0"
-    "@babel/preset-typescript" "7.3.3"
-    "@babel/runtime" "7.4.3"
-    babel-plugin-dynamic-import-node "2.2.0"
-    babel-plugin-macros "2.5.1"
+    "@babel/preset-typescript" "7.6.0"
+    "@babel/runtime" "7.6.0"
+    babel-plugin-dynamic-import-node "2.3.0"
+    babel-plugin-macros "2.6.1"
     babel-plugin-transform-react-remove-prop-types "0.4.24"
 
 babel-runtime@^6.18.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0:
@@ -4033,9 +3565,9 @@ balanced-match@^1.0.0:
   integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
 
 base64-js@^1.0.2:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3"
-  integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
+  integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
 
 base@^0.11.1:
   version "0.11.2"
@@ -4062,11 +3594,6 @@ bcrypt-pbkdf@^1.0.0:
   dependencies:
     tweetnacl "^0.14.3"
 
-before-after-hook@^1.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.4.0.tgz#2b6bf23dca4f32e628fd2747c10a37c74a4b484d"
-  integrity sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==
-
 before-after-hook@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"
@@ -4077,15 +3604,15 @@ big.js@^5.2.2:
   resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
   integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
 
-bin-links@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.2.tgz#fb74bd54bae6b7befc6c6221f25322ac830d9757"
-  integrity sha512-8eEHVgYP03nILphilltWjeIjMbKyJo3wvp9K816pHbhP301ismzw15mxAAEVQ/USUwcP++1uNrbERbp8lOA6Fg==
+bin-links@^1.1.2, bin-links@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.3.tgz#702fd59552703727313bc624bdbc4c0d3431c2ca"
+  integrity sha512-TEwmH4PHU/D009stP+fkkazMJgkBNCv60z01lQ/Mn8E6+ThHoD03svMnBVuCowwXo2nP2qKyKZxKxp58OHRzxw==
   dependencies:
-    bluebird "^3.5.0"
-    cmd-shim "^2.0.2"
-    gentle-fs "^2.0.0"
-    graceful-fs "^4.1.11"
+    bluebird "^3.5.3"
+    cmd-shim "^3.0.0"
+    gentle-fs "^2.0.1"
+    graceful-fs "^4.1.15"
     write-file-atomic "^2.3.0"
 
 binary-extensions@^1.0.0:
@@ -4100,10 +3627,15 @@ block-stream@*:
   dependencies:
     inherits "~2.0.0"
 
-bluebird@^3.3.5, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3:
-  version "3.5.4"
-  resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.4.tgz#d6cc661595de30d5b3af5fcedd3c0b3ef6ec5714"
-  integrity sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==
+bluebird@^3.3.5, bluebird@^3.5.1, bluebird@^3.5.3:
+  version "3.7.0"
+  resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.0.tgz#56a6a886e03f6ae577cffedeb524f8f2450293cf"
+  integrity sha512-aBQ1FxIa7kSWCcmKHlcHFlT2jt6J/l4FzC7KcPELkOJOsPOb/bccdhmIrKDfXhwFrmc7vDoDrrepFvGqjyXGJg==
+
+bluebird@^3.5.5:
+  version "3.7.1"
+  resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.1.tgz#df70e302b471d7473489acf26a93d63b53f874de"
+  integrity sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==
 
 bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
   version "4.11.8"
@@ -4143,15 +3675,10 @@ boolbase@^1.0.0, boolbase@~1.0.0:
   resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
   integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
 
-bottleneck@^2.0.1:
-  version "2.18.1"
-  resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.18.1.tgz#cf7c494d90283ecbe896baa46a1397ae8b3c19d7"
-  integrity sha512-EhSYARs0MHsNRBPrp1TaeHpgmWFUpA6yl3NNBPjGNilBaQZr4iSbrJ16JbQVXuZkIaB7YVYfaiMiRq7NgyZFQg==
-
 bottleneck@^2.18.1:
-  version "2.19.4"
-  resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.4.tgz#63c505687a0ddaf89a6f515225c75e05833bb079"
-  integrity sha512-2poBdvpAGG+dkMVKZqtDhyuMN6JviD81h89W4bfmt3UO7O60F+qf/84V0alNqL8PM1RByl4SZ1fVMu/ZvxkmcA==
+  version "2.19.5"
+  resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91"
+  integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==
 
 boxen@^1.2.1:
   version "1.3.0"
@@ -4292,32 +3819,14 @@ browserify-zlib@^0.2.0:
   dependencies:
     pako "~1.0.5"
 
-browserslist@4.5.4:
-  version "4.5.4"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.5.4.tgz#166c4ecef3b51737a42436ea8002aeea466ea2c7"
-  integrity sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag==
-  dependencies:
-    caniuse-lite "^1.0.30000955"
-    electron-to-chromium "^1.3.122"
-    node-releases "^1.1.13"
-
-browserslist@^4.5.2, browserslist@^4.6.2, browserslist@^4.6.3:
-  version "4.6.6"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453"
-  integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==
-  dependencies:
-    caniuse-lite "^1.0.30000984"
-    electron-to-chromium "^1.3.191"
-    node-releases "^1.1.25"
-
-browserslist@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.0.tgz#5274028c26f4d933d5b1323307c1d1da5084c9ff"
-  integrity sha512-Jk0YFwXBuMOOol8n6FhgkDzn3mY9PYLYGk29zybF05SbRTsMgPqmTNeQQhOghCxq5oFqAXE3u4sYddr4C0uRhg==
+browserslist@4.7.0, browserslist@^4.6.0, browserslist@^4.6.6, browserslist@^4.7.0:
+  version "4.7.0"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.0.tgz#9ee89225ffc07db03409f2fee524dc8227458a17"
+  integrity sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA==
   dependencies:
-    caniuse-lite "^1.0.30000967"
-    electron-to-chromium "^1.3.133"
-    node-releases "^1.1.19"
+    caniuse-lite "^1.0.30000989"
+    electron-to-chromium "^1.3.247"
+    node-releases "^1.1.29"
 
 bs-logger@0.x:
   version "0.2.6"
@@ -4354,9 +3863,9 @@ buffer-xor@^1.0.3:
   integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
 
 buffer@^4.3.0:
-  version "4.9.1"
-  resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
-  integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=
+  version "4.9.2"
+  resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8"
+  integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==
   dependencies:
     base64-js "^1.0.2"
     ieee754 "^1.1.4"
@@ -4392,22 +3901,23 @@ bytes@3.1.0:
   resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
   integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
 
-cacache@^11.0.1, cacache@^11.3.2:
-  version "11.3.2"
-  resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa"
-  integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==
+cacache@^12.0.0, cacache@^12.0.2, cacache@^12.0.3:
+  version "12.0.3"
+  resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390"
+  integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==
   dependencies:
-    bluebird "^3.5.3"
+    bluebird "^3.5.5"
     chownr "^1.1.1"
     figgy-pudding "^3.5.1"
-    glob "^7.1.3"
+    glob "^7.1.4"
     graceful-fs "^4.1.15"
+    infer-owner "^1.0.3"
     lru-cache "^5.1.1"
     mississippi "^3.0.0"
     mkdirp "^0.5.1"
     move-concurrently "^1.0.1"
     promise-inflight "^1.0.1"
-    rimraf "^2.6.2"
+    rimraf "^2.6.3"
     ssri "^6.0.1"
     unique-filename "^1.1.1"
     y18n "^4.0.0"
@@ -4432,10 +3942,10 @@ cachedir@2.2.0:
   resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.2.0.tgz#19afa4305e05d79e417566882e0c8f960f62ff0e"
   integrity sha512-VvxA0xhNqIIfg0V9AmJkDg91DaJwryutH5rVEZAhcNi4iJFj9f+QxmAjgK1LT9I8OgToX27fypX6/MeCXVbBjQ==
 
-call-limit@~1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.0.tgz#6fd61b03f3da42a2cd0ec2b60f02bd0e71991fea"
-  integrity sha1-b9YbA/PaQqLNDsK2DwK9DnGZH+o=
+call-limit@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4"
+  integrity sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ==
 
 call-me-maybe@^1.0.1:
   version "1.0.1"
@@ -4466,7 +3976,7 @@ callsites@^3.0.0:
   resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
   integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
 
-camel-case@3.0.x:
+camel-case@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
   integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=
@@ -4516,27 +4026,17 @@ can-use-dom@^0.1.0:
   resolved "https://registry.yarnpkg.com/can-use-dom/-/can-use-dom-0.1.0.tgz#22cc4a34a0abc43950f42c6411024a3f6366b45a"
   integrity sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo=
 
-caniuse-lite@^1.0.30000955:
-  version "1.0.30000985"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000985.tgz#0eb40f6c8a8c219155cbe43c4975c0efb4a0f77f"
-  integrity sha512-1ngiwkgqAYPG0JSSUp3PUDGPKKY59EK7NrGGX+VOxaKCNzRbNc7uXMny+c3VJfZxtoK3wSImTvG9T9sXiTw2+w==
-
-caniuse-lite@^1.0.30000967:
-  version "1.0.30000971"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000971.tgz#d1000e4546486a6977756547352bc96a4cfd2b13"
-  integrity sha512-TQFYFhRS0O5rdsmSbF1Wn+16latXYsQJat66f7S7lizXW1PVpWJeZw9wqqVLIjuxDRz7s7xRUj13QCfd8hKn6g==
-
-caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984:
-  version "1.0.30000984"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000984.tgz#dc96c3c469e9bcfc6ad5bdd24c77ec918ea76fe0"
-  integrity sha512-n5tKOjMaZ1fksIpQbjERuqCyfgec/m9pferkFQbLmWtqLUdmt12hNhjSwsmPdqeiG2NkITOQhr1VYIwWSAceiA==
+caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30000998:
+  version "1.0.30000999"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000999.tgz#427253a69ad7bea4aa8d8345687b8eec51ca0e43"
+  integrity sha512-1CUyKyecPeksKwXZvYw0tEoaMCo/RwBlXmEtN5vVnabvO0KPd9RQLcaAuR9/1F+KDMv6esmOFWlsXuzDk+8rxg==
 
 canvas@^2.4.1:
-  version "2.5.0"
-  resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.5.0.tgz#cf0ef59d4790575689c0d50e59c7b8023a11f38a"
-  integrity sha512-wwRz2cLMgb9d+rnotOJCoc04Bzj3aJMpWc6JxAD6lP7bYz0ldcn0sKddoZ0vhD5T8HBxrK+XmRDJb68/2VqARw==
+  version "2.6.0"
+  resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.6.0.tgz#7a8f87b6148845d97e6ee30947fba1508bed4941"
+  integrity sha512-bEO9f1ThmbknLPxCa8Es7obPlN9W3stB1bo7njlhOFKIdUTldeTqXCh9YclCPAi2pSQs84XA0jq/QEZXSzgyMw==
   dependencies:
-    nan "^2.13.2"
+    nan "^2.14.0"
     node-pre-gyp "^0.11.0"
     simple-get "^3.0.3"
 
@@ -4570,20 +4070,11 @@ caseless@~0.12.0:
   resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
   integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
 
-ccount@^1.0.0, ccount@^1.0.3:
+ccount@^1.0.0:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.4.tgz#9cf2de494ca84060a2a8d2854edd6dfb0445f386"
   integrity sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w==
 
-chalk@2.3.1:
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796"
-  integrity sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==
-  dependencies:
-    ansi-styles "^3.2.0"
-    escape-string-regexp "^1.0.5"
-    supports-color "^5.2.0"
-
 chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2:
   version "2.4.2"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -4646,10 +4137,10 @@ cheerio@^1.0.0-rc.2:
     lodash "^4.15.0"
     parse5 "^3.0.1"
 
-chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.6:
-  version "2.1.6"
-  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5"
-  integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==
+chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.8:
+  version "2.1.8"
+  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
+  integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==
   dependencies:
     anymatch "^2.0.0"
     async-each "^1.0.1"
@@ -4665,15 +4156,15 @@ chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.6:
   optionalDependencies:
     fsevents "^1.2.7"
 
-chownr@^1.1.1:
+chownr@^1.1.1, chownr@^1.1.2:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142"
   integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==
 
-chrome-trace-event@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48"
-  integrity sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==
+chrome-trace-event@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4"
+  integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==
   dependencies:
     tslib "^1.9.0"
 
@@ -4717,7 +4208,7 @@ classnames@^2.2.5, classnames@^2.2.6:
   resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
   integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
 
-clean-css@4.2.x:
+clean-css@^4.2.1:
   version "4.2.1"
   resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17"
   integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==
@@ -4725,9 +4216,9 @@ clean-css@4.2.x:
     source-map "~0.6.0"
 
 clean-stack@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.1.0.tgz#9e7fec7f3f8340a2ab4f127c80273085e8fbbdd0"
-  integrity sha512-uQWrpRm+iZZUCAp7ZZJQbd4Za9I3AjR/3YTjmcnAtkauaIm/T5CT6U8zVI6e60T6OANqBFAzuR9/HB3NzuZCRA==
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
+  integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
 
 cli-boxes@^1.0.0:
   version "1.0.0"
@@ -4823,15 +4314,14 @@ clone-deep@^0.2.4:
     lazy-cache "^1.0.3"
     shallow-clone "^0.1.2"
 
-clone-deep@^2.0.1:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-2.0.2.tgz#00db3a1e173656730d1188c3d6aced6d7ea97713"
-  integrity sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==
+clone-deep@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
+  integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
   dependencies:
-    for-own "^1.0.0"
     is-plain-object "^2.0.4"
-    kind-of "^6.0.0"
-    shallow-clone "^1.0.0"
+    kind-of "^6.0.2"
+    shallow-clone "^3.0.0"
 
 clone@^1.0.2:
   version "1.0.4"
@@ -4843,10 +4333,10 @@ clsx@^1.0.1:
   resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.0.4.tgz#0c0171f6d5cb2fe83848463c15fcc26b4df8c2ec"
   integrity sha512-1mQ557MIZTrL/140j+JVdRM6e31/OA4vTYxXgqIIZlndyfjHpyawKZia1Im05Vp9BWmImkcNrNtFYQMyFcgJDg==
 
-cmd-shim@^2.0.2, cmd-shim@~2.0.2:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb"
-  integrity sha1-b8vamUg6j9FdfTChlspp1oii79s=
+cmd-shim@^3.0.0, cmd-shim@^3.0.3:
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-3.0.3.tgz#2c35238d3df37d98ecdd7d5f6b8dc6b21cadc7cb"
+  integrity sha512-DtGg+0xiFhQIntSBRzL2fRQBnmtAVwXIDo4Qq46HPpObYquxMaZS4sb82U9nH91qJrlosC1wa9gwr0QyL/HypA==
   dependencies:
     graceful-fs "^4.1.2"
     mkdirp "~0.5.0"
@@ -4900,12 +4390,7 @@ colors@1.0.3:
   resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
   integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
 
-colors@^1.1.2:
-  version "1.3.3"
-  resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d"
-  integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==
-
-colors@^1.3.3:
+colors@^1.1.2, colors@^1.3.3:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
   integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
@@ -4930,20 +4415,25 @@ comma-separated-tokens@^1.0.0:
   resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz#419cd7fb3258b1ed838dc0953167a25e152f5b59"
   integrity sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ==
 
-commander@2.17.x:
-  version "2.17.1"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
-  integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
-
-commander@^2.11.0, commander@^2.17.1, commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.0:
+commander@2.20.0:
   version "2.20.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
   integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
 
-commander@~2.19.0:
-  version "2.19.0"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
-  integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
+commander@^2.11.0, commander@^2.17.1, commander@^2.19.0:
+  version "2.20.1"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.1.tgz#3863ce3ca92d0831dcf2a102f5fb4b5926afd0f9"
+  integrity sha512-cCuLsMhJeWQ/ZpsFTbE765kvVfoeSddc4nU3up4fV+fDBcfUXnbITJ+JzhkdjzOqhURjZgujxaioam4RM9yGUg==
+
+commander@^2.20.0:
+  version "2.20.3"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
+  integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+
+commander@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e"
+  integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==
 
 commitizen@^4.0.3:
   version "4.0.3"
@@ -5050,11 +4540,9 @@ connect-history-api-fallback@^1.6.0:
   integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
 
 console-browserify@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
-  integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=
-  dependencies:
-    date-now "^0.1.4"
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
+  integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
 
 console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0:
   version "1.1.0"
@@ -5092,40 +4580,40 @@ conventional-changelog-angular@^1.3.3:
     q "^1.5.1"
 
 conventional-changelog-angular@^5.0.0:
-  version "5.0.3"
-  resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.3.tgz#299fdd43df5a1f095283ac16aeedfb0a682ecab0"
-  integrity sha512-YD1xzH7r9yXQte/HF9JBuEDfvjxxwDGGwZU1+ndanbY0oFgA+Po1T9JDSpPLdP0pZT6MhCAsdvFKC4TJ4MTJTA==
+  version "5.0.5"
+  resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.5.tgz#69b541bcf3e538a8578b1e5fbaabe9bd8f572b57"
+  integrity sha512-RrkdWnL/TVyWV1ayWmSsrWorsTDqjL/VwG5ZSEneBQrd65ONcfeA1cW7FLtNweQyMiKOyriCMTKRSlk18DjTrw==
   dependencies:
     compare-func "^1.3.1"
     q "^1.5.1"
 
 conventional-changelog-writer@^4.0.0:
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.3.tgz#916a2b302d0bb5ef18efd236a034c13fb273cde1"
-  integrity sha512-bIlpSiQtQZ1+nDVHEEh798Erj2jhN/wEjyw9sfxY9es6h7pREE5BNJjfv0hXGH/FTrAsEpHUq4xzK99eePpwuA==
+  version "4.0.9"
+  resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.9.tgz#44ac4c48121bc90e71cb2947e1ea1a6c222ccd7f"
+  integrity sha512-2Y3QfiAM37WvDMjkVNaRtZgxVzWKj73HE61YQ/95T53yle+CRwTVSl6Gbv/lWVKXeZcM5af9n9TDVf0k7Xh+cw==
   dependencies:
     compare-func "^1.3.1"
-    conventional-commits-filter "^2.0.1"
+    conventional-commits-filter "^2.0.2"
     dateformat "^3.0.0"
-    handlebars "^4.1.0"
+    handlebars "^4.4.0"
     json-stringify-safe "^5.0.1"
     lodash "^4.2.1"
     meow "^4.0.0"
-    semver "^5.5.0"
+    semver "^6.0.0"
     split "^1.0.0"
-    through2 "^2.0.0"
+    through2 "^3.0.0"
 
 conventional-commit-types@^2.0.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/conventional-commit-types/-/conventional-commit-types-2.1.1.tgz#352eb53f56fbc7c1a6c1ba059c2b6670c90b2a8a"
-  integrity sha512-0Ts+fEdmjqYDOQ1yZ+LNgdSPO335XZw9qC10M7CxtLP3nIMGmeMhmkM8Taffa4+MXN13bRPlp0CtH+QfOzKTzw==
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/conventional-commit-types/-/conventional-commit-types-2.3.0.tgz#bc3c8ebba0a9e4b3ecc548f1d0674e251ab8be22"
+  integrity sha512-6iB39PrcGYdz0n3z31kj6/Km6mK9hm9oMRhwcLnKxE7WNoeRKZbTAobliKrbYZ5jqyCvtcVEfjCiaEzhL3AVmQ==
 
-conventional-commits-filter@^2.0.0, conventional-commits-filter@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.1.tgz#55a135de1802f6510b6758e0a6aa9e0b28618db3"
-  integrity sha512-92OU8pz/977udhBjgPEbg3sbYzIxMDFTlQT97w7KdhR9igNqdJvy8smmedAAgn4tPiqseFloKkrVfbXCVd+E7A==
+conventional-commits-filter@^2.0.0, conventional-commits-filter@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz#f122f89fbcd5bb81e2af2fcac0254d062d1039c1"
+  integrity sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ==
   dependencies:
-    is-subset "^0.1.1"
+    lodash.ismatch "^4.4.0"
     modify-values "^1.0.0"
 
 conventional-commits-parser@^2.1.0:
@@ -5142,16 +4630,16 @@ conventional-commits-parser@^2.1.0:
     trim-off-newlines "^1.0.0"
 
 conventional-commits-parser@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.1.tgz#fe1c49753df3f98edb2285a5e485e11ffa7f2e4c"
-  integrity sha512-P6U5UOvDeidUJ8ebHVDIoXzI7gMlQ1OF/id6oUvp8cnZvOXMt1n8nYl74Ey9YMn0uVQtxmCtjPQawpsssBWtGg==
+  version "3.0.5"
+  resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.5.tgz#df471d6cb3f6fecfd1356ac72e0b577dbdae0a9c"
+  integrity sha512-qVz9+5JwdJzsbt7JbJ6P7NOXBGt8CyLFJYSjKAuPSgO+5UGfcsbk9EMR+lI8Unlvx6qwIc2YDJlrGIfay2ehNA==
   dependencies:
     JSONStream "^1.0.4"
-    is-text-path "^1.0.0"
+    is-text-path "^2.0.0"
     lodash "^4.2.1"
     meow "^4.0.0"
     split2 "^2.0.0"
-    through2 "^2.0.0"
+    through2 "^3.0.0"
     trim-off-newlines "^1.0.0"
 
 convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1:
@@ -5195,33 +4683,18 @@ copy-to-clipboard@^3.0.8:
   dependencies:
     toggle-selection "^1.0.6"
 
-core-js-compat@^3.0.0:
-  version "3.1.4"
-  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.1.4.tgz#e4d0c40fbd01e65b1d457980fe4112d4358a7408"
-  integrity sha512-Z5zbO9f1d0YrJdoaQhphVAnKPimX92D6z8lCGphH89MNRxlL1prI9ExJPqVwP0/kgkQCv8c4GJGT8X16yUncOg==
-  dependencies:
-    browserslist "^4.6.2"
-    core-js-pure "3.1.4"
-    semver "^6.1.1"
-
 core-js-compat@^3.1.1:
-  version "3.1.2"
-  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.1.2.tgz#c29ab9722517094b98622175e2218c3b7398176d"
-  integrity sha512-X0Ch5f6itrHxhg5HSJucX6nNLNAGr+jq+biBh6nPGc3YAWz2a8p/ZIZY8cUkDzSRNG54omAuu3hoEF8qZbu/6Q==
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.2.1.tgz#0cbdbc2e386e8e00d3b85dc81c848effec5b8150"
+  integrity sha512-MwPZle5CF9dEaMYdDeWm73ao/IflDH+FjeJCWEADcEgFSE9TLimFKwJsfmkwzI8eC0Aj0mgvMDjeQjrElkz4/A==
   dependencies:
-    browserslist "^4.6.0"
-    core-js-pure "3.1.2"
-    semver "^6.0.0"
-
-core-js-pure@3.1.2:
-  version "3.1.2"
-  resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.2.tgz#62fc435f35b7374b9b782013cdcb2f97e9f6dffa"
-  integrity sha512-5ckIdBF26B3ldK9PM177y2ZcATP2oweam9RskHSoqfZCrJ2As6wVg8zJ1zTriFsZf6clj/N1ThDFRGaomMsh9w==
+    browserslist "^4.6.6"
+    semver "^6.3.0"
 
-core-js-pure@3.1.4, core-js-pure@^3.0.1:
-  version "3.1.4"
-  resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.4.tgz#5fa17dc77002a169a3566cc48dc774d2e13e3769"
-  integrity sha512-uJ4Z7iPNwiu1foygbcZYJsJs1jiXrTTCvxfLDXNhI/I+NHbSIEyr548y4fcsCEyWY0XgfAG/qqaunJ1SThHenA==
+core-js-pure@^3.0.1:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.2.1.tgz#879a23699cff46175bfd2d09158b5c50645a3c45"
+  integrity sha512-+qpvnYrsi/JDeQTArB7NnNc2VoMYLE1YSkziCDHgjexC2KH7OFiGhLUd3urxfyWmNjSwSW7NYXPWHMhuIJx9Ow==
 
 core-js@^1.0.0:
   version "1.2.7"
@@ -5229,14 +4702,14 @@ core-js@^1.0.0:
   integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
 
 core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5:
-  version "2.6.8"
-  resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.8.tgz#dc3a1e633a04267944e0cb850d3880f340248139"
-  integrity sha512-RWlREFU74TEkdXzyl1bka66O3kYp8jeTXrvJZDzVVMH8AiHUSOFpL1yfhQJ+wHocAm1m+4971W1PPzfLuCv1vg==
+  version "2.6.9"
+  resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
+  integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
 
 core-js@^3.0.1, core-js@^3.0.4:
-  version "3.1.4"
-  resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.1.4.tgz#3a2837fc48e582e1ae25907afcd6cf03b0cc7a07"
-  integrity sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.2.1.tgz#cd41f38534da6cc59f7db050fe67307de9868b09"
+  integrity sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==
 
 core-util-is@1.0.2, core-util-is@~1.0.0:
   version "1.0.2"
@@ -5244,24 +4717,14 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
   integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
 
 corejs-upgrade-webpack-plugin@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/corejs-upgrade-webpack-plugin/-/corejs-upgrade-webpack-plugin-2.1.0.tgz#6afa44672486353ae639c297548c0686b64fb325"
-  integrity sha512-gc+S4t8VT9YFSgOPrhZlD6kDoGZtUq71QwXxS2neGNPhli0veKhbzzilODIpy73TjXGUrCHCpevK8vBnzUPuhw==
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/corejs-upgrade-webpack-plugin/-/corejs-upgrade-webpack-plugin-2.2.0.tgz#503293bf1fdcb104918eb40d0294e4776ad6923a"
+  integrity sha512-J0QMp9GNoiw91Kj/dkIQFZeiCXgXoja/Wlht1SPybxerBWh4NCmb0pOgCv61lrlQZETwvVVfAFAA3IqoEO9aqQ==
   dependencies:
     resolve-from "^5.0.0"
-    webpack "^4.33.0"
-
-cosmiconfig@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc"
-  integrity sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==
-  dependencies:
-    is-directory "^0.3.1"
-    js-yaml "^3.9.0"
-    parse-json "^4.0.0"
-    require-from-string "^2.0.1"
+    webpack "^4.38.0"
 
-cosmiconfig@^5.0.1, cosmiconfig@^5.0.7, cosmiconfig@^5.2.0:
+cosmiconfig@^5.0.0, cosmiconfig@^5.0.1, cosmiconfig@^5.0.7, cosmiconfig@^5.2.0, cosmiconfig@^5.2.1:
   version "5.2.1"
   resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
   integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
@@ -5322,14 +4785,6 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
     safe-buffer "^5.0.1"
     sha.js "^2.4.8"
 
-create-react-context@<=0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.2.tgz#9836542f9aaa22868cd7d4a6f82667df38019dca"
-  integrity sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==
-  dependencies:
-    fbjs "^0.8.0"
-    gud "^1.0.0"
-
 create-react-context@^0.2.1:
   version "0.2.3"
   resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.3.tgz#9ec140a6914a22ef04b8b09b7771de89567cb6f3"
@@ -5338,6 +4793,14 @@ create-react-context@^0.2.1:
     fbjs "^0.8.0"
     gud "^1.0.0"
 
+create-react-context@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c"
+  integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==
+  dependencies:
+    gud "^1.0.0"
+    warning "^4.0.3"
+
 cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
   version "6.0.5"
   resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
@@ -5398,11 +4861,11 @@ crypto-random-string@^1.0.0:
   integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=
 
 css-box-model@^1.1.1:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.1.2.tgz#c0e2c9d23b1b2fd98759706b88cfd4e2c38db727"
-  integrity sha512-pFBTZXDPcr61VZzhZgZaulX1Ot0Q5CfXMjFjbWK5NuzZFsi9H4kBOyEZ9FiBvbe1TimJxIJO4WFsLP4/EBBtkg==
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.0.tgz#3a26377b4162b3200d2ede4b064ec5b6a75186d0"
+  integrity sha512-lri0br+jSNV0kkkiGEp9y9y3Njq2PmpqbeGWRFQJuZteZzY9iC9GZhQ8Y4WpPwM/2YocjHePxy14igJY7YKzkA==
   dependencies:
-    tiny-invariant "^1.0.4"
+    tiny-invariant "^1.0.6"
 
 css-loader@^2.1.0, css-loader@^2.1.1:
   version "2.1.1"
@@ -5446,14 +4909,6 @@ css-select@^2.0.0:
     domutils "^1.7.0"
     nth-check "^1.0.2"
 
-css-tree@1.0.0-alpha.28:
-  version "1.0.0-alpha.28"
-  resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.28.tgz#8e8968190d886c9477bc8d61e96f61af3f7ffa7f"
-  integrity sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==
-  dependencies:
-    mdn-data "~1.1.0"
-    source-map "^0.5.3"
-
 css-tree@1.0.0-alpha.29:
   version "1.0.0-alpha.29"
   resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39"
@@ -5462,10 +4917,13 @@ css-tree@1.0.0-alpha.29:
     mdn-data "~1.1.0"
     source-map "^0.5.3"
 
-css-url-regex@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec"
-  integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=
+css-tree@1.0.0-alpha.33:
+  version "1.0.0-alpha.33"
+  resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.33.tgz#970e20e5a91f7a378ddd0fc58d0b6c8d4f3be93e"
+  integrity sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==
+  dependencies:
+    mdn-data "2.0.4"
+    source-map "^0.5.3"
 
 css-what@2.1, css-what@^2.1.2:
   version "2.1.3"
@@ -5484,39 +4942,22 @@ csso@^3.5.1:
   dependencies:
     css-tree "1.0.0-alpha.29"
 
-cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
+cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@^0.3.4:
   version "0.3.8"
   resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
   integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
 
-cssom@^0.3.4:
-  version "0.3.6"
-  resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.6.tgz#f85206cee04efa841f3c5982a74ba96ab20d65ad"
-  integrity sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==
-
-cssstyle@^1.0.0:
+cssstyle@^1.0.0, cssstyle@^1.1.1:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1"
   integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==
   dependencies:
     cssom "0.3.x"
 
-cssstyle@^1.1.1:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.2.2.tgz#427ea4d585b18624f6fdbf9de7a2a1a3ba713077"
-  integrity sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==
-  dependencies:
-    cssom "0.3.x"
-
-csstype@^2.2.0:
-  version "2.6.4"
-  resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.4.tgz#d585a6062096e324e7187f80e04f92bd0f00e37f"
-  integrity sha512-lAJUJP3M6HxFXbqtGRc0iZrdyeN+WzOWeY0q/VnFzI+kqVrYIzC7bWlKqCW7oCIdzoPkvfp82EVvrTlQ8zsWQg==
-
-csstype@^2.5.2, csstype@^2.5.7:
-  version "2.6.6"
-  resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41"
-  integrity sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==
+csstype@^2.2.0, csstype@^2.5.2, csstype@^2.5.7:
+  version "2.6.7"
+  resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.7.tgz#20b0024c20b6718f4eda3853a1f5a1cce7f5e4a5"
+  integrity sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ==
 
 currently-unhandled@^0.4.1:
   version "0.4.1"
@@ -5533,10 +4974,10 @@ cwd@^0.10.0:
     find-pkg "^0.1.2"
     fs-exists-sync "^0.1.0"
 
-cyclist@~0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
-  integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=
+cyclist@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
+  integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
 
 cz-conventional-changelog@3.0.1:
   version "3.0.1"
@@ -5578,14 +5019,14 @@ d3-collection@1, d3-collection@^1.0.7:
   integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==
 
 d3-color@1:
-  version "1.2.3"
-  resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.2.3.tgz#6c67bb2af6df3cc8d79efcc4d3a3e83e28c8048f"
-  integrity sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.0.tgz#89c45a995ed773b13314f06460df26d60ba0ecaf"
+  integrity sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg==
 
 d3-format@1:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.3.2.tgz#6a96b5e31bcb98122a30863f7d92365c00603562"
-  integrity sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ==
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.1.tgz#c45f74b17c5a290c072a4ba7039dd19662cd5ce6"
+  integrity sha512-TUswGe6hfguUX1CtKxyG2nymO+1lyThbkS1ifLX0Sr+dOQtAD5gkrffpHnx+yHNKUZ0Bmg5T4AjUQwugPDrm0g==
 
 d3-interpolate@1:
   version "1.3.2"
@@ -5595,9 +5036,9 @@ d3-interpolate@1:
     d3-color "1"
 
 d3-path@1:
-  version "1.0.7"
-  resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.7.tgz#8de7cd693a75ac0b5480d3abaccd94793e58aae8"
-  integrity sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==
+  version "1.0.8"
+  resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.8.tgz#4a0606a794d104513ec4a8af43525f374b278719"
+  integrity sha512-J6EfUNwcMQ+aM5YPOB8ZbgAZu6wc82f/0WFxrxwV6Ll8wBwLaHLKCqQ5Imub02JriCVVdPjgI+6P3a4EWJCxAg==
 
 d3-random@^1.1.2:
   version "1.1.2"
@@ -5632,16 +5073,17 @@ d3-time-format@2:
     d3-time "1"
 
 d3-time@1:
-  version "1.0.11"
-  resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.11.tgz#1d831a3e25cd189eb256c17770a666368762bbce"
-  integrity sha512-Z3wpvhPLW4vEScGeIMUckDW7+3hWKOQfAWg/U7PlWBnQmeKQ00gCUsTtWSYulrKNA7ta8hJ+xXc6MHrMuITwEw==
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1"
+  integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==
 
-d@1:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
-  integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=
+d@1, d@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
+  integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
   dependencies:
-    es5-ext "^0.10.9"
+    es5-ext "^0.10.50"
+    type "^1.0.1"
 
 dargs@^4.0.1:
   version "4.1.0"
@@ -5666,17 +5108,12 @@ data-urls@^1.0.0, data-urls@^1.1.0:
     whatwg-mimetype "^2.2.0"
     whatwg-url "^7.0.0"
 
-date-now@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
-  integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=
-
 dateformat@^3.0.0:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
   integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
 
-debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9:
+debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9:
   version "2.6.9"
   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
   integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@@ -5690,7 +5127,7 @@ debug@3.1.0:
   dependencies:
     ms "2.0.0"
 
-debug@^3.1.0, debug@^3.2.5, debug@^3.2.6:
+debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
   version "3.2.6"
   resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
   integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
@@ -5727,12 +5164,12 @@ decode-uri-component@^0.2.0:
   resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
   integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
 
-decompress-response@^3.3.0:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
-  integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
+decompress-response@^4.2.0:
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986"
+  integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==
   dependencies:
-    mimic-response "^1.0.0"
+    mimic-response "^2.0.0"
 
 dedent@0.7.0:
   version "0.7.0"
@@ -5740,9 +5177,16 @@ dedent@0.7.0:
   integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
 
 deep-equal@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
-  integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
+  integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==
+  dependencies:
+    is-arguments "^1.0.4"
+    is-date-object "^1.0.1"
+    is-regex "^1.0.4"
+    object-is "^1.0.1"
+    object-keys "^1.1.1"
+    regexp.prototype.flags "^1.2.0"
 
 deep-extend@^0.6.0:
   version "0.6.0"
@@ -5759,11 +5203,6 @@ deep-object-diff@^1.1.0:
   resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.0.tgz#d6fabf476c2ed1751fc94d5ca693d2ed8c18bc5a"
   integrity sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw==
 
-deepmerge@3.2.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.0.tgz#58ef463a57c08d376547f8869fdc5bcee957f44e"
-  integrity sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow==
-
 default-gateway@^4.2.0:
   version "4.2.0"
   resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b"
@@ -5847,14 +5286,14 @@ dependency-graph@^0.8.0:
   integrity sha512-DCvzSq2UiMsuLnj/9AL484ummEgLtZIcRS7YvtO38QnpX3vqh9nJ8P+zhu8Ja+SmLrBHO2iDbva20jq38qvBkQ==
 
 deprecation@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.0.0.tgz#dd0427cd920c78bc575ec39dab2f22e7c304fb9d"
-  integrity sha512-lbQN037mB3VfA2JFuguM5GCJ+zPinMeCrFe+AfSZ6eqrnJA/Fs+EYMnd6Nb2mn9lf2jO9xwEd9o9lic+D4vkcw==
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
+  integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
 
 des.js@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc"
-  integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
+  integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==
   dependencies:
     inherits "^2.0.1"
     minimalistic-assert "^1.0.0"
@@ -5940,7 +5379,7 @@ dir-glob@2.0.0:
     arrify "^1.0.1"
     path-type "^3.0.0"
 
-dir-glob@^2.0.0, dir-glob@^2.2.2:
+dir-glob@^2.2.2:
   version "2.2.2"
   resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4"
   integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==
@@ -6024,7 +5463,15 @@ dom-converter@^0.2:
   dependencies:
     "@babel/runtime" "^7.1.2"
 
-dom-serializer@0, dom-serializer@~0.1.1:
+dom-serializer@0:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.1.tgz#13650c850daffea35d8b626a4cfc4d3a17643fdb"
+  integrity sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==
+  dependencies:
+    domelementtype "^2.0.1"
+    entities "^2.0.0"
+
+dom-serializer@~0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0"
   integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
@@ -6047,6 +5494,11 @@ domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1:
   resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
   integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
 
+domelementtype@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d"
+  integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==
+
 domexception@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
@@ -6121,9 +5573,9 @@ dotenv@^6.2.0:
   integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==
 
 dotenv@^8.0.0:
-  version "8.0.0"
-  resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.0.0.tgz#ed310c165b4e8a97bb745b0a9d99c31bda566440"
-  integrity sha512-30xVGqjLjiUOArT4+M5q9sYdvuR4riM6yK9wMcas9Vbp6zZa+ocC9dp6QoftuhTPhFAiLK/0C5Ni2nou/Bk8lg==
+  version "8.1.0"
+  resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.1.0.tgz#d811e178652bfb8a1e593c6dd704ec7e90d85ea2"
+  integrity sha512-GUE3gqcDCaMltj2++g6bRQ5rBJWtkWTmqmD0fo1RnnMuUqHNCt2oTPeDnS9n6fKYvlhn7AeBkb38lymBtWBQdA==
 
 duplexer2@~0.1.0:
   version "0.1.4"
@@ -6171,29 +5623,19 @@ ee-first@1.1.1:
   integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
 
 ejs@^2.6.1:
-  version "2.6.1"
-  resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
-  integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==
-
-electron-to-chromium@^1.3.122:
-  version "1.3.200"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.200.tgz#78fb858b466269e8eb46d31a52562f00c865127f"
-  integrity sha512-PUurrpyDA74MuAjJRD+79ss5BqJlU3mdArRbuu4wO/dt6jc3Ic/6BDmFJxkdwbfq39cHf/XKm2vW98XSvut9Dg==
-
-electron-to-chromium@^1.3.133:
-  version "1.3.136"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.136.tgz#758a156109077536780cfa8207b1aeaa99843e33"
-  integrity sha512-xHkYkbEi4kI+2w5v6yBGCQTRXL7N0PWscygTFZu/1bArnPSo2WR9xjdw4m06RR4J5PncrWJcuOVv+MAG2mK5JQ==
+  version "2.7.1"
+  resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228"
+  integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ==
 
-electron-to-chromium@^1.3.191:
-  version "1.3.193"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.193.tgz#de9b89959288070bffb14557daf8cf9f75b2caf8"
-  integrity sha512-WX01CG1UoPtTUFaKKwMn+u8nJ63loP6hNxePWtk1pN8ibWMyX1q6TiWPsz1ABBKXezvmaIdtP+0BwzjC1wyCaw==
+electron-to-chromium@^1.3.247:
+  version "1.3.280"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.280.tgz#5f8950c8329e3e11b59c705fd59b4b8d9b3de5b9"
+  integrity sha512-qYWNMjKLEfQAWZF2Sarvo+ahigu0EArnpCFSoUuZJS3W5wIeVfeEvsgmT2mgIrieQkeQ0+xFmykK3nx2ezekPQ==
 
 elliptic@^6.0.0:
-  version "6.4.1"
-  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a"
-  integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==
+  version "6.5.1"
+  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.1.tgz#c380f5f909bf1b9b4428d028cd18d3b0efd6b52b"
+  integrity sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==
   dependencies:
     bn.js "^4.4.0"
     brorand "^1.0.1"
@@ -6214,12 +5656,12 @@ emojis-list@^2.0.0:
   integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
 
 emotion-theming@^10.0.10, emotion-theming@^10.0.9:
-  version "10.0.14"
-  resolved "https://registry.yarnpkg.com/emotion-theming/-/emotion-theming-10.0.14.tgz#e548d388493d07bedbb0d9d3bbe221766174b1f4"
-  integrity sha512-zMGhPSYz48AAR6DYjQVaZHeO42cYKPq4VyB1XjxzgR62/NmO99679fx8qDDB1QZVYGkRWZtsOe+zJE/e30XdbA==
+  version "10.0.19"
+  resolved "https://registry.yarnpkg.com/emotion-theming/-/emotion-theming-10.0.19.tgz#66d13db74fccaefad71ba57c915b306cf2250295"
+  integrity sha512-dQRBPLAAQ6eA8JKhkLCIWC8fdjPbiNC1zNTdFF292h9amhZXofcNGUP7axHoHX4XesqQESYwZrXp53OPInMrKw==
   dependencies:
-    "@babel/runtime" "^7.4.3"
-    "@emotion/weak-memoize" "0.2.3"
+    "@babel/runtime" "^7.5.5"
+    "@emotion/weak-memoize" "0.2.4"
     hoist-non-react-statics "^3.3.0"
 
 emotion@^9.1.2:
@@ -6242,21 +5684,14 @@ encoding@^0.1.11:
   dependencies:
     iconv-lite "~0.4.13"
 
-end-of-stream@^1.0.0:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
-  integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==
-  dependencies:
-    once "^1.4.0"
-
-end-of-stream@^1.1.0:
+end-of-stream@^1.0.0, end-of-stream@^1.1.0:
   version "1.4.4"
   resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
   integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
   dependencies:
     once "^1.4.0"
 
-enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0:
+enhanced-resolve@4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f"
   integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==
@@ -6265,32 +5700,52 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0:
     memory-fs "^0.4.0"
     tapable "^1.0.0"
 
+enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66"
+  integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==
+  dependencies:
+    graceful-fs "^4.1.2"
+    memory-fs "^0.5.0"
+    tapable "^1.0.0"
+
 entities@^1.1.1, entities@~1.1.1:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
   integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
 
+entities@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
+  integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
+
 env-ci@^4.0.0:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/env-ci/-/env-ci-4.1.1.tgz#b8438fc7258a0dc7a4f4c4816de730767946a718"
-  integrity sha512-eTgpkALDeYRGNhYM2fO9LKsWDifoUgKL7hxpPZqFMP2IU7f+r89DtKqCmk3yQB/jxS8CmZTfKnWO5TiIDFs9Hw==
+  version "4.5.0"
+  resolved "https://registry.yarnpkg.com/env-ci/-/env-ci-4.5.0.tgz#96fdb4fde14cfc16b70126da1be7853440e0d6ec"
+  integrity sha512-0b5ihp/O/tsxWvzEY/Ags+3SL+F9eFci9ZF2Mqx/NHYCaV3cfpoPZW8qx1fcQAHOjWD9wSWsByewzimvGar/4Q==
   dependencies:
     execa "^1.0.0"
     java-properties "^1.0.0"
 
+env-paths@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0"
+  integrity sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=
+
 enzyme-adapter-react-16@^1.10.0:
-  version "1.13.1"
-  resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.13.1.tgz#2e8ee300e38674b9914ae52b04af9493050355e2"
-  integrity sha512-DCKbkiVlfLTbn4SXO8mXDQx1SmmwON5oKXn2QfQSMCt8eTYGwUXy/OBGSuss6KKwY5w5QfK1sQFxhgFOkMCjrw==
+  version "1.15.0"
+  resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.0.tgz#f7f72ab13b6596f944918c60f42e4ce38d890860"
+  integrity sha512-p5k5TAG9hiyFNgJ7ABkfg5Poc3Gp5D2uArDEv7BW/FE0AflqIRfHFi4G3Ei+MpPuwy5Ao+ZisYWKuxC5LRCr1Q==
   dependencies:
     enzyme-adapter-utils "^1.12.0"
+    enzyme-shallow-equal "^1.0.0"
     has "^1.0.3"
     object.assign "^4.1.0"
     object.values "^1.1.0"
     prop-types "^15.7.2"
     react-is "^16.8.6"
     react-test-renderer "^16.0.0-0"
-    semver "^5.6.0"
+    semver "^5.7.0"
 
 enzyme-adapter-utils@^1.12.0:
   version "1.12.0"
@@ -6304,10 +5759,18 @@ enzyme-adapter-utils@^1.12.0:
     prop-types "^15.7.2"
     semver "^5.6.0"
 
+enzyme-shallow-equal@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.0.tgz#d8e4603495e6ea279038eef05a4bf4887b55dc69"
+  integrity sha512-VUf+q5o1EIv2ZaloNQQtWCJM9gpeux6vudGVH6vLmfPXFLRuxl5+Aq3U260wof9nn0b0i+P5OEUXm1vnxkRpXQ==
+  dependencies:
+    has "^1.0.3"
+    object-is "^1.0.1"
+
 enzyme@^3.9.0:
-  version "3.9.0"
-  resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.9.0.tgz#2b491f06ca966eb56b6510068c7894a7e0be3909"
-  integrity sha512-JqxI2BRFHbmiP7/UFqvsjxTirWoM1HfeaJrmVSZ9a1EADKkZgdPcAuISPMpoUiHlac9J4dYt81MC5BBIrbJGMg==
+  version "3.10.0"
+  resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.10.0.tgz#7218e347c4a7746e133f8e964aada4a3523452f6"
+  integrity sha512-p2yy9Y7t/PFbPoTvrWde7JIYB2ZyGC+NgTNbVEGvZ5/EyoYSr9aG/2rSbVvyNvMHEhw9/dmGUJHWtfQIEiX9pg==
   dependencies:
     array.prototype.flat "^1.2.1"
     cheerio "^1.0.0-rc.2"
@@ -6350,22 +5813,10 @@ error-ex@^1.2.0, error-ex@^1.3.1:
   dependencies:
     is-arrayish "^0.2.1"
 
-es-abstract@^1.10.0, es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.13.0, es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.7.0, es-abstract@^1.9.0:
-  version "1.13.0"
-  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9"
-  integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==
-  dependencies:
-    es-to-primitive "^1.2.0"
-    function-bind "^1.1.1"
-    has "^1.0.3"
-    is-callable "^1.1.4"
-    is-regex "^1.0.4"
-    object-keys "^1.0.12"
-
-es-abstract@^1.5.1:
-  version "1.14.2"
-  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.14.2.tgz#7ce108fad83068c8783c3cdf62e504e084d8c497"
-  integrity sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==
+es-abstract@^1.10.0, es-abstract@^1.12.0, es-abstract@^1.13.0, es-abstract@^1.14.2, es-abstract@^1.15.0, es-abstract@^1.4.3, es-abstract@^1.5.1, es-abstract@^1.7.0:
+  version "1.15.0"
+  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.15.0.tgz#8884928ec7e40a79e3c9bc812d37d10c8b24cc57"
+  integrity sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==
   dependencies:
     es-to-primitive "^1.2.0"
     function-bind "^1.1.1"
@@ -6375,8 +5826,8 @@ es-abstract@^1.5.1:
     is-regex "^1.0.4"
     object-inspect "^1.6.0"
     object-keys "^1.1.1"
-    string.prototype.trimleft "^2.0.0"
-    string.prototype.trimright "^2.0.0"
+    string.prototype.trimleft "^2.1.0"
+    string.prototype.trimright "^2.1.0"
 
 es-to-primitive@^1.2.0:
   version "1.2.0"
@@ -6387,10 +5838,10 @@ es-to-primitive@^1.2.0:
     is-date-object "^1.0.1"
     is-symbol "^1.0.2"
 
-es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14:
-  version "0.10.50"
-  resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778"
-  integrity sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==
+es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@^0.10.51:
+  version "0.10.51"
+  resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.51.tgz#ed2d7d9d48a12df86e0299287e93a09ff478842f"
+  integrity sha512-oRpWzM2WcLHVKpnrcyB7OW8j/s67Ba04JCm0WnNv3RiABSvs7mrQlutB8DBv793gKcp0XENR8Il8WxGTlZ73gQ==
   dependencies:
     es6-iterator "~2.0.3"
     es6-symbol "~3.1.1"
@@ -6411,9 +5862,9 @@ es6-iterator@~2.0.3:
     es6-symbol "^3.1.1"
 
 es6-promise@^4.0.3:
-  version "4.2.6"
-  resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f"
-  integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==
+  version "4.2.8"
+  resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
+  integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
 
 es6-promisify@^5.0.0:
   version "5.0.0"
@@ -6428,12 +5879,12 @@ es6-shim@^0.35.5:
   integrity sha512-E9kK/bjtCQRpN1K28Xh4BlmP8egvZBGJJ+9GtnzOwt7mdqtrjHFuVGr7QJfdjBIKqrlU5duPf3pCBoDrkjVYFg==
 
 es6-symbol@^3.1.1, es6-symbol@~3.1.1:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
-  integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.2.tgz#859fdd34f32e905ff06d752e7171ddd4444a7ed1"
+  integrity sha512-/ZypxQsArlv+KHpGvng52/Iz8by3EQPxhmbuz8yFG89N/caTFBSbcXONDw0aMjy827gQg26XAjP4uXFvnfINmQ==
   dependencies:
-    d "1"
-    es5-ext "~0.10.14"
+    d "^1.0.1"
+    es5-ext "^0.10.51"
 
 escape-html@^1.0.3, escape-html@~1.0.3:
   version "1.0.3"
@@ -6445,19 +5896,7 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
   integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
 
-escodegen@^1.11.0:
-  version "1.11.1"
-  resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510"
-  integrity sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==
-  dependencies:
-    esprima "^3.1.3"
-    estraverse "^4.2.0"
-    esutils "^2.0.2"
-    optionator "^0.8.1"
-  optionalDependencies:
-    source-map "~0.6.1"
-
-escodegen@^1.9.1:
+escodegen@^1.11.0, escodegen@^1.9.1:
   version "1.12.0"
   resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541"
   integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==
@@ -6485,17 +5924,17 @@ eslint-import-resolver-node@^0.3.2:
     resolve "^1.5.0"
 
 eslint-module-utils@^2.4.0:
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz#8b93499e9b00eab80ccb6614e69f03678e84e09a"
-  integrity sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==
+  version "2.4.1"
+  resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz#7b4675875bf96b0dbf1b21977456e5bb1f5e018c"
+  integrity sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==
   dependencies:
     debug "^2.6.8"
     pkg-dir "^2.0.0"
 
 eslint-plugin-import@^2.17.3:
-  version "2.17.3"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.17.3.tgz#00548b4434c18faebaba04b24ae6198f280de189"
-  integrity sha512-qeVf/UwXFJbeyLbxuY8RgqDyEKCkqV7YC+E5S5uOjAp4tOc8zj01JP3ucoBM8JcEqd1qRasJSg6LLlisirfy0Q==
+  version "2.18.2"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6"
+  integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==
   dependencies:
     array-includes "^3.0.3"
     contains-path "^0.1.0"
@@ -6504,35 +5943,39 @@ eslint-plugin-import@^2.17.3:
     eslint-import-resolver-node "^0.3.2"
     eslint-module-utils "^2.4.0"
     has "^1.0.3"
-    lodash "^4.17.11"
     minimatch "^3.0.4"
+    object.values "^1.1.0"
     read-pkg-up "^2.0.0"
     resolve "^1.11.0"
 
 eslint-plugin-jest@^22.6.4:
-  version "22.6.4"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.6.4.tgz#2895b047dd82f90f43a58a25cf136220a21c9104"
-  integrity sha512-36OqnZR/uMCDxXGmTsqU4RwllR0IiB/XF8GW3ODmhsjiITKuI0GpgultWFt193ipN3HARkaIcKowpE6HBvRHNg==
+  version "22.17.0"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.17.0.tgz#dc170ec8369cd1bff9c5dd8589344e3f73c88cf6"
+  integrity sha512-WT4DP4RoGBhIQjv+5D0FM20fAdAUstfYAf/mkufLNTojsfgzc5/IYW22cIg/Q4QBavAZsROQlqppiWDpFZDS8Q==
+  dependencies:
+    "@typescript-eslint/experimental-utils" "^1.13.0"
 
 eslint-plugin-prettier@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz#8695188f95daa93b0dc54b249347ca3b79c4686d"
-  integrity sha512-XWX2yVuwVNLOUhQijAkXz+rMPPoCr7WFiAl8ig6I7Xn+pPVhDhzg4DxHpmbeb0iqjO9UronEA3Tb09ChnFVHHA==
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.1.tgz#507b8562410d02a03f0ddc949c616f877852f2ba"
+  integrity sha512-A+TZuHZ0KU0cnn56/9mfR7/KjUJ9QNVXUhwvRFSR7PGPe0zQR6PTkmyqg1AtUUEOzTqeRsUwyKFh0oVZKVCrtA==
   dependencies:
     prettier-linter-helpers "^1.0.0"
 
 eslint-plugin-react@^7.13.0:
-  version "7.13.0"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.13.0.tgz#bc13fd7101de67996ea51b33873cd9dc2b7e5758"
-  integrity sha512-uA5LrHylu8lW/eAH3bEQe9YdzpPaFd9yAJTwTi/i/BKTD7j6aQMKVAdGM/ML72zD6womuSK7EiGtMKuK06lWjQ==
+  version "7.16.0"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.16.0.tgz#9928e4f3e2122ed3ba6a5b56d0303ba3e41d8c09"
+  integrity sha512-GacBAATewhhptbK3/vTP09CbFrgUJmBSaaRcWdbQLFvUZy9yVcQxigBNHGPU/KE2AyHpzj3AWXpxoMTsIDiHug==
   dependencies:
     array-includes "^3.0.3"
     doctrine "^2.1.0"
     has "^1.0.3"
-    jsx-ast-utils "^2.1.0"
+    jsx-ast-utils "^2.2.1"
+    object.entries "^1.1.0"
     object.fromentries "^2.0.0"
+    object.values "^1.1.0"
     prop-types "^15.7.2"
-    resolve "^1.10.1"
+    resolve "^1.12.0"
 
 eslint-scope@^4.0.0, eslint-scope@^4.0.3:
   version "4.0.3"
@@ -6548,26 +5991,16 @@ eslint-scope@^5.0.0:
   integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==
   dependencies:
     esrecurse "^4.1.0"
-    estraverse "^4.1.1"
-
-eslint-utils@^1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512"
-  integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==
+    estraverse "^4.1.1"
 
-eslint-utils@^1.4.2:
+eslint-utils@^1.3.1, eslint-utils@^1.4.2:
   version "1.4.2"
   resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab"
   integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==
   dependencies:
     eslint-visitor-keys "^1.0.0"
 
-eslint-visitor-keys@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
-  integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==
-
-eslint-visitor-keys@^1.1.0:
+eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
   integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
@@ -6647,22 +6080,12 @@ esrecurse@^4.1.0:
   dependencies:
     estraverse "^4.1.0"
 
-estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
-  integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=
-
-estraverse@^4.2.0:
+estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
   version "4.3.0"
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
   integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
 
-esutils@^2.0.0:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
-  integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=
-
-esutils@^2.0.2:
+esutils@^2.0.0, esutils@^2.0.2:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
   integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
@@ -6672,11 +6095,16 @@ etag@~1.8.1:
   resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
   integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
 
-eventemitter3@^3.0.0, eventemitter3@^3.1.0:
+eventemitter3@^3.1.0:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
   integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==
 
+eventemitter3@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb"
+  integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==
+
 events@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88"
@@ -6728,7 +6156,7 @@ execa@^1.0.0:
     signal-exit "^3.0.0"
     strip-eof "^1.0.0"
 
-execa@^2.1.0:
+execa@^2.0.2, execa@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/execa/-/execa-2.1.0.tgz#e5d3ecd837d2a60ec50f3da78fd39767747bbe99"
   integrity sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==
@@ -6792,10 +6220,10 @@ expect@^24.1.0, expect@^24.9.0:
     jest-message-util "^24.9.0"
     jest-regex-util "^24.9.0"
 
-express@^4.17.0:
-  version "4.17.0"
-  resolved "https://registry.yarnpkg.com/express/-/express-4.17.0.tgz#288af62228a73f4c8ea2990ba3b791bb87cd4438"
-  integrity sha512-1Z7/t3Z5ZnBG252gKUPyItc4xdeaA0X934ca2ewckAsVsw9EG71i++ZHZPYnus8g/s5Bty8IMpSVEuRkmwwPRQ==
+express@^4.17.0, express@^4.17.1:
+  version "4.17.1"
+  resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
+  integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==
   dependencies:
     accepts "~1.3.7"
     array-flatten "1.1.1"
@@ -6849,9 +6277,9 @@ extend@^3.0.0, extend@~3.0.2:
   integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
 
 external-editor@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27"
-  integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
+  integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==
   dependencies:
     chardet "^0.7.0"
     iconv-lite "^0.4.24"
@@ -6914,15 +6342,14 @@ fast-glob@^2.0.2, fast-glob@^2.2.6:
     micromatch "^3.1.10"
 
 fast-glob@^3.0.3:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.0.4.tgz#d484a41005cb6faeb399b951fd1bd70ddaebb602"
-  integrity sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.1.0.tgz#77375a7e3e6f6fc9b18f061cddd28b8d1eec75ae"
+  integrity sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==
   dependencies:
-    "@nodelib/fs.stat" "^2.0.1"
-    "@nodelib/fs.walk" "^1.2.1"
-    glob-parent "^5.0.0"
-    is-glob "^4.0.1"
-    merge2 "^1.2.3"
+    "@nodelib/fs.stat" "^2.0.2"
+    "@nodelib/fs.walk" "^1.2.3"
+    glob-parent "^5.1.0"
+    merge2 "^1.3.0"
     micromatch "^4.0.2"
 
 fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0:
@@ -6957,9 +6384,9 @@ faye-websocket@^0.10.0:
     websocket-driver ">=0.5.1"
 
 faye-websocket@~0.11.1:
-  version "0.11.1"
-  resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38"
-  integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=
+  version "0.11.3"
+  resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
+  integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==
   dependencies:
     websocket-driver ">=0.5.1"
 
@@ -7068,7 +6495,7 @@ finalhandler@~1.1.2:
     statuses "~1.5.0"
     unpipe "~1.0.0"
 
-find-cache-dir@^2.0.0:
+find-cache-dir@^2.0.0, find-cache-dir@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
   integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==
@@ -7166,17 +6593,7 @@ find-versions@^3.0.0:
     array-uniq "^2.1.0"
     semver-regex "^2.0.0"
 
-findup-sync@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc"
-  integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=
-  dependencies:
-    detect-file "^1.0.0"
-    is-glob "^3.1.0"
-    micromatch "^3.0.4"
-    resolve-dir "^1.0.1"
-
-findup-sync@^3.0.0:
+findup-sync@3.0.0, findup-sync@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1"
   integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==
@@ -7196,9 +6613,9 @@ flat-cache@^2.0.1:
     write "1.0.3"
 
 flatted@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916"
-  integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08"
+  integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==
 
 flush-write-stream@^1.0.0:
   version "1.1.1"
@@ -7209,16 +6626,16 @@ flush-write-stream@^1.0.0:
     readable-stream "^2.3.6"
 
 focus-lock@^0.6.3:
-  version "0.6.4"
-  resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.6.4.tgz#066af3ed5875d85745ab45ef4fbbb43e8a73514a"
-  integrity sha512-+waElh6m7dbNmEabXQIblZjJMIRQOoHMNqB8RZkyemK+vN1XQ9uHLi740DVwTcK5fzAq3g+tBglLjIqUDHX/Og==
+  version "0.6.5"
+  resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.6.5.tgz#f6eb37832a9b1b205406175f5277396a28c0fce1"
+  integrity sha512-i/mVBOoa9o+tl+u9owOJUF8k8L85odZNIsctB+JAK2HFT8jckiBwmk+3uydlm6FN8czgnkIwQtBv6yyAbrzXjw==
 
 follow-redirects@^1.0.0:
-  version "1.7.0"
-  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76"
-  integrity sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.9.0.tgz#8d5bcdc65b7108fe1508649c79c12d732dcedb4f"
+  integrity sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==
   dependencies:
-    debug "^3.2.6"
+    debug "^3.0.0"
 
 for-in@^0.1.3:
   version "0.1.8"
@@ -7237,22 +6654,15 @@ for-own@^0.1.3:
   dependencies:
     for-in "^1.0.1"
 
-for-own@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b"
-  integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=
-  dependencies:
-    for-in "^1.0.1"
-
 forever-agent@~0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
   integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
 
-fork-ts-checker-webpack-plugin@1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-1.1.1.tgz#caf2a210778fb1e171b6993ca0a40f9b6589e3b7"
-  integrity sha512-gqWAEMLlae/oeVnN6RWCAhesOJMswAN1MaKNqhhjXHV5O0/rTUjWI4UbgQHdlrVbCnb+xLotXmJbBlC66QmpFw==
+fork-ts-checker-webpack-plugin@1.5.0:
+  version "1.5.0"
+  resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-1.5.0.tgz#ce1d77190b44d81a761b10b6284a373795e41f0c"
+  integrity sha512-zEhg7Hz+KhZlBhILYpXy+Beu96gwvkROWJiTXOCyOOMMrdBIRPvsBpBqgTI4jfJGrJXcqGwJR8zsBGDmzY0jsA==
   dependencies:
     babel-code-frame "^6.22.0"
     chalk "^2.4.1"
@@ -7282,10 +6692,10 @@ forwarded@~0.1.2:
   resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
   integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
 
-fp-ts@^1.0.0, fp-ts@^1.14.2:
-  version "1.18.2"
-  resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.18.2.tgz#b9a7025174e1a59bc43b485b3a0ca6f78e371d01"
-  integrity sha512-kznerusCuG5dUt0bH6eiQHVp2fstPiSlyzGb//rYgMMxCuromWEoVS0riH++86vyJm9Nv1B+pbe6udDx1tqjfA==
+fp-ts@^1.0.0:
+  version "1.19.5"
+  resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a"
+  integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A==
 
 fragment-cache@^0.2.1:
   version "0.2.1"
@@ -7307,7 +6717,7 @@ from2@^1.3.0:
     inherits "~2.0.1"
     readable-stream "~1.1.10"
 
-from2@^2.1.0, from2@^2.1.1, from2@^2.3.0:
+from2@^2.1.0, from2@^2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
   integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=
@@ -7403,20 +6813,26 @@ function-bind@^1.0.2, function-bind@^1.1.1:
   resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
   integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
 
-function.prototype.name@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
-  integrity sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg==
+function.prototype.name@^1.1.0, function.prototype.name@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.1.tgz#6d252350803085abc2ad423d4fe3be2f9cbda392"
+  integrity sha512-e1NzkiJuw6xqVH7YSdiW/qDHebcmMhPNe6w+4ZYYEg0VA+LaLzx37RimbPLuonHhYGFGPx1ME2nSi74JiaCr/Q==
   dependencies:
-    define-properties "^1.1.2"
+    define-properties "^1.1.3"
     function-bind "^1.1.1"
-    is-callable "^1.1.3"
+    functions-have-names "^1.1.1"
+    is-callable "^1.1.4"
 
 functional-red-black-tree@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
   integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
 
+functions-have-names@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.1.1.tgz#79d35927f07b8e7103d819fed475b64ccf7225ea"
+  integrity sha512-U0kNHUoxwPNPWOJaMG7Z00d4a/qZVrFtzWJRaK8V9goaVOCXBSQSJpt3MYGNtkScKEBKovxLjnNdC9MlXwo5Pw==
+
 fuse.js@^3.4.4:
   version "3.4.5"
   resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.5.tgz#8954fb43f9729bd5dbcb8c08f251db552595a7a6"
@@ -7448,15 +6864,17 @@ genfun@^5.0.0:
   resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537"
   integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==
 
-gentle-fs@^2.0.0, gentle-fs@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.0.1.tgz#585cfd612bfc5cd52471fdb42537f016a5ce3687"
-  integrity sha512-cEng5+3fuARewXktTEGbwsktcldA+YsnUEaXZwcK/3pjSE1X9ObnTs+/8rYf8s+RnIcQm2D5x3rwpN7Zom8Bew==
+gentle-fs@^2.0.1, gentle-fs@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.2.1.tgz#1f38df4b4ead685566257201fd526de401ebb215"
+  integrity sha512-e7dRgUM5fsS+7wm2oggZpgcRx6sEvJHXujPH5RzgQ1ziQY4+HuVBYsnUzJwJ+C7mjOJN27DjiFy1TaL+TNltow==
   dependencies:
     aproba "^1.1.2"
+    chownr "^1.1.2"
     fs-vacuum "^1.2.10"
     graceful-fs "^4.1.11"
     iferr "^0.1.5"
+    infer-owner "^1.0.4"
     mkdirp "^0.5.1"
     path-is-inside "^1.0.2"
     read-cmd-shim "^1.0.1"
@@ -7472,11 +6890,6 @@ get-caller-file@^2.0.1:
   resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
   integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
 
-get-own-enumerable-property-symbols@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203"
-  integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==
-
 get-stdin@7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6"
@@ -7559,10 +6972,10 @@ glob-parent@^3.1.0:
     is-glob "^3.1.0"
     path-dirname "^1.0.0"
 
-glob-parent@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954"
-  integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==
+glob-parent@^5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2"
+  integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==
   dependencies:
     is-glob "^4.0.1"
 
@@ -7571,7 +6984,7 @@ glob-to-regexp@^0.3.0:
   resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
   integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=
 
-glob@7.1.4, glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1:
+glob@7.1.4, glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1:
   version "7.1.4"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
   integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
@@ -7583,6 +6996,18 @@ glob@7.1.4, glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glo
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
+glob@^7.0.3, glob@^7.1.3, glob@^7.1.4:
+  version "7.1.6"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
+  integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
+  dependencies:
+    fs.realpath "^1.0.0"
+    inflight "^1.0.4"
+    inherits "2"
+    minimatch "^3.0.4"
+    once "^1.3.0"
+    path-is-absolute "^1.0.0"
+
 global-dirs@^0.1.0, global-dirs@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445"
@@ -7645,12 +7070,12 @@ global-prefix@^3.0.0:
     which "^1.3.1"
 
 global@^4.3.2:
-  version "4.3.2"
-  resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
-  integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=
+  version "4.4.0"
+  resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
+  integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
   dependencies:
     min-document "^2.19.0"
-    process "~0.5.1"
+    process "^0.11.10"
 
 globals@^11.1.0, globals@^11.7.0:
   version "11.12.0"
@@ -7757,20 +7182,15 @@ got@^6.7.1:
     url-parse-lax "^1.0.0"
 
 graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2:
+  version "4.2.3"
+  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
+  integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
+
+graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2:
   version "4.2.2"
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
   integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
 
-graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
-  version "4.1.15"
-  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
-  integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
-
-graceful-fs@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b"
-  integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==
-
 growly@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
@@ -7781,34 +7201,23 @@ gud@^1.0.0:
   resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0"
   integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==
 
-gzip-size@5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80"
-  integrity sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA==
+gzip-size@5.1.1:
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274"
+  integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==
   dependencies:
     duplexer "^0.1.1"
-    pify "^3.0.0"
+    pify "^4.0.1"
 
 handle-thing@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754"
   integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==
 
-handlebars@^4.1.0:
-  version "4.1.2"
-  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67"
-  integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==
-  dependencies:
-    neo-async "^2.6.0"
-    optimist "^0.6.1"
-    source-map "^0.6.1"
-  optionalDependencies:
-    uglify-js "^3.1.4"
-
-handlebars@^4.1.2:
-  version "4.3.1"
-  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.3.1.tgz#6febc1890851f62a8932d495cc88d29390fa850d"
-  integrity sha512-c0HoNHzDiHpBt4Kqe99N8tdLPKAnGCQ73gYMPWtAYM4PwGnf7xl8PBUHJqh9ijlzt2uQKaSRxbXRt+rZ7M2/kA==
+handlebars@^4.1.2, handlebars@^4.4.0:
+  version "4.4.3"
+  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.4.3.tgz#180bae52c1d0e9ec0c15d7e82a4362d662762f6e"
+  integrity sha512-B0W4A2U1ww3q7VVthTKfh+epHx+q4mCt6iK+zEAzbMBpWQAwxCeKxEGpj/1oQTpzPXDNSOG7hmG14TsISH50yw==
   dependencies:
     neo-async "^2.6.0"
     optimist "^0.6.1"
@@ -7910,41 +7319,30 @@ hash.js@^1.0.0, hash.js@^1.0.3:
     inherits "^2.0.3"
     minimalistic-assert "^1.0.1"
 
-hast-util-from-parse5@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.0.tgz#a505a05766e0f96e389bfb0b1dd809eeefcef47b"
-  integrity sha512-A7ev5OseS/J15214cvDdcI62uwovJO2PB60Xhnq7kaxvvQRFDEccuqbkrFXU03GPBGopdPqlpQBRqIcDS/Fjbg==
-  dependencies:
-    ccount "^1.0.3"
-    hastscript "^5.0.0"
-    property-information "^5.0.0"
-    web-namespaces "^1.1.2"
-    xtend "^4.0.1"
-
 hast-util-parse-selector@^2.2.0:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.1.tgz#4ddbae1ae12c124e3eb91b581d2556441766f0ab"
-  integrity sha512-Xyh0v+nHmQvrOqop2Jqd8gOdyQtE8sIP9IQf7mlVDqp924W4w/8Liuguk2L2qei9hARnQSG2m+wAOCxM7npJVw==
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.2.tgz#66aabccb252c47d94975f50a281446955160380b"
+  integrity sha512-jIMtnzrLTjzqgVEQqPEmwEZV+ea4zHRFTP8Z2Utw0I5HuBOXHzUPPQWr6ouJdJqDKLbFU/OEiYwZ79LalZkmmw==
 
 hastscript@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.0.0.tgz#fee10382c1bc4ba3f1be311521d368c047d2c43a"
-  integrity sha512-xJtuJ8D42Xtq5yJrnDg/KAIxl2cXBXKoiIJwmWX9XMf8113qHTGl/Bf7jEsxmENJ4w6q4Tfl8s/Y6mEZo8x8qw==
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.0.tgz#a19b3cca6a26a2bcd0f1b1eac574af9427c1c7df"
+  integrity sha512-7mOQX5VfVs/gmrOGlN8/EDfp1GqV6P3gTNVt+KnX4gbYhpASTM8bklFdFQCbFRAadURXAmw0R1QQdBdqp7jswQ==
   dependencies:
     comma-separated-tokens "^1.0.0"
     hast-util-parse-selector "^2.2.0"
     property-information "^5.0.1"
     space-separated-tokens "^1.0.0"
 
-he@1.2.x, he@^1.1.1:
+he@^1.1.1, he@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
   integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
 
 highlight.js@^9.12.0:
-  version "9.15.8"
-  resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.15.8.tgz#f344fda123f36f1a65490e932cf90569e4999971"
-  integrity sha512-RrapkKQWwE+wKdF73VsOa2RQdIoO3mxwJ4P8mhbI6KYJUraUHRKM5w5zQQKXNk0xNL4UVRdulV9SBJcmzJNzVA==
+  version "9.15.10"
+  resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.15.10.tgz#7b18ed75c90348c045eef9ed08ca1319a2219ad2"
+  integrity sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw==
 
 highlight.js@~9.12.0:
   version "9.12.0"
@@ -7965,7 +7363,7 @@ hoist-non-react-statics@^2.3.1:
   resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
   integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==
 
-hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0:
+hoist-non-react-statics@^3.3.0:
   version "3.3.0"
   resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b"
   integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==
@@ -7984,15 +7382,17 @@ hook-std@^2.0.0:
   resolved "https://registry.yarnpkg.com/hook-std/-/hook-std-2.0.0.tgz#ff9aafdebb6a989a354f729bb6445cf4a3a7077c"
   integrity sha512-zZ6T5WcuBMIUVh49iPQS9t977t7C0l7OtHrpeMb5uk48JdflRX0NSFvCekfYNmGQETnLq9W/isMyHl69kxGi8g==
 
-hosted-git-info@^2.1.4:
-  version "2.8.4"
-  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546"
-  integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==
+hosted-git-info@^2.1.4, hosted-git-info@^2.7.1, hosted-git-info@^2.8.5:
+  version "2.8.5"
+  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c"
+  integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==
 
-hosted-git-info@^2.6.0, hosted-git-info@^2.7.1:
-  version "2.7.1"
-  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047"
-  integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==
+hosted-git-info@^3.0.0:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.2.tgz#8b7e3bd114b59b51786f8bade0f39ddc80275a97"
+  integrity sha512-ezZMWtHXm7Eb7Rq4Mwnx2vs79WUx2QmRg3+ZqeGroKzfDO+EprOcgRPYghsOP9JuYBfK18VojmRTGCg8Ma+ktw==
+  dependencies:
+    lru-cache "^5.1.1"
 
 hpack.js@^2.1.6:
   version "2.1.6"
@@ -8005,9 +7405,9 @@ hpack.js@^2.1.6:
     wbuf "^1.1.0"
 
 html-element-map@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/html-element-map/-/html-element-map-1.0.1.tgz#3c4fcb4874ebddfe4283b51c8994e7713782b592"
-  integrity sha512-BZSfdEm6n706/lBfXKWa4frZRZcT5k1cOusw95ijZsHlI+GdgY0v95h6IzO3iIDf2ROwq570YTwqNPqHcNMozw==
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/html-element-map/-/html-element-map-1.1.0.tgz#e5aab9a834caf883b421f8bd9eaedcaac887d63c"
+  integrity sha512-iqiG3dTZmy+uUaTmHarTL+3/A2VW9ox/9uasKEZC+R/wAtUrTcRlXPSaPqsnWPfIu8wqn09jQNwMRqzL54jSYA==
   dependencies:
     array-filter "^1.0.0"
 
@@ -8023,29 +7423,29 @@ html-entities@^1.2.0, html-entities@^1.2.1:
   resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
   integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=
 
-html-minifier@^3.5.20:
-  version "3.5.21"
-  resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c"
-  integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==
+html-minifier@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-4.0.0.tgz#cca9aad8bce1175e02e17a8c33e46d8988889f56"
+  integrity sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==
   dependencies:
-    camel-case "3.0.x"
-    clean-css "4.2.x"
-    commander "2.17.x"
-    he "1.2.x"
-    param-case "2.1.x"
-    relateurl "0.2.x"
-    uglify-js "3.4.x"
+    camel-case "^3.0.0"
+    clean-css "^4.2.1"
+    commander "^2.19.0"
+    he "^1.2.0"
+    param-case "^2.1.1"
+    relateurl "^0.2.7"
+    uglify-js "^3.5.1"
 
 html-webpack-plugin@^4.0.0-beta.2:
-  version "4.0.0-beta.5"
-  resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.5.tgz#2c53083c1151bfec20479b1f8aaf0039e77b5513"
-  integrity sha512-y5l4lGxOW3pz3xBTFdfB9rnnrWRPVxlAhX6nrBYIcW+2k2zC3mSp/3DxlWVCMBfnO6UAnoF8OcFn0IMy6kaKAQ==
+  version "4.0.0-beta.8"
+  resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.8.tgz#d9a8d4322d8cf310f1568f6f4f585a80df0ad378"
+  integrity sha512-n5S2hJi3/vioRvEDswZP2WFgZU8TUqFoYIrkg5dt+xDC4TigQEhIcl4Y81Qs2La/EqKWuJZP8+ikbHGVmzQ4Mg==
   dependencies:
-    html-minifier "^3.5.20"
-    loader-utils "^1.1.0"
+    html-minifier "^4.0.0"
+    loader-utils "^1.2.3"
     lodash "^4.17.11"
     pretty-error "^2.1.1"
-    tapable "^1.1.0"
+    tapable "^1.1.3"
     util.promisify "1.0.0"
 
 html@^1.0.0:
@@ -8077,7 +7477,7 @@ http-deceiver@^1.2.7:
   resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
   integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=
 
-http-errors@1.7.2, http-errors@~1.7.2:
+http-errors@1.7.2:
   version "1.7.2"
   resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
   integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
@@ -8098,10 +7498,21 @@ http-errors@~1.6.2:
     setprototypeof "1.1.0"
     statuses ">= 1.4.0 < 2"
 
-http-parser-js@>=0.4.0:
-  version "0.5.0"
-  resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8"
-  integrity sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==
+http-errors@~1.7.2:
+  version "1.7.3"
+  resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
+  integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
+  dependencies:
+    depd "~1.1.2"
+    inherits "2.0.4"
+    setprototypeof "1.1.1"
+    statuses ">= 1.5.0 < 2"
+    toidentifier "1.0.0"
+
+"http-parser-js@>=0.4.0 <0.4.11":
+  version "0.4.10"
+  resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4"
+  integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=
 
 http-proxy-agent@^2.1.0:
   version "2.1.0"
@@ -8111,7 +7522,7 @@ http-proxy-agent@^2.1.0:
     agent-base "4"
     debug "3.1.0"
 
-http-proxy-middleware@^0.19.1:
+http-proxy-middleware@0.19.1:
   version "0.19.1"
   resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a"
   integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==
@@ -8122,11 +7533,11 @@ http-proxy-middleware@^0.19.1:
     micromatch "^3.1.10"
 
 http-proxy@^1.17.0:
-  version "1.17.0"
-  resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a"
-  integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==
+  version "1.18.0"
+  resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a"
+  integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==
   dependencies:
-    eventemitter3 "^3.0.0"
+    eventemitter3 "^4.0.0"
     follow-redirects "^1.0.0"
     requires-port "^1.0.0"
 
@@ -8145,11 +7556,19 @@ https-browserify@^1.0.0:
   integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
 
 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==
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz#271ea8e90f836ac9f119daccd39c19ff7dfb0793"
+  integrity sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==
+  dependencies:
+    agent-base "^4.3.0"
+    debug "^3.1.0"
+
+https-proxy-agent@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.0.tgz#0106efa5d63d6d6f3ab87c999fa4877a3fd1ff97"
+  integrity sha512-y4jAxNEihqvBI5F3SaO2rtsjIOnnNA8sEbuiP+UhJZJHeM2NRm6c09ax2tgqme+SgUUvjao2fJXF4h3D6Cb2HQ==
   dependencies:
-    agent-base "^4.1.0"
+    agent-base "^4.3.0"
     debug "^3.1.0"
 
 humanize-ms@^1.2.1:
@@ -8188,9 +7607,9 @@ icss-replace-symbols@^1.1.0:
   integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=
 
 icss-utils@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.0.tgz#339dbbffb9f8729a243b701e1c29d4cc58c52f0e"
-  integrity sha512-3DEun4VOeMvSczifM3F2cKQrDQ5Pj6WKhkOq6HD4QTnDUAq8MQRxy5TX6Sy1iY6WPBe4gQ3p5vTECjbIkglkkQ==
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467"
+  integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==
   dependencies:
     postcss "^7.0.14"
 
@@ -8210,9 +7629,9 @@ iferr@^1.0.2:
   integrity sha512-9AfeLfji44r5TKInjhz3W9DyZI1zR1JAf2hVBMGhddAKPqBsupb89jGfbCTHIGZd6fGZl9WlHdn4AObygyMKwg==
 
 ignore-walk@^3.0.1:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.2.tgz#99d83a246c196ea5c93ef9315ad7b0819c35069b"
-  integrity sha512-EXyErtpHbn75ZTsOADsfx6J/FPo6/5cjev46PXrcTpd8z3BoRkXgYu9/JVqrI7tusjmwCZutGeRJeU0Wo1e4Cw==
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
+  integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
   dependencies:
     minimatch "^3.0.4"
 
@@ -8226,12 +7645,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:
-  version "5.1.2"
-  resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.2.tgz#e28e584d43ad7e92f96995019cc43b9e1ac49558"
-  integrity sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==
-
-ignore@^5.1.4:
+ignore@^5.1.1, ignore@^5.1.4:
   version "5.1.4"
   resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf"
   integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==
@@ -8257,9 +7671,9 @@ import-fresh@^2.0.0:
     resolve-from "^3.0.0"
 
 import-fresh@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390"
-  integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118"
+  integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==
   dependencies:
     parent-module "^1.0.0"
     resolve-from "^4.0.0"
@@ -8283,7 +7697,7 @@ import-lazy@^2.1.0:
   resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
   integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=
 
-import-local@^2.0.0:
+import-local@2.0.0, import-local@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d"
   integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==
@@ -8308,20 +7722,25 @@ indent-string@^2.1.0:
   dependencies:
     repeating "^2.0.0"
 
-indent-string@^3.0.0, indent-string@^3.2.0:
+indent-string@^3.0.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
   integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=
 
+indent-string@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
+  integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
+
 indexes-of@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
   integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc=
 
-indexof@0.0.1:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
-  integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=
+infer-owner@^1.0.3, infer-owner@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"
+  integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==
 
 inflight@^1.0.4, inflight@~1.0.6:
   version "1.0.6"
@@ -8331,7 +7750,7 @@ inflight@^1.0.4, inflight@~1.0.6:
     once "^1.3.0"
     wrappy "1"
 
-inherits@2, inherits@~2.0.3:
+inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
   integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -8341,7 +7760,7 @@ inherits@2.0.1:
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
   integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
 
-inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1:
+inherits@2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
   integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
@@ -8365,25 +7784,6 @@ init-package-json@^1.10.3:
     validate-npm-package-license "^3.0.1"
     validate-npm-package-name "^3.0.0"
 
-inquirer@6.2.2:
-  version "6.2.2"
-  resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406"
-  integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==
-  dependencies:
-    ansi-escapes "^3.2.0"
-    chalk "^2.4.2"
-    cli-cursor "^2.1.0"
-    cli-width "^2.0.0"
-    external-editor "^3.0.3"
-    figures "^2.0.0"
-    lodash "^4.17.11"
-    mute-stream "0.0.7"
-    run-async "^2.2.0"
-    rxjs "^6.4.0"
-    string-width "^2.1.0"
-    strip-ansi "^5.0.0"
-    through "^2.3.6"
-
 inquirer@6.5.0:
   version "6.5.0"
   resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42"
@@ -8404,9 +7804,9 @@ inquirer@6.5.0:
     through "^2.3.6"
 
 inquirer@^6.2.0, inquirer@^6.2.2:
-  version "6.3.1"
-  resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.3.1.tgz#7a413b5e7950811013a3db491c61d1f3b776e8e7"
-  integrity sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==
+  version "6.5.2"
+  resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca"
+  integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==
   dependencies:
     ansi-escapes "^3.2.0"
     chalk "^2.4.2"
@@ -8414,7 +7814,7 @@ inquirer@^6.2.0, inquirer@^6.2.2:
     cli-width "^2.0.0"
     external-editor "^3.0.3"
     figures "^2.0.0"
-    lodash "^4.17.11"
+    lodash "^4.17.12"
     mute-stream "0.0.7"
     run-async "^2.2.0"
     rxjs "^6.4.0"
@@ -8430,26 +7830,18 @@ internal-ip@^4.3.0:
     default-gateway "^4.2.0"
     ipaddr.js "^1.9.0"
 
-interpret@^1.0.0, interpret@^1.1.0, interpret@^1.2.0:
+interpret@1.2.0, interpret@^1.0.0, interpret@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
   integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
 
-into-stream@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-4.0.0.tgz#ef10ee2ffb6f78af34c93194bbdc36c35f7d8a9d"
-  integrity sha512-i29KNyE5r0Y/UQzcQ0IbZO1MYJ53Jn0EcFRZPj5FzWKYH17kDFEOwuA+3jroymOI06SW1dEDnly9A1CAreC5dg==
-  dependencies:
-    from2 "^2.1.1"
-    p-is-promise "^2.0.0"
-
 into-stream@^5.0.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-5.1.0.tgz#b05f37d8fed05c06a0b43b556d74e53e5af23878"
-  integrity sha512-cbDhb8qlxKMxPBk/QxTtYg1DQ4CwXmadu7quG3B7nrJsgSncEreF2kwWKZFdnjc/lSNNIkFPsjI7SM0Cx/QXPw==
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-5.1.1.tgz#f9a20a348a11f3c13face22763f2d02e127f4db8"
+  integrity sha512-krrAJ7McQxGGmvaYbB7Q1mcA+cRwg9Ij2RfWIeVesNBgVDZmzY/Fa4IpZUT3bmdRzMzdf/mzltCG2Dq99IZGBA==
   dependencies:
     from2 "^2.3.0"
-    p-is-promise "^2.0.0"
+    p-is-promise "^3.0.0"
 
 invariant@2.2.4, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4:
   version "2.2.4"
@@ -8478,11 +7870,21 @@ ip@^1.1.0, ip@^1.1.5:
   resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
   integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
 
-ipaddr.js@1.9.0, ipaddr.js@^1.9.0:
+ipaddr.js@1.9.0:
   version "1.9.0"
   resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65"
   integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==
 
+ipaddr.js@^1.9.0:
+  version "1.9.1"
+  resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
+  integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
+
+is-absolute-url@^3.0.3:
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698"
+  integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==
+
 is-accessor-descriptor@^0.1.6:
   version "0.1.6"
   resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
@@ -8515,6 +7917,11 @@ is-alphanumerical@^1.0.0:
     is-alphabetical "^1.0.0"
     is-decimal "^1.0.0"
 
+is-arguments@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3"
+  integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==
+
 is-arrayish@^0.2.1:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
@@ -8537,12 +7944,7 @@ is-buffer@^1.0.2, is-buffer@^1.1.4, is-buffer@^1.1.5:
   resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
   integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
 
-is-buffer@^2.0.0:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725"
-  integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==
-
-is-callable@^1.1.3, is-callable@^1.1.4:
+is-callable@^1.1.4:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
   integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
@@ -8562,9 +7964,9 @@ is-ci@^2.0.0:
     ci-info "^2.0.0"
 
 is-cidr@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-3.0.0.tgz#1acf35c9e881063cd5f696d48959b30fed3eed56"
-  integrity sha512-8Xnnbjsb0x462VoYiGlhEi+drY8SFwrHiSYuzc/CEwco55vkehTaxAyIjEdpi3EMvLPPJAJi9FlzP+h+03gp0Q==
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-3.1.0.tgz#72e233d8e1c4cd1d3f11713fcce3eba7b0e3476f"
+  integrity sha512-3kxTForpuj8O4iHn0ocsn1jxRm5VYm60GDghK6HXmpn4IyZOoRy9/GmdjFA2yEMqw91TB1/K3bFTuI7FlFNR1g==
   dependencies:
     cidr-regex "^2.0.10"
 
@@ -8616,9 +8018,12 @@ is-directory@^0.3.1:
   integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
 
 is-dom@^1.0.9:
-  version "1.0.9"
-  resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.0.9.tgz#483832d52972073de12b9fe3f60320870da8370d"
-  integrity sha1-SDgy1SlyBz3hK5/j9gMghw2oNw0=
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a"
+  integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==
+  dependencies:
+    is-object "^1.0.1"
+    is-window "^1.0.2"
 
 is-extendable@^0.1.0, is-extendable@^0.1.1:
   version "0.1.1"
@@ -8715,15 +8120,20 @@ is-number@^7.0.0:
   resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
   integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
 
-is-obj@^1.0.0, is-obj@^1.0.1:
+is-obj@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
   integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
 
+is-object@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
+  integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA=
+
 is-path-cwd@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.1.0.tgz#2e0c7e463ff5b7a0eb60852d851a6809347a124c"
-  integrity sha512-Sc5j3/YnM8tDeyCsVeKlm/0p95075DyLmDEIkSgQ7mXkrOX+uTCtmQFm0CYzVyJwcCCmO3k8qfJt17SxQwB5Zw==
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
+  integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==
 
 is-path-in-cwd@^2.0.0:
   version "2.1.0"
@@ -8782,20 +8192,15 @@ is-regex@^1.0.4:
   dependencies:
     has "^1.0.1"
 
-is-regexp@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
-  integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk=
-
 is-retry-allowed@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
-  integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
+  integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
 
-is-root@2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.0.0.tgz#838d1e82318144e5a6f77819d90207645acc7019"
-  integrity sha512-F/pJIk8QD6OX5DNhRB7hWamLsUilmkDGho48KbgZ6xg/lmAZXHxzXQ91jzB3yRSw5kdQGGGc4yz8HYhTYIMWPg==
+is-root@2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c"
+  integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==
 
 is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
   version "1.1.0"
@@ -8831,6 +8236,13 @@ is-text-path@^1.0.0:
   dependencies:
     text-extensions "^1.0.0"
 
+is-text-path@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-2.0.0.tgz#b2484e2b720a633feb2e85b67dc193ff72c75636"
+  integrity sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==
+  dependencies:
+    text-extensions "^2.0.0"
+
 is-typedarray@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
@@ -8851,6 +8263,11 @@ is-whitespace-character@^1.0.0:
   resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz#b3ad9546d916d7d3ffa78204bca0c26b56257fac"
   integrity sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ==
 
+is-window@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d"
+  integrity sha1-LIlspT25feRdPDMTOmXYyfVjSA0=
+
 is-windows@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c"
@@ -8916,21 +8333,10 @@ isstream@~0.1.2:
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
   integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
 
-issue-parser@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/issue-parser/-/issue-parser-3.0.1.tgz#ee8dd677fdb5be64541f81fa5e7267baa271a7ee"
-  integrity sha512-5wdT3EE8Kq38x/hJD8QZCJ9scGoOZ5QnzwXyClkviSWTS+xOCE6hJ0qco3H5n5jCsFqpbofZCcMWqlXJzF72VQ==
-  dependencies:
-    lodash.capitalize "^4.2.1"
-    lodash.escaperegexp "^4.1.2"
-    lodash.isplainobject "^4.0.6"
-    lodash.isstring "^4.0.1"
-    lodash.uniqby "^4.7.0"
-
-issue-parser@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/issue-parser/-/issue-parser-4.0.0.tgz#397817323abbb70c7c29cea2ff62448cf83b686c"
-  integrity sha512-1RmmAXHl5+cqTZ9dRr861xWy0Gkc9TWTEklgjKv+nhlB1dY1NmGBV8b20jTWRL5cPGpOIXkz84kEcDBM8Nc0cw==
+issue-parser@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/issue-parser/-/issue-parser-5.0.0.tgz#0e22a40bc275b6c7da6ddf4a9b979e8ca9faf0d4"
+  integrity sha512-q/16W7EPHRL0FKVz9NU++TUsoygXGj6JOi88oulyAcQG+IEZ0T6teVdE+VLbe19OfL/tbV8Wi3Dfo0HedeHW0Q==
   dependencies:
     lodash.capitalize "^4.2.1"
     lodash.escaperegexp "^4.1.2"
@@ -9237,20 +8643,13 @@ jest-message-util@^24.9.0:
     slash "^2.0.0"
     stack-utils "^1.0.1"
 
-jest-mock@^24, jest-mock@^24.9.0:
+jest-mock@^24, jest-mock@^24.5.0, jest-mock@^24.9.0:
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6"
   integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==
   dependencies:
     "@jest/types" "^24.9.0"
 
-jest-mock@^24.5.0:
-  version "24.8.0"
-  resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.8.0.tgz#2f9d14d37699e863f1febf4e4d5a33b7fdbbde56"
-  integrity sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==
-  dependencies:
-    "@jest/types" "^24.8.0"
-
 jest-pnp-resolver@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a"
@@ -9376,25 +8775,7 @@ jest-snapshot@^24.9.0:
     pretty-format "^24.9.0"
     semver "^6.2.0"
 
-jest-util@^24.5.0:
-  version "24.8.0"
-  resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.8.0.tgz#41f0e945da11df44cc76d64ffb915d0716f46cd1"
-  integrity sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==
-  dependencies:
-    "@jest/console" "^24.7.1"
-    "@jest/fake-timers" "^24.8.0"
-    "@jest/source-map" "^24.3.0"
-    "@jest/test-result" "^24.8.0"
-    "@jest/types" "^24.8.0"
-    callsites "^3.0.0"
-    chalk "^2.0.1"
-    graceful-fs "^4.1.15"
-    is-ci "^2.0.0"
-    mkdirp "^0.5.1"
-    slash "^2.0.0"
-    source-map "^0.6.0"
-
-jest-util@^24.9.0:
+jest-util@^24.5.0, jest-util@^24.9.0:
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162"
   integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==
@@ -9473,7 +8854,7 @@ js-tokens@^3.0.2:
   resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
   integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
 
-js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.9.0:
+js-yaml@^3.13.0, js-yaml@^3.13.1:
   version "3.13.1"
   resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
   integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
@@ -9586,14 +8967,14 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
   integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
 
 json3@^3.3.2:
-  version "3.3.2"
-  resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
-  integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=
+  version "3.3.3"
+  resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
+  integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
 
 json5@2.x, json5@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850"
-  integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6"
+  integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==
   dependencies:
     minimist "^1.2.0"
 
@@ -9618,11 +8999,6 @@ jsonfile@^4.0.0:
   optionalDependencies:
     graceful-fs "^4.1.6"
 
-jsonify@~0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
-  integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
-
 jsonparse@^1.2.0:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
@@ -9638,12 +9014,13 @@ jsprim@^1.2.2:
     json-schema "0.2.3"
     verror "1.10.0"
 
-jsx-ast-utils@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz#0ee4e2c971fb9601c67b5641b71be80faecf0b36"
-  integrity sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA==
+jsx-ast-utils@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz#4d4973ebf8b9d2837ee91a8208cc66f3a2776cfb"
+  integrity sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==
   dependencies:
     array-includes "^3.0.3"
+    object.assign "^4.1.0"
 
 keymirror@^0.1.1:
   version "0.1.1"
@@ -9726,11 +9103,11 @@ lazy-property@~1.0.0:
   integrity sha1-hN3Es3Bnm6i9TNz6TAa0PVcREUc=
 
 lazy-universal-dotenv@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.0.tgz#e71f07f89d8de6bbf491478e4503df3c96729b8d"
-  integrity sha512-Mbf5AeGOs74lE5BdQXHFJ7Rt383jxnWKNfW2EWL0Pibnhea5JRStRIiUpdTenyMxCGuCjlMpYQhhay1XZBSSQA==
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38"
+  integrity sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ==
   dependencies:
-    "@babel/runtime" "^7.0.0"
+    "@babel/runtime" "^7.5.0"
     app-root-dir "^1.0.2"
     core-js "^3.0.4"
     dotenv "^8.0.0"
@@ -9768,10 +9145,10 @@ levn@^0.3.0, levn@~0.3.0:
     prelude-ls "~1.1.2"
     type-check "~0.3.2"
 
-libcipm@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-3.0.3.tgz#2e764effe0b90d458790dab3165794c804075ed3"
-  integrity sha512-71V5CpTI+zFydTc5IjJ/tx8JHbXEJvmYF2zaSVW1V3X1rRnRjXqh44iuiyry1xgi3ProUQ1vX1uwFiWs00+2og==
+libcipm@^4.0.4:
+  version "4.0.7"
+  resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-4.0.7.tgz#76cd675c98bdaae64db88b782b01b804b6d02c8a"
+  integrity sha512-fTq33otU3PNXxxCTCYCYe7V96o59v/o7bvtspmbORXpgFk+wcWrGf5x6tBgui5gCed/45/wtPomBsZBYm5KbIw==
   dependencies:
     bin-links "^1.1.2"
     bluebird "^3.5.1"
@@ -9781,7 +9158,7 @@ libcipm@^3.0.3:
     ini "^1.3.5"
     lock-verify "^2.0.2"
     mkdirp "^0.5.1"
-    npm-lifecycle "^2.0.3"
+    npm-lifecycle "^3.0.0"
     npm-logical-tree "^1.2.1"
     npm-package-arg "^6.1.0"
     pacote "^9.1.0"
@@ -9789,41 +9166,41 @@ libcipm@^3.0.3:
     rimraf "^2.6.2"
     worker-farm "^1.6.0"
 
-libnpm@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/libnpm/-/libnpm-2.0.1.tgz#a48fcdee3c25e13c77eb7c60a0efe561d7fb0d8f"
-  integrity sha512-qTKoxyJvpBxHZQB6k0AhSLajyXq9ZE/lUsZzuHAplr2Bpv9G+k4YuYlExYdUCeVRRGqcJt8hvkPh4tBwKoV98w==
+libnpm@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/libnpm/-/libnpm-3.0.1.tgz#0be11b4c9dd4d1ffd7d95c786e92e55d65be77a2"
+  integrity sha512-d7jU5ZcMiTfBqTUJVZ3xid44fE5ERBm9vBnmhp2ECD2Ls+FNXWxHSkO7gtvrnbLO78gwPdNPz1HpsF3W4rjkBQ==
   dependencies:
     bin-links "^1.1.2"
     bluebird "^3.5.3"
     find-npm-prefix "^1.0.2"
-    libnpmaccess "^3.0.1"
+    libnpmaccess "^3.0.2"
     libnpmconfig "^1.2.1"
-    libnpmhook "^5.0.2"
-    libnpmorg "^1.0.0"
-    libnpmpublish "^1.1.0"
-    libnpmsearch "^2.0.0"
-    libnpmteam "^1.0.1"
+    libnpmhook "^5.0.3"
+    libnpmorg "^1.0.1"
+    libnpmpublish "^1.1.2"
+    libnpmsearch "^2.0.2"
+    libnpmteam "^1.0.2"
     lock-verify "^2.0.2"
-    npm-lifecycle "^2.1.0"
+    npm-lifecycle "^3.0.0"
     npm-logical-tree "^1.2.1"
     npm-package-arg "^6.1.0"
-    npm-profile "^4.0.1"
-    npm-registry-fetch "^3.8.0"
+    npm-profile "^4.0.2"
+    npm-registry-fetch "^4.0.0"
     npmlog "^4.1.2"
-    pacote "^9.2.3"
+    pacote "^9.5.3"
     read-package-json "^2.0.13"
     stringify-package "^1.0.0"
 
-libnpmaccess@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.1.tgz#5b3a9de621f293d425191aa2e779102f84167fa8"
-  integrity sha512-RlZ7PNarCBt+XbnP7R6PoVgOq9t+kou5rvhaInoNibhPO7eMlRfS0B8yjatgn2yaHIwWNyoJDolC/6Lc5L/IQA==
+libnpmaccess@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.2.tgz#8b2d72345ba3bef90d3b4f694edd5c0417f58923"
+  integrity sha512-01512AK7MqByrI2mfC7h5j8N9V4I7MHJuk9buo8Gv+5QgThpOgpjB7sQBDDkeZqRteFb1QM/6YNdHfG7cDvfAQ==
   dependencies:
     aproba "^2.0.0"
     get-stream "^4.0.0"
     npm-package-arg "^6.1.0"
-    npm-registry-fetch "^3.8.0"
+    npm-registry-fetch "^4.0.0"
 
 libnpmconfig@^1.2.1:
   version "1.2.1"
@@ -9834,30 +9211,30 @@ libnpmconfig@^1.2.1:
     find-up "^3.0.0"
     ini "^1.3.5"
 
-libnpmhook@^5.0.2:
-  version "5.0.2"
-  resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-5.0.2.tgz#d12817b0fb893f36f1d5be20017f2aea25825d94"
-  integrity sha512-vLenmdFWhRfnnZiNFPNMog6CK7Ujofy2TWiM2CrpZUjBRIhHkJeDaAbJdYCT6W4lcHtyrJR8yXW8KFyq6UAp1g==
+libnpmhook@^5.0.3:
+  version "5.0.3"
+  resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-5.0.3.tgz#4020c0f5edbf08ebe395325caa5ea01885b928f7"
+  integrity sha512-UdNLMuefVZra/wbnBXECZPefHMGsVDTq5zaM/LgKNE9Keyl5YXQTnGAzEo+nFOpdRqTWI9LYi4ApqF9uVCCtuA==
   dependencies:
     aproba "^2.0.0"
     figgy-pudding "^3.4.1"
     get-stream "^4.0.0"
-    npm-registry-fetch "^3.8.0"
+    npm-registry-fetch "^4.0.0"
 
-libnpmorg@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-1.0.0.tgz#979b868c48ba28c5820e3bb9d9e73c883c16a232"
-  integrity sha512-o+4eVJBoDGMgRwh2lJY0a8pRV2c/tQM/SxlqXezjcAg26Qe9jigYVs+Xk0vvlYDWCDhP0g74J8UwWeAgsB7gGw==
+libnpmorg@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-1.0.1.tgz#5d2503f6ceb57f33dbdcc718e6698fea6d5ad087"
+  integrity sha512-0sRUXLh+PLBgZmARvthhYXQAWn0fOsa6T5l3JSe2n9vKG/lCVK4nuG7pDsa7uMq+uTt2epdPK+a2g6btcY11Ww==
   dependencies:
     aproba "^2.0.0"
     figgy-pudding "^3.4.1"
     get-stream "^4.0.0"
-    npm-registry-fetch "^3.8.0"
+    npm-registry-fetch "^4.0.0"
 
-libnpmpublish@^1.1.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-1.1.1.tgz#ff0c6bb0b4ad2bda2ad1f5fba6760a4af37125f0"
-  integrity sha512-nefbvJd/wY38zdt+b9SHL6171vqBrMtZ56Gsgfd0duEKb/pB8rDT4/ObUQLrHz1tOfht1flt2zM+UGaemzAG5g==
+libnpmpublish@^1.1.2:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-1.1.3.tgz#e3782796722d79eef1a0a22944c117e0c4ca4280"
+  integrity sha512-/3LsYqVc52cHXBmu26+J8Ed7sLs/hgGVFMH1mwYpL7Qaynb9RenpKqIKu0sJ130FB9PMkpMlWjlbtU8A4m7CQw==
   dependencies:
     aproba "^2.0.0"
     figgy-pudding "^3.5.1"
@@ -9865,28 +9242,28 @@ libnpmpublish@^1.1.0:
     lodash.clonedeep "^4.5.0"
     normalize-package-data "^2.4.0"
     npm-package-arg "^6.1.0"
-    npm-registry-fetch "^3.8.0"
+    npm-registry-fetch "^4.0.0"
     semver "^5.5.1"
     ssri "^6.0.1"
 
-libnpmsearch@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-2.0.0.tgz#de05af47ada81554a5f64276a69599070d4a5685"
-  integrity sha512-vd+JWbTGzOSfiOc+72MU6y7WqmBXn49egCCrIXp27iE/88bX8EpG64ST1blWQI1bSMUr9l1AKPMVsqa2tS5KWA==
+libnpmsearch@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-2.0.2.tgz#9a4f059102d38e3dd44085bdbfe5095f2a5044cf"
+  integrity sha512-VTBbV55Q6fRzTdzziYCr64+f8AopQ1YZ+BdPOv16UegIEaE8C0Kch01wo4s3kRTFV64P121WZJwgmBwrq68zYg==
   dependencies:
     figgy-pudding "^3.5.1"
     get-stream "^4.0.0"
-    npm-registry-fetch "^3.8.0"
+    npm-registry-fetch "^4.0.0"
 
-libnpmteam@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-1.0.1.tgz#ff704b1b6c06ea674b3b1101ac3e305f5114f213"
-  integrity sha512-gDdrflKFCX7TNwOMX1snWojCoDE5LoRWcfOC0C/fqF7mBq8Uz9zWAX4B2RllYETNO7pBupBaSyBDkTAC15cAMg==
+libnpmteam@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-1.0.2.tgz#8b48bcbb6ce70dd8150c950fcbdbf3feb6eec820"
+  integrity sha512-p420vM28Us04NAcg1rzgGW63LMM6rwe+6rtZpfDxCcXxM0zUTLl7nPFEnRF3JfFBF5skF/yuZDUthTsHgde8QA==
   dependencies:
     aproba "^2.0.0"
     figgy-pudding "^3.4.1"
     get-stream "^4.0.0"
-    npm-registry-fetch "^3.8.0"
+    npm-registry-fetch "^4.0.0"
 
 libnpx@^10.2.0:
   version "10.2.0"
@@ -9943,7 +9320,7 @@ load-json-file@^4.0.0:
     pify "^3.0.0"
     strip-bom "^3.0.0"
 
-loader-runner@^2.3.0:
+loader-runner@^2.4.0:
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
   integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==
@@ -9995,7 +9372,7 @@ lockfile@^1.0.4:
   dependencies:
     signal-exit "^3.0.2"
 
-lodash-es@^4.17.11:
+lodash-es@^4.17.15:
   version "4.17.15"
   resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78"
   integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==
@@ -10063,6 +9440,11 @@ lodash.isequal@^4.1.1, lodash.isequal@^4.5.0:
   resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
   integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
 
+lodash.ismatch@^4.4.0:
+  version "4.4.0"
+  resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37"
+  integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=
+
 lodash.isplainobject@^4.0.6:
   version "4.0.6"
   resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
@@ -10088,21 +9470,11 @@ lodash.set@^4.3.2:
   resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
   integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
 
-lodash.some@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
-  integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=
-
 lodash.sortby@^4.7.0:
   version "4.7.0"
   resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
   integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
 
-lodash.tail@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
-  integrity sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=
-
 lodash.template@^4.0.2:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
@@ -10158,7 +9530,7 @@ lodash@4.17.14:
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
   integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
 
-lodash@4.17.15, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.2.1, lodash@~4.17.10:
+lodash@4.17.15, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.2.1, lodash@~4.17.10:
   version "4.17.15"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
   integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@@ -10170,10 +9542,10 @@ log-symbols@^2.1.0, log-symbols@^2.2.0:
   dependencies:
     chalk "^2.0.1"
 
-loglevel@^1.6.1:
-  version "1.6.1"
-  resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
-  integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=
+loglevel@^1.6.4:
+  version "1.6.6"
+  resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.6.tgz#0ee6300cc058db6b3551fa1c4bf73b83bb771312"
+  integrity sha512-Sgr5lbboAUBo3eXCSPL4/KoVz3ROKquOjcctxmHIt+vol2DrqTQe3SwkKKuYhEiWB5kYa13YyopJ69deJ1irzQ==
 
 loglevelnext@^1.0.1:
   version "1.0.5"
@@ -10233,7 +9605,7 @@ lowlight@~1.9.1:
     fault "^1.0.2"
     highlight.js "~9.12.0"
 
-lru-cache@^4.0.1, lru-cache@^4.1.2, lru-cache@^4.1.3, lru-cache@^4.1.5:
+lru-cache@^4.0.1:
   version "4.1.5"
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
   integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
@@ -10249,14 +9621,14 @@ lru-cache@^5.1.1:
     yallist "^3.0.2"
 
 luxon@^1.11.3:
-  version "1.15.0"
-  resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.15.0.tgz#d06643c437982332a3feff4ee7c718bdbbae09fd"
-  integrity sha512-HIpK4zIonObWHj9UC80ElykmM/0jTuuXcbPYBYbDGZ3Cq2bL9rACcmppoc6zm5JnmHpnK5bRMIp8/+ei4O0y2Q==
+  version "1.19.3"
+  resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.19.3.tgz#86c04a1395529b4386ae235a8fe16d0a82a0695b"
+  integrity sha512-YwTDjGRQC0QC9Iya2g2eKZfgEFqRId4ZoLHORQcfTMB/5xrTx427V7ZPjQJ1vzvhA2vJfG2bh1Kv8V8IFMWCUA==
 
 macos-release@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.2.0.tgz#ab58d55dd4714f0a05ad4b0e90f4370fef5cdea8"
-  integrity sha512-iV2IDxZaX8dIcM7fG6cI46uNmHUxHE4yN+Z8tKHAW1TBPMZDIKHf/3L+YnOuj/FK9il14UaVdHmiQ1tsi90ltA==
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f"
+  integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==
 
 make-dir@^1.0.0:
   version "1.3.0"
@@ -10285,17 +9657,17 @@ make-error@1.x:
   resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8"
   integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==
 
-make-fetch-happen@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz#141497cb878f243ba93136c83d8aba12c216c083"
-  integrity sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ==
+make-fetch-happen@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.0.tgz#a8e3fe41d3415dd656fe7b8e8172e1fb4458b38d"
+  integrity sha512-nFr/vpL1Jc60etMVKeaLOqfGjMMb3tAHFVJWxHOFCFS04Zmd7kGlMxo0l1tzfhoQje0/UPnd0X8OeGUiXXnfPA==
   dependencies:
     agentkeepalive "^3.4.1"
-    cacache "^11.0.1"
+    cacache "^12.0.0"
     http-cache-semantics "^3.8.1"
     http-proxy-agent "^2.1.0"
     https-proxy-agent "^2.2.1"
-    lru-cache "^4.1.2"
+    lru-cache "^5.1.1"
     mississippi "^3.0.0"
     node-fetch-npm "^2.0.2"
     promise-retry "^1.1.1"
@@ -10359,17 +9731,17 @@ markdown-table@^1.1.0:
   integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==
 
 markdown-to-jsx@^6.9.1, markdown-to-jsx@^6.9.3:
-  version "6.10.2"
-  resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-6.10.2.tgz#644f602b81d088f10aef1c3674874876146cf38b"
-  integrity sha512-eDCsRobOkbQ4PqCphrxNi/U8geA8DGf52dMP4BrrYsVFyQ2ILFnXIB5sRcIxnRK2nPl8k5hUYdRNRXLlQNYLYg==
+  version "6.10.3"
+  resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-6.10.3.tgz#7f0946684acd321125ff2de7fd258a9b9c7c40b7"
+  integrity sha512-PSoUyLnW/xoW6RsxZrquSSz5eGEOTwa15H5eqp3enmrp8esmgDJmhzd6zmQ9tgAA9TxJzx1Hmf3incYU/IamoQ==
   dependencies:
     prop-types "^15.6.2"
     unquote "^1.1.0"
 
 marked-terminal@^3.2.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-3.2.0.tgz#3fc91d54569332bcf096292af178d82219000474"
-  integrity sha512-Yr1yVS0BbDG55vx7be1D0mdv+jGs9AW563o/Tt/7FTsId2J0yqhrTeXAqq/Q0DyyXltIn6CSxzesQuFqXgafjQ==
+  version "3.3.0"
+  resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-3.3.0.tgz#25ce0c0299285998c7636beaefc87055341ba1bd"
+  integrity sha512-+IUQJ5VlZoAFsM5MHNT7g3RHSkA3eETqhRCdXv4niUMAKHQ7lb1yvAcuGPmm4soxhmtX13u4Li6ZToXtvSEH+A==
   dependencies:
     ansi-escapes "^3.1.0"
     cardinal "^2.1.1"
@@ -10418,6 +9790,11 @@ mdast-util-compact@^1.0.0:
   dependencies:
     unist-util-visit "^1.1.0"
 
+mdn-data@2.0.4:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b"
+  integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==
+
 mdn-data@~1.1.0:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01"
@@ -10433,13 +9810,6 @@ media-typer@0.3.0:
   resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
   integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
 
-mem@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76"
-  integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=
-  dependencies:
-    mimic-fn "^1.0.0"
-
 mem@^4.0.0:
   version "4.3.0"
   resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178"
@@ -10449,15 +9819,10 @@ mem@^4.0.0:
     mimic-fn "^2.0.0"
     p-is-promise "^2.0.0"
 
-memoize-one@^5.0.0:
-  version "5.0.5"
-  resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.5.tgz#8cd3809555723a07684afafcd6f756072ac75d7e"
-  integrity sha512-ey6EpYv0tEaIbM/nTDOpHciXUvd+ackQrJgEzBwemhZZIWZjcyodqEcrmqDy2BKRTM3a65kKBV4WtLXJDt26SQ==
-
-memoize-one@^5.0.1:
-  version "5.0.4"
-  resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.4.tgz#005928aced5c43d890a4dfab18ca908b0ec92cbc"
-  integrity sha512-P0z5IeAH6qHHGkJIXWw0xC2HNEgkx/9uWWBQw64FJj3/ol14VYdfVGWWr0fXfjhhv3TKVIqUq65os6O4GUNksA==
+memoize-one@^5.0.0, memoize-one@^5.0.1:
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0"
+  integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==
 
 memoizerific@^1.11.3:
   version "1.11.3"
@@ -10466,10 +9831,18 @@ memoizerific@^1.11.3:
   dependencies:
     map-or-similar "^1.5.0"
 
-memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1:
-  version "0.4.1"
-  resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
-  integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=
+memory-fs@^0.4.0, memory-fs@^0.4.1:
+  version "0.4.1"
+  resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
+  integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=
+  dependencies:
+    errno "^0.1.3"
+    readable-stream "^2.0.1"
+
+memory-fs@^0.5.0:
+  version "0.5.0"
+  resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c"
+  integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==
   dependencies:
     errno "^0.1.3"
     readable-stream "^2.0.1"
@@ -10539,10 +9912,10 @@ merge-stream@^2.0.0:
   resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
   integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
 
-merge2@^1.2.3:
-  version "1.2.3"
-  resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5"
-  integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==
+merge2@^1.2.3, merge2@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81"
+  integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==
 
 merge@^1.2.1:
   version "1.2.1"
@@ -10559,7 +9932,7 @@ microevent.ts@~0.1.1:
   resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0"
   integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==
 
-micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8:
+micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4:
   version "3.1.10"
   resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
   integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
@@ -10594,29 +9967,36 @@ miller-rabin@^4.0.0:
     bn.js "^4.0.0"
     brorand "^1.0.1"
 
-mime-db@1.40.0, "mime-db@>= 1.40.0 < 2":
+mime-db@1.40.0:
   version "1.40.0"
   resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32"
   integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
 
-mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
+mime-db@1.42.0, "mime-db@>= 1.40.0 < 2":
+  version "1.42.0"
+  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac"
+  integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==
+
+mime-types@^2.1.12, mime-types@~2.1.19:
   version "2.1.24"
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
   integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
   dependencies:
     mime-db "1.40.0"
 
+mime-types@~2.1.17, mime-types@~2.1.24:
+  version "2.1.25"
+  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437"
+  integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==
+  dependencies:
+    mime-db "1.42.0"
+
 mime@1.6.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
   integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
 
-mime@^2.0.3, mime@^2.4.2:
-  version "2.4.3"
-  resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.3.tgz#229687331e86f68924e6cb59e1cdd937f18275fe"
-  integrity sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==
-
-mime@^2.4.3:
+mime@^2.0.3, mime@^2.4.3, mime@^2.4.4:
   version "2.4.4"
   resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5"
   integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==
@@ -10631,10 +10011,10 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0:
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
   integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
 
-mimic-response@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
-  integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
+mimic-response@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.0.0.tgz#996a51c60adf12cb8a87d7fb8ef24c2f3d5ebb46"
+  integrity sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==
 
 min-document@^2.19.0:
   version "2.19.0"
@@ -10693,28 +10073,20 @@ minimist@~0.0.1:
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
   integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=
 
-minipass@^2.2.1, minipass@^2.3.4, minipass@^2.6.0, minipass@^2.8.6:
-  version "2.8.6"
-  resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.8.6.tgz#620d889ace26356391d010ecb9458749df9b6db5"
-  integrity sha512-lFG7d6g3+/UaFDCOtqPiKAC9zngWWsQZl1g5q6gaONqrjq61SX2xFqXMleQiFVyDpYwa018E9hmlAFY22PCb+A==
-  dependencies:
-    safe-buffer "^5.1.2"
-    yallist "^3.0.0"
-
-minipass@^2.3.5:
-  version "2.3.5"
-  resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848"
-  integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==
+minipass@^2.3.5, minipass@^2.6.0, 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==
   dependencies:
     safe-buffer "^5.1.2"
     yallist "^3.0.0"
 
-minizlib@^1.1.1, minizlib@^1.2.1:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.2.tgz#6f0ccc82fa53e1bf2ff145f220d2da9fa6e3a166"
-  integrity sha512-hR3At21uSrsjjDTWrbu0IMLTpnkpv8IIMFDFaoz43Tmu4LkmAXfH44vNNzpTnf+OAQQCHrb91y/wc2J4x5XgSQ==
+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==
   dependencies:
-    minipass "^2.2.1"
+    minipass "^2.9.0"
 
 mississippi@^3.0.0:
   version "3.0.0"
@@ -10748,26 +10120,13 @@ mixin-object@^2.0.1:
     for-in "^0.1.3"
     is-extendable "^0.1.1"
 
-mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
+mkdirp@0.5.1, mkdirp@0.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
   version "0.5.1"
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
   integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
   dependencies:
     minimist "0.0.8"
 
-mobx-react@^5.4.3:
-  version "5.4.4"
-  resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-5.4.4.tgz#b3de9c6eabcd0ed8a40036888cb0221ab9568b80"
-  integrity sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ==
-  dependencies:
-    hoist-non-react-statics "^3.0.0"
-    react-lifecycles-compat "^3.0.2"
-
-mobx@^4.9.2:
-  version "4.9.4"
-  resolved "https://registry.yarnpkg.com/mobx/-/mobx-4.9.4.tgz#bb37a0e4e05f0b02be89ced9d23445cad73377ad"
-  integrity sha512-RaEpydw7D1ebp1pdFHrEMZcLk4nALAZyHAroCPQpqLzuIXIxJpLmMIe5PUZwYHqvlcWL6DVqDYCANZpPOi9iXA==
-
 modify-values@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
@@ -10817,12 +10176,12 @@ ms@2.0.0:
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
   integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
 
-ms@2.1.1, ms@^2.0.0:
+ms@2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
   integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
 
-ms@^2.1.1:
+ms@^2.0.0, ms@^2.1.1:
   version "2.1.2"
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
   integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
@@ -10861,7 +10220,7 @@ mute-stream@~0.0.4:
   resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
   integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
 
-nan@^2.12.1, nan@^2.13.2:
+nan@^2.12.1, nan@^2.13.2, nan@^2.14.0:
   version "2.14.0"
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
   integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
@@ -10889,9 +10248,9 @@ natural-compare@^1.4.0:
   integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
 
 nearley@^2.7.10:
-  version "2.16.0"
-  resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.16.0.tgz#77c297d041941d268290ec84b739d0ee297e83a7"
-  integrity sha512-Tr9XD3Vt/EujXbZBv6UAHYoLUSMQAxSsTnm9K3koXzjzNWY195NqALeyrzLZBKzAkL3gl92BcSogqrHjD8QuUg==
+  version "2.19.0"
+  resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.19.0.tgz#37717781d0fd0f2bfc95e233ebd75678ca4bda46"
+  integrity sha512-2v52FTw7RPqieZr3Gth1luAXZR7Je6q3KaDHY5bjl/paDUdMu35fZ8ICNgiYJRr3tf3NMvIQQR1r27AvEr9CRA==
   dependencies:
     commander "^2.19.0"
     moo "^0.4.3"
@@ -10913,7 +10272,7 @@ negotiator@0.6.2:
   resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
   integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
 
-neo-async@^2.5.0, neo-async@^2.6.0:
+neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1:
   version "2.6.1"
   resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"
   integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==
@@ -10989,10 +10348,10 @@ node-fetch@^2.3.0, node-fetch@^2.6.0:
   resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
   integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
 
-node-forge@0.7.5:
-  version "0.7.5"
-  resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"
-  integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==
+node-forge@0.9.0:
+  version "0.9.0"
+  resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579"
+  integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==
 
 node-gyp@^3.8.0:
   version "3.8.0"
@@ -11012,21 +10371,21 @@ node-gyp@^3.8.0:
     tar "^2.0.0"
     which "1"
 
-node-gyp@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-4.0.0.tgz#972654af4e5dd0cd2a19081b4b46fe0442ba6f45"
-  integrity sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==
+node-gyp@^5.0.2, node-gyp@^5.0.5:
+  version "5.0.5"
+  resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.0.5.tgz#f6cf1da246eb8c42b097d7cd4d6c3ce23a4163af"
+  integrity sha512-WABl9s4/mqQdZneZHVWVG4TVr6QQJZUC6PAx47ITSk9lreZ1n+7Z9mMAIbA3vnO4J9W20P7LhCxtzfWsAD/KDw==
   dependencies:
+    env-paths "^1.0.0"
     glob "^7.0.3"
     graceful-fs "^4.1.2"
     mkdirp "^0.5.0"
     nopt "2 || 3"
     npmlog "0 || 1 || 2 || 3 || 4"
-    osenv "0"
     request "^2.87.0"
     rimraf "2"
     semver "~5.3.0"
-    tar "^4.4.8"
+    tar "^4.4.12"
     which "1"
 
 node-int64@^0.4.0:
@@ -11034,10 +10393,10 @@ node-int64@^0.4.0:
   resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
   integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
 
-node-libs-browser@^2.0.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.0.tgz#c72f60d9d46de08a940dedbb25f3ffa2f9bbaa77"
-  integrity sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==
+node-libs-browser@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
+  integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==
   dependencies:
     assert "^1.1.1"
     browserify-zlib "^0.2.0"
@@ -11049,7 +10408,7 @@ node-libs-browser@^2.0.0:
     events "^3.0.0"
     https-browserify "^1.0.0"
     os-browserify "^0.3.0"
-    path-browserify "0.0.0"
+    path-browserify "0.0.1"
     process "^0.11.10"
     punycode "^1.2.4"
     querystring-es3 "^0.2.0"
@@ -11061,7 +10420,7 @@ node-libs-browser@^2.0.0:
     tty-browserify "0.0.0"
     url "^0.11.0"
     util "^0.11.0"
-    vm-browserify "0.0.4"
+    vm-browserify "^1.0.1"
 
 node-modules-regexp@^1.0.0:
   version "1.0.0"
@@ -11111,26 +10470,12 @@ node-pre-gyp@^0.12.0:
     semver "^5.3.0"
     tar "^4"
 
-node-releases@^1.1.13:
-  version "1.1.26"
-  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.26.tgz#f30563edc5c7dc20cf524cc8652ffa7be0762937"
-  integrity sha512-fZPsuhhUHMTlfkhDLGtfY80DSJTjOcx+qD1j5pqPkuhUHVS7xHZIg9EE4DHK8O3f0zTxXHX5VIkDG8pu98/wfQ==
-  dependencies:
-    semver "^5.3.0"
-
-node-releases@^1.1.19:
-  version "1.1.20"
-  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.20.tgz#f77f9f9a4fcb22e74ba88fe15732a3a8b037146d"
-  integrity sha512-YnC3NemTLgzOkQTmR4+0yl/7pIsXZcfWXoquNp0Dql03GQ+CYURhnjUDFsSJxpX/Q9nw8lAjLFdnACQoKs6h5w==
-  dependencies:
-    semver "^5.3.0"
-
-node-releases@^1.1.25:
-  version "1.1.25"
-  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.25.tgz#0c2d7dbc7fed30fbe02a9ee3007b8c90bf0133d3"
-  integrity sha512-fI5BXuk83lKEoZDdH3gRhtsNgh05/wZacuXkgbiYkceE7+QIMXOg98n9ZV7mz27B+kFHnqHcUpscZZlGRSmTpQ==
+node-releases@^1.1.29:
+  version "1.1.35"
+  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.35.tgz#32a74a3cd497aa77f23d509f483475fd160e4c48"
+  integrity sha512-JGcM/wndCN/2elJlU0IGdVEJQQnJwsLbgPCFd2pY7V0mxf17bZ0Gb/lgOtL29ZQhvEX5shnVhxQyZz3ex94N8w==
   dependencies:
-    semver "^5.3.0"
+    semver "^6.3.0"
 
 node-sass@^4.11.0:
   version "4.12.0"
@@ -11215,9 +10560,9 @@ normalize-url@1.9.1:
     sort-keys "^1.0.0"
 
 normalize-url@^4.0.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.3.0.tgz#9c49e10fc1876aeb76dba88bf1b2b5d9fa57b2ee"
-  integrity sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ==
+  version "4.5.0"
+  resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
+  integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
 
 npm-audit-report@^1.3.2:
   version "1.3.2"
@@ -11237,21 +10582,21 @@ npm-cache-filename@~1.0.2:
   resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11"
   integrity sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=
 
-npm-install-checks@~3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.0.tgz#d4aecdfd51a53e3723b7b2f93b2ee28e307bc0d7"
-  integrity sha1-1K7N/VGlPjcjt7L5Oy7ijjB7wNc=
+npm-install-checks@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.2.tgz#ab2e32ad27baa46720706908e5b14c1852de44d9"
+  integrity sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg==
   dependencies:
     semver "^2.3.0 || 3.x || 4 || 5"
 
-npm-lifecycle@^2.0.3, npm-lifecycle@^2.1.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-2.1.1.tgz#0027c09646f0fd346c5c93377bdaba59c6748fdf"
-  integrity sha512-+Vg6I60Z75V/09pdcH5iUo/99Q/vop35PaI99elvxk56azSVVsdsSsS/sXqKDNwbRRNN1qSxkcO45ZOu0yOWew==
+npm-lifecycle@^3.0.0, npm-lifecycle@^3.1.4:
+  version "3.1.4"
+  resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.4.tgz#de6975c7d8df65f5150db110b57cce498b0b604c"
+  integrity sha512-tgs1PaucZwkxECGKhC/stbEgFyc3TGh2TJcg2CDr6jbvQRdteHNhmMeljRzpe4wgFAXQADoy1cSqqi7mtiAa5A==
   dependencies:
     byline "^5.0.0"
     graceful-fs "^4.1.15"
-    node-gyp "^4.0.0"
+    node-gyp "^5.0.2"
     resolve-from "^4.0.0"
     slide "^1.1.6"
     uid-number "0.0.6"
@@ -11263,61 +10608,54 @@ npm-logical-tree@^1.2.1:
   resolved "https://registry.yarnpkg.com/npm-logical-tree/-/npm-logical-tree-1.2.1.tgz#44610141ca24664cad35d1e607176193fd8f5b88"
   integrity sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg==
 
-"npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0:
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1"
-  integrity sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==
+"npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0, npm-package-arg@^6.1.1:
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7"
+  integrity sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==
   dependencies:
-    hosted-git-info "^2.6.0"
+    hosted-git-info "^2.7.1"
     osenv "^0.1.5"
-    semver "^5.5.0"
+    semver "^5.6.0"
     validate-npm-package-name "^3.0.0"
 
-npm-packlist@^1.1.12, npm-packlist@^1.4.1:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc"
-  integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==
-  dependencies:
-    ignore-walk "^3.0.1"
-    npm-bundled "^1.0.1"
-
-npm-packlist@^1.1.6:
-  version "1.4.4"
-  resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.4.tgz#866224233850ac534b63d1a6e76050092b5d2f44"
-  integrity sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==
+npm-packlist@^1.1.12, npm-packlist@^1.1.6, npm-packlist@^1.4.4:
+  version "1.4.6"
+  resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.6.tgz#53ba3ed11f8523079f1457376dd379ee4ea42ff4"
+  integrity sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg==
   dependencies:
     ignore-walk "^3.0.1"
     npm-bundled "^1.0.1"
 
-npm-pick-manifest@^2.2.3:
-  version "2.2.3"
-  resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz#32111d2a9562638bb2c8f2bf27f7f3092c8fae40"
-  integrity sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==
+npm-pick-manifest@^3.0.0, npm-pick-manifest@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz#f4d9e5fd4be2153e5f4e5f9b7be8dc419a99abb7"
+  integrity sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==
   dependencies:
     figgy-pudding "^3.5.1"
     npm-package-arg "^6.0.0"
     semver "^5.4.1"
 
-npm-profile@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-4.0.1.tgz#d350f7a5e6b60691c7168fbb8392c3603583f5aa"
-  integrity sha512-NQ1I/1Q7YRtHZXkcuU1/IyHeLy6pd+ScKg4+DQHdfsm769TGq6HPrkbuNJVJS4zwE+0mvvmeULzQdWn2L2EsVA==
+npm-profile@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-4.0.2.tgz#8272a71c19634d0dce9c35a5daf8ee589cbb0f52"
+  integrity sha512-VRsC04pvRH+9cF+PoVh2nTmJjiG21yu59IHpsBpkxk+jaGAV8lxx96G4SDc0jOHAkfWLXbc6kIph3dGAuRnotQ==
   dependencies:
     aproba "^1.1.2 || 2"
     figgy-pudding "^3.4.1"
-    npm-registry-fetch "^3.8.0"
+    npm-registry-fetch "^4.0.0"
 
-npm-registry-fetch@^3.8.0, npm-registry-fetch@^3.9.0:
-  version "3.9.0"
-  resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.9.0.tgz#44d841780e2833f06accb34488f8c7450d1a6856"
-  integrity sha512-srwmt8YhNajAoSAaDWndmZgx89lJwIZ1GWxOuckH4Coek4uHv5S+o/l9FLQe/awA+JwTnj4FJHldxhlXdZEBmw==
+npm-registry-fetch@^4.0.0:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.2.tgz#2b1434f93ccbe6b6385f8e45f45db93e16921d7a"
+  integrity sha512-Z0IFtPEozNdeZRPh3aHHxdG+ZRpzcbQaJLthsm3VhNf6DScicTFRHZzK82u8RsJUsUHkX+QH/zcB/5pmd20H4A==
   dependencies:
     JSONStream "^1.3.4"
     bluebird "^3.5.1"
     figgy-pudding "^3.4.1"
-    lru-cache "^4.1.3"
-    make-fetch-happen "^4.0.1"
+    lru-cache "^5.1.1"
+    make-fetch-happen "^5.0.0"
     npm-package-arg "^6.1.0"
+    safe-buffer "^5.2.0"
 
 npm-run-path@^2.0.0:
   version "2.0.2"
@@ -11338,10 +10676,10 @@ npm-user-validate@~1.0.0:
   resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.0.tgz#8ceca0f5cea04d4e93519ef72d0557a75122e951"
   integrity sha1-jOyg9c6gTU6TUZ73LQVXp1Ei6VE=
 
-npm@^6.8.0:
-  version "6.9.0"
-  resolved "https://registry.yarnpkg.com/npm/-/npm-6.9.0.tgz#5296720486814a64a7fb082de00c4b5cfd11211f"
-  integrity sha512-91V+zB5hDxO+Jyp2sUKS7juHlIM95dGQxTeQtmZI1nAI/7kjWXFipPrtwwKjhyKmV4GsS2LzJhrxRjGWsU9z/w==
+npm@^6.10.3:
+  version "6.12.0"
+  resolved "https://registry.yarnpkg.com/npm/-/npm-6.12.0.tgz#255e6fbb514be15c6595f9cbc5bc248e251e1476"
+  integrity sha512-juj5VkB3/k+PWbJUnXD7A/8oc8zLusDnK/sV9PybSalsbOVOTIp5vSE0rz5rQ7BsmUgQS47f/L2GYQnWXaKgnQ==
   dependencies:
     JSONStream "^1.3.5"
     abbrev "~1.1.1"
@@ -11349,16 +10687,16 @@ npm@^6.8.0:
     ansistyles "~0.1.3"
     aproba "^2.0.0"
     archy "~1.0.0"
-    bin-links "^1.1.2"
-    bluebird "^3.5.3"
+    bin-links "^1.1.3"
+    bluebird "^3.5.5"
     byte-size "^5.0.1"
-    cacache "^11.3.2"
-    call-limit "~1.1.0"
-    chownr "^1.1.1"
+    cacache "^12.0.3"
+    call-limit "^1.1.1"
+    chownr "^1.1.2"
     ci-info "^2.0.0"
     cli-columns "^3.1.2"
     cli-table3 "^0.5.1"
-    cmd-shim "~2.0.2"
+    cmd-shim "^3.0.3"
     columnify "~1.5.4"
     config-chain "^1.1.12"
     detect-indent "~5.0.0"
@@ -11369,22 +10707,27 @@ npm@^6.8.0:
     find-npm-prefix "^1.0.2"
     fs-vacuum "~1.2.10"
     fs-write-stream-atomic "~1.0.10"
-    gentle-fs "^2.0.1"
-    glob "^7.1.3"
-    graceful-fs "^4.1.15"
+    gentle-fs "^2.2.1"
+    glob "^7.1.4"
+    graceful-fs "^4.2.2"
     has-unicode "~2.0.1"
-    hosted-git-info "^2.7.1"
+    hosted-git-info "^2.8.5"
     iferr "^1.0.2"
+    infer-owner "^1.0.4"
     inflight "~1.0.6"
-    inherits "~2.0.3"
+    inherits "^2.0.4"
     ini "^1.3.5"
     init-package-json "^1.10.3"
     is-cidr "^3.0.0"
     json-parse-better-errors "^1.0.2"
     lazy-property "~1.0.0"
-    libcipm "^3.0.3"
-    libnpm "^2.0.1"
-    libnpmhook "^5.0.2"
+    libcipm "^4.0.4"
+    libnpm "^3.0.1"
+    libnpmaccess "^3.0.2"
+    libnpmhook "^5.0.3"
+    libnpmorg "^1.0.1"
+    libnpmsearch "^2.0.2"
+    libnpmteam "^1.0.2"
     libnpx "^10.2.0"
     lock-verify "^2.1.0"
     lockfile "^1.0.4"
@@ -11393,51 +10736,53 @@ npm@^6.8.0:
     lodash.union "~4.6.0"
     lodash.uniq "~4.5.0"
     lodash.without "~4.4.0"
-    lru-cache "^4.1.5"
+    lru-cache "^5.1.1"
     meant "~1.0.1"
     mississippi "^3.0.0"
     mkdirp "~0.5.1"
     move-concurrently "^1.0.1"
-    node-gyp "^3.8.0"
+    node-gyp "^5.0.5"
     nopt "~4.0.1"
     normalize-package-data "^2.5.0"
     npm-audit-report "^1.3.2"
     npm-cache-filename "~1.0.2"
-    npm-install-checks "~3.0.0"
-    npm-lifecycle "^2.1.0"
-    npm-package-arg "^6.1.0"
-    npm-packlist "^1.4.1"
-    npm-pick-manifest "^2.2.3"
-    npm-registry-fetch "^3.9.0"
+    npm-install-checks "^3.0.2"
+    npm-lifecycle "^3.1.4"
+    npm-package-arg "^6.1.1"
+    npm-packlist "^1.4.4"
+    npm-pick-manifest "^3.0.2"
+    npm-profile "^4.0.2"
+    npm-registry-fetch "^4.0.0"
     npm-user-validate "~1.0.0"
     npmlog "~4.1.2"
     once "~1.4.0"
     opener "^1.5.1"
     osenv "^0.1.5"
-    pacote "^9.5.0"
+    pacote "^9.5.8"
     path-is-inside "~1.0.2"
     promise-inflight "~1.0.1"
     qrcode-terminal "^0.12.0"
-    query-string "^6.2.0"
+    query-string "^6.8.2"
     qw "~1.0.1"
     read "~1.0.7"
-    read-cmd-shim "~1.0.1"
+    read-cmd-shim "^1.0.4"
     read-installed "~4.0.3"
-    read-package-json "^2.0.13"
-    read-package-tree "^5.2.2"
-    readable-stream "^3.1.1"
+    read-package-json "^2.1.0"
+    read-package-tree "^5.3.1"
+    readable-stream "^3.4.0"
+    readdir-scoped-modules "^1.1.0"
     request "^2.88.0"
     retry "^0.12.0"
     rimraf "^2.6.3"
     safe-buffer "^5.1.2"
-    semver "^5.6.0"
-    sha "~2.0.1"
+    semver "^5.7.1"
+    sha "^3.0.0"
     slide "~1.1.6"
     sorted-object "~2.0.1"
     sorted-union-stream "~2.1.3"
     ssri "^6.0.1"
-    stringify-package "^1.0.0"
-    tar "^4.4.8"
+    stringify-package "^1.0.1"
+    tar "^4.4.12"
     text-table "~0.2.0"
     tiny-relative-date "^1.3.0"
     uid-number "0.0.6"
@@ -11449,8 +10794,8 @@ npm@^6.8.0:
     validate-npm-package-license "^3.0.4"
     validate-npm-package-name "~3.0.0"
     which "^1.3.1"
-    worker-farm "^1.6.0"
-    write-file-atomic "^2.4.2"
+    worker-farm "^1.7.0"
+    write-file-atomic "^2.4.3"
 
 "npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2, npmlog@^4.1.2, npmlog@~4.1.2:
   version "4.1.2"
@@ -11551,14 +10896,14 @@ object.entries@^1.0.4, object.entries@^1.1.0:
     has "^1.0.3"
 
 object.fromentries@^2.0.0, "object.fromentries@^2.0.0 || ^1.0.0":
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab"
-  integrity sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.1.tgz#050f077855c7af8ae6649f45c80b16ee2d31e704"
+  integrity sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA==
   dependencies:
-    define-properties "^1.1.2"
-    es-abstract "^1.11.0"
+    define-properties "^1.1.3"
+    es-abstract "^1.15.0"
     function-bind "^1.1.1"
-    has "^1.0.1"
+    has "^1.0.3"
 
 object.getownpropertydescriptors@^2.0.3:
   version "2.0.3"
@@ -11628,7 +10973,7 @@ onetime@^5.1.0:
   dependencies:
     mimic-fn "^2.1.0"
 
-open@^6.1.0:
+open@^6.1.0, open@^6.3.0:
   version "6.4.0"
   resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9"
   integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==
@@ -11640,13 +10985,6 @@ opener@^1.5.1:
   resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
   integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==
 
-opn@5.4.0:
-  version "5.4.0"
-  resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035"
-  integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==
-  dependencies:
-    is-wsl "^1.1.0"
-
 opn@^5.5.0:
   version "5.5.0"
   resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"
@@ -11698,15 +11036,6 @@ os-locale@^1.4.0:
   dependencies:
     lcid "^1.0.0"
 
-os-locale@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2"
-  integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==
-  dependencies:
-    execa "^0.7.0"
-    lcid "^1.0.0"
-    mem "^1.1.0"
-
 os-locale@^3.0.0, os-locale@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
@@ -11716,7 +11045,7 @@ os-locale@^3.0.0, os-locale@^3.1.0:
     lcid "^2.0.0"
     mem "^4.0.0"
 
-os-name@^3.0.0:
+os-name@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801"
   integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==
@@ -11749,13 +11078,6 @@ p-each-series@^1.0.0:
   dependencies:
     p-reduce "^1.0.0"
 
-p-filter@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-1.0.0.tgz#629d317150209c8fd508ba137713ef4bb920e9db"
-  integrity sha1-Yp0xcVAgnI/VCLoTdxPvS7kg6ds=
-  dependencies:
-    p-map "^1.0.0"
-
 p-filter@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c"
@@ -11778,6 +11100,11 @@ p-is-promise@^2.0.0:
   resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
   integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
 
+p-is-promise@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-3.0.0.tgz#58e78c7dfe2e163cf2a04ff869e7c1dba64a5971"
+  integrity sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==
+
 p-limit@^1.1.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
@@ -11785,20 +11112,13 @@ p-limit@^1.1.0:
   dependencies:
     p-try "^1.0.0"
 
-p-limit@^2.0.0:
+p-limit@^2.0.0, p-limit@^2.2.0:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537"
   integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==
   dependencies:
     p-try "^2.0.0"
 
-p-limit@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2"
-  integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==
-  dependencies:
-    p-try "^2.0.0"
-
 p-locate@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
@@ -11820,11 +11140,6 @@ p-locate@^4.0.0, p-locate@^4.1.0:
   dependencies:
     p-limit "^2.2.0"
 
-p-map@^1.0.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
-  integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==
-
 p-map@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
@@ -11840,7 +11155,7 @@ p-reduce@^2.0.0:
   resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a"
   integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==
 
-p-retry@^3.0.0:
+p-retry@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328"
   integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==
@@ -11875,18 +11190,20 @@ package-json@^4.0.0:
     registry-url "^3.0.3"
     semver "^5.1.0"
 
-pacote@^9.1.0, pacote@^9.2.3, pacote@^9.5.0:
-  version "9.5.0"
-  resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.0.tgz#85f3013a3f6dd51c108b0ccabd3de8102ddfaeda"
-  integrity sha512-aUplXozRbzhaJO48FaaeClmN+2Mwt741MC6M3bevIGZwdCaP7frXzbUOfOWa91FPHoLITzG0hYaKY363lxO3bg==
+pacote@^9.1.0, pacote@^9.5.3, pacote@^9.5.8:
+  version "9.5.8"
+  resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.8.tgz#23480efdc4fa74515855c9ecf39cf64078f99786"
+  integrity sha512-0Tl8Oi/K0Lo4MZmH0/6IsT3gpGf9eEAznLXEQPKgPq7FscnbUOyopnVpwXlnQdIbCUaojWy1Wd7VMyqfVsRrIw==
   dependencies:
     bluebird "^3.5.3"
-    cacache "^11.3.2"
+    cacache "^12.0.2"
+    chownr "^1.1.2"
     figgy-pudding "^3.5.1"
     get-stream "^4.1.0"
     glob "^7.1.3"
+    infer-owner "^1.0.4"
     lru-cache "^5.1.1"
-    make-fetch-happen "^4.0.1"
+    make-fetch-happen "^5.0.0"
     minimatch "^3.0.4"
     minipass "^2.3.5"
     mississippi "^3.0.0"
@@ -11894,8 +11211,8 @@ pacote@^9.1.0, pacote@^9.2.3, pacote@^9.5.0:
     normalize-package-data "^2.4.0"
     npm-package-arg "^6.1.0"
     npm-packlist "^1.1.12"
-    npm-pick-manifest "^2.2.3"
-    npm-registry-fetch "^3.8.0"
+    npm-pick-manifest "^3.0.0"
+    npm-registry-fetch "^4.0.0"
     osenv "^0.1.5"
     promise-inflight "^1.0.1"
     promise-retry "^1.1.1"
@@ -11904,7 +11221,7 @@ pacote@^9.1.0, pacote@^9.2.3, pacote@^9.5.0:
     safe-buffer "^5.1.2"
     semver "^5.6.0"
     ssri "^6.0.1"
-    tar "^4.4.8"
+    tar "^4.4.10"
     unique-filename "^1.1.1"
     which "^1.3.1"
 
@@ -11914,15 +11231,15 @@ pako@~1.0.5:
   integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==
 
 parallel-transform@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06"
-  integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc"
+  integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==
   dependencies:
-    cyclist "~0.2.2"
+    cyclist "^1.0.1"
     inherits "^2.0.3"
     readable-stream "^2.1.5"
 
-param-case@2.1.x:
+param-case@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
   integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc=
@@ -11937,9 +11254,9 @@ parent-module@^1.0.0:
     callsites "^3.0.0"
 
 parse-asn1@^5.0.0:
-  version "5.1.4"
-  resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc"
-  integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==
+  version "5.1.5"
+  resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e"
+  integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==
   dependencies:
     asn1.js "^4.0.0"
     browserify-aes "^1.0.0"
@@ -12000,7 +11317,7 @@ parse5@4.0.0:
   resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
   integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==
 
-parse5@5.1.0, parse5@^5.0.0:
+parse5@5.1.0:
   version "5.1.0"
   resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2"
   integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==
@@ -12022,10 +11339,10 @@ pascalcase@^0.1.1:
   resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
   integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
 
-path-browserify@0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a"
-  integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=
+path-browserify@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
+  integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==
 
 path-dirname@^1.0.0:
   version "1.0.2"
@@ -12129,9 +11446,9 @@ performance-now@^2.1.0:
   integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
 
 picomatch@^2.0.5:
-  version "2.0.7"
-  resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6"
-  integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.1.tgz#ecdfbea7704adb5fe6fb47f9866c4c0e15e905c5"
+  integrity sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==
 
 pify@^2.0.0, pify@^2.3.0:
   version "2.3.0"
@@ -12211,9 +11528,9 @@ pkg-up@2.0.0:
     find-up "^2.1.0"
 
 please-upgrade-node@^3.1.1:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac"
-  integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"
+  integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==
   dependencies:
     semver-compare "^1.0.0"
 
@@ -12246,14 +11563,14 @@ popper.js@^1.14.4, popper.js@^1.14.7:
   resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.15.0.tgz#5560b99bbad7647e9faa475c6b8056621f5a4ff2"
   integrity sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA==
 
-portfinder@^1.0.20:
-  version "1.0.20"
-  resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a"
-  integrity sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==
+portfinder@^1.0.25:
+  version "1.0.25"
+  resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca"
+  integrity sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==
   dependencies:
-    async "^1.5.2"
-    debug "^2.2.0"
-    mkdirp "0.5.x"
+    async "^2.6.2"
+    debug "^3.1.1"
+    mkdirp "^0.5.1"
 
 posix-character-classes@^0.1.0:
   version "0.1.1"
@@ -12286,11 +11603,11 @@ postcss-flexbugs-fixes@^4.1.0:
     postcss "^7.0.0"
 
 postcss-load-config@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.0.0.tgz#f1312ddbf5912cd747177083c5ef7a19d62ee484"
-  integrity sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003"
+  integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==
   dependencies:
-    cosmiconfig "^4.0.0"
+    cosmiconfig "^5.0.0"
     import-cwd "^2.0.0"
 
 postcss-loader@^3.0.0:
@@ -12359,24 +11676,15 @@ postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1:
   resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
   integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
 
-postcss-value-parser@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz#99a983d365f7b2ad8d0f9b8c3094926eab4b936d"
-  integrity sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ==
-
-postcss@^7.0.0, postcss@^7.0.14, postcss@^7.0.5, postcss@^7.0.6:
-  version "7.0.16"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.16.tgz#48f64f1b4b558cb8b52c88987724359acb010da2"
-  integrity sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==
-  dependencies:
-    chalk "^2.4.2"
-    source-map "^0.6.1"
-    supports-color "^6.1.0"
+postcss-value-parser@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9"
+  integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==
 
-postcss@^7.0.17, postcss@^7.0.7:
-  version "7.0.17"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.17.tgz#4da1bdff5322d4a0acaab4d87f3e782436bad31f"
-  integrity sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==
+postcss@^7.0.0, postcss@^7.0.14, postcss@^7.0.18, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
+  version "7.0.18"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.18.tgz#4b9cda95ae6c069c67a4d933029eddd4838ac233"
+  integrity sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==
   dependencies:
     chalk "^2.4.2"
     source-map "^0.6.1"
@@ -12447,13 +11755,20 @@ pretty-quick@^2.0.0:
     mri "^1.1.4"
     multimatch "^4.0.0"
 
-prismjs@^1.8.4, prismjs@~1.16.0:
+prismjs@^1.8.4:
   version "1.16.0"
   resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.16.0.tgz#406eb2c8aacb0f5f0f1167930cb83835d10a4308"
   integrity sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA==
   optionalDependencies:
     clipboard "^2.0.0"
 
+prismjs@~1.17.0:
+  version "1.17.1"
+  resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.17.1.tgz#e669fcbd4cdd873c35102881c33b14d0d68519be"
+  integrity sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q==
+  optionalDependencies:
+    clipboard "^2.0.0"
+
 private@^0.1.6, private@^0.1.8, private@~0.1.5:
   version "0.1.8"
   resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@@ -12469,11 +11784,6 @@ process@^0.11.10:
   resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
   integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
 
-process@~0.5.1:
-  version "0.5.2"
-  resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
-  integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=
-
 progress@^2.0.0, progress@^2.0.1:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
@@ -12502,12 +11812,12 @@ promise.allsettled@^1.0.0:
     function-bind "^1.1.1"
 
 promise.prototype.finally@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.0.tgz#66f161b1643636e50e7cf201dc1b84a857f3864e"
-  integrity sha512-7p/K2f6dI+dM8yjRQEGrTQs5hTQixUAdOGpMEA3+pVxpX5oHKRSKAXyLw9Q9HUWDTdwtoo39dSHGQtN90HcEwQ==
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.1.tgz#cb279d3a5020ca6403b3d92357f8e22d50ed92aa"
+  integrity sha512-gnt8tThx0heJoI3Ms8a/JdkYBVhYP/wv+T7yQimR+kdOEJL21xTFbiJhMRqnSPcr54UVvMbsscDk2w+ivyaLPw==
   dependencies:
-    define-properties "^1.1.2"
-    es-abstract "^1.9.0"
+    define-properties "^1.1.3"
+    es-abstract "^1.13.0"
     function-bind "^1.1.1"
 
 promise@^7.1.1:
@@ -12550,10 +11860,10 @@ prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0,
     object-assign "^4.1.1"
     react-is "^16.8.1"
 
-property-information@^5.0.0, property-information@^5.0.1:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.1.0.tgz#e4755eee5319f03f7f6f5a9bc1a6a7fea6609e2c"
-  integrity sha512-tODH6R3+SwTkAQckSp2S9xyYX8dEKYkeXw+4TmJzTxnNzd6mQPu1OD4f9zPrvw/Rm4wpPgI+Zp63mNSGNzUgHg==
+property-information@^5.0.1:
+  version "5.3.0"
+  resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.3.0.tgz#bc87ac82dc4e72a31bb62040544b1bf9653da039"
+  integrity sha512-IslotQn1hBCZDY7SaJ3zmCjVea219VTwmOk6Pu3z9haU9m4+T8GwaDubur+6NMHEU+Fjs/6/p66z6QULPkcL1w==
   dependencies:
     xtend "^4.0.1"
 
@@ -12673,11 +11983,16 @@ qrcode-terminal@^0.12.0:
   resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819"
   integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==
 
-qs@6.7.0, qs@^6.6.0:
+qs@6.7.0:
   version "6.7.0"
   resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
   integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
 
+qs@^6.6.0:
+  version "6.9.0"
+  resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.0.tgz#d1297e2a049c53119cb49cca366adbbacc80b409"
+  integrity sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==
+
 qs@~6.5.2:
   version "6.5.2"
   resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
@@ -12691,10 +12006,10 @@ query-string@^4.1.0:
     object-assign "^4.1.0"
     strict-uri-encode "^1.0.0"
 
-query-string@^6.2.0:
-  version "6.5.0"
-  resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.5.0.tgz#2e1a70125af01f6f04573692d02c09302a1d8bfc"
-  integrity sha512-TYC4hDjZSvVxLMEucDMySkuAS9UIzSbAiYGyA9GWCjLKB8fQpviFbjd20fD7uejCDxZS+ftSdBKE6DS+xucJFg==
+query-string@^6.8.2:
+  version "6.8.3"
+  resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.3.tgz#fd9fb7ffb068b79062b43383685611ee47777d4b"
+  integrity sha512-llcxWccnyaWlODe7A9hRjkvdCKamEKTh+wH8ITdTc3OhchaqUZteiSCX/2ablWHVrkVIe04dntnaZJ7BdyW0lQ==
   dependencies:
     decode-uri-component "^0.2.0"
     split-on-first "^1.0.0"
@@ -12725,10 +12040,10 @@ qw@~1.0.1:
   resolved "https://registry.yarnpkg.com/qw/-/qw-1.0.1.tgz#efbfdc740f9ad054304426acb183412cc8b996d4"
   integrity sha1-77/cdA+a0FQwRCassYNBLMi5ltQ=
 
-raf-schd@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.0.tgz#9855756c5045ff4ed4516e14a47719387c3c907b"
-  integrity sha512-m7zq0JkIrECzw9mO5Zcq6jN4KayE34yoIS9hJoiZNXyOAT06PPA8PrR+WtJIeFW09YjUfNkMMN9lrmAt6BURCA==
+raf-schd@^4.0.0, raf-schd@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.2.tgz#bd44c708188f2e84c810bf55fcea9231bcaed8a0"
+  integrity sha512-VhlMZmGy6A6hrkJWHLNTGl5gtgMUm+xfGza6wbwnE914yeQ5Ybm18vgM734RZhMgfw4tacUrWseGZlpUrrakEQ==
 
 raf@^3.4.0:
   version "3.4.1"
@@ -12803,6 +12118,11 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8:
     minimist "^1.2.0"
     strip-json-comments "~2.0.1"
 
+re-reselect@^3.4.0:
+  version "3.4.0"
+  resolved "https://registry.yarnpkg.com/re-reselect/-/re-reselect-3.4.0.tgz#0f2303f3c84394f57f0cd31fea08a1ca4840a7cd"
+  integrity sha512-JsecfN+JlckncVXTWFWjn0Vk6uInl8GSf4eEd9tTk5qXHlgqkPdILpnYpgZcISXNYAzvfvsCZviaDk8AxyS5sg==
+
 react-ace@^5.5.0:
   version "5.10.0"
   resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-5.10.0.tgz#e328b37ac52759f700be5afdb86ada2f5ec84c5e"
@@ -12837,12 +12157,11 @@ react-beautiful-dnd@^10.1.0:
     tiny-invariant "^1.0.4"
 
 react-clientside-effect@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.0.tgz#db823695f75e9616a5e4dd6d908e5ea627fb2516"
-  integrity sha512-cVIsGG7SNHsQsCP4+fw7KFUB0HiYiU8hbvL640XaLCbZ31aK8/lj0qOKJ2K+xRjuQz/IM4Q4qclI0aEqTtcXtA==
+  version "1.2.2"
+  resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.2.tgz#6212fb0e07b204e714581dd51992603d1accc837"
+  integrity sha512-nRmoyxeok5PBO6ytPvSjKp9xwXg9xagoTK1mMjwnQxqM9Hd7MNPl+LS1bOSOe+CV2+4fnEquc7H/S8QD3q697A==
   dependencies:
     "@babel/runtime" "^7.0.0"
-    shallowequal "^1.1.0"
 
 react-color@^2.17.0:
   version "2.17.3"
@@ -12857,44 +12176,44 @@ react-color@^2.17.0:
     tinycolor2 "^1.4.1"
 
 react-dev-utils@^9.0.0:
-  version "9.0.1"
-  resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-9.0.1.tgz#5c03d85a0b2537d0c46af7165c24a7dfb274bef2"
-  integrity sha512-pnaeMo/Pxel8aZpxk1WwxT3uXxM3tEwYvsjCYn5R7gNxjhN1auowdcLDzFB8kr7rafAj2rxmvfic/fbac5CzwQ==
+  version "9.1.0"
+  resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-9.1.0.tgz#3ad2bb8848a32319d760d0a84c56c14bdaae5e81"
+  integrity sha512-X2KYF/lIGyGwP/F/oXgGDF24nxDA2KC4b7AFto+eqzc/t838gpSGiaU8trTqHXOohuLxxc5qi1eDzsl9ucPDpg==
   dependencies:
-    "@babel/code-frame" "7.0.0"
-    address "1.0.3"
-    browserslist "4.5.4"
+    "@babel/code-frame" "7.5.5"
+    address "1.1.2"
+    browserslist "4.7.0"
     chalk "2.4.2"
     cross-spawn "6.0.5"
     detect-port-alt "1.1.6"
     escape-string-regexp "1.0.5"
     filesize "3.6.1"
     find-up "3.0.0"
-    fork-ts-checker-webpack-plugin "1.1.1"
+    fork-ts-checker-webpack-plugin "1.5.0"
     global-modules "2.0.0"
     globby "8.0.2"
-    gzip-size "5.0.0"
+    gzip-size "5.1.1"
     immer "1.10.0"
-    inquirer "6.2.2"
-    is-root "2.0.0"
+    inquirer "6.5.0"
+    is-root "2.1.0"
     loader-utils "1.2.3"
-    opn "5.4.0"
+    open "^6.3.0"
     pkg-up "2.0.0"
-    react-error-overlay "^5.1.6"
+    react-error-overlay "^6.0.3"
     recursive-readdir "2.2.2"
-    shell-quote "1.6.1"
-    sockjs-client "1.3.0"
+    shell-quote "1.7.2"
+    sockjs-client "1.4.0"
     strip-ansi "5.2.0"
     text-table "0.2.0"
 
 react-docgen-typescript-loader@^3.0.1:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/react-docgen-typescript-loader/-/react-docgen-typescript-loader-3.1.0.tgz#09cacf872617c97f946ee920d2239f51d543be41"
-  integrity sha512-gY+b7RkRPty5ZN4NMQ+jwx9MzTVuIj6LJCwdWRAi1+nrHJfH2gMMytQfxFdzQ7BlgD4COWnSE8Ixtl2L62kCRw==
+  version "3.3.0"
+  resolved "https://registry.yarnpkg.com/react-docgen-typescript-loader/-/react-docgen-typescript-loader-3.3.0.tgz#c1f5c1db9a2b6a6bca220bc50fee0a071bc75499"
+  integrity sha512-gC0TeWTz7s7OMyeABppQGbbrtSNi0yl/gBgZJElBtaBFNSJlHH1sfgQybHZmlZqFcn4UBa+8DOGT6wEJKWTV6g==
   dependencies:
     "@webpack-contrib/schema-utils" "^1.0.0-beta.0"
     loader-utils "^1.2.3"
-    react-docgen-typescript "^1.12.3"
+    react-docgen-typescript "^1.15.0"
 
 react-docgen-typescript-webpack-plugin@^1.1.0:
   version "1.1.0"
@@ -12904,10 +12223,10 @@ react-docgen-typescript-webpack-plugin@^1.1.0:
     ajv "^6.1.1"
     react-docgen-typescript "^1.2.3"
 
-react-docgen-typescript@^1.12.3, react-docgen-typescript@^1.2.3:
-  version "1.12.4"
-  resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-1.12.4.tgz#9ec8080e9ef41067ff17153bf42b3b2d49ae5503"
-  integrity sha512-OSmUfmdtcz4kLRWPiR8uUdE8ta+s5DV0uXOz1YsWaAUf3Ty64use7DYWK97zH8ZOlD4slq5zUfGc+UbfGLqfEQ==
+react-docgen-typescript@^1.15.0, react-docgen-typescript@^1.2.3:
+  version "1.15.0"
+  resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-1.15.0.tgz#963f14210841f9b51ed18c65152a6cc37f1c3184"
+  integrity sha512-8xObdkRQbrc0505tEdVRO+pdId8pKFyD6jhLYM9FDdceKma+iB+a17Dk7e3lPRBRh8ArQLCedOCOfN/bO338kw==
 
 react-docgen@^4.1.0:
   version "4.1.1"
@@ -12923,35 +12242,35 @@ react-docgen@^4.1.0:
     recast "^0.17.3"
 
 react-dom@^16.8.3:
-  version "16.8.6"
-  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f"
-  integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==
+  version "16.10.2"
+  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.10.2.tgz#4840bce5409176bc3a1f2bd8cb10b92db452fda6"
+  integrity sha512-kWGDcH3ItJK4+6Pl9DZB16BXYAZyrYQItU4OMy0jAkv5aNqc+mAKb4TpFtAteI6TJZu+9ZlNhaeNQSVQDHJzkw==
   dependencies:
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
     prop-types "^15.6.2"
-    scheduler "^0.13.6"
+    scheduler "^0.16.2"
 
 react-draggable@^3.1.1:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-3.3.0.tgz#2ed7ea3f92e7d742d747f9e6324860606cd4d997"
-  integrity sha512-U7/jD0tAW4T0S7DCPK0kkKLyL0z61sC/eqU+NUfDjnq+JtBKaYKDHpsK2wazctiA4alEzCXUnzkREoxppOySVw==
+  version "3.3.2"
+  resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-3.3.2.tgz#966ef1d90f2387af3c2d8bd3516f601ea42ca359"
+  integrity sha512-oaz8a6enjbPtx5qb0oDWxtDNuybOylvto1QLydsXgKmwT7e3GXC2eMVDwEMIUYJIFqVG72XpOv673UuuAq6LhA==
   dependencies:
     classnames "^2.2.5"
     prop-types "^15.6.0"
 
 react-element-to-jsx-string@^14.0.2:
-  version "14.0.3"
-  resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-14.0.3.tgz#64f50fdbf6ba154d6439da3d7307f79069b94d58"
-  integrity sha512-ziZAm7OwEfFtyhCmQiFNI87KFu+G9EP8qVW4XtDHdKNqqprYifLzqXkzHqC1vnVsPhyp2znoPm0bJHAf1mUBZA==
+  version "14.1.0"
+  resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-14.1.0.tgz#31fcc3a82459d5e57ef852aa6879bcd0a578a8cb"
+  integrity sha512-uvfAsY6bn2c8HMBkxwj+2MMXcvNIkKDl0aZg2Jhzp+c096hZaXUNivVCP2H4RBtmGSSJcfMqQA5oPk8YdqFOVw==
   dependencies:
+    "@base2/pretty-print-object" "^1.0.0"
     is-plain-object "3.0.0"
-    stringify-object "3.3.0"
 
-react-error-overlay@^5.1.6:
-  version "5.1.6"
-  resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-5.1.6.tgz#0cd73407c5d141f9638ae1e0c63e7b2bf7e9929d"
-  integrity sha512-X1Y+0jR47ImDVr54Ab6V9eGk0Hnu7fVWGeHQSOXHf/C2pF9c6uy3gef8QUeuUiWlNb0i08InPSE5a/KJzNzw1Q==
+react-error-overlay@^6.0.3:
+  version "6.0.3"
+  resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.3.tgz#c378c4b0a21e88b2e159a3e62b2f531fd63bf60d"
+  integrity sha512-bOUvMWFQVk5oz8Ded9Xb7WVdEi3QGLC8tH7HmYP0Fdp4Bn3qw0tRFmr5TW6mvahzvmrK4a6bqWGfCevBflP+Xw==
 
 react-fast-compare@2.0.4:
   version "2.0.4"
@@ -12969,9 +12288,9 @@ react-focus-lock@^1.17.7, react-focus-lock@^1.18.3:
     react-clientside-effect "^1.2.0"
 
 react-helmet-async@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.0.2.tgz#bb55dd8268f7b15aac69c6b22e2f950abda8cc44"
-  integrity sha512-qzzchrM/ibHuPS/60ief8jaibPunuRdeta4iBDQV+ri2SFKwOV+X2NlEpvevZOauhmHrH/I6dI4E90EPVfJBBg==
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.0.3.tgz#68a176dd266c2caf63762879c573a866b89a2098"
+  integrity sha512-hthnzAPasSX0ZU0adR1YW51xtMhwQuMwxtyjb/OeS2Gu2bzqFnCtt2h93nENE0+97NPeUS0+YHOriEMX8j/W0w==
   dependencies:
     "@babel/runtime" "7.3.4"
     invariant "2.2.4"
@@ -12987,9 +12306,9 @@ react-hotkeys@2.0.0-pre4:
     prop-types "^15.6.1"
 
 react-input-autosize@^2.2.1:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8"
-  integrity sha512-3+K4CD13iE4lQQ2WlF8PuV5htfmTRLH6MDnfndHM6LuBRszuXnuyIfE7nhSKt8AzRBZ50bu0sAhkNMeS5pxQQA==
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.2.tgz#fcaa7020568ec206bc04be36f4eb68e647c4d8c2"
+  integrity sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw==
   dependencies:
     prop-types "^15.5.8"
 
@@ -13002,15 +12321,10 @@ react-inspector@^3.0.2:
     is-dom "^1.0.9"
     prop-types "^15.6.1"
 
-react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.6:
-  version "16.8.6"
-  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
-  integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
-
-react-is@^16.8.4:
-  version "16.9.0"
-  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb"
-  integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==
+react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0:
+  version "16.10.2"
+  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.2.tgz#984120fd4d16800e9a738208ab1fba422d23b5ab"
+  integrity sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA==
 
 react-is@~16.3.0:
   version "16.3.2"
@@ -13031,20 +12345,20 @@ react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.2, react-lifecycles
   integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
 
 react-popper-tooltip@^2.8.3:
-  version "2.8.3"
-  resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.8.3.tgz#1c63e7473a96362bd93be6c94fa404470a265197"
-  integrity sha512-g5tfxmuj8ClNVwH4zswYJcD3GKoc5RMeRawd/WZnbyZGEDecsRKaVL+Kj7L3BG7w5qb6/MHcLTG8yE4CidwezQ==
+  version "2.9.1"
+  resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.9.1.tgz#cc602c89a937aea378d9e2675b1ce62805beb4f6"
+  integrity sha512-LSbvXLEQlNKWig2GMKQW/1bBwCkWIr9cpJ+WJpSGGGhX45CthRtwyilPPLJQkc3qI6UMTAXPp0Fe/pj9E77trg==
   dependencies:
-    "@babel/runtime" "^7.4.5"
-    react-popper "^1.3.3"
+    "@babel/runtime" "^7.6.3"
+    react-popper "^1.3.4"
 
-react-popper@^1.3.3:
-  version "1.3.3"
-  resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.3.tgz#2c6cef7515a991256b4f0536cd4bdcb58a7b6af6"
-  integrity sha512-ynMZBPkXONPc5K4P5yFWgZx5JGAUIP3pGGLNs58cfAPgK67olx7fmLp+AdpZ0+GoQ+ieFDa/z4cdV6u7sioH6w==
+react-popper@^1.3.4:
+  version "1.3.4"
+  resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.4.tgz#f0cd3b0d30378e1f663b0d79bcc8614221652ced"
+  integrity sha512-9AcQB29V+WrBKk6X7p0eojd1f25/oJajVdMZkywIoAV6Ag7hzE1Mhyeup2Q1QnvFRtGQFQvtqfhlEoDAPfKAVA==
   dependencies:
     "@babel/runtime" "^7.1.2"
-    create-react-context "<=0.2.2"
+    create-react-context "^0.3.0"
     popper.js "^1.14.4"
     prop-types "^15.6.1"
     typed-styles "^0.0.7"
@@ -13061,27 +12375,39 @@ react-reconciler@^0.20.1:
     scheduler "^0.13.6"
 
 react-redux@^5.0.7:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.1.1.tgz#88e368682c7fa80e34e055cd7ac56f5936b0f52f"
-  integrity sha512-LE7Ned+cv5qe7tMV5BPYkGQ5Lpg8gzgItK07c67yHvJ8t0iaD9kPFPAli/mYkiyJYrs2pJgExR2ZgsGqlrOApg==
+  version "5.1.2"
+  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.1.2.tgz#b19cf9e21d694422727bf798e934a916c4080f57"
+  integrity sha512-Ns1G0XXc8hDyH/OcBHOxNgQx9ayH3SPxBnFCOidGKSle8pKihysQw2rG/PmciUQRoclhVBO8HMhiRmGXnDja9Q==
   dependencies:
     "@babel/runtime" "^7.1.2"
-    hoist-non-react-statics "^3.1.0"
+    hoist-non-react-statics "^3.3.0"
     invariant "^2.2.4"
     loose-envify "^1.1.0"
     prop-types "^15.6.1"
     react-is "^16.6.0"
     react-lifecycles-compat "^3.0.0"
 
+react-redux@^7.1.0:
+  version "7.1.1"
+  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.1.1.tgz#ce6eee1b734a7a76e0788b3309bf78ff6b34fa0a"
+  integrity sha512-QsW0vcmVVdNQzEkrgzh2W3Ksvr8cqpAv5FhEk7tNEft+5pp7rXxAudTz3VOPawRkLIepItpkEIyLcN/VVXzjTg==
+  dependencies:
+    "@babel/runtime" "^7.5.5"
+    hoist-non-react-statics "^3.3.0"
+    invariant "^2.2.4"
+    loose-envify "^1.4.0"
+    prop-types "^15.7.2"
+    react-is "^16.9.0"
+
 react-resize-detector@^4.0.5:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-4.2.0.tgz#b87aee6b37c9e8a52daca8736b3230cf6a2a8647"
-  integrity sha512-AtOaNIxs0ydua7tEoglXR3902/EdlIj9PXDu1Zj0ug2VAUnkSQjguLGzaG/N6CXLOhJSccTsUCZxjLayQ1mE9Q==
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-4.2.1.tgz#8982b74c3e1cf949afaa3c41050458c87b033982"
+  integrity sha512-ZfPMBPxXi0o3xox42MIEtz84tPSVMW9GgwLHYvjVXlFM+OkNzbeEtpVSV+mSTJmk4Znwomolzt35zHN9LNBQMQ==
   dependencies:
-    lodash "^4.17.11"
-    lodash-es "^4.17.11"
+    lodash "^4.17.15"
+    lodash-es "^4.17.15"
     prop-types "^15.7.2"
-    raf-schd "^4.0.0"
+    raf-schd "^4.0.2"
     resize-observer-polyfill "^1.5.1"
 
 react-select@^2.2.0:
@@ -13098,9 +12424,9 @@ react-select@^2.2.0:
     react-transition-group "^2.2.1"
 
 react-spring@^8.0.8:
-  version "8.0.20"
-  resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-8.0.20.tgz#e25967f6059364b09cf0339168d73014e87c9d17"
-  integrity sha512-40ZUQ5uI5YHsoQWLPchWNcEUh6zQ6qvcVDeTI2vW10ldoCN3PvDsII9wBH2xEbMl+BQvYmHzGdfLTQxPxJWGnQ==
+  version "8.0.27"
+  resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-8.0.27.tgz#97d4dee677f41e0b2adcb696f3839680a3aa356a"
+  integrity sha512-nDpWBe3ZVezukNRandTeLSPcwwTMjNVu1IDq9qA/AMiUqHuRN4BeSWvKr3eIxxg1vtiYiOLy4FqdfCP5IoP77g==
   dependencies:
     "@babel/runtime" "^7.3.1"
     prop-types "^15.5.8"
@@ -13117,14 +12443,14 @@ react-syntax-highlighter@^8.0.1:
     refractor "^2.4.1"
 
 react-test-renderer@^16.0.0-0:
-  version "16.8.6"
-  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.6.tgz#188d8029b8c39c786f998aa3efd3ffe7642d5ba1"
-  integrity sha512-H2srzU5IWYT6cZXof6AhUcx/wEyJddQ8l7cLM/F7gDXYyPr4oq+vCIxJYXVGhId1J706sqziAjuOEjyNkfgoEw==
+  version "16.10.2"
+  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.10.2.tgz#4d8492f8678c9b43b721a7d79ed0840fdae7c518"
+  integrity sha512-k9Qzyev6cTIcIfrhgrFlYQAFxh5EEDO6ALNqYqmKsWVA7Q/rUMTay5nD3nthi6COmYsd4ghVYyi8U86aoeMqYQ==
   dependencies:
     object-assign "^4.1.1"
     prop-types "^15.6.2"
     react-is "^16.8.6"
-    scheduler "^0.13.6"
+    scheduler "^0.16.2"
 
 react-textarea-autosize@^7.1.0:
   version "7.1.0"
@@ -13158,14 +12484,13 @@ react-virtualized@^9.18.5:
     react-lifecycles-compat "^3.0.4"
 
 react@^16.8.3:
-  version "16.8.6"
-  resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe"
-  integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==
+  version "16.10.2"
+  resolved "https://registry.yarnpkg.com/react/-/react-16.10.2.tgz#a5ede5cdd5c536f745173c8da47bda64797a4cf0"
+  integrity sha512-MFVIq0DpIhrHFyqLU0S3+4dIcBhhOvBE8bJ/5kHPVOVaGdo0KuiQzpcjCPsf585WvhypqtrMILyoE2th6dT+Lw==
   dependencies:
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
     prop-types "^15.6.2"
-    scheduler "^0.13.6"
 
 reactcss@^1.2.0:
   version "1.2.3"
@@ -13181,10 +12506,10 @@ read-cache@^1.0.0:
   dependencies:
     pify "^2.3.0"
 
-read-cmd-shim@^1.0.1, read-cmd-shim@~1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b"
-  integrity sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs=
+read-cmd-shim@^1.0.1, read-cmd-shim@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.4.tgz#b4a53d43376211b45243f0072b6e603a8e37640d"
+  integrity sha512-Pqpl3qJ/QdOIjRYA0q5DND/gLvGOfpIz/fYVDGYpOXfW/lFrIttmLsBnd6IkyK10+JHU9zhsaudfvrQTBB9YFQ==
   dependencies:
     graceful-fs "^4.1.2"
 
@@ -13202,10 +12527,10 @@ read-installed@~4.0.3:
   optionalDependencies:
     graceful-fs "^4.1.2"
 
-"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.13:
-  version "2.0.13"
-  resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.13.tgz#2e82ebd9f613baa6d2ebe3aa72cefe3f68e41f4a"
-  integrity sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg==
+"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.13, read-package-json@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.0.tgz#e3d42e6c35ea5ae820d9a03ab0c7291217fc51d5"
+  integrity sha512-KLhu8M1ZZNkMcrq1+0UJbR8Dii8KZUqB0Sha4mOx/bknfKI/fyrQVrG/YIt2UOtG667sD8+ee4EXMM91W9dC+A==
   dependencies:
     glob "^7.1.1"
     json-parse-better-errors "^1.0.1"
@@ -13214,16 +12539,14 @@ read-installed@~4.0.3:
   optionalDependencies:
     graceful-fs "^4.1.2"
 
-read-package-tree@^5.2.2:
-  version "5.2.2"
-  resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.2.2.tgz#4b6a0ef2d943c1ea36a578214c9a7f6b7424f7a8"
-  integrity sha512-rW3XWUUkhdKmN2JKB4FL563YAgtINifso5KShykufR03nJ5loGFlkUMe1g/yxmqX073SoYYTsgXu7XdDinKZuA==
+read-package-tree@^5.3.1:
+  version "5.3.1"
+  resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.3.1.tgz#a32cb64c7f31eb8a6f31ef06f9cedf74068fe636"
+  integrity sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==
   dependencies:
-    debuglog "^1.0.1"
-    dezalgo "^1.0.0"
-    once "^1.3.0"
     read-package-json "^2.0.0"
     readdir-scoped-modules "^1.0.0"
+    util-promisify "^2.1.0"
 
 read-pkg-up@^1.0.1:
   version "1.0.1"
@@ -13302,17 +12625,7 @@ read-pkg@^4.0.1:
     parse-json "^4.0.0"
     pify "^3.0.0"
 
-read-pkg@^5.0.0:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.1.1.tgz#5cf234dde7a405c90c88a519ab73c467e9cb83f5"
-  integrity sha512-dFcTLQi6BZ+aFUaICg7er+/usEoqFdQxiEBsEMNGoipenihtxxtdrQuBXvyANCEI8VuUIVYFgeHGx9sLLvim4w==
-  dependencies:
-    "@types/normalize-package-data" "^2.4.0"
-    normalize-package-data "^2.5.0"
-    parse-json "^4.0.0"
-    type-fest "^0.4.1"
-
-read-pkg@^5.1.1:
+read-pkg@^5.0.0, read-pkg@^5.1.1:
   version "5.2.0"
   resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
   integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
@@ -13342,10 +12655,10 @@ read@1, read@~1.0.1, read@~1.0.7:
     string_decoder "~1.1.1"
     util-deprecate "~1.0.1"
 
-readable-stream@^3.0.6, readable-stream@^3.1.1:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.3.0.tgz#cb8011aad002eb717bf040291feba8569c986fb9"
-  integrity sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==
+"readable-stream@2 || 3", readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0:
+  version "3.4.0"
+  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc"
+  integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==
   dependencies:
     inherits "^2.0.3"
     string_decoder "^1.1.1"
@@ -13361,10 +12674,10 @@ readable-stream@~1.1.10:
     isarray "0.0.1"
     string_decoder "~0.10.x"
 
-readdir-scoped-modules@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747"
-  integrity sha1-n6+jfShr5dksuuve4DDcm19AZ0c=
+readdir-scoped-modules@^1.0.0, readdir-scoped-modules@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309"
+  integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==
   dependencies:
     debuglog "^1.0.1"
     dezalgo "^1.0.0"
@@ -13456,10 +12769,15 @@ redeyed@~2.1.0:
   dependencies:
     esprima "~4.0.0"
 
-redux@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5"
-  integrity sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==
+redux-devtools-extension@^2.13.8:
+  version "2.13.8"
+  resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz#37b982688626e5e4993ff87220c9bbb7cd2d96e1"
+  integrity sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg==
+
+redux@^4.0.0, redux@^4.0.1, redux@^4.0.4:
+  version "4.0.4"
+  resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.4.tgz#4ee1aeb164b63d6a1bcc57ae4aa0b6e6fa7a3796"
+  integrity sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q==
   dependencies:
     loose-envify "^1.4.0"
     symbol-observable "^1.2.0"
@@ -13470,15 +12788,15 @@ reflect.ownkeys@^0.2.0:
   integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=
 
 refractor@^2.4.1:
-  version "2.9.0"
-  resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.9.0.tgz#0a381aadb51513e4e6ec1ed410b5104dd65e2489"
-  integrity sha512-lCnCYvXpqd8hC7ksuvo516rz5q4NwzBbq0X5qjH5pxRfcQKiQxKZ8JctrSQmrR/7pcV2TRrs9TT+Whmq/wtluQ==
+  version "2.10.0"
+  resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.10.0.tgz#4cc7efc0028a87924a9b31d82d129dec831a287b"
+  integrity sha512-maW2ClIkm9IYruuFYGTqKzj+m31heq92wlheW4h7bOstP+gf8bocmMec+j7ljLcaB1CAID85LMB3moye31jH1g==
   dependencies:
     hastscript "^5.0.0"
     parse-entities "^1.1.2"
-    prismjs "~1.16.0"
+    prismjs "~1.17.0"
 
-regenerate-unicode-properties@^8.0.2:
+regenerate-unicode-properties@^8.1.0:
   version "8.1.0"
   resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e"
   integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==
@@ -13506,14 +12824,14 @@ regenerator-runtime@^0.12.0, regenerator-runtime@^0.12.1:
   integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==
 
 regenerator-runtime@^0.13.2:
-  version "0.13.2"
-  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447"
-  integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==
+  version "0.13.3"
+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5"
+  integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==
 
 regenerator-transform@^0.14.0:
-  version "0.14.0"
-  resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.0.tgz#2ca9aaf7a2c239dd32e4761218425b8c7a86ecaf"
-  integrity sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==
+  version "0.14.1"
+  resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb"
+  integrity sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==
   dependencies:
     private "^0.1.6"
 
@@ -13525,11 +12843,6 @@ regex-not@^1.0.0, regex-not@^1.0.2:
     extend-shallow "^3.0.2"
     safe-regex "^1.1.0"
 
-regexp-tree@^0.1.6:
-  version "0.1.10"
-  resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.10.tgz#d837816a039c7af8a8d64d7a7c3cf6a1d93450bc"
-  integrity sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==
-
 regexp.prototype.flags@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz#6b30724e306a27833eeb171b66ac8890ba37e41c"
@@ -13542,19 +12855,19 @@ regexpp@^2.0.1:
   resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
   integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
 
-regexpu-core@^4.5.4:
-  version "4.5.4"
-  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae"
-  integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==
+regexpu-core@^4.6.0:
+  version "4.6.0"
+  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6"
+  integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==
   dependencies:
     regenerate "^1.4.0"
-    regenerate-unicode-properties "^8.0.2"
+    regenerate-unicode-properties "^8.1.0"
     regjsgen "^0.5.0"
     regjsparser "^0.6.0"
     unicode-match-property-ecmascript "^1.0.4"
     unicode-match-property-value-ecmascript "^1.1.0"
 
-registry-auth-token@^3.0.1, registry-auth-token@^3.3.1:
+registry-auth-token@^3.0.1:
   version "3.4.0"
   resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e"
   integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==
@@ -13589,16 +12902,7 @@ regjsparser@^0.6.0:
   dependencies:
     jsesc "~0.5.0"
 
-rehype-parse@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.0.tgz#f681555f2598165bee2c778b39f9073d17b16bca"
-  integrity sha512-V2OjMD0xcSt39G4uRdMTqDXXm6HwkUbLMDayYKA/d037j8/OtVSQ+tqKwYWOuyBeoCs/3clXRe30VUjeMDTBSA==
-  dependencies:
-    hast-util-from-parse5 "^5.0.0"
-    parse5 "^5.0.0"
-    xtend "^4.0.1"
-
-relateurl@0.2.x:
+relateurl@^0.2.7:
   version "0.2.7"
   resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
   integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
@@ -13729,11 +13033,6 @@ require-directory@^2.1.1:
   resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
   integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
 
-require-from-string@^2.0.1:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
-  integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
-
 require-main-filename@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
@@ -13749,6 +13048,11 @@ requires-port@^1.0.0:
   resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
   integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
 
+reselect@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7"
+  integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==
+
 resize-observer-polyfill@^1.5.0, resize-observer-polyfill@^1.5.1:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
@@ -13809,14 +13113,7 @@ resolve@1.1.7:
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
   integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
 
-resolve@1.x, resolve@^1.1.6, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.5.0, resolve@^1.8.1:
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232"
-  integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==
-  dependencies:
-    path-parse "^1.0.6"
-
-resolve@^1.10.0, resolve@^1.3.2:
+resolve@1.x, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1:
   version "1.12.0"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6"
   integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==
@@ -13856,20 +13153,20 @@ right-pad@^1.0.1:
   resolved "https://registry.yarnpkg.com/right-pad/-/right-pad-1.0.1.tgz#8ca08c2cbb5b55e74dafa96bf7fd1a27d568c8d0"
   integrity sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA=
 
-rimraf@2, rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.6.2:
-  version "2.6.3"
-  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
-  integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
-  dependencies:
-    glob "^7.1.3"
-
-rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3:
+rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3:
   version "2.7.1"
   resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
   integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
   dependencies:
     glob "^7.1.3"
 
+rimraf@2.6.3:
+  version "2.6.3"
+  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
+  integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
+  dependencies:
+    glob "^7.1.3"
+
 ripemd160@^2.0.0, ripemd160@^2.0.1:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
@@ -13921,9 +13218,9 @@ rx@^4.1.0:
   integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=
 
 rxjs@^6.4.0:
-  version "6.5.2"
-  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7"
-  integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==
+  version "6.5.3"
+  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a"
+  integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==
   dependencies:
     tslib "^1.9.0"
 
@@ -13932,12 +13229,12 @@ safe-buffer@5.1.1:
   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
   integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==
 
-safe-buffer@5.1.2, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
   version "5.1.2"
   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
   integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
 
-safe-buffer@^5.0.1, safe-buffer@^5.1.2:
+safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
   version "5.2.0"
   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
   integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
@@ -13990,16 +13287,15 @@ sass-graph@^3.0.4:
     yargs "^12.0.2"
 
 sass-loader@^7.1.0:
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-7.1.0.tgz#16fd5138cb8b424bf8a759528a1972d72aad069d"
-  integrity sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==
+  version "7.3.1"
+  resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-7.3.1.tgz#a5bf68a04bcea1c13ff842d747150f7ab7d0d23f"
+  integrity sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA==
   dependencies:
-    clone-deep "^2.0.1"
+    clone-deep "^4.0.1"
     loader-utils "^1.0.1"
-    lodash.tail "^4.1.1"
     neo-async "^2.5.0"
-    pify "^3.0.0"
-    semver "^5.5.0"
+    pify "^4.0.1"
+    semver "^6.3.0"
 
 sax@^1.2.4, sax@~1.2.4:
   version "1.2.4"
@@ -14007,11 +13303,11 @@ sax@^1.2.4, sax@~1.2.4:
   integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
 
 saxes@^3.1.9:
-  version "3.1.9"
-  resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.9.tgz#c1c197cd54956d88c09f960254b999e192d7058b"
-  integrity sha512-FZeKhJglhJHk7eWG5YM0z46VHmI3KJpMBAQm3xa9meDvd+wevB5GuBB0wc0exPInZiBBHqi00DbS8AcvCGCFMw==
+  version "3.1.11"
+  resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b"
+  integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==
   dependencies:
-    xmlchars "^1.3.1"
+    xmlchars "^2.1.1"
 
 scheduler@^0.13.3, scheduler@^0.13.6:
   version "0.13.6"
@@ -14021,6 +13317,14 @@ scheduler@^0.13.3, scheduler@^0.13.6:
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
 
+scheduler@^0.16.2:
+  version "0.16.2"
+  resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.16.2.tgz#f74cd9d33eff6fc554edfb79864868e4819132c1"
+  integrity sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg==
+  dependencies:
+    loose-envify "^1.1.0"
+    object-assign "^4.1.1"
+
 schema-utils@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
@@ -14061,26 +13365,26 @@ select@^1.1.2:
   resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
   integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
 
-selfsigned@^1.10.4:
-  version "1.10.4"
-  resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd"
-  integrity sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==
+selfsigned@^1.10.7:
+  version "1.10.7"
+  resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b"
+  integrity sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==
   dependencies:
-    node-forge "0.7.5"
+    node-forge "0.9.0"
 
 semantic-release-slack-bot@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/semantic-release-slack-bot/-/semantic-release-slack-bot-1.2.0.tgz#895d95c802d855853f257b403eb15587f0b5b98d"
-  integrity sha512-Bqny8WmV3CuJSfwpn0POxVmt3dZZ+WzoecwF+SFzkuzE0Aad/wyZdzmXGnBCKs0UE7n0b/tGeojQchLnhwvwmQ==
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/semantic-release-slack-bot/-/semantic-release-slack-bot-1.3.0.tgz#fcdaae5cbfe2019fabf4f558d2d340a888dcfc08"
+  integrity sha512-Q56c30yBukmI/Ewm20JxdZ1qr4x9yXtvUMRKlbZPLDpM5rP0Ika1C0rGbkEM3AJDNWKtT5osj93L4vI3J86LIg==
   dependencies:
     "@semantic-release/error" "^2.2.0"
     node-fetch "^2.3.0"
     slackify-markdown "^1.1.1"
 
 semantic-release@^15.13.19:
-  version "15.13.19"
-  resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-15.13.19.tgz#d1d05b3516fb8701d81f4e6b9be42bafffef13cb"
-  integrity sha512-6eqqAmzGaJWgP5R5IkWIQK9is+cWUp/A+pwzxf/YaG1hJv1eD25klUP7Y0fedsPOxxI8eLuDUVlEs7U8SOlK0Q==
+  version "15.13.24"
+  resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-15.13.24.tgz#f0b9544427d059ba5e3c89ac1545234130796be7"
+  integrity sha512-OPshm6HSp+KmZP9dUv1o3MRILDgOeHYWPI+XSpQRERMri7QkaEiIPkZzoNm2d6KDeFDnp03GphQQS4+Zfo+x/Q==
   dependencies:
     "@semantic-release/commit-analyzer" "^6.1.0"
     "@semantic-release/error" "^2.2.0"
@@ -14097,8 +13401,8 @@ semantic-release@^15.13.19:
     get-stream "^5.0.0"
     git-log-parser "^1.2.0"
     hook-std "^2.0.0"
-    hosted-git-info "^2.7.1"
-    lodash "^4.17.4"
+    hosted-git-info "^3.0.0"
+    lodash "^4.17.15"
     marked "^0.7.0"
     marked-terminal "^3.2.0"
     p-locate "^4.0.0"
@@ -14107,7 +13411,7 @@ semantic-release@^15.13.19:
     resolve-from "^5.0.0"
     semver "^6.0.0"
     signale "^1.2.1"
-    yargs "^13.1.0"
+    yargs "^14.0.0"
 
 semver-compare@^1.0.0:
   version "1.0.0"
@@ -14126,22 +13430,22 @@ semver-regex@^2.0.0:
   resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338"
   integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==
 
-"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0:
+"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
   version "5.7.1"
   resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
   integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
 
-"semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.5, semver@^5.5.1:
-  version "5.7.0"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
-  integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==
+semver@5.5.0:
+  version "5.5.0"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
+  integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==
 
-semver@6.1.1:
-  version "6.1.1"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-6.1.1.tgz#53f53da9b30b2103cd4f15eab3a18ecbcb210c9b"
-  integrity sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==
+semver@6.2.0:
+  version "6.2.0"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db"
+  integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==
 
-semver@^6.0.0, semver@^6.1.1, semver@^6.2.0, semver@^6.3.0:
+semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
   version "6.3.0"
   resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
   integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
@@ -14171,9 +13475,9 @@ send@0.17.1:
     statuses "~1.5.0"
 
 serialize-javascript@^1.7.0:
-  version "1.7.0"
-  resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65"
-  integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==
+  version "1.9.1"
+  resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.9.1.tgz#cfc200aef77b600c47da9bb8149c943e798c2fdb"
+  integrity sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==
 
 serve-favicon@^2.5.0:
   version "2.5.0"
@@ -14247,13 +13551,12 @@ sha.js@^2.4.0, sha.js@^2.4.8:
     inherits "^2.0.1"
     safe-buffer "^5.0.1"
 
-sha@~2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/sha/-/sha-2.0.1.tgz#6030822fbd2c9823949f8f72ed6411ee5cf25aae"
-  integrity sha1-YDCCL70smCOUn49y7WQR7lzyWq4=
+sha@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/sha/-/sha-3.0.0.tgz#b2f2f90af690c16a3a839a6a6c680ea51fedd1ae"
+  integrity sha512-DOYnM37cNsLNSGIG/zZWch5CKIRNoLdYUQTQlcgkRkoYIUwDYjqDyye16YcDZg/OPdcbUgTKMjc4SY6TB7ZAPw==
   dependencies:
     graceful-fs "^4.1.2"
-    readable-stream "^2.0.2"
 
 shallow-clone@^0.1.2:
   version "0.1.2"
@@ -14265,21 +13568,19 @@ shallow-clone@^0.1.2:
     lazy-cache "^0.2.3"
     mixin-object "^2.0.1"
 
-shallow-clone@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-1.0.0.tgz#4480cd06e882ef68b2ad88a3ea54832e2c48b571"
-  integrity sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==
-  dependencies:
-    is-extendable "^0.1.1"
-    kind-of "^5.0.0"
-    mixin-object "^2.0.1"
+shallow-clone@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
+  integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==
+  dependencies:
+    kind-of "^6.0.2"
 
 shallow-equal@^1.1.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.0.tgz#fd828d2029ff4e19569db7e19e535e94e2d1f5cc"
   integrity sha512-Z21pVxR4cXsfwpMKMhCEIO1PCi5sp7KEp+CmOpBQ+E8GpHwKOw2sEzk7sgblM3d/j4z4gakoWEoPcjK0VJQogA==
 
-shallowequal@1.1.0, shallowequal@^1.1.0:
+shallowequal@1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
   integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
@@ -14308,15 +13609,10 @@ shebang-regex@^3.0.0:
   resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
   integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
 
-shell-quote@1.6.1:
-  version "1.6.1"
-  resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767"
-  integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=
-  dependencies:
-    array-filter "~0.0.0"
-    array-map "~0.0.0"
-    array-reduce "~0.0.0"
-    jsonify "~0.0.0"
+shell-quote@1.7.2:
+  version "1.7.2"
+  resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2"
+  integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==
 
 shelljs@0.7.6:
   version "0.7.6"
@@ -14361,26 +13657,26 @@ simple-concat@^1.0.0:
   integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=
 
 simple-get@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.0.3.tgz#924528ac3f9d7718ce5e9ec1b1a69c0be4d62efa"
-  integrity sha512-Wvre/Jq5vgoz31Z9stYWPLn0PqRqmBDpFSdypAnHu5AvRVCYPRYGnvryNLiXu8GOBNDH82J2FRHUGMjjHUpXFw==
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3"
+  integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==
   dependencies:
-    decompress-response "^3.3.0"
+    decompress-response "^4.2.0"
     once "^1.3.1"
     simple-concat "^1.0.0"
 
 simplebar-react@^1.0.0-alpha.6:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/simplebar-react/-/simplebar-react-1.1.0.tgz#9241817265aee28b40abced66d6a2663e046d721"
-  integrity sha512-0nbUpoB5Gq3z2dbhRjPxwTLlscgFjCw8vKQRmbXIr47JMc5BeHj/WbZdVAESuKAvua7ESh6mkxbzywMNgRdbCw==
+  version "1.2.3"
+  resolved "https://registry.yarnpkg.com/simplebar-react/-/simplebar-react-1.2.3.tgz#bd81fa9827628470e9470d06caef6ece15e1c882"
+  integrity sha512-1EOWJzFC7eqHUp1igD1/tb8GBv5aPQA5ZMvpeDnVkpNJ3jAuvmrL2kir3HuijlxhG7njvw9ssxjjBa89E5DrJg==
   dependencies:
     prop-types "^15.6.1"
-    simplebar "^4.1.0"
+    simplebar "^4.2.3"
 
-simplebar@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/simplebar/-/simplebar-4.1.0.tgz#c4b78b278dd0ce41ed70a71473bfad8132a6260f"
-  integrity sha512-kX+CsWbWLeufIsqJl8xg5J4WbYMyq5NONR/aTaehN8XLQxOthSgRT/uAXsqX9Yrw3iiGxD9PPwM1PmEJfWAdcg==
+simplebar@^4.2.3:
+  version "4.2.3"
+  resolved "https://registry.yarnpkg.com/simplebar/-/simplebar-4.2.3.tgz#dac40aced299c17928329eab3d5e6e795fafc10c"
+  integrity sha512-9no0pK7/1y+8/oTF3sy/+kx0PjQ3uk4cYwld5F1CJGk2gx+prRyUq8GRfvcVLq5niYWSozZdX73a2wIr1o9l/g==
   dependencies:
     can-use-dom "^0.1.0"
     core-js "^3.0.1"
@@ -14469,10 +13765,10 @@ snapdragon@^0.8.1:
     source-map-resolve "^0.5.0"
     use "^3.1.0"
 
-sockjs-client@1.3.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177"
-  integrity sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==
+sockjs-client@1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5"
+  integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==
   dependencies:
     debug "^3.2.5"
     eventsource "^1.0.7"
@@ -14549,10 +13845,10 @@ source-map-support@^0.5.6:
     buffer-from "^1.0.0"
     source-map "^0.6.0"
 
-source-map-support@~0.5.10, source-map-support@~0.5.12:
-  version "0.5.12"
-  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599"
-  integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==
+source-map-support@~0.5.12:
+  version "0.5.16"
+  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
+  integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==
   dependencies:
     buffer-from "^1.0.0"
     source-map "^0.6.0"
@@ -14642,10 +13938,10 @@ spdy-transport@^3.0.0:
     readable-stream "^3.0.6"
     wbuf "^1.7.3"
 
-spdy@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.0.tgz#81f222b5a743a329aa12cea6a390e60e9b613c52"
-  integrity sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==
+spdy@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.1.tgz#6f12ed1c5db7ea4f24ebb8b89ba58c87c08257f2"
+  integrity sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==
   dependencies:
     debug "^4.1.0"
     handle-thing "^2.0.0"
@@ -14754,9 +14050,9 @@ stealthy-require@^1.1.1:
   integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
 
 store2@^2.7.1:
-  version "2.8.0"
-  resolved "https://registry.yarnpkg.com/store2/-/store2-2.8.0.tgz#032d5dcbd185a5d74049d67a1765ff1e75faa04b"
-  integrity sha512-FBJpcOEZQLZBIGL4Yp7W5RgZ0ejaURmcfUjIpyOb64BpI8z/iJXw7zd/NTBeq304dVMxuWVDZEUUCGn7llaVrA==
+  version "2.10.0"
+  resolved "https://registry.yarnpkg.com/store2/-/store2-2.10.0.tgz#46b82bb91878daf1b0d56dec2f1d41e54d5103cf"
+  integrity sha512-tWEpK0snS2RPUq1i3R6OahfJNjWCQYNxq0+by1amCSuw0mXtymJpzmZIeYpA1UAa+7B0grCpNYIbDcd7AgTbFg==
 
 stream-browserify@^2.0.1:
   version "2.0.2"
@@ -14851,12 +14147,12 @@ string-width@^3.0.0, string-width@^3.1.0:
     strip-ansi "^5.1.0"
 
 string.prototype.matchall@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-3.0.1.tgz#5a9e0b64bcbeb336aa4814820237c2006985646d"
-  integrity sha512-NSiU0ILQr9PQ1SZmM1X327U5LsM+KfDTassJfqN1al1+0iNpKzmQ4BfXOJwRnTEqv8nKJ67mFpqRoPaGWwvy5A==
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-3.0.2.tgz#c1fdb23f90058e929a69cfa2e8b12300daefe030"
+  integrity sha512-hsRe42jQ8+OJej2GVjhnSVodQ3NQgHV0FDD6dW7ZTM22J4uIbuYiAADCCc1tfyN7ocEl/KUUbudM36E2tZcF8w==
   dependencies:
     define-properties "^1.1.3"
-    es-abstract "^1.12.0"
+    es-abstract "^1.14.2"
     function-bind "^1.1.1"
     has-symbols "^1.0.0"
     regexp.prototype.flags "^1.2.0"
@@ -14880,15 +14176,15 @@ string.prototype.padstart@^3.0.0:
     function-bind "^1.0.2"
 
 string.prototype.trim@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
-  integrity sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.0.tgz#75a729b10cfc1be439543dae442129459ce61e3d"
+  integrity sha512-9EIjYD/WdlvLpn987+ctkLf0FfvBefOCuiEr2henD8X+7jfwPnyvTdmW8OJhj5p+M0/96mBdynLWkxUr+rHlpg==
   dependencies:
-    define-properties "^1.1.2"
-    es-abstract "^1.5.0"
-    function-bind "^1.0.2"
+    define-properties "^1.1.3"
+    es-abstract "^1.13.0"
+    function-bind "^1.1.1"
 
-string.prototype.trimleft@^2.0.0:
+string.prototype.trimleft@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634"
   integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==
@@ -14896,7 +14192,7 @@ string.prototype.trimleft@^2.0.0:
     define-properties "^1.1.3"
     function-bind "^1.1.1"
 
-string.prototype.trimright@^2.0.0:
+string.prototype.trimright@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58"
   integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==
@@ -14905,11 +14201,11 @@ string.prototype.trimright@^2.0.0:
     function-bind "^1.1.1"
 
 string_decoder@^1.0.0, string_decoder@^1.1.1:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
-  integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
+  integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
   dependencies:
-    safe-buffer "~5.1.0"
+    safe-buffer "~5.2.0"
 
 string_decoder@~0.10.x:
   version "0.10.31"
@@ -14933,19 +14229,10 @@ stringify-entities@^1.0.1:
     is-alphanumerical "^1.0.0"
     is-hexadecimal "^1.0.0"
 
-stringify-object@3.3.0:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629"
-  integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==
-  dependencies:
-    get-own-enumerable-property-symbols "^3.0.0"
-    is-obj "^1.0.1"
-    is-regexp "^1.0.0"
-
-stringify-package@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.0.tgz#e02828089333d7d45cd8c287c30aa9a13375081b"
-  integrity sha512-JIQqiWmLiEozOC0b0BtxZ/AOUtdUZHCBPgqIZ2kSJJqGwgb9neo44XdTHUC4HZSGqi03hOeB7W/E8rAlKnGe9g==
+stringify-package@^1.0.0, stringify-package@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85"
+  integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==
 
 strip-ansi@5.2.0, strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
   version "5.2.0"
@@ -15035,25 +14322,25 @@ stylis@^3.5.0:
   resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
   integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
 
+supports-color@6.1.0, supports-color@^6.1.0:
+  version "6.1.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
+  integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
+  dependencies:
+    has-flag "^3.0.0"
+
 supports-color@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
   integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
 
-supports-color@^5.0.0, supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.5.0:
+supports-color@^5.0.0, supports-color@^5.3.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@^6.1.0:
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
-  integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
-  dependencies:
-    has-flag "^3.0.0"
-
 supports-hyperlinks@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz#71daedf36cc1060ac5100c351bb3da48c29c0ef7"
@@ -15062,17 +14349,21 @@ supports-hyperlinks@^1.0.1:
     has-flag "^2.0.0"
     supports-color "^5.0.0"
 
-svgo@^1.2.1:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.2.2.tgz#0253d34eccf2aed4ad4f283e11ee75198f9d7316"
-  integrity sha512-rAfulcwp2D9jjdGu+0CuqlrAUin6bBWrpoqXWwKDZZZJfXcUXQSxLJOFJCQCSA0x0pP2U0TxSlJu2ROq5Bq6qA==
+svg-parser@^2.0.0:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.2.tgz#d134cc396fa2681dc64f518330784e98bd801ec8"
+  integrity sha512-1gtApepKFweigFZj3sGO8KT8LvVZK8io146EzXrpVuWCDAbISz/yMucco3hWTkpZNoPabM+dnMOpy6Swue68Zg==
+
+svgo@^1.2.2:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.0.tgz#bae51ba95ded9a33a36b7c46ce9c359ae9154313"
+  integrity sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==
   dependencies:
     chalk "^2.4.1"
     coa "^2.0.2"
     css-select "^2.0.0"
     css-select-base-adapter "^0.1.1"
-    css-tree "1.0.0-alpha.28"
-    css-url-regex "^1.1.0"
+    css-tree "1.0.0-alpha.33"
     csso "^3.5.1"
     js-yaml "^3.13.1"
     mkdirp "~0.5.1"
@@ -15105,16 +14396,16 @@ tabbable@^1.1.0:
   integrity sha512-nOWwx35/JuDI4ONuF0ZTo6lYvI0fY0tZCH1ErzY2EXfu4az50ZyiUX8X073FLiZtmWUVlkRnuXsehjJgCw9tYg==
 
 table@^5.2.3:
-  version "5.4.0"
-  resolved "https://registry.yarnpkg.com/table/-/table-5.4.0.tgz#d772a3216e68829920a41a32c18eda286c95d780"
-  integrity sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==
+  version "5.4.6"
+  resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"
+  integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==
   dependencies:
-    ajv "^6.9.1"
-    lodash "^4.17.11"
+    ajv "^6.10.2"
+    lodash "^4.17.14"
     slice-ansi "^2.1.0"
     string-width "^3.0.0"
 
-tapable@^1.0.0, tapable@^1.1.0:
+tapable@^1.0.0, tapable@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
   integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
@@ -15128,7 +14419,7 @@ tar@^2.0.0:
     fstream "^1.0.12"
     inherits "2"
 
-tar@^4:
+tar@^4, tar@^4.4.10, tar@^4.4.12:
   version "4.4.13"
   resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
   integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
@@ -15141,30 +14432,17 @@ tar@^4:
     safe-buffer "^5.1.2"
     yallist "^3.0.3"
 
-tar@^4.4.8:
-  version "4.4.8"
-  resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d"
-  integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==
-  dependencies:
-    chownr "^1.1.1"
-    fs-minipass "^1.2.5"
-    minipass "^2.3.4"
-    minizlib "^1.1.1"
-    mkdirp "^0.5.0"
-    safe-buffer "^5.1.2"
-    yallist "^3.0.2"
-
 telejson@^2.2.1:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/telejson/-/telejson-2.2.1.tgz#d9ee7e7eba0c81d9378257342fde7142a03787e2"
-  integrity sha512-JtFAnITek+Z9t+uQjVl4Fxur9Z3Bi3flytBLc3KZVXmMUHLXdtAxiP0g8IBkHvKn1kQIYZC57IG0jjGH1s64HQ==
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/telejson/-/telejson-2.2.2.tgz#d61d721d21849a6e4070d547aab302a9bd22c720"
+  integrity sha512-YyNwnKY0ilabOwYgC/J754En1xOe5PBIUIw+C9e0+5HjVVcnQE5/gdu2yET2pmSbp5bxIDqYNjvndj2PUkIiYA==
   dependencies:
     global "^4.3.2"
     is-function "^1.0.1"
     is-regex "^1.0.4"
     is-symbol "^1.0.2"
     isobject "^3.0.1"
-    lodash.get "^4.4.2"
+    lodash "^4.17.11"
     memoizerific "^1.11.3"
 
 term-size@^1.2.0:
@@ -15174,50 +14452,25 @@ term-size@^1.2.0:
   dependencies:
     execa "^0.7.0"
 
-terser-webpack-plugin@^1.1.0:
-  version "1.2.4"
-  resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.2.4.tgz#56f87540c28dd5265753431009388f473b5abba3"
-  integrity sha512-64IiILNQlACWZLzFlpzNaG0bpQ4ytaB7fwOsbpsdIV70AfLUmIGGeuKL0YV2WmtcrURjE2aOvHD4/lrFV3Rg+Q==
-  dependencies:
-    cacache "^11.3.2"
-    find-cache-dir "^2.0.0"
-    is-wsl "^1.1.0"
-    schema-utils "^1.0.0"
-    serialize-javascript "^1.7.0"
-    source-map "^0.6.1"
-    terser "^3.17.0"
-    webpack-sources "^1.3.0"
-    worker-farm "^1.7.0"
-
-terser-webpack-plugin@^1.2.4:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz#69aa22426299f4b5b3775cbed8cb2c5d419aa1d4"
-  integrity sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==
+terser-webpack-plugin@^1.2.4, terser-webpack-plugin@^1.4.1:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz#61b18e40eaee5be97e771cdbb10ed1280888c2b4"
+  integrity sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==
   dependencies:
-    cacache "^11.3.2"
-    find-cache-dir "^2.0.0"
+    cacache "^12.0.2"
+    find-cache-dir "^2.1.0"
     is-wsl "^1.1.0"
-    loader-utils "^1.2.3"
     schema-utils "^1.0.0"
     serialize-javascript "^1.7.0"
     source-map "^0.6.1"
-    terser "^4.0.0"
-    webpack-sources "^1.3.0"
+    terser "^4.1.2"
+    webpack-sources "^1.4.0"
     worker-farm "^1.7.0"
 
-terser@^3.17.0:
-  version "3.17.0"
-  resolved "https://registry.yarnpkg.com/terser/-/terser-3.17.0.tgz#f88ffbeda0deb5637f9d24b0da66f4e15ab10cb2"
-  integrity sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==
-  dependencies:
-    commander "^2.19.0"
-    source-map "~0.6.1"
-    source-map-support "~0.5.10"
-
-terser@^4.0.0:
-  version "4.1.2"
-  resolved "https://registry.yarnpkg.com/terser/-/terser-4.1.2.tgz#b2656c8a506f7ce805a3f300a2ff48db022fa391"
-  integrity sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==
+terser@^4.1.2:
+  version "4.4.0"
+  resolved "https://registry.yarnpkg.com/terser/-/terser-4.4.0.tgz#22c46b4817cf4c9565434bfe6ad47336af259ac3"
+  integrity sha512-oDG16n2WKm27JO8h4y/w3iqBGAOSCtq7k8dRmrn4Wf9NouL0b2WpMHGChFGZq4nFAQy1FsNJrVQHfurXOSTmOA==
   dependencies:
     commander "^2.20.0"
     source-map "~0.6.1"
@@ -15238,6 +14491,11 @@ text-extensions@^1.0.0:
   resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26"
   integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==
 
+text-extensions@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-2.0.0.tgz#43eabd1b495482fae4a2bf65e5f56c29f69220f6"
+  integrity sha512-F91ZqLgvi1E0PdvmxMgp+gcf6q8fMH7mhdwWfzXnl1k+GbpQDmi8l7DzLC5JTASKbwpY3TfxajAUzAXcv2NmsQ==
+
 text-table@0.2.0, text-table@^0.2.0, text-table@~0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -15256,15 +14514,22 @@ through2@^2.0.0, through2@^2.0.2, through2@~2.0.0:
     readable-stream "~2.3.6"
     xtend "~4.0.1"
 
+through2@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a"
+  integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==
+  dependencies:
+    readable-stream "2 || 3"
+
 through@2, "through@>=2.2.7 <3", through@^2.3.6:
   version "2.3.8"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
   integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
 
 thunky@^1.0.2:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826"
-  integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
+  integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==
 
 timed-out@^4.0.0:
   version "4.0.1"
@@ -15272,9 +14537,9 @@ timed-out@^4.0.0:
   integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
 
 timers-browserify@^2.0.4:
-  version "2.0.10"
-  resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae"
-  integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==
+  version "2.0.11"
+  resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f"
+  integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==
   dependencies:
     setimmediate "^1.0.4"
 
@@ -15283,10 +14548,10 @@ tiny-emitter@^2.0.0:
   resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
   integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
 
-tiny-invariant@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.0.4.tgz#346b5415fd93cb696b0c4e8a96697ff590f92463"
-  integrity sha512-lMhRd/djQJ3MoaHEBrw8e2/uM4rs9YMNk0iOr8rHQ0QdbM7D4l0gFl3szKdeixrlyfm9Zqi4dxHCM2qVG8ND5g==
+tiny-invariant@^1.0.4, tiny-invariant@^1.0.6:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.0.6.tgz#b3f9b38835e36a41c843a3b0907a5a7b3755de73"
+  integrity sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA==
 
 tiny-relative-date@^1.3.0:
   version "1.3.0"
@@ -15417,11 +14682,6 @@ trim-off-newlines@^1.0.0:
   resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3"
   integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM=
 
-trim-right@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
-  integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
-
 trim-trailing-lines@^1.0.0:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz#d2f1e153161152e9f02fabc670fb40bec2ea2e3a"
@@ -15466,9 +14726,9 @@ ts-jest@^24.1.0:
     yargs-parser "10.x"
 
 ts-loader@^6.1.2:
-  version "6.1.2"
-  resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-6.1.2.tgz#ff6bc767334970226438949fbde2e211147a1325"
-  integrity sha512-dudxFKm0Ellrg/gLNlu+97/UgwvoMK0SdUVImPUSzq3IcRUVtShylZvcMX+CgvCQL1BEKb913NL0gAP1GA/OFw==
+  version "6.2.1"
+  resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-6.2.1.tgz#67939d5772e8a8c6bdaf6277ca023a4812da02ef"
+  integrity sha512-Dd9FekWuABGgjE1g0TlQJ+4dFUfYGbYcs52/HQObE0ZmUNjQlmLAS7xXsSzy23AMaMwipsx5sNHvoEpT2CZq1g==
   dependencies:
     chalk "^2.3.0"
     enhanced-resolve "^4.0.0"
@@ -15477,14 +14737,14 @@ ts-loader@^6.1.2:
     semver "^6.0.0"
 
 ts-pnp@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.2.tgz#be8e4bfce5d00f0f58e0666a82260c34a57af552"
-  integrity sha512-f5Knjh7XCyRIzoC/z1Su1yLLRrPrFCgtUAh/9fCSP6NKbATwpOL1+idQVXQokK9GRFURn/jYPGPfegIctwunoA==
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.4.tgz#ae27126960ebaefb874c6d7fa4729729ab200d90"
+  integrity sha512-1J/vefLC+BWSo+qe8OnJQfWTYRS6ingxjwqmHMqaMxXMj7kFtKLgAaYW3JeX3mktjgUL+etlU8/B4VUAUI9QGw==
 
 tslib@^1.8.1, tslib@^1.9.0:
-  version "1.9.3"
-  resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
-  integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
+  version "1.10.0"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
+  integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
 
 tsutils@^3.17.1:
   version "3.17.1"
@@ -15522,11 +14782,6 @@ type-fest@^0.3.0:
   resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1"
   integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==
 
-type-fest@^0.4.1:
-  version "0.4.1"
-  resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8"
-  integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==
-
 type-fest@^0.5.0:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2"
@@ -15545,6 +14800,11 @@ type-is@~1.6.17, type-is@~1.6.18:
     media-typer "0.3.0"
     mime-types "~2.1.24"
 
+type@^1.0.1:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
+  integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
+
 typed-styles@^0.0.7:
   version "0.0.7"
   resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9"
@@ -15556,29 +14816,21 @@ typedarray@^0.0.6:
   integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
 
 typescript@^3.6.3:
-  version "3.6.3"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.3.tgz#fea942fabb20f7e1ca7164ff626f1a9f3f70b4da"
-  integrity sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==
+  version "3.7.2"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb"
+  integrity sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==
 
 ua-parser-js@^0.7.18:
-  version "0.7.19"
-  resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b"
-  integrity sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==
-
-uglify-js@3.4.x:
-  version "3.4.10"
-  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"
-  integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==
-  dependencies:
-    commander "~2.19.0"
-    source-map "~0.6.1"
+  version "0.7.20"
+  resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098"
+  integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==
 
-uglify-js@^3.1.4:
-  version "3.6.0"
-  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5"
-  integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==
+uglify-js@^3.1.4, uglify-js@^3.5.1:
+  version "3.6.1"
+  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.1.tgz#ae7688c50e1bdcf2f70a0e162410003cf9798311"
+  integrity sha512-+dSJLJpXBb6oMHP+Yvw8hUgElz4gLTh82XuX68QiJVTXaE5ibl6buzhNkQdYhBlIhozWOC9ge16wyRmjG4TwVQ==
   dependencies:
-    commander "~2.20.0"
+    commander "2.20.0"
     source-map "~0.6.1"
 
 uid-number@0.0.6:
@@ -15634,20 +14886,6 @@ unified@^6.1.6:
     vfile "^2.0.0"
     x-is-string "^0.1.0"
 
-unified@^7.1.0:
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/unified/-/unified-7.1.0.tgz#5032f1c1ee3364bd09da12e27fdd4a7553c7be13"
-  integrity sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==
-  dependencies:
-    "@types/unist" "^2.0.0"
-    "@types/vfile" "^3.0.0"
-    bail "^1.0.0"
-    extend "^3.0.0"
-    is-plain-obj "^1.1.0"
-    trough "^1.0.0"
-    vfile "^3.0.0"
-    x-is-string "^0.1.0"
-
 union-value@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
@@ -15671,9 +14909,9 @@ unique-filename@^1.1.1:
     unique-slug "^2.0.0"
 
 unique-slug@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6"
-  integrity sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c"
+  integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==
   dependencies:
     imurmurhash "^0.1.4"
 
@@ -15701,13 +14939,6 @@ unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1:
   resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6"
   integrity sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==
 
-unist-util-stringify-position@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.0.tgz#4c452c0dbcbc509f7bcd366e9a8afd646f9d51ae"
-  integrity sha512-Uz5negUTrf9zm2ZT2Z9kdOL7Mr7FJLyq3ByqagUi7QZRVK1HnspVazvSqwHt73jj7APHtpuJ4K110Jm8O6/elw==
-  dependencies:
-    "@types/unist" "^2.0.2"
-
 unist-util-visit-parents@^2.0.0:
   version "2.1.2"
   resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9"
@@ -15722,19 +14953,12 @@ unist-util-visit@^1.1.0, unist-util-visit@^1.3.0:
   dependencies:
     unist-util-visit-parents "^2.0.0"
 
-universal-user-agent@^2.0.0, universal-user-agent@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-2.1.0.tgz#5abfbcc036a1ba490cb941f8fd68c46d3669e8e4"
-  integrity sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==
-  dependencies:
-    os-name "^3.0.0"
-
-universal-user-agent@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-3.0.0.tgz#4cc88d68097bffd7ac42e3b7c903e7481424b4b9"
-  integrity sha512-T3siHThqoj5X0benA5H0qcDnrKGXzU8TKoX15x/tQHw1hQBvIEBHjxQ2klizYsqBOO/Q+WuxoQUihadeeqDnoA==
+universal-user-agent@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-4.0.0.tgz#27da2ec87e32769619f68a14996465ea1cb9df16"
+  integrity sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==
   dependencies:
-    os-name "^3.0.0"
+    os-name "^3.1.0"
 
 universalify@^0.1.0:
   version "0.1.2"
@@ -15765,9 +14989,9 @@ unzip-response@^2.0.1:
   integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=
 
 upath@^1.1.1:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068"
-  integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
+  integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
 
 update-notifier@^2.3.0, update-notifier@^2.5.0:
   version "2.5.0"
@@ -15803,9 +15027,9 @@ urix@^0.1.0:
   integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
 
 url-join@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a"
-  integrity sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7"
+  integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==
 
 url-loader@^1.1.2:
   version "1.1.2"
@@ -15831,11 +15055,6 @@ url-parse@^1.4.3:
     querystringify "^2.1.1"
     requires-port "^1.0.0"
 
-url-template@^2.0.8:
-  version "2.0.8"
-  resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21"
-  integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE=
-
 url@^0.11.0:
   version "0.11.0"
   resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@@ -15859,6 +15078,13 @@ util-extend@^1.0.1:
   resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f"
   integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=
 
+util-promisify@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/util-promisify/-/util-promisify-2.1.0.tgz#3c2236476c4d32c5ff3c47002add7c13b9a82a53"
+  integrity sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=
+  dependencies:
+    object.getownpropertydescriptors "^2.0.3"
+
 util.promisify@1.0.0, util.promisify@^1.0.0, util.promisify@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030"
@@ -15897,11 +15123,11 @@ utils-merge@1.0.1:
   integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
 
 uuid@^3.0.1, uuid@^3.1.0, uuid@^3.3.2:
-  version "3.3.2"
-  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
-  integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
+  version "3.3.3"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866"
+  integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==
 
-v8-compile-cache@^2.0.2:
+v8-compile-cache@2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe"
   integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==
@@ -15947,14 +15173,6 @@ vfile-message@^1.0.0:
   dependencies:
     unist-util-stringify-position "^1.1.1"
 
-vfile-message@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.0.tgz#750bbb86fe545988a67e899b329bbcabb73edef6"
-  integrity sha512-YS6qg6UpBfIeiO+6XlhPOuJaoLvt1Y9g2cmlwqhBOOU0XRV8j5RLeoz72t6PWLvNXq3EBG1fQ05wNPrUoz0deQ==
-  dependencies:
-    "@types/unist" "^2.0.2"
-    unist-util-stringify-position "^1.1.1"
-
 vfile@^2.0.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a"
@@ -15965,33 +15183,10 @@ vfile@^2.0.0:
     unist-util-stringify-position "^1.0.0"
     vfile-message "^1.0.0"
 
-vfile@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/vfile/-/vfile-3.0.1.tgz#47331d2abe3282424f4a4bb6acd20a44c4121803"
-  integrity sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==
-  dependencies:
-    is-buffer "^2.0.0"
-    replace-ext "1.0.0"
-    unist-util-stringify-position "^1.0.0"
-    vfile-message "^1.0.0"
-
-vfile@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.0.0.tgz#ebf3b48af9fcde524d5e08d5f75812058a5f78ad"
-  integrity sha512-WMNeHy5djSl895BqE86D7WqA0Ie5fAIeGCa7V1EqiXyJg5LaGch2SUaZueok5abYQGH6mXEAsZ45jkoILIOlyA==
-  dependencies:
-    "@types/unist" "^2.0.2"
-    is-buffer "^2.0.0"
-    replace-ext "1.0.0"
-    unist-util-stringify-position "^2.0.0"
-    vfile-message "^2.0.0"
-
-vm-browserify@0.0.4:
-  version "0.0.4"
-  resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
-  integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=
-  dependencies:
-    indexof "0.0.1"
+vm-browserify@^1.0.1:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
+  integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
 
 w3c-hr-time@^1.0.1:
   version "1.0.1"
@@ -16021,13 +15216,13 @@ wait-on@^3.3.0:
     rx "^4.1.0"
 
 wait-port@^0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/wait-port/-/wait-port-0.2.2.tgz#d51a491e484a17bf75a947e711a2f012b4e6f2e3"
-  integrity sha1-1RpJHkhKF791qUfnEaLwErTm8uM=
+  version "0.2.6"
+  resolved "https://registry.yarnpkg.com/wait-port/-/wait-port-0.2.6.tgz#261e615adb2e10c8b91c836722c85919ccf081cc"
+  integrity sha512-nXE5Yp0Zs1obhFVc0Da7WVJc3y0LxoCq3j4mtV0NdI5P/ZvRdKp5yhuojvMOcOxSwpQL1hGbOgMNQ+4wpRpwCA==
   dependencies:
-    chalk "^1.1.3"
-    commander "^2.9.0"
-    debug "^2.6.6"
+    chalk "^2.4.2"
+    commander "^3.0.2"
+    debug "^4.1.1"
 
 walker@^1.0.7, walker@~1.0.5:
   version "1.0.7"
@@ -16043,14 +15238,14 @@ warning@^3.0.0:
   dependencies:
     loose-envify "^1.0.0"
 
-warning@^4.0.2:
+warning@^4.0.2, warning@^4.0.3:
   version "4.0.3"
   resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
   integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
   dependencies:
     loose-envify "^1.0.0"
 
-watchpack@^1.5.0:
+watchpack@^1.6.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00"
   integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==
@@ -16073,77 +15268,76 @@ wcwidth@^1.0.0:
   dependencies:
     defaults "^1.0.3"
 
-web-namespaces@^1.1.2:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.3.tgz#9bbf5c99ff0908d2da031f1d732492a96571a83f"
-  integrity sha512-r8sAtNmgR0WKOKOxzuSgk09JsHlpKlB+uHi937qypOu3PZ17UxPrierFKDye/uNHjNTTEshu5PId8rojIPj/tA==
-
 webidl-conversions@^4.0.2:
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
   integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
 
 webpack-cli@^3.3.1:
-  version "3.3.2"
-  resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.2.tgz#aed2437b0db0a7faa2ad28484e166a5360014a91"
-  integrity sha512-FLkobnaJJ+03j5eplxlI0TUxhGCOdfewspIGuvDVtpOlrAuKMFC57K42Ukxqs1tn8947/PM6tP95gQc0DCzRYA==
+  version "3.3.10"
+  resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.10.tgz#17b279267e9b4fb549023fae170da8e6e766da13"
+  integrity sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg==
   dependencies:
-    chalk "^2.4.1"
-    cross-spawn "^6.0.5"
-    enhanced-resolve "^4.1.0"
-    findup-sync "^2.0.0"
-    global-modules "^1.0.0"
-    import-local "^2.0.0"
-    interpret "^1.1.0"
-    loader-utils "^1.1.0"
-    supports-color "^5.5.0"
-    v8-compile-cache "^2.0.2"
-    yargs "^12.0.5"
+    chalk "2.4.2"
+    cross-spawn "6.0.5"
+    enhanced-resolve "4.1.0"
+    findup-sync "3.0.0"
+    global-modules "2.0.0"
+    import-local "2.0.0"
+    interpret "1.2.0"
+    loader-utils "1.2.3"
+    supports-color "6.1.0"
+    v8-compile-cache "2.0.3"
+    yargs "13.2.4"
 
-webpack-dev-middleware@^3.7.0:
-  version "3.7.0"
-  resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz#ef751d25f4e9a5c8a35da600c5fda3582b5c6cff"
-  integrity sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==
+webpack-dev-middleware@^3.7.0, webpack-dev-middleware@^3.7.2:
+  version "3.7.2"
+  resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3"
+  integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==
   dependencies:
     memory-fs "^0.4.1"
-    mime "^2.4.2"
+    mime "^2.4.4"
+    mkdirp "^0.5.1"
     range-parser "^1.2.1"
     webpack-log "^2.0.0"
 
 webpack-dev-server@^3.3.1:
-  version "3.4.1"
-  resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.4.1.tgz#a5fd8dec95dec410098e7d9a037ff9405395d51a"
-  integrity sha512-CRqZQX2ryMtrg0r3TXQPpNh76eM1HD3Wmu6zDBxIKi/d2y+4aa28Ia8weNT0bfgWpY6Vs3Oq/K8+DjfbR+tWYw==
+  version "3.9.0"
+  resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.9.0.tgz#27c3b5d0f6b6677c4304465ac817623c8b27b89c"
+  integrity sha512-E6uQ4kRrTX9URN9s/lIbqTAztwEPdvzVrcmHE8EQ9YnuT9J8Es5Wrd8n9BKg1a0oZ5EgEke/EQFgUsp18dSTBw==
   dependencies:
     ansi-html "0.0.7"
     bonjour "^3.5.0"
-    chokidar "^2.1.6"
+    chokidar "^2.1.8"
     compression "^1.7.4"
     connect-history-api-fallback "^1.6.0"
     debug "^4.1.1"
     del "^4.1.1"
-    express "^4.17.0"
+    express "^4.17.1"
     html-entities "^1.2.1"
-    http-proxy-middleware "^0.19.1"
+    http-proxy-middleware "0.19.1"
     import-local "^2.0.0"
     internal-ip "^4.3.0"
     ip "^1.1.5"
+    is-absolute-url "^3.0.3"
     killable "^1.0.1"
-    loglevel "^1.6.1"
+    loglevel "^1.6.4"
     opn "^5.5.0"
-    portfinder "^1.0.20"
+    p-retry "^3.0.1"
+    portfinder "^1.0.25"
     schema-utils "^1.0.0"
-    selfsigned "^1.10.4"
-    semver "^6.0.0"
+    selfsigned "^1.10.7"
+    semver "^6.3.0"
     serve-index "^1.9.1"
     sockjs "0.3.19"
-    sockjs-client "1.3.0"
-    spdy "^4.0.0"
+    sockjs-client "1.4.0"
+    spdy "^4.0.1"
     strip-ansi "^3.0.1"
     supports-color "^6.1.0"
     url "^0.11.0"
-    webpack-dev-middleware "^3.7.0"
+    webpack-dev-middleware "^3.7.2"
     webpack-log "^2.0.0"
+    ws "^6.2.1"
     yargs "12.0.5"
 
 webpack-hot-middleware@^2.25.0:
@@ -16174,79 +15368,79 @@ webpack-log@^2.0.0:
     ansi-colors "^3.0.0"
     uuid "^3.3.2"
 
-webpack-sources@^1.1.0, webpack-sources@^1.3.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85"
-  integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==
+webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1:
+  version "1.4.3"
+  resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933"
+  integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==
   dependencies:
     source-list-map "^2.0.0"
     source-map "~0.6.1"
 
 webpack@^4.29.5:
-  version "4.32.1"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.32.1.tgz#afe0cc7dd2b196e5a58f8d1d385311cfbb5d68c0"
-  integrity sha512-R0S2tfWP2tZ8ZC2dwgnUVfa9LPvhGWJXjqfgIQ6jply+9ncBbt8IZ9p83uVeqsZ/s8zKA3XyepciWNHnSxxnHg==
+  version "4.41.2"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.2.tgz#c34ec76daa3a8468c9b61a50336d8e3303dce74e"
+  integrity sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A==
   dependencies:
     "@webassemblyjs/ast" "1.8.5"
     "@webassemblyjs/helper-module-context" "1.8.5"
     "@webassemblyjs/wasm-edit" "1.8.5"
     "@webassemblyjs/wasm-parser" "1.8.5"
-    acorn "^6.0.5"
-    acorn-dynamic-import "^4.0.0"
-    ajv "^6.1.0"
-    ajv-keywords "^3.1.0"
-    chrome-trace-event "^1.0.0"
+    acorn "^6.2.1"
+    ajv "^6.10.2"
+    ajv-keywords "^3.4.1"
+    chrome-trace-event "^1.0.2"
     enhanced-resolve "^4.1.0"
-    eslint-scope "^4.0.0"
+    eslint-scope "^4.0.3"
     json-parse-better-errors "^1.0.2"
-    loader-runner "^2.3.0"
-    loader-utils "^1.1.0"
-    memory-fs "~0.4.1"
-    micromatch "^3.1.8"
-    mkdirp "~0.5.0"
-    neo-async "^2.5.0"
-    node-libs-browser "^2.0.0"
+    loader-runner "^2.4.0"
+    loader-utils "^1.2.3"
+    memory-fs "^0.4.1"
+    micromatch "^3.1.10"
+    mkdirp "^0.5.1"
+    neo-async "^2.6.1"
+    node-libs-browser "^2.2.1"
     schema-utils "^1.0.0"
-    tapable "^1.1.0"
-    terser-webpack-plugin "^1.1.0"
-    watchpack "^1.5.0"
-    webpack-sources "^1.3.0"
+    tapable "^1.1.3"
+    terser-webpack-plugin "^1.4.1"
+    watchpack "^1.6.0"
+    webpack-sources "^1.4.1"
 
-webpack@^4.33.0:
-  version "4.37.0"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.37.0.tgz#3508ef10f7996612c2be6026076d89760f776f54"
-  integrity sha512-iJPPvL7XpbcbwOthbzpa2BSPlmGp8lGDokAj/LdWtK80rsPoPOdANSbDBf2GAVLKZD3GhCuQ/gGkgN9HWs0Keg==
+webpack@^4.33.0, webpack@^4.38.0:
+  version "4.41.0"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.0.tgz#db6a254bde671769f7c14e90a1a55e73602fc70b"
+  integrity sha512-yNV98U4r7wX1VJAj5kyMsu36T8RPPQntcb5fJLOsMz/pt/WrKC0Vp1bAlqPLkA1LegSwQwf6P+kAbyhRKVQ72g==
   dependencies:
     "@webassemblyjs/ast" "1.8.5"
     "@webassemblyjs/helper-module-context" "1.8.5"
     "@webassemblyjs/wasm-edit" "1.8.5"
     "@webassemblyjs/wasm-parser" "1.8.5"
-    acorn "^6.2.0"
-    ajv "^6.1.0"
-    ajv-keywords "^3.1.0"
-    chrome-trace-event "^1.0.0"
+    acorn "^6.2.1"
+    ajv "^6.10.2"
+    ajv-keywords "^3.4.1"
+    chrome-trace-event "^1.0.2"
     enhanced-resolve "^4.1.0"
-    eslint-scope "^4.0.0"
+    eslint-scope "^4.0.3"
     json-parse-better-errors "^1.0.2"
-    loader-runner "^2.3.0"
-    loader-utils "^1.1.0"
-    memory-fs "~0.4.1"
-    micromatch "^3.1.8"
-    mkdirp "~0.5.0"
-    neo-async "^2.5.0"
-    node-libs-browser "^2.0.0"
+    loader-runner "^2.4.0"
+    loader-utils "^1.2.3"
+    memory-fs "^0.4.1"
+    micromatch "^3.1.10"
+    mkdirp "^0.5.1"
+    neo-async "^2.6.1"
+    node-libs-browser "^2.2.1"
     schema-utils "^1.0.0"
-    tapable "^1.1.0"
-    terser-webpack-plugin "^1.1.0"
-    watchpack "^1.5.0"
-    webpack-sources "^1.3.0"
+    tapable "^1.1.3"
+    terser-webpack-plugin "^1.4.1"
+    watchpack "^1.6.0"
+    webpack-sources "^1.4.1"
 
 websocket-driver@>=0.5.1:
-  version "0.7.0"
-  resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb"
-  integrity sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=
+  version "0.7.3"
+  resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9"
+  integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==
   dependencies:
-    http-parser-js ">=0.4.0"
+    http-parser-js ">=0.4.0 <0.4.11"
+    safe-buffer ">=5.1.0"
     websocket-extensions ">=0.1.1"
 
 websocket-extensions@>=0.1.1:
@@ -16394,10 +15588,10 @@ write-file-atomic@2.4.1:
     imurmurhash "^0.1.4"
     signal-exit "^3.0.2"
 
-write-file-atomic@^2.0.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.2:
-  version "2.4.2"
-  resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9"
-  integrity sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==
+write-file-atomic@^2.0.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.3:
+  version "2.4.3"
+  resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481"
+  integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==
   dependencies:
     graceful-fs "^4.1.11"
     imurmurhash "^0.1.4"
@@ -16417,7 +15611,7 @@ ws@^5.2.0:
   dependencies:
     async-limiter "~1.0.0"
 
-ws@^6.1.0, ws@^6.1.2:
+ws@^6.1.0, ws@^6.1.2, ws@^6.2.1:
   version "6.2.1"
   resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb"
   integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==
@@ -16439,15 +15633,15 @@ xml-name-validator@^3.0.0:
   resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
   integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
 
-xmlchars@^1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-1.3.1.tgz#1dda035f833dbb4f86a0c28eaa6ca769214793cf"
-  integrity sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==
+xmlchars@^2.1.1:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
+  integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
 
 xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
-  integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
+  integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
 
 y18n@^3.2.1:
   version "3.2.1"
@@ -16465,9 +15659,9 @@ yallist@^2.1.2:
   integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
 
 yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9"
-  integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
+  integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
 
 yargs-parser@10.x, yargs-parser@^10.0.0:
   version "10.1.0"
@@ -16484,18 +15678,18 @@ yargs-parser@^11.1.1:
     camelcase "^5.0.0"
     decamelize "^1.2.0"
 
-yargs-parser@^13.1.0:
-  version "13.1.0"
-  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.0.tgz#7016b6dd03e28e1418a510e258be4bff5a31138f"
-  integrity sha512-Yq+32PrijHRri0vVKQEm+ys8mbqWjLiwQkMFNXEENutzLPP0bE4Lcd4iA3OQY5HF+GD3xXxf0MEHb8E4/SA3AA==
+yargs-parser@^13.1.0, yargs-parser@^13.1.1:
+  version "13.1.1"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0"
+  integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==
   dependencies:
     camelcase "^5.0.0"
     decamelize "^1.2.0"
 
-yargs-parser@^13.1.1:
-  version "13.1.1"
-  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0"
-  integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==
+yargs-parser@^15.0.0:
+  version "15.0.0"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.0.tgz#cdd7a97490ec836195f59f3f4dbe5ea9e8f75f08"
+  integrity sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==
   dependencies:
     camelcase "^5.0.0"
     decamelize "^1.2.0"
@@ -16514,7 +15708,7 @@ yargs-parser@^9.0.2:
   dependencies:
     camelcase "^4.1.0"
 
-yargs@12.0.5, yargs@^12.0.1, yargs@^12.0.2, yargs@^12.0.5:
+yargs@12.0.5, yargs@^12.0.1, yargs@^12.0.2:
   version "12.0.5"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
   integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
@@ -16532,16 +15726,33 @@ yargs@12.0.5, yargs@^12.0.1, yargs@^12.0.2, yargs@^12.0.5:
     y18n "^3.2.1 || ^4.0.0"
     yargs-parser "^11.1.1"
 
+yargs@13.2.4:
+  version "13.2.4"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83"
+  integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==
+  dependencies:
+    cliui "^5.0.0"
+    find-up "^3.0.0"
+    get-caller-file "^2.0.1"
+    os-locale "^3.1.0"
+    require-directory "^2.1.1"
+    require-main-filename "^2.0.0"
+    set-blocking "^2.0.0"
+    string-width "^3.0.0"
+    which-module "^2.0.0"
+    y18n "^4.0.0"
+    yargs-parser "^13.1.0"
+
 yargs@^11.0.0:
-  version "11.1.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77"
-  integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==
+  version "11.1.1"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.1.tgz#5052efe3446a4df5ed669c995886cc0f13702766"
+  integrity sha512-PRU7gJrJaXv3q3yQZ/+/X6KBswZiaQ+zOmdprZcouPYtQgvNU35i+68M4b1ZHLZtYFT5QObFLV+ZkmJYcwKdiw==
   dependencies:
     cliui "^4.0.0"
     decamelize "^1.1.1"
     find-up "^2.1.0"
     get-caller-file "^1.0.1"
-    os-locale "^2.0.0"
+    os-locale "^3.1.0"
     require-directory "^2.1.1"
     require-main-filename "^1.0.1"
     set-blocking "^2.0.0"
@@ -16550,29 +15761,29 @@ yargs@^11.0.0:
     y18n "^3.2.1"
     yargs-parser "^9.0.2"
 
-yargs@^13.1.0:
-  version "13.2.4"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83"
-  integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==
+yargs@^13.3.0:
+  version "13.3.0"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83"
+  integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==
   dependencies:
     cliui "^5.0.0"
     find-up "^3.0.0"
     get-caller-file "^2.0.1"
-    os-locale "^3.1.0"
     require-directory "^2.1.1"
     require-main-filename "^2.0.0"
     set-blocking "^2.0.0"
     string-width "^3.0.0"
     which-module "^2.0.0"
     y18n "^4.0.0"
-    yargs-parser "^13.1.0"
+    yargs-parser "^13.1.1"
 
-yargs@^13.3.0:
-  version "13.3.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83"
-  integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==
+yargs@^14.0.0:
+  version "14.2.0"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.0.tgz#f116a9242c4ed8668790b40759b4906c276e76c3"
+  integrity sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg==
   dependencies:
     cliui "^5.0.0"
+    decamelize "^1.2.0"
     find-up "^3.0.0"
     get-caller-file "^2.0.1"
     require-directory "^2.1.1"
@@ -16581,7 +15792,7 @@ yargs@^13.3.0:
     string-width "^3.0.0"
     which-module "^2.0.0"
     y18n "^4.0.0"
-    yargs-parser "^13.1.1"
+    yargs-parser "^15.0.0"
 
 yargs@^7.0.0:
   version "7.1.0"