From c084268f51b46bc5008a33010b6c7c58f5725f88 Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Tue, 2 Feb 2021 15:40:20 +0100 Subject: [PATCH] feat: display warning banner when using the app with no account --- app/assets/fonts/ionicons.svg | 38 -- app/assets/icons/ic_close.svg | 3 + app/assets/javascripts/@types/modules.ts | 3 + app/assets/javascripts/app.ts | 6 +- .../components/NoAccountWarning.tsx | 46 +++ .../SessionsModal.tsx} | 42 +-- app/assets/javascripts/components/utils.ts | 56 +++ .../javascripts/services/desktopManager.ts | 2 +- .../javascripts/services/localStorage.ts | 4 + app/assets/javascripts/tsconfig.json | 3 +- app/assets/javascripts/ui_models/app_state.ts | 99 +++-- app/assets/javascripts/utils.ts | 6 + .../views/application/application-view.pug | 1 + .../javascripts/views/footer/footer_view.ts | 17 +- .../javascripts/views/notes/notes-view.pug | 6 +- .../javascripts/views/tags/tags-view.pug | 12 +- app/assets/stylesheets/_ionicons.scss | 3 +- app/assets/stylesheets/_notes.scss | 10 +- app/assets/stylesheets/_sn.scss | 14 + app/assets/stylesheets/_ui.scss | 176 ++++++--- app/assets/stylesheets/index.css.scss | 1 + .../templates/directives/account-menu.pug | 2 +- .../directives/permissions-modal.pug | 8 +- package.json | 1 + webpack.config.js | 6 +- yarn.lock | 341 +++++++++++++++++- 26 files changed, 709 insertions(+), 197 deletions(-) delete mode 100644 app/assets/fonts/ionicons.svg create mode 100644 app/assets/icons/ic_close.svg create mode 100644 app/assets/javascripts/@types/modules.ts create mode 100644 app/assets/javascripts/components/NoAccountWarning.tsx rename app/assets/javascripts/{directives/views/sessionsModal.tsx => components/SessionsModal.tsx} (89%) create mode 100644 app/assets/javascripts/components/utils.ts create mode 100644 app/assets/stylesheets/_sn.scss diff --git a/app/assets/fonts/ionicons.svg b/app/assets/fonts/ionicons.svg deleted file mode 100644 index 67f37aadf..000000000 --- a/app/assets/fonts/ionicons.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - -Created by FontForge 20190318 at Thu Apr 11 10:47:26 2019 - By Mo Bitar -Copyright (c) 2019, Mo Bitar - - - - - - - - - - - diff --git a/app/assets/icons/ic_close.svg b/app/assets/icons/ic_close.svg new file mode 100644 index 000000000..0b2f305d8 --- /dev/null +++ b/app/assets/icons/ic_close.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/assets/javascripts/@types/modules.ts b/app/assets/javascripts/@types/modules.ts new file mode 100644 index 000000000..b5518926f --- /dev/null +++ b/app/assets/javascripts/@types/modules.ts @@ -0,0 +1,3 @@ +declare module '*.svg' { + export default function SvgComponent(props: React.SVGProps): JSX.Element; +} diff --git a/app/assets/javascripts/app.ts b/app/assets/javascripts/app.ts index 1d414d8df..8f1aab4d7 100644 --- a/app/assets/javascripts/app.ts +++ b/app/assets/javascripts/app.ts @@ -55,7 +55,8 @@ import { BrowserBridge } from './services/browserBridge'; import { startErrorReporting } from './services/errorReporting'; import { StartApplication } from './startApplication'; import { Bridge } from './services/bridge'; -import { SessionsModalDirective } from './directives/views/sessionsModal'; +import { SessionsModalDirective } from './components/SessionsModal'; +import { NoAccountWarningDirective } from './components/NoAccountWarning'; function reloadHiddenFirefoxTab(): boolean { @@ -141,7 +142,8 @@ const startApplication: StartApplication = async function startApplication( .directive('revisionPreviewModal', () => new RevisionPreviewModal()) .directive('historyMenu', () => new HistoryMenu()) .directive('syncResolutionMenu', () => new SyncResolutionMenu()) - .directive('sessionsModal', SessionsModalDirective); + .directive('sessionsModal', SessionsModalDirective) + .directive('noAccountWarning', NoAccountWarningDirective); // Filters angular.module('app').filter('trusted', ['$sce', trusted]); diff --git a/app/assets/javascripts/components/NoAccountWarning.tsx b/app/assets/javascripts/components/NoAccountWarning.tsx new file mode 100644 index 000000000..299de54b0 --- /dev/null +++ b/app/assets/javascripts/components/NoAccountWarning.tsx @@ -0,0 +1,46 @@ +import { WebApplication } from '@/ui_models/application'; +import { toDirective, useAutorunValue } from './utils'; +import Close from '../../icons/ic_close.svg'; +import { AppState } from '@/ui_models/app_state'; + +function NoAccountWarning({ + application, + appState, +}: { + application: WebApplication; + appState: AppState; +}) { + const canShow = useAutorunValue(() => appState.noAccountWarning.show); + if (!canShow || application.hasAccount()) { + return null; + } + return ( +
+

Data not backed up

+

+ Sign in or register to back up your notes +

+ + +
+ ); +} + +export const NoAccountWarningDirective = toDirective(NoAccountWarning); diff --git a/app/assets/javascripts/directives/views/sessionsModal.tsx b/app/assets/javascripts/components/SessionsModal.tsx similarity index 89% rename from app/assets/javascripts/directives/views/sessionsModal.tsx rename to app/assets/javascripts/components/SessionsModal.tsx index 89ad38eff..52cbf4533 100644 --- a/app/assets/javascripts/directives/views/sessionsModal.tsx +++ b/app/assets/javascripts/components/SessionsModal.tsx @@ -1,14 +1,12 @@ import { AppState } from '@/ui_models/app_state'; -import { PureViewCtrl } from '@/views'; import { SNApplication, - RemoteSession, SessionStrings, UuidString, isNullOrUndefined, + RemoteSession, } from '@standardnotes/snjs'; -import { autorun, IAutorunOptions, IReactionPublic } from 'mobx'; -import { render, FunctionComponent } from 'preact'; +import { FunctionComponent } from 'preact'; import { useState, useEffect, useRef, useMemo } from 'preact/hooks'; import { Dialog } from '@reach/dialog'; import { Alert } from '@reach/alert'; @@ -17,13 +15,8 @@ import { AlertDialogDescription, AlertDialogLabel, } from '@reach/alert-dialog'; - -function useAutorun( - view: (r: IReactionPublic) => unknown, - opts?: IAutorunOptions -) { - useEffect(() => autorun(view, opts), [view, opts]); -} +import { toDirective, useAutorun } from './utils'; +import { WebApplication } from '@/ui_models/application'; type Session = RemoteSession & { revoking?: true; @@ -250,7 +243,7 @@ const SessionsModal: FunctionComponent<{ const Sessions: FunctionComponent<{ appState: AppState; - application: SNApplication; + application: WebApplication; }> = ({ appState, application }) => { const [showModal, setShowModal] = useState(false); useAutorun(() => setShowModal(appState.isSessionsModalVisible)); @@ -262,27 +255,4 @@ const Sessions: FunctionComponent<{ } }; -class SessionsModalCtrl extends PureViewCtrl { - /* @ngInject */ - constructor(private $element: JQLite, $timeout: ng.ITimeoutService) { - super($timeout); - this.$element = $element; - } - $onChanges() { - render( - , - this.$element[0] - ); - } -} - -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function SessionsModalDirective() { - return { - controller: SessionsModalCtrl, - bindToController: true, - scope: { - application: '=', - }, - }; -} +export const SessionsModalDirective = toDirective(Sessions); diff --git a/app/assets/javascripts/components/utils.ts b/app/assets/javascripts/components/utils.ts new file mode 100644 index 000000000..96fa8a4f8 --- /dev/null +++ b/app/assets/javascripts/components/utils.ts @@ -0,0 +1,56 @@ +import { WebApplication } from '@/ui_models/application'; +import { AppState } from '@/ui_models/app_state'; +import { autorun, IAutorunOptions, IReactionPublic } from 'mobx'; +import { FunctionComponent, h, render } from 'preact'; +import { useEffect } from 'preact/hooks'; +import { useState } from 'react'; + +export function useAutorunValue(query: () => T): T { + const [value, setValue] = useState(query); + useAutorun(() => { + setValue(query()); + }); + return value; +} + +export function useAutorun( + view: (r: IReactionPublic) => unknown, + opts?: IAutorunOptions +): void { + useEffect(() => autorun(view, opts), [view, opts]); +} + +export function toDirective( + component: FunctionComponent<{ + application: WebApplication; + appState: AppState; + }> +) { + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + return function () { + return { + controller: [ + '$element', + '$scope', + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ($element: JQLite, $scope: any) => { + return { + $onChanges() { + render( + h(component, { + application: $scope.application, + appState: $scope.appState, + }), + $element[0] + ); + }, + }; + }, + ], + scope: { + application: '=', + appState: '=', + }, + }; + }; +} diff --git a/app/assets/javascripts/services/desktopManager.ts b/app/assets/javascripts/services/desktopManager.ts index 9da6afcf3..3587b174c 100644 --- a/app/assets/javascripts/services/desktopManager.ts +++ b/app/assets/javascripts/services/desktopManager.ts @@ -75,7 +75,7 @@ export class DesktopManager extends ApplicationService { getExtServerHost() { console.assert( - this.bridge.extensionsServerHost, + !!this.bridge.extensionsServerHost, 'extServerHost is null' ); return this.bridge.extensionsServerHost; diff --git a/app/assets/javascripts/services/localStorage.ts b/app/assets/javascripts/services/localStorage.ts index 07e11fe5a..fa03d7c9b 100644 --- a/app/assets/javascripts/services/localStorage.ts +++ b/app/assets/javascripts/services/localStorage.ts @@ -1,11 +1,15 @@ export enum StorageKey { DisableErrorReporting = 'DisableErrorReporting', AnonymousUserId = 'AnonymousUserId', + ShowBetaWarning = 'ShowBetaWarning', + ShowNoAccountWarning = 'ShowNoAccountWarning', } export type StorageValue = { [StorageKey.DisableErrorReporting]: boolean; [StorageKey.AnonymousUserId]: string; + [StorageKey.ShowBetaWarning]: boolean; + [StorageKey.ShowNoAccountWarning]: boolean; } export const storage = { diff --git a/app/assets/javascripts/tsconfig.json b/app/assets/javascripts/tsconfig.json index 1381b681e..afff29158 100644 --- a/app/assets/javascripts/tsconfig.json +++ b/app/assets/javascripts/tsconfig.json @@ -6,7 +6,7 @@ "allowJs": true, "noEmit": true, "strict": true, - "isolatedModules": true, + "isolatedModules": false, "esModuleInterop": true, "declaration": true, "newLine": "lf", @@ -14,6 +14,7 @@ "baseUrl": ".", "jsx": "react-jsx", "jsxImportSource": "preact", + "typeRoots": ["./@types"], "paths": { "%/*": ["../templates/*"], "@/*": ["./*"], diff --git a/app/assets/javascripts/ui_models/app_state.ts b/app/assets/javascripts/ui_models/app_state.ts index dca220cc9..8ab3b443b 100644 --- a/app/assets/javascripts/ui_models/app_state.ts +++ b/app/assets/javascripts/ui_models/app_state.ts @@ -15,6 +15,7 @@ import { WebApplication } from '@/ui_models/application'; import { Editor } from '@/ui_models/editor'; import { action, makeObservable, observable } from 'mobx'; import { Bridge } from '@/services/bridge'; +import { storage, StorageKey } from '@/services/localStorage'; export enum AppStateEvent { TagChanged, @@ -30,7 +31,7 @@ export enum AppStateEvent { export type PanelResizedData = { panel: string; collapsed: boolean; -} +}; export enum EventSource { UserInteraction, @@ -39,8 +40,6 @@ export enum EventSource { type ObserverCallback = (event: AppStateEvent, data?: any) => Promise; -const SHOW_BETA_WARNING_KEY = 'show_beta_warning'; - class ActionsMenuState { hiddenExtensions: Record = {}; @@ -75,7 +74,7 @@ export class SyncState { }); } - update(status: SyncOpStatus) { + update(status: SyncOpStatus): void { this.errorMessage = status.error?.message; this.inProgress = status.syncInProgress; const stats = status.getStats(); @@ -95,6 +94,41 @@ export class SyncState { } } +class AccountMenuState { + show = false; + constructor() { + makeObservable(this, { + show: observable, + setShow: action, + toggleShow: action, + }); + } + setShow(show: boolean) { + this.show = show; + } + toggleShow() { + this.show = !this.show; + } +} + +class NoAccountWarningState { + show: boolean; + constructor() { + this.show = storage.get(StorageKey.ShowNoAccountWarning) ?? true; + makeObservable(this, { + show: observable, + hide: action, + }); + } + hide() { + this.show = false; + storage.set(StorageKey.ShowNoAccountWarning, false); + } + reset() { + storage.remove(StorageKey.ShowNoAccountWarning); + } +} + export class AppState { readonly enableUnfinishedFeatures = isDev || location.host.includes('app-dev.standardnotes.org'); @@ -109,8 +143,10 @@ export class AppState { rootScopeCleanup2: any; onVisibilityChange: any; selectedTag?: SNTag; - showBetaWarning = false; + showBetaWarning: boolean; + readonly accountMenu = new AccountMenuState(); readonly actionsMenu = new ActionsMenuState(); + readonly noAccountWarning = new NoAccountWarningState(); readonly sync = new SyncState(); isSessionsModalVisible = false; @@ -124,15 +160,6 @@ export class AppState { this.$timeout = $timeout; this.$rootScope = $rootScope; this.application = application; - makeObservable(this, { - showBetaWarning: observable, - isSessionsModalVisible: observable, - - enableBetaWarning: action, - disableBetaWarning: action, - openSessionsModal: action, - closeSessionsModal: action, - }); this.addAppEventObserver(); this.streamNotesAndTags(); this.onVisibilityChange = () => { @@ -143,12 +170,28 @@ export class AppState { this.notifyEvent(event); }; this.registerVisibilityObservers(); - this.determineBetaWarningValue(); + + if (this.bridge.appVersion.includes('-beta')) { + this.showBetaWarning = storage.get(StorageKey.ShowBetaWarning) ?? true; + } else { + this.showBetaWarning = false; + } + + makeObservable(this, { + showBetaWarning: observable, + isSessionsModalVisible: observable, + + enableBetaWarning: action, + disableBetaWarning: action, + openSessionsModal: action, + closeSessionsModal: action, + }); } - deinit(source: DeinitSource) { + deinit(source: DeinitSource): void { if (source === DeinitSource.SignOut) { - localStorage.removeItem(SHOW_BETA_WARNING_KEY); + storage.remove(StorageKey.ShowBetaWarning); + this.noAccountWarning.reset(); } this.actionsMenu.deinit(); this.unsubApp(); @@ -174,30 +217,12 @@ export class AppState { disableBetaWarning() { this.showBetaWarning = false; - localStorage.setItem(SHOW_BETA_WARNING_KEY, 'false'); + storage.set(StorageKey.ShowBetaWarning, false); } enableBetaWarning() { this.showBetaWarning = true; - localStorage.setItem(SHOW_BETA_WARNING_KEY, 'true'); - } - - clearBetaWarning() { - localStorage.setItem(SHOW_BETA_WARNING_KEY, 'true'); - } - - private determineBetaWarningValue() { - if (this.bridge.appVersion.includes('-beta')) { - switch (localStorage.getItem(SHOW_BETA_WARNING_KEY)) { - case 'true': - default: - this.enableBetaWarning(); - break; - case 'false': - this.disableBetaWarning(); - break; - } - } + storage.set(StorageKey.ShowBetaWarning, true); } /** diff --git a/app/assets/javascripts/utils.ts b/app/assets/javascripts/utils.ts index 54e51b6bc..8c94fe42e 100644 --- a/app/assets/javascripts/utils.ts +++ b/app/assets/javascripts/utils.ts @@ -1,3 +1,9 @@ +declare const process : { + env: { + NODE_ENV: string | null | undefined + } +}; + export const isDev = process.env.NODE_ENV === 'development'; export function getPlatformString() { diff --git a/app/assets/javascripts/views/application/application-view.pug b/app/assets/javascripts/views/application/application-view.pug index 91f15b7fd..b428a9fab 100644 --- a/app/assets/javascripts/views/application/application-view.pug +++ b/app/assets/javascripts/views/application/application-view.pug @@ -26,6 +26,7 @@ path(d="M480 256l-75.53-33.53L256.1 290.6l-148.77-68.17L32 256l224 102 224-102z") sessions-modal( application='self.application' + app-state='self.appState' ) challenge-modal( ng-repeat="challenge in self.challenges track by challenge.id" diff --git a/app/assets/javascripts/views/footer/footer_view.ts b/app/assets/javascripts/views/footer/footer_view.ts index 4012a2176..5b36ebef0 100644 --- a/app/assets/javascripts/views/footer/footer_view.ts +++ b/app/assets/javascripts/views/footer/footer_view.ts @@ -62,7 +62,7 @@ class FooterViewCtrl extends PureViewCtrl void> = []; private completedInitialSync = false; private showingDownloadStatus = false; - private removeBetaWarningListener?: IReactionDisposer; + private autorunDisposer?: IReactionDisposer; /* @ngInject */ constructor( @@ -103,7 +103,7 @@ class FooterViewCtrl extends PureViewCtrl { + this.autorunDisposer = autorun(() => { const showBetaWarning = this.appState.showBetaWarning; + this.showAccountMenu = this.appState.accountMenu.show; this.setState({ showBetaWarning: showBetaWarning, showDataUpgrade: !showBetaWarning @@ -255,7 +256,7 @@ class FooterViewCtrl extends PureViewCtrl=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5: +mkdirp@0.5.5, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -5525,7 +5771,7 @@ npm-run-path@^2.0.0: gauge "~2.7.3" set-blocking "~2.0.0" -nth-check@~1.0.1: +nth-check@^1.0.2, nth-check@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== @@ -5621,7 +5867,7 @@ object.fromentries@^2.0.2: es-abstract "^1.18.0-next.1" has "^1.0.3" -object.getownpropertydescriptors@^2.0.3: +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz#0dfda8d108074d9c563e80490c883b6661091544" integrity sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng== @@ -5637,7 +5883,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.1: +object.values@^1.1.0, object.values@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.2.tgz#7a2015e06fcb0f546bd652486ce8583a4731c731" integrity sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag== @@ -5817,6 +6063,16 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -6292,6 +6548,11 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" @@ -6780,6 +7041,11 @@ sass-loader@^8.0.2: schema-utils "^2.6.1" semver "^6.3.0" +sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + schema-utils@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" @@ -7193,6 +7459,11 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + stack-generator@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" @@ -7430,6 +7701,30 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +svg-parser@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + +svgo@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + 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.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + table@^6.0.4: version "6.0.7" resolved "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34" @@ -7745,6 +8040,11 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -7822,6 +8122,16 @@ util.promisify@1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" +util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -8155,6 +8465,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" + integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== + yargs-parser@13.1.2, yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"