diff --git a/jest.config.js b/jest.config.js
index 18331a7..45b21bc 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -59,7 +59,9 @@ module.exports = {
// globalTeardown: undefined,
// A set of global variables that need to be available in all test environments
- // globals: {},
+ globals: {
+ window: true
+ },
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
// maxWorkers: "50%",
@@ -138,7 +140,7 @@ module.exports = {
// snapshotSerializers: [],
// The test environment that will be used for testing
- testEnvironment: 'node',
+ testEnvironment: 'jsdom',
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
diff --git a/packages/utils/package.json b/packages/utils/package.json
index 6e84f4d..0914d0e 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -23,6 +23,9 @@
"peerDependencies": {
"@alfalab/data": "^0.2.0"
},
+ "dependencies": {
+ "bezier-easing": "2.1.0"
+ },
"publishConfig": {
"access": "public"
}
diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts
index 85f3b8d..df89924 100644
--- a/packages/utils/src/index.ts
+++ b/packages/utils/src/index.ts
@@ -7,3 +7,4 @@ export * from './crop-account-number';
export * from './pluralize';
export * from './get-countries';
export * from './format-phone';
+export * from './scroll-to';
diff --git a/packages/utils/src/scroll-to/easings.ts b/packages/utils/src/scroll-to/easings.ts
new file mode 100644
index 0000000..abf7a39
--- /dev/null
+++ b/packages/utils/src/scroll-to/easings.ts
@@ -0,0 +1,35 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ import bezierEasing from 'bezier-easing';
+
+ const easings = {
+ easeInSine: bezierEasing(0.47, 0, 0.745, 0.715),
+ easeOutSine: bezierEasing(0.39, 0.575, 0.565, 1),
+ easeInOutSine: bezierEasing(0.445, 0.05, 0.55, 0.95),
+ easeInQuad: bezierEasing(0.55, 0.085, 0.68, 0.53),
+ easeOutQuad: bezierEasing(0.25, 0.46, 0.45, 0.94),
+ easeInOutQuad: bezierEasing(0.455, 0.03, 0.515, 0.955),
+ easeInCubic: bezierEasing(0.55, 0.055, 0.675, 0.19),
+ easeOutCubic: bezierEasing(0.215, 0.61, 0.355, 1),
+ easeInOutCubic: bezierEasing(0.645, 0.045, 0.355, 1),
+ easeInQuart: bezierEasing(0.895, 0.03, 0.685, 0.22),
+ easeOutQuart: bezierEasing(0.165, 0.84, 0.44, 1),
+ easeInOutQuart: bezierEasing(0.77, 0, 0.175, 1),
+ easeInQuint: bezierEasing(0.755, 0.05, 0.855, 0.06),
+ easeOutQuint: bezierEasing(0.23, 1, 0.32, 1),
+ easeInOutQuint: bezierEasing(0.86, 0, 0.07, 1),
+ easeInExpo: bezierEasing(0.95, 0.05, 0.795, 0.035),
+ easeOutExpo: bezierEasing(0.19, 1, 0.22, 1),
+ easeInOutExpo: bezierEasing(1, 0, 0, 1),
+ easeInCirc: bezierEasing(0.6, 0.04, 0.98, 0.335),
+ easeOutCirc: bezierEasing(0.075, 0.82, 0.165, 1),
+ easeInOutCirc: bezierEasing(0.785, 0.135, 0.15, 0.86),
+ easeInBack: bezierEasing(0.6, -0.28, 0.735, 0.045),
+ easeOutBack: bezierEasing(0.175, 0.885, 0.32, 1.275),
+ easeInOutBack: bezierEasing(0.68, -0.55, 0.265, 1.55),
+ };
+
+ export type EasingType = keyof typeof easings;
+ export default easings;
\ No newline at end of file
diff --git a/packages/utils/src/scroll-to/index.ts b/packages/utils/src/scroll-to/index.ts
new file mode 100644
index 0000000..133b1de
--- /dev/null
+++ b/packages/utils/src/scroll-to/index.ts
@@ -0,0 +1 @@
+export * from './util';
\ No newline at end of file
diff --git a/packages/utils/src/scroll-to/util.test.ts b/packages/utils/src/scroll-to/util.test.ts
new file mode 100644
index 0000000..2dc7c13
--- /dev/null
+++ b/packages/utils/src/scroll-to/util.test.ts
@@ -0,0 +1,114 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ import scrollTo from './util';
+
+ function getContainer() {
+ return document.getElementById('container') as HTMLElement;
+ }
+
+ function getScrollContainer() {
+ return document.getElementById('scroll-container') as HTMLElement;
+ }
+
+ function getScrollContainerChild(n: number) {
+ return getScrollContainer().children[n] as HTMLElement;
+ }
+
+ describe('scroll-to', () => {
+ const originalWindowScrollTo = window.scrollTo;
+
+ beforeEach(() => {
+ const domContainerNode = document.createElement('div');
+
+ domContainerNode.setAttribute('id', 'container');
+ domContainerNode.setAttribute('style', 'min-height: 9999px; margin: 0; padding: 0;');
+ domContainerNode.innerHTML = `
+
+ `;
+ document.body.appendChild(domContainerNode);
+
+ window.scrollTo = jest.fn();
+ });
+
+ afterEach(() => {
+ const domContainerNode = getContainer();
+
+ document.body.removeChild(domContainerNode);
+ window.scrollTo = originalWindowScrollTo;
+ });
+
+ it('should scroll to Y in window', async () => {
+ await scrollTo({
+ targetY: 100,
+ duration: 200,
+ });
+ expect(window.scrollTo).toHaveBeenCalledWith(0, 100);
+ });
+
+ it('should scroll to Y in container', async () => {
+ const container = getScrollContainer();
+
+ await scrollTo({
+ targetY: 100,
+ container,
+ });
+
+ expect(container.scrollTop).toBe(100);
+ });
+
+ it('should catch error with incorrect easing', () => {
+ const fn = function () {
+ scrollTo({
+ targetY: 100,
+ duration: 200,
+ easing: 'incorrectEase',
+ } as any);
+ };
+
+ expect(fn).toThrow('Incorrect easing in options');
+ });
+
+ it('should catch error with incorrect duration', () => {
+ const fn = function () {
+ scrollTo({
+ targetY: 100,
+ duration: -200,
+ });
+ };
+
+ expect(fn).toThrow('Incorrect duration in options');
+ });
+
+ it('should scroll down to element in container', async () => {
+ const element = getScrollContainerChild(3);
+ const container = getScrollContainer();
+ const correction = element.offsetHeight;
+
+ if (element.offsetTop + correction > container.scrollTop + container.offsetHeight) {
+ await scrollTo({ container, targetY: element.offsetTop });
+ expect(container.scrollTop).toBe(500);
+ }
+ });
+
+ it('should scroll up to element in container', async () => {
+ const element = getScrollContainerChild(0);
+ const container = getScrollContainer();
+ const correction = element.offsetHeight;
+
+ container.scrollTop = 500;
+
+ if (element.offsetTop < container.scrollTop) {
+ await scrollTo({ container, targetY: (element.offsetTop - container.offsetHeight) + correction });
+
+ expect(container.scrollTop).toBe(0);
+ }
+ });
+ });
\ No newline at end of file
diff --git a/packages/utils/src/scroll-to/util.ts b/packages/utils/src/scroll-to/util.ts
new file mode 100644
index 0000000..b4d1a69
--- /dev/null
+++ b/packages/utils/src/scroll-to/util.ts
@@ -0,0 +1,86 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ import easings, { EasingType } from './easings';
+
+ export const SCROLL_TO_CORRECTION = 16;
+ export const SCROLL_TO_DEFAULT_DURATION = 0;
+ export const SCROLL_TO_NORMAL_DURATION = 250;
+ export const SCROLL_TO_EASING = 'easeInOutSine';
+
+ type ScrollToOptions = {
+ /**
+ * Цель по оси Y
+ */
+ targetY: number;
+ /**
+ * Элемент в котором скроллим
+ */
+ container?: HTMLElement;
+ /**
+ * Продолжительность анимации в миллесекундах
+ */
+ duration?: number;
+ /**
+ * Название функции плавности для анимации
+ */
+ easing?: EasingType;
+ }
+ /**
+ * Скроллит по элементу или странице.
+ * В настоящее время доступно перемещение только по оси Y.
+ * TODO: Make a move on the x axis
+ */
+ export default function scrollTo({
+ targetY,
+ container,
+ duration = 0,
+ easing = SCROLL_TO_EASING,
+ }: ScrollToOptions): Promise {
+ const scrollY = container ? container.scrollTop : window.pageYOffset;
+ const startTime = window.performance.now();
+
+ if (duration < 0) {
+ throw new Error('Incorrect duration in options');
+ }
+
+ if (!easings[easing]) {
+ throw new Error('Incorrect easing in options');
+ }
+
+ const easingFunc = easings[easing];
+
+ return new Promise((resolve) => {
+ function scrollToTarget(y: number): void {
+ if (container) {
+ // eslint-disable-next-line no-param-reassign
+ container.scrollTop = y;
+ } else {
+ window.scrollTo(0, y);
+ }
+ }
+
+ function loop(timestamp: number): void {
+ const currentTime = Math.abs(timestamp - startTime);
+ const t = currentTime / duration;
+ const val = easingFunc(t);
+ const currentTargetY = scrollY + ((targetY - scrollY) * val);
+
+ if (t < 1) {
+ window.requestAnimationFrame(loop);
+ scrollToTarget(currentTargetY);
+ } else {
+ scrollToTarget(targetY);
+ resolve();
+ }
+ }
+
+ if (duration === 0) {
+ scrollToTarget(targetY);
+ resolve();
+ } else {
+ loop(window.performance.now());
+ }
+ });
+ }
\ No newline at end of file
diff --git a/packages/utils/yarn.lock b/packages/utils/yarn.lock
new file mode 100644
index 0000000..62978e5
--- /dev/null
+++ b/packages/utils/yarn.lock
@@ -0,0 +1,210 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@alfalab/data@^0.2.0":
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/@alfalab/data/-/data-0.2.0.tgz#4956618252d0eb754652ec20554ff71292578add"
+ integrity sha512-so5/YttRoIvaulQincuwpensE4zmC9nSRdD2ikCgo6nhyZs6vPB4o7VNhvBcMddrvPOiXRYLerCU+J98GPe22Q==
+
+ansi-regex@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
+ integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
+
+ansi-styles@^4.0.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+ integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+ dependencies:
+ color-convert "^2.0.1"
+
+bezier-easing@2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/bezier-easing/-/bezier-easing-2.1.0.tgz#c04dfe8b926d6ecaca1813d69ff179b7c2025d86"
+ integrity sha1-wE3+i5JtbsrKGBPWn/F5t8ICXYY=
+
+camelcase@^5.0.0:
+ version "5.3.1"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
+ integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
+
+cliui@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
+ integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
+ dependencies:
+ string-width "^4.2.0"
+ strip-ansi "^6.0.0"
+ wrap-ansi "^6.2.0"
+
+color-convert@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+ integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+ dependencies:
+ color-name "~1.1.4"
+
+color-name@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+ integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+decamelize@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+ integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
+
+dts-bundle-generator@^5.6.0:
+ version "5.7.0"
+ resolved "https://registry.yarnpkg.com/dts-bundle-generator/-/dts-bundle-generator-5.7.0.tgz#914b90b96dfb19dd7b9696567c02b6fe71595b9a"
+ integrity sha512-sSFtdHL/G8y90wWRB8HCWPwdXXbToOuPLgON1q8f1+vXuiDdRez12M4RAf770dLWb05ekaFdYYGaT68jUU52zw==
+ dependencies:
+ typescript ">=3.0.1"
+ yargs "^15.3.1"
+
+emoji-regex@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
+ integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+
+find-up@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
+ integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
+ dependencies:
+ locate-path "^5.0.0"
+ path-exists "^4.0.0"
+
+fsevents@~2.3.1:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
+ integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
+
+get-caller-file@^2.0.1:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
+ integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+
+is-fullwidth-code-point@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
+ integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
+
+locate-path@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
+ integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
+ dependencies:
+ p-locate "^4.1.0"
+
+p-limit@^2.2.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
+ integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
+ dependencies:
+ p-try "^2.0.0"
+
+p-locate@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
+ integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
+ dependencies:
+ p-limit "^2.2.0"
+
+p-try@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
+ integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+
+path-exists@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
+ integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
+
+require-directory@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+ integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
+
+require-main-filename@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
+ integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
+
+rollup@^2.38.0:
+ version "2.41.0"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.41.0.tgz#b2a398bbabbf227738dedaef099e494aed468982"
+ integrity sha512-Gk76XHTggulWPH95q8V62bw6uqDH6UGvbD6LOa3QUyhuMF3eOuaeDHR7SLm1T9faitkpNrqzUAVYx47klcMnlA==
+ optionalDependencies:
+ fsevents "~2.3.1"
+
+set-blocking@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+ integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
+
+string-width@^4.1.0, string-width@^4.2.0:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
+ integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.0"
+
+strip-ansi@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
+ integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
+ dependencies:
+ ansi-regex "^5.0.0"
+
+typescript@>=3.0.1:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3"
+ integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==
+
+which-module@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
+ integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
+
+wrap-ansi@^6.2.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
+ integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
+y18n@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
+ integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==
+
+yargs-parser@^18.1.2:
+ version "18.1.3"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
+ integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
+ dependencies:
+ camelcase "^5.0.0"
+ decamelize "^1.2.0"
+
+yargs@^15.3.1:
+ version "15.4.1"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
+ integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
+ dependencies:
+ cliui "^6.0.0"
+ decamelize "^1.2.0"
+ find-up "^4.1.0"
+ get-caller-file "^2.0.1"
+ require-directory "^2.1.1"
+ require-main-filename "^2.0.0"
+ set-blocking "^2.0.0"
+ string-width "^4.2.0"
+ which-module "^2.0.0"
+ y18n "^4.0.0"
+ yargs-parser "^18.1.2"