From f25ef46afb921d4a432de39875fed72a7183269d Mon Sep 17 00:00:00 2001 From: Marco Vettorello Date: Mon, 8 Apr 2019 14:05:01 +0200 Subject: [PATCH] test(canvas): test text bbox calculator on real canvas (#153) Removed the jest-canvas-mock package that doesn't use any canvas implementation, substitute the existing test environment with jsdom 14 and updated canvas. Removed an old mock of getContext inside the enzime setup. Increased the scale font size for the bbox calculator and configured few tests for that, to fix the relative issue on chrome. Canvas on node depends on the os, installed library, fonts etc. This commit checks for a maximum difference between the expected value of the measured text of 2px. This commit also revisit the chart_state test suite decoupling each test from each other. fix #152 --- .storybook/config.ts | 1 + jest.config.json | 13 +- package.json | 4 +- scripts/setup_enzyme.ts | 2 - .../axes/canvas_text_bbox_calculator.test.ts | 55 +++- src/lib/axes/canvas_text_bbox_calculator.ts | 4 +- src/state/chart_state.test.ts | 54 ++-- src/state/chart_state.ts | 8 +- stories/interactions.tsx | 41 +++ yarn.lock | 252 +++++++++++++++--- 10 files changed, 348 insertions(+), 86 deletions(-) diff --git a/.storybook/config.ts b/.storybook/config.ts index bd429173b4..e2350792f8 100644 --- a/.storybook/config.ts +++ b/.storybook/config.ts @@ -31,6 +31,7 @@ addDecorator( ); function loadStories() { + require('../stories/playground.tsx'); require('../stories/bar_chart.tsx'); require('../stories/line_chart.tsx'); require('../stories/area_chart.tsx'); diff --git a/jest.config.json b/jest.config.json index a429dc7e47..93ecde46c1 100644 --- a/jest.config.json +++ b/jest.config.json @@ -1,11 +1,6 @@ { - "roots": [ - "/src" - ], + "roots": ["/src"], "preset": "ts-jest", - "testEnvironment": "jsdom", - "setupFilesAfterEnv": [ - "/scripts/setup_enzyme.ts", - "jest-canvas-mock" - ] -} \ No newline at end of file + "testEnvironment": "jest-environment-jsdom-fourteen", + "setupFilesAfterEnv": ["/scripts/setup_enzyme.ts"] +} diff --git a/package.json b/package.json index 388acc66ec..0e94a104f7 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "@types/storybook__addon-options": "^4.0.1", "@types/storybook__react": "^4.0.0", "babel-loader": "^8.0.5", - "canvas": "^2.3.1", + "canvas": "^2.4.1", "commitizen": "^3.0.7", "css-loader": "^2.1.0", "cz-conventional-changelog": "^2.1.0", @@ -88,7 +88,7 @@ "enzyme-adapter-react-16": "^1.10.0", "husky": "^1.3.1", "jest": "^24.1.0", - "jest-canvas-mock": "^2.0.0-beta.1", + "jest-environment-jsdom-fourteen": "^0.1.0", "moment": "^2.24.0", "node-sass": "^4.11.0", "prettier": "1.16.4", diff --git a/scripts/setup_enzyme.ts b/scripts/setup_enzyme.ts index 17bb3833bd..82edfc9e5a 100644 --- a/scripts/setup_enzyme.ts +++ b/scripts/setup_enzyme.ts @@ -2,5 +2,3 @@ import { configure } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; configure({ adapter: new Adapter() }); - -HTMLCanvasElement.prototype.getContext = jest.fn(); diff --git a/src/lib/axes/canvas_text_bbox_calculator.test.ts b/src/lib/axes/canvas_text_bbox_calculator.test.ts index 47c1460257..12aa0c05cc 100644 --- a/src/lib/axes/canvas_text_bbox_calculator.test.ts +++ b/src/lib/axes/canvas_text_bbox_calculator.test.ts @@ -8,15 +8,56 @@ describe('CanvasTextBBoxCalculator', () => { width: 0, height: 0, }); - - const expectedDims = { - width: 10.6, - height: 16, - }; - - expect(bbox).toEqual(expectedDims); + expect(Math.abs(bbox.width - 23.2)).toBeLessThanOrEqual(2); + expect(bbox.height).toBe(16); canvasBboxCalculator.context = null; expect(canvasBboxCalculator.compute('foo')).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').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').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').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').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').getOrElse({ + width: 0, + height: 0, + }); + expect(Math.abs(bbox.width - 23.2)).toBeLessThanOrEqual(2); + expect(bbox.height).toBe(16); + }); }); diff --git a/src/lib/axes/canvas_text_bbox_calculator.ts b/src/lib/axes/canvas_text_bbox_calculator.ts index 970662c891..f3143cf9a8 100644 --- a/src/lib/axes/canvas_text_bbox_calculator.ts +++ b/src/lib/axes/canvas_text_bbox_calculator.ts @@ -7,7 +7,7 @@ export class CanvasTextBBoxCalculator implements BBoxCalculator { private offscreenCanvas: HTMLCanvasElement; private scaledFontSize: number; - constructor(rootElement?: HTMLElement) { + constructor(rootElement?: HTMLElement, scaledFontSize: number = 100) { this.offscreenCanvas = document.createElement('canvas'); this.offscreenCanvas.style.position = 'absolute'; this.offscreenCanvas.style.top = '-9999px'; @@ -15,7 +15,7 @@ export class CanvasTextBBoxCalculator implements BBoxCalculator { this.context = this.offscreenCanvas.getContext('2d'); this.attachedRoot = rootElement || document.documentElement; this.attachedRoot.appendChild(this.offscreenCanvas); - this.scaledFontSize = 5; + this.scaledFontSize = scaledFontSize; } compute(text: string, fontSize = 16, fontFamily = 'Arial', padding: number = 1): Option { if (!this.context) { diff --git a/src/state/chart_state.test.ts b/src/state/chart_state.test.ts index 99afa7488a..0c0113506a 100644 --- a/src/state/chart_state.test.ts +++ b/src/state/chart_state.test.ts @@ -8,6 +8,8 @@ import { BarSeriesSpec, Position, } from '../lib/series/specs'; +import { LIGHT_THEME } from '../lib/themes/light_theme'; +import { mergeWithDefaultTheme } from '../lib/themes/theme'; import { getAnnotationId, getAxisId, getGroupId, getSpecId } from '../lib/utils/ids'; import { TooltipType, TooltipValue } from '../lib/utils/interactions'; import { ScaleBand } from '../lib/utils/scales/scale_band'; @@ -16,7 +18,7 @@ import { ScaleType } from '../lib/utils/scales/scales'; import { ChartStore } from './chart_state'; describe('Chart Store', () => { - const store = new ChartStore(); + let store = new ChartStore(); const SPEC_ID = getSpecId('spec_1'); const AXIS_ID = getAxisId('axis_1'); @@ -54,6 +56,11 @@ describe('Chart Store', () => { colorValues: [], }, }; + beforeEach(() => { + store = new ChartStore(); + store.updateParentDimensions(600, 600, 0, 0); + store.computeChart(); + }); test('can add a single spec', () => { store.addSeriesSpec(spec); @@ -70,6 +77,7 @@ describe('Chart Store', () => { }); test('can add an axis', () => { + store.addSeriesSpec(spec); const axisSpec: AxisSpec = { id: AXIS_ID, groupId: GROUP_ID, @@ -342,30 +350,42 @@ describe('Chart Store', () => { }, ); - const start = { x: 0, y: 0 }; - const end1 = { x: 100, y: 0 }; - const end2 = { x: -100, y: 0 }; - store.chartDimensions.left = 10; - + const start1 = { x: 0, y: 0 }; + const start2 = { x: 100, y: 0 }; + const end1 = { x: 600, y: 0 }; + const end2 = { x: 300, y: 0 }; + store.chartTheme = mergeWithDefaultTheme( + { + chartMargins: { + left: 0, + right: 0, + top: 0, + bottom: 0, + }, + }, + LIGHT_THEME, + ); + store.addSeriesSpec(spec); + store.computeChart(); store.onBrushEndListener = undefined; store.onBrushStart(); expect(store.isBrushing.get()).toBe(false); - store.onBrushEnd(start, end1); + store.onBrushEnd(start1, end1); expect(brushEndListener).not.toBeCalled(); store.setOnBrushEndListener(brushEndListener); store.onBrushStart(); expect(store.isBrushing.get()).toBe(true); - store.onBrushEnd(start, start); + store.onBrushEnd(start1, start1); expect(brushEndListener).not.toBeCalled(); - store.onBrushEnd(start, end1); - expect(brushEndListener.mock.calls[0][0]).toBeCloseTo(0.9, 1); - expect(brushEndListener.mock.calls[0][1]).toBeCloseTo(1.5, 1); + store.onBrushEnd(start1, end1); + expect(brushEndListener.mock.calls[0][0]).toBe(1); + expect(brushEndListener.mock.calls[0][1]).toBe(4); - store.onBrushEnd(start, end2); - expect(brushEndListener.mock.calls[1][0]).toBeCloseTo(0.3, 1); - expect(brushEndListener.mock.calls[1][1]).toBeCloseTo(0.9, 1); + store.onBrushEnd(start2, end2); + expect(brushEndListener.mock.calls[1][0]).toBe(1.5); + expect(brushEndListener.mock.calls[1][1]).toBe(2.5); }); test('can update parent dimensions', () => { @@ -604,6 +624,8 @@ describe('Chart Store', () => { }); test('can disable tooltip on brushing', () => { + store.addSeriesSpec(spec); + store.setOnBrushEndListener(() => ({})); const tooltipValue: TooltipValue = { name: 'a', value: 'a', @@ -613,7 +635,7 @@ describe('Chart Store', () => { }; store.xScale = new ScaleContinuous([0, 100], [0, 100], ScaleType.Linear); store.cursorPosition.x = 1; - store.cursorPosition.x = 1; + store.cursorPosition.y = 1; store.tooltipType.set(TooltipType.Crosshairs); store.tooltipData.replace([tooltipValue]); store.onBrushStart(); @@ -621,7 +643,7 @@ describe('Chart Store', () => { expect(store.isTooltipVisible.get()).toBe(false); store.cursorPosition.x = 1; - store.cursorPosition.x = 1; + store.cursorPosition.y = 1; store.tooltipType.set(TooltipType.Crosshairs); store.tooltipData.replace([tooltipValue]); store.onBrushEnd({ x: 0, y: 0 }, { x: 1, y: 1 }); diff --git a/src/state/chart_state.ts b/src/state/chart_state.ts index 537f78732c..7dd6a8a7f6 100644 --- a/src/state/chart_state.ts +++ b/src/state/chart_state.ts @@ -743,10 +743,10 @@ export class ChartStore { this.customSeriesColors = new Map([...this.customSeriesColors, ...updatedCustomSeriesColors]); // tslint:disable-next-line:no-console - // console.log({colors: seriesDomains.seriesColors}); + console.log({ colors: seriesDomains.seriesColors }); // tslint:disable-next-line:no-console - // console.log({ seriesDomains }); + console.log({ seriesDomains }); this.seriesColorMap = getSeriesColorMap( seriesDomains.seriesColors, this.chartTheme.colors, @@ -761,7 +761,7 @@ export class ChartStore { this.deselectedDataSeries, ); // tslint:disable-next-line:no-console - // console.log({ legendItems: this.legendItems }); + console.log({ legendItems: this.legendItems }); const { xDomain, @@ -822,7 +822,7 @@ export class ChartStore { ); // tslint:disable-next-line:no-console - // console.log({ seriesGeometries }); + console.log({ seriesGeometries }); this.geometries = seriesGeometries.geometries; this.xScale = seriesGeometries.scales.xScale; this.yScales = seriesGeometries.scales.yScales; diff --git a/stories/interactions.tsx b/stories/interactions.tsx index dd7be8434f..0d268758b2 100644 --- a/stories/interactions.tsx +++ b/stories/interactions.tsx @@ -449,6 +449,47 @@ storiesOf('Interactions', module) ); }) + .add('brush selection tool on bar chart linear', () => { + return ( + + + + Number(d).toFixed(2)} + /> + + Number(d).toFixed(2)} + /> + + + + ); + }) .add('brush selection tool on time charts', () => { const now = DateTime.fromISO('2019-01-11T00:00:00.000Z').toMillis(); const oneDay = 1000 * 60 * 60 * 24; diff --git a/yarn.lock b/yarn.lock index ac3a2abf6d..6d4fb6e068 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1183,6 +1183,50 @@ resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8" integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw== +"@jest/console@^24.7.1": + version "24.7.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545" + integrity sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg== + dependencies: + "@jest/source-map" "^24.3.0" + chalk "^2.0.1" + slash "^2.0.0" + +"@jest/fake-timers@^24.7.1": + version "24.7.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.7.1.tgz#56e5d09bdec09ee81050eaff2794b26c71d19db2" + integrity sha512-4vSQJDKfR2jScOe12L9282uiwuwQv9Lk7mgrCSZHA9evB9efB/qx8i0KJxsAKtp8fgJYBJdYY7ZU6u3F4/pyjA== + dependencies: + "@jest/types" "^24.7.0" + jest-message-util "^24.7.1" + jest-mock "^24.7.0" + +"@jest/source-map@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28" + integrity sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + +"@jest/test-result@^24.7.1": + version "24.7.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.7.1.tgz#19eacdb29a114300aed24db651e5d975f08b6bbe" + integrity sha512-3U7wITxstdEc2HMfBX7Yx3JZgiNBubwDqQMh+BXmZXHa3G13YWF3p6cK+5g0hGkN3iufg/vGPl3hLxQXD74Npg== + dependencies: + "@jest/console" "^24.7.1" + "@jest/types" "^24.7.0" + "@types/istanbul-lib-coverage" "^2.0.0" + +"@jest/types@^24.7.0": + version "24.7.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.7.0.tgz#c4ec8d1828cdf23234d9b4ee31f5482a3f04f48b" + integrity sha512-ipJUa2rFWiKoBqMKP63Myb6h9+iT3FHRTF2M8OR6irxWzItisa8i4dcSg14IbvmXUnBlHBlUQPYUHWyX3UPpYA== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/yargs" "^12.0.9" + "@marionebl/sander@^0.6.0": version "0.6.1" resolved "https://registry.yarnpkg.com/@marionebl/sander/-/sander-0.6.1.tgz#1958965874f24bc51be48875feb50d642fc41f7b" @@ -1818,6 +1862,11 @@ "@types/cheerio" "*" "@types/react" "*" +"@types/istanbul-lib-coverage@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz#1eb8c033e98cf4e1a4cedcaf8bcafe8cb7591e85" + integrity sha512-eAtOAFZefEnfJiRFQBGw1eYqa5GTLCZ1y86N0XSI/D6EB+E8z6VPV/UL7Gi5UEclFqoQk+6NRqEDsfmDLXn8sg== + "@types/jest-diff@*": version "20.0.1" resolved "https://registry.yarnpkg.com/@types/jest-diff/-/jest-diff-20.0.1.tgz#35cc15b9c4f30a18ef21852e255fdb02f6d59b89" @@ -1875,6 +1924,11 @@ "@types/prop-types" "*" csstype "^2.2.0" +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== + "@types/storybook__addon-actions@^3.4.2": version "3.4.2" resolved "https://registry.yarnpkg.com/@types/storybook__addon-actions/-/storybook__addon-actions-3.4.2.tgz#1d08689cc3259269ddb3479a2307c9d16944309e" @@ -1938,6 +1992,11 @@ resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.7.tgz#137a4e57aa31ab57b1baf66f5dc3b6bf085e9944" integrity sha512-rzi6fw7hhxPcCoNVsgysHFlKnhYYvVj7AJwdAO0HQNP5vg9sY0DoRRC1pfuCQm94cOa1sab82HGUtdFlWHIhBg== +"@types/yargs@^12.0.9": + version "12.0.11" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.11.tgz#a090d88e1f40a910e6443c95493c1c035c76ebdc" + integrity sha512-IsU1TD+8cQCyG76ZqxP0cVFnofvfzT8p/wO8ENT4jbN/KKN3grsHFgHNl/U+08s33ayX4LwI85cEhYXCOlOkMw== + "@webassemblyjs/ast@1.8.3": version "1.8.3" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.3.tgz#63a741bd715a6b6783f2ea5c6ab707516aa215eb" @@ -2137,7 +2196,7 @@ acorn-dynamic-import@^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.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103" integrity sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw== @@ -2155,7 +2214,7 @@ 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.5: +acorn@^6.0.1, acorn@^6.0.4, acorn@^6.0.5: version "6.1.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== @@ -3385,10 +3444,10 @@ caniuse-lite@^1.0.30000884, caniuse-lite@^1.0.30000939: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000939.tgz#b9ab7ac9e861bf78840b80c5dfbc471a5cd7e679" integrity sha512-oXB23ImDJOgQpGjRv1tCtzAvJr4/OvrHi5SO2vUgB0g0xpdZZoA/BxfImiWfdwoYdUTtQrPsXsvYU/dmCSM8gg== -canvas@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.3.1.tgz#da0c8a916505aa34f9365d6b77d28b969241bfd0" - integrity sha512-jSxwf4V9AGD6t6yBC600xFZKjrfKTR0T0RUNlX/AODs/ifrfJHIQjFEK8iF2euNy6z7K3GNv82DJgTjYZZktqA== +canvas@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.4.1.tgz#d3b40efc7c281006ca0ff9cc854aaa8b82abec7a" + integrity sha512-SaFomFqDuuuSTScTHQ7nXc5ea71Ieb8ctvwXjR7vzLsBMfp3euTv2xsTY70zIoC5r4sSQZYXv6tiHiORJ4y1vg== dependencies: nan "^2.12.1" node-pre-gyp "^0.11.0" @@ -3732,11 +3791,6 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" -color-convert@~0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd" - integrity sha1-vbbGnOZg+t/+CwAHzER+G59ygr0= - color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" @@ -4247,11 +4301,6 @@ cssesc@^0.1.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q= -cssfontparser@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/cssfontparser/-/cssfontparser-1.2.1.tgz#f4022fc8f9700c68029d542084afbaf425a3f3e3" - integrity sha1-9AIvyPlwDGgCnVQghK+69CWj8+M= - csso@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/csso/-/csso-3.5.1.tgz#7b9eb8be61628973c1b261e169d2f024008e758b" @@ -4259,7 +4308,7 @@ 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.6" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.6.tgz#f85206cee04efa841f3c5982a74ba96ab20d65ad" integrity sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A== @@ -4271,6 +4320,13 @@ cssstyle@^1.0.0: 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.2" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.2.tgz#3043d5e065454579afc7478a18de41909c8a2f01" @@ -4439,7 +4495,7 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-urls@^1.0.0: +data-urls@^1.0.0, data-urls@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== @@ -5077,7 +5133,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.9.1: +escodegen@^1.11.0, escodegen@^1.9.1: version "1.11.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510" integrity sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw== @@ -7030,14 +7086,6 @@ java-properties@^0.2.9: resolved "https://registry.yarnpkg.com/java-properties/-/java-properties-0.2.10.tgz#2551560c25fa1ad94d998218178f233ad9b18f60" integrity sha512-CpKJh9VRNhS+XqZtg1UMejETGEiqwCGDC/uwPEEQwc2nfdbSm73SIE29TplG2gLYuBOOTNDqxzG6A9NtEPLt0w== -jest-canvas-mock@^2.0.0-beta.1: - version "2.0.0-beta.1" - resolved "https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.0.0-beta.1.tgz#a99f3dd5bcdc10b57c00da43cbe17847697a9425" - integrity sha512-OwUcVnJc0qXUxt+ADSWbADVHUTt5wOmOIqL9N22mXCFclQXcLGPB/CeM3Wnu1eZcRWGE2aGHk5RqbH9qznJhEQ== - dependencies: - cssfontparser "^1.2.1" - parse-color "^1.0.0" - jest-changed-files@^24.0.0: version "24.0.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.0.0.tgz#c02c09a8cc9ca93f513166bc773741bd39898ff7" @@ -7138,6 +7186,15 @@ jest-each@^24.0.0: jest-util "^24.0.0" pretty-format "^24.0.0" +jest-environment-jsdom-fourteen@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-0.1.0.tgz#aad6393a9d4b565b69a609109bf469f62bf18ccc" + integrity sha512-4vtoRMg7jAstitRzL4nbw83VmGH8Rs13wrND3Ud2o1fczDhMUF32iIrNKwYGgeOPUdfvZU4oy8Bbv+ni1fgVCA== + dependencies: + jest-mock "^24.5.0" + jest-util "^24.5.0" + jsdom "^14.0.0" + jest-environment-jsdom@^24.0.0: version "24.0.0" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.0.0.tgz#5affa0654d6e44cd798003daa1a8701dbd6e4d11" @@ -7220,11 +7277,32 @@ jest-message-util@^24.0.0: slash "^2.0.0" stack-utils "^1.0.1" +jest-message-util@^24.7.1: + version "24.7.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.7.1.tgz#f1dc3a6c195647096a99d0f1dadbc447ae547018" + integrity sha512-dk0gqVtyqezCHbcbk60CdIf+8UHgD+lmRHifeH3JRcnAqh4nEyPytSc9/L1+cQyxC+ceaeP696N4ATe7L+omcg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.7.1" + "@jest/types" "^24.7.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + jest-mock@^24.0.0: version "24.0.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.0.0.tgz#9a4b53e01d66a0e780f7d857462d063e024c617d" integrity sha512-sQp0Hu5fcf5NZEh1U9eIW2qD0BwJZjb63Yqd98PQJFvf/zzUTBoUAwv/Dc/HFeNHIw1f3hl/48vNn+j3STaI7A== +jest-mock@^24.5.0, jest-mock@^24.7.0: + version "24.7.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.7.0.tgz#e49ce7262c12d7f5897b0d8af77f6db8e538023b" + integrity sha512-6taW4B4WUcEiT2V9BbOmwyGuwuAFT2G8yghF7nyNW1/2gq5+6aTqSPcS9lS6ArvEkX55vbPAS/Jarx5LSm4Fng== + dependencies: + "@jest/types" "^24.7.0" + jest-regex-util@^24.0.0: version "24.0.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.0.0.tgz#4feee8ec4a358f5bee0a654e94eb26163cb9089a" @@ -7330,6 +7408,24 @@ jest-util@^24.0.0: slash "^2.0.0" source-map "^0.6.0" +jest-util@^24.5.0: + version "24.7.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.7.1.tgz#b4043df57b32a23be27c75a2763d8faf242038ff" + integrity sha512-/KilOue2n2rZ5AnEBYoxOXkeTu6vi7cjgQ8MXEkih0oeAXT6JkS3fr7/j8+engCjciOU1Nq5loMSKe0A1oeX0A== + dependencies: + "@jest/console" "^24.7.1" + "@jest/fake-timers" "^24.7.1" + "@jest/source-map" "^24.3.0" + "@jest/test-result" "^24.7.1" + "@jest/types" "^24.7.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-validate@^24.0.0: version "24.0.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.0.0.tgz#aa8571a46983a6538328fef20406b4a496b6c020" @@ -7432,6 +7528,38 @@ jsdom@^11.5.1: ws "^5.2.0" xml-name-validator "^3.0.0" +jsdom@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-14.0.0.tgz#c7f1441ebcc57902d08d5fb2f6ba2baf746da7c6" + integrity sha512-/VkyPmdtbwqpJSkwDx3YyJ3U1oawYNB/h5z8vTUZGAzjtu2OHTeFRfnJqyMHsJ5Cyes23trOmvUpM1GfHH1leA== + dependencies: + abab "^2.0.0" + acorn "^6.0.4" + acorn-globals "^4.3.0" + array-equal "^1.0.0" + cssom "^0.3.4" + cssstyle "^1.1.1" + data-urls "^1.1.0" + domexception "^1.0.1" + escodegen "^1.11.0" + html-encoding-sniffer "^1.0.2" + nwsapi "^2.0.9" + parse5 "5.1.0" + pn "^1.1.0" + request "^2.88.0" + request-promise-native "^1.0.5" + saxes "^3.1.5" + symbol-tree "^3.2.2" + tough-cookie "^2.5.0" + w3c-hr-time "^1.0.1" + w3c-xmlserializer "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^7.0.0" + ws "^6.1.2" + xml-name-validator "^3.0.0" + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -8486,11 +8614,16 @@ mute-stream@~0.0.4: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.10.0, nan@^2.12.1, nan@^2.9.2: +nan@^2.10.0, nan@^2.9.2: version "2.12.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== +nan@^2.12.1: + version "2.13.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" + integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -9094,6 +9227,11 @@ nwsapi@^2.0.7: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.1.tgz#08d6d75e69fd791bdea31507ffafe8c843b67e9c" integrity sha512-T5GaA1J/d34AC8mkrFD2O0DR17kwJ702ZOtJOsS8RpbsQZVOC2/xYFb1i/cw+xdM54JIlMuojjDOYct8GIWtwg== +nwsapi@^2.0.9: + version "2.1.3" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.3.tgz#25f3a5cec26c654f7376df6659cdf84b99df9558" + integrity sha512-RowAaJGEgYXEZfQ7tvvdtAQUKPyTR6T6wNu0fwlNsGQYr/h3yQc6oI8WnVZh3Y/Sylwc+dtAlvPqfFZjhTyk3A== + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -9486,13 +9624,6 @@ parse-asn1@^5.0.0: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" -parse-color@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-color/-/parse-color-1.0.0.tgz#7b748b95a83f03f16a94f535e52d7f3d94658619" - integrity sha1-e3SLlag/A/FqlPU15S1/PZRlhhk= - dependencies: - color-convert "~0.5.0" - parse-entities@^1.1.2: version "1.2.1" resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.1.tgz#2c761ced065ba7dc68148580b5a225e4918cdd69" @@ -9535,6 +9666,11 @@ 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: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" + integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== + parse5@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" @@ -9542,11 +9678,6 @@ parse5@^3.0.1: dependencies: "@types/node" "*" -parse5@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" - integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== - parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" @@ -11192,6 +11323,13 @@ sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +saxes@^3.1.5: + version "3.1.9" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.9.tgz#c1c197cd54956d88c09f960254b999e192d7058b" + integrity sha512-FZeKhJglhJHk7eWG5YM0z46VHmI3KJpMBAQm3xa9meDvd+wevB5GuBB0wc0exPInZiBBHqi00DbS8AcvCGCFMw== + dependencies: + xmlchars "^1.3.1" + scheduler@^0.13.3: version "0.13.3" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.3.tgz#bed3c5850f62ea9c716a4d781f9daeb9b2a58896" @@ -11279,11 +11417,16 @@ 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 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@5.6.0, "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.1, 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@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@5.6.0, "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== +semver@^5.3.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -12241,7 +12384,7 @@ toggle-selection@^1.0.3: resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI= -tough-cookie@^2.3.3, tough-cookie@^2.3.4: +tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -12757,6 +12900,15 @@ w3c-hr-time@^1.0.1: dependencies: browser-process-hrtime "^0.1.2" +w3c-xmlserializer@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" + integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== + dependencies: + domexception "^1.0.1" + webidl-conversions "^4.0.2" + xml-name-validator "^3.0.0" + walker@~1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" @@ -12894,7 +13046,7 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== @@ -12906,7 +13058,7 @@ whatwg-fetch@>=0.10.0: resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== -whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== @@ -13027,6 +13179,13 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" +ws@^6.1.2: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + x-is-string@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" @@ -13042,6 +13201,11 @@ 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== + 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"