diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index e5f7cac433e..2b1e95dbb8c 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -3,6 +3,7 @@ name: Dev on: push: branches: [ develop ] + workflow_dispatch: jobs: diff --git a/app/assets/icons/ic_tune.svg b/app/assets/icons/ic_tune.svg new file mode 100644 index 00000000000..fbf26572ac9 --- /dev/null +++ b/app/assets/icons/ic_tune.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/assets/javascripts/app.ts b/app/assets/javascripts/app.ts index 7b7273056e1..a2bcbd446d3 100644 --- a/app/assets/javascripts/app.ts +++ b/app/assets/javascripts/app.ts @@ -58,6 +58,7 @@ import { Bridge } from './services/bridge'; import { SessionsModalDirective } from './components/SessionsModal'; import { NoAccountWarningDirective } from './components/NoAccountWarning'; import { NoProtectionsdNoteWarningDirective } from './components/NoProtectionsNoteWarning'; +import { SearchOptionsDirective } from './components/SearchOptions'; function reloadHiddenFirefoxTab(): boolean { /** @@ -145,7 +146,8 @@ const startApplication: StartApplication = async function startApplication( .directive('syncResolutionMenu', () => new SyncResolutionMenu()) .directive('sessionsModal', SessionsModalDirective) .directive('noAccountWarning', NoAccountWarningDirective) - .directive('protectedNotePanel', NoProtectionsdNoteWarningDirective); + .directive('protectedNotePanel', NoProtectionsdNoteWarningDirective) + .directive('searchOptions', SearchOptionsDirective); // Filters angular.module('app').filter('trusted', ['$sce', trusted]); diff --git a/app/assets/javascripts/components/NoAccountWarning.tsx b/app/assets/javascripts/components/NoAccountWarning.tsx index f9f8ea71917..6803936042a 100644 --- a/app/assets/javascripts/components/NoAccountWarning.tsx +++ b/app/assets/javascripts/components/NoAccountWarning.tsx @@ -5,7 +5,9 @@ import { AppState } from '@/ui_models/app_state'; type Props = { appState: AppState }; function NoAccountWarning({ appState }: Props) { - const canShow = useAutorunValue(() => appState.noAccountWarning.show); + const canShow = useAutorunValue(() => appState.noAccountWarning.show, [ + appState, + ]); if (!canShow) { return null; } diff --git a/app/assets/javascripts/components/SearchOptions.tsx b/app/assets/javascripts/components/SearchOptions.tsx new file mode 100644 index 00000000000..2c24e6c44c8 --- /dev/null +++ b/app/assets/javascripts/components/SearchOptions.tsx @@ -0,0 +1,114 @@ +import { AppState } from '@/ui_models/app_state'; +import { toDirective, useAutorunValue } from './utils'; +import { useRef, useState } from 'preact/hooks'; +import { WebApplication } from '@/ui_models/application'; +import VisuallyHidden from '@reach/visually-hidden'; +import { + Disclosure, + DisclosureButton, + DisclosurePanel, +} from '@reach/disclosure'; +import { FocusEvent } from 'react'; +import { Switch } from './Switch'; +import TuneIcon from '../../icons/ic_tune.svg'; + +type Props = { + appState: AppState; + application: WebApplication; +}; + +function SearchOptions({ appState }: Props) { + const { searchOptions } = appState; + + const { + includeProtectedContents, + includeArchived, + includeTrashed, + } = useAutorunValue( + () => ({ + includeProtectedContents: searchOptions.includeProtectedContents, + includeArchived: searchOptions.includeArchived, + includeTrashed: searchOptions.includeTrashed, + }), + [searchOptions] + ); + + const [ + togglingIncludeProtectedContents, + setTogglingIncludeProtectedContents, + ] = useState(false); + + async function toggleIncludeProtectedContents() { + setTogglingIncludeProtectedContents(true); + try { + await searchOptions.toggleIncludeProtectedContents(); + } finally { + setTogglingIncludeProtectedContents(false); + } + } + + const [open, setOpen] = useState(false); + const [optionsPanelTop, setOptionsPanelTop] = useState(0); + const buttonRef = useRef(); + const panelRef = useRef(); + + function closeOnBlur(event: FocusEvent) { + if ( + !togglingIncludeProtectedContents && + !panelRef.current.contains(event.relatedTarget as Node) + ) { + setOpen(false); + } + } + + return ( + { + const { height } = buttonRef.current.getBoundingClientRect(); + setOptionsPanelTop(height); + setOpen((prevOpen) => !prevOpen); + }} + > + + Search options + + + + +

Include protected contents

+
+ +

Include archived notes

+
+ +

Include trashed notes

+
+
+
+ ); +} + +export const SearchOptionsDirective = toDirective(SearchOptions); diff --git a/app/assets/javascripts/components/SessionsModal.tsx b/app/assets/javascripts/components/SessionsModal.tsx index e00b07a2679..b8c82daf4fe 100644 --- a/app/assets/javascripts/components/SessionsModal.tsx +++ b/app/assets/javascripts/components/SessionsModal.tsx @@ -15,7 +15,7 @@ import { AlertDialogDescription, AlertDialogLabel, } from '@reach/alert-dialog'; -import { toDirective, useAutorun } from './utils'; +import { toDirective, useAutorunValue } from './utils'; import { WebApplication } from '@/ui_models/application'; type Session = RemoteSession & { @@ -211,22 +211,22 @@ const SessionsModal: FunctionComponent<{

{SessionStrings.RevokeText}

- - + +
@@ -243,8 +243,9 @@ const Sessions: FunctionComponent<{ appState: AppState; application: WebApplication; }> = ({ appState, application }) => { - const [showModal, setShowModal] = useState(false); - useAutorun(() => setShowModal(appState.isSessionsModalVisible)); + const showModal = useAutorunValue(() => appState.isSessionsModalVisible, [ + appState, + ]); if (showModal) { return ; diff --git a/app/assets/javascripts/components/Switch.tsx b/app/assets/javascripts/components/Switch.tsx new file mode 100644 index 00000000000..44dbf7dc5d9 --- /dev/null +++ b/app/assets/javascripts/components/Switch.tsx @@ -0,0 +1,48 @@ +import { ComponentChildren, FunctionalComponent } from 'preact'; +import { useState } from 'preact/hooks'; +import { HTMLProps } from 'react'; +import { + CustomCheckboxContainer, + CustomCheckboxInput, + CustomCheckboxInputProps, +} from '@reach/checkbox'; +import '@reach/checkbox/styles.css'; + +export type SwitchProps = HTMLProps & { + checked?: boolean; + onChange: (checked: boolean) => void; + children: ComponentChildren; +}; + +export const Switch: FunctionalComponent = ( + props: SwitchProps +) => { + const [checkedState, setChecked] = useState(props.checked || false); + const checked = props.checked ?? checkedState; + return ( + + ); +}; diff --git a/app/assets/javascripts/components/utils.ts b/app/assets/javascripts/components/utils.ts index f1918328f55..33e437c46ab 100644 --- a/app/assets/javascripts/components/utils.ts +++ b/app/assets/javascripts/components/utils.ts @@ -1,25 +1,18 @@ -import { WebApplication } from '@/ui_models/application'; -import { AppState } from '@/ui_models/app_state'; -import { autorun, IAutorunOptions, IReactionPublic } from 'mobx'; +import { autorun } from 'mobx'; import { FunctionComponent, h, render } from 'preact'; -import { useEffect } from 'preact/hooks'; -import { useState } from 'react'; +import { Inputs, useEffect, useState } from 'preact/hooks'; -export function useAutorunValue(query: () => T): T { +export function useAutorunValue(query: () => T, inputs: Inputs): T { const [value, setValue] = useState(query); - useAutorun(() => { - setValue(query()); - }); + useEffect(() => { + return autorun(() => { + setValue(query()); + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, inputs); return value; } -export function useAutorun( - view: (r: IReactionPublic) => unknown, - opts?: IAutorunOptions -): void { - useEffect(() => autorun(view, opts), [view, opts]); -} - export function toDirective( component: FunctionComponent, scope: Record = {} @@ -32,12 +25,12 @@ export function toDirective( '$scope', // eslint-disable-next-line @typescript-eslint/no-explicit-any ($element: JQLite, $scope: any) => { + if ($scope.class) { + $element.addClass($scope.class); + } return { $onChanges() { - render( - h(component, $scope), - $element[0] - ); + render(h(component, $scope), $element[0]); }, }; }, diff --git a/app/assets/javascripts/directives/views/historyMenu.ts b/app/assets/javascripts/directives/views/historyMenu.ts index 76279107027..2fcfad95fd6 100644 --- a/app/assets/javascripts/directives/views/historyMenu.ts +++ b/app/assets/javascripts/directives/views/historyMenu.ts @@ -1,71 +1,67 @@ import { WebDirective } from '../../types'; import { WebApplication } from '@/ui_models/application'; import template from '%/directives/history-menu.pug'; -import { SNItem, ItemHistoryEntry } from '@standardnotes/snjs'; +import { HistoryEntry, SNItem } from '@standardnotes/snjs'; import { PureViewCtrl } from '@/views'; -import { ItemSessionHistory } from '@standardnotes/snjs'; import { RevisionListEntry, SingleRevision } from '@standardnotes/snjs'; -import { confirmDialog } from '@/services/alertService'; +import { alertDialog, confirmDialog } from '@/services/alertService'; type HistoryState = { - fetchingRemoteHistory: boolean -} - -interface HistoryScope { - application: WebApplication - item: SNItem -} + sessionHistory?: HistoryEntry[]; + remoteHistory?: RevisionListEntry[]; + fetchingRemoteHistory: boolean; + autoOptimize: boolean; + diskEnabled: boolean; +}; -class HistoryMenuCtrl extends PureViewCtrl implements HistoryScope { +class HistoryMenuCtrl extends PureViewCtrl { + application!: WebApplication; + item!: SNItem; - diskEnabled = false - autoOptimize = false - application!: WebApplication - item!: SNItem - sessionHistory?: ItemSessionHistory - remoteHistory?: RevisionListEntry[] + /** @template */ + showSessionOptions = false; /* @ngInject */ - constructor( - $timeout: ng.ITimeoutService - ) { + constructor($timeout: ng.ITimeoutService) { super($timeout); - this.state = { - fetchingRemoteHistory: false - }; - } - - $onInit() { - super.$onInit(); - this.reloadSessionHistory(); - this.fetchRemoteHistory(); - this.diskEnabled = this.application.historyManager!.isDiskEnabled(); - this.autoOptimize = this.application.historyManager!.isAutoOptimizeEnabled(); - } - - reloadSessionHistory() { - this.sessionHistory = this.application.historyManager!.sessionHistoryForItem(this.item); } - get isfetchingRemoteHistory() { - return this.state.fetchingRemoteHistory; + getInitialState() { + return { + fetchingRemoteHistory: false, + autoOptimize: this.application.historyManager.autoOptimize, + diskEnabled: this.application.historyManager.isDiskEnabled(), + sessionHistory: this.application.historyManager.sessionHistoryForItem( + this.item + ), + }; } - set fetchingRemoteHistory(value: boolean) { + reloadState() { this.setState({ - fetchingRemoteHistory: value + ...this.getInitialState(), + fetchingRemoteHistory: this.state.fetchingRemoteHistory, }); } + $onInit() { + super.$onInit(); + this.fetchRemoteHistory(); + } + async fetchRemoteHistory() { - this.fetchingRemoteHistory = true; - this.remoteHistory = await this.application.historyManager!.remoteHistoryForItem(this.item) - .finally(() => { - this.fetchingRemoteHistory = false; - }); + this.setState({ fetchingRemoteHistory: true }); + try { + const remoteHistory = await this.application.historyManager.remoteHistoryForItem( + this.item + ); + this.setState({ remoteHistory }); + } finally { + this.setState({ fetchingRemoteHistory: false }); + } } - async openSessionRevision(revision: ItemHistoryEntry) { + async openSessionRevision(revision: HistoryEntry) { this.application.presentRevisionPreviewModal( revision.payload.uuid, revision.payload.content @@ -73,11 +69,17 @@ class HistoryMenuCtrl extends PureViewCtrl implements His } async openRemoteRevision(revision: RevisionListEntry) { - this.fetchingRemoteHistory = true; - const remoteRevision = await this.application.historyManager!.fetchRemoteRevision(this.item.uuid, revision); - this.fetchingRemoteHistory = false; + this.setState({ fetchingRemoteHistory: true }); + const remoteRevision = await this.application.historyManager.fetchRemoteRevision( + this.item.uuid, + revision + ); + this.setState({ fetchingRemoteHistory: false }); if (!remoteRevision) { - this.application.alertService!.alert("The remote revision could not be loaded. Please try again later."); + alertDialog({ + text: + 'The remote revision could not be loaded. Please try again later.', + }); return; } this.application.presentRevisionPreviewModal( @@ -86,7 +88,7 @@ class HistoryMenuCtrl extends PureViewCtrl implements His ); } - classForSessionRevision(revision: ItemHistoryEntry) { + classForSessionRevision(revision: HistoryEntry) { const vector = revision.operationVector(); if (vector === 0) { return 'default'; @@ -97,81 +99,63 @@ class HistoryMenuCtrl extends PureViewCtrl implements His } } - clearItemSessionHistory() { - confirmDialog({ - text: "Are you sure you want to delete the local session history for this note?", - confirmButtonStyle: "danger" - }).then((confirmed) => { - if (!confirmed) { - return; - } - this.application.historyManager!.clearHistoryForItem(this.item).then(() => { - this.$timeout(() => { - this.reloadSessionHistory(); - }); - }); - }); + async clearItemSessionHistory() { + if ( + await confirmDialog({ + text: + 'Are you sure you want to delete the local session history for this note?', + confirmButtonStyle: 'danger', + }) + ) { + this.application.historyManager.clearHistoryForItem(this.item); + this.reloadState(); + } } - clearAllSessionHistory() { - confirmDialog({ - text: "Are you sure you want to delete the local session history for all notes?", - confirmButtonStyle: "danger" - }).then((confirmed) => { - if (!confirmed) { - return; - } - this.application.historyManager!.clearAllHistory().then(() => { - this.$timeout(() => { - this.reloadSessionHistory(); - }); - }); - }); + async clearAllSessionHistory() { + if ( + await confirmDialog({ + text: + 'Are you sure you want to delete the local session history for all notes?', + confirmButtonStyle: 'danger', + }) + ) { + await this.application.historyManager.clearAllHistory(); + this.reloadState(); + } } + /** @entries */ get sessionHistoryEntries() { - return this.sessionHistory?.entries; - } - - get remoteHistoryEntries() { - return this.remoteHistory; - } - - toggleSessionHistoryDiskSaving() { - const run = () => { - this.application.historyManager!.toggleDiskSaving().then(() => { - this.$timeout(() => { - this.diskEnabled = this.application.historyManager!.isDiskEnabled(); - }); - }); - }; - if (!this.application.historyManager!.isDiskEnabled()) { - confirmDialog({ - text: "Are you sure you want to save history to disk? This will decrease general " + - "performance, especially as you type. You are advised to disable this feature " + - "if you experience any lagging.", - confirmButtonStyle: "danger" - }).then((confirmed) => { - if (confirmed) { - run(); - } - }); + return this.state.sessionHistory; + } + + async toggleSessionHistoryDiskSaving() { + if (!this.state.diskEnabled) { + if ( + await confirmDialog({ + text: + 'Are you sure you want to save history to disk? This will decrease general ' + + 'performance, especially as you type. You are advised to disable this feature ' + + 'if you experience any lagging.', + confirmButtonStyle: 'danger', + }) + ) { + this.application.historyManager.toggleDiskSaving(); + } } else { - run(); + this.application.historyManager.toggleDiskSaving(); } + this.reloadState(); } toggleSessionHistoryAutoOptimize() { - this.application.historyManager!.toggleAutoOptimize().then(() => { - this.$timeout(() => { - this.autoOptimize = this.application.historyManager!.autoOptimize; - }); - }); + this.application.historyManager.toggleAutoOptimize(); + this.reloadState(); } previewRemoteHistoryTitle(revision: SingleRevision) { - const createdAt = revision.created_at!; - return new Date(createdAt).toLocaleString(); + return new Date(revision.created_at).toLocaleString(); } } @@ -185,7 +169,7 @@ export class HistoryMenu extends WebDirective { this.bindToController = true; this.scope = { item: '=', - application: '=' + application: '=', }; } } diff --git a/app/assets/javascripts/index.ts b/app/assets/javascripts/index.ts index 592300a31a5..78abf2bf4d9 100644 --- a/app/assets/javascripts/index.ts +++ b/app/assets/javascripts/index.ts @@ -2,7 +2,6 @@ // css import '@reach/dialog/styles.css'; -import 'sn-stylekit/dist/stylekit.css'; import '../stylesheets/index.css.scss'; // Vendor diff --git a/app/assets/javascripts/routes.ts b/app/assets/javascripts/routes.ts index 42d646e3757..66880fab8fb 100644 --- a/app/assets/javascripts/routes.ts +++ b/app/assets/javascripts/routes.ts @@ -3,7 +3,7 @@ import { isDesktopApplication } from './utils'; /* @ngInject */ export function configRoutes($locationProvider: ng.ILocationProvider) { if (!isDesktopApplication()) { - if (window.history && window.history.pushState) { + if (typeof window?.history?.pushState === 'function') { $locationProvider.html5Mode({ enabled: true, requireBase: false diff --git a/app/assets/javascripts/services/archiveManager.ts b/app/assets/javascripts/services/archiveManager.ts index d80635a1ddd..c73e4b046b3 100644 --- a/app/assets/javascripts/services/archiveManager.ts +++ b/app/assets/javascripts/services/archiveManager.ts @@ -7,21 +7,20 @@ import { PayloadContent, } from '@standardnotes/snjs'; -function zippableTxtName(name: string, suffix = ""): string { - const sanitizedName = name - .replace(/\//g, '') - .replace(/\\+/g, '') - .replace(/:/g, ' ') - .replace(/\./g, ' '); - const nameEnd = suffix + ".txt"; - const maxFileNameLength = 255; +function sanitizeFileName(name: string): string { + return name.trim().replace(/[.\\/:"?*|<>]/g, '_'); +} + +function zippableTxtName(name: string, suffix = ''): string { + const sanitizedName = sanitizeFileName(name); + const nameEnd = suffix + '.txt'; + const maxFileNameLength = 100; return sanitizedName.slice(0, maxFileNameLength - nameEnd.length) + nameEnd; } export class ArchiveManager { - - private readonly application: WebApplication - private textFile?: string + private readonly application: WebApplication; + private textFile?: string; constructor(application: WebApplication) { this.application = application; @@ -36,10 +35,9 @@ export class ArchiveManager { if (!data) { return; } - const blobData = new Blob( - [JSON.stringify(data, null, 2)], - { type: 'text/json' } - ); + const blobData = new Blob([JSON.stringify(data, null, 2)], { + type: 'text/json', + }); if (encrypted) { this.downloadData( blobData, @@ -85,21 +83,18 @@ export class ArchiveManager { }); } - private async downloadZippedDecryptedItems( - data: BackupFile - ) { + private async downloadZippedDecryptedItems(data: BackupFile) { await this.loadZip(); const items = data.items; this.zip.createWriter( new this.zip.BlobWriter('application/zip'), async (zipWriter: any) => { await new Promise((resolve) => { - const blob = new Blob( - [JSON.stringify(data, null, 2)], - { type: 'text/plain' } - ); + const blob = new Blob([JSON.stringify(data, null, 2)], { + type: 'text/plain', + }); const fileName = zippableTxtName( - 'Standard Notes Backup and Import File.txt' + 'Standard Notes Backup and Import File' ); zipWriter.add(fileName, new this.zip.BlobReader(blob), resolve); }); @@ -120,7 +115,8 @@ export class ArchiveManager { name = ''; } const blob = new Blob([contents], { type: 'text/plain' }); - const fileName = `Items/${item.content_type}/` + + const fileName = + `Items/${sanitizeFileName(item.content_type)}/` + zippableTxtName(name, `-${item.uuid.split('-')[0]}`); zipWriter.add(fileName, new this.zip.BlobReader(blob), () => { index++; @@ -138,7 +134,9 @@ export class ArchiveManager { }); }; nextFile(); - }, onerror); + }, + onerror + ); } private hrefForData(data: Blob) { diff --git a/app/assets/javascripts/ui_models/app_state/account_menu_state.ts b/app/assets/javascripts/ui_models/app_state/account_menu_state.ts new file mode 100644 index 00000000000..bf7489495ea --- /dev/null +++ b/app/assets/javascripts/ui_models/app_state/account_menu_state.ts @@ -0,0 +1,21 @@ +import { action, makeObservable, observable } from "mobx"; + +export class AccountMenuState { + show = false; + + constructor() { + makeObservable(this, { + show: observable, + setShow: action, + toggleShow: action, + }); + } + + setShow = (show: boolean): void => { + this.show = show; + } + + toggleShow = (): void => { + this.show = !this.show; + } +} diff --git a/app/assets/javascripts/ui_models/app_state/actions_menu_state.ts b/app/assets/javascripts/ui_models/app_state/actions_menu_state.ts new file mode 100644 index 00000000000..8ba5dd61ef0 --- /dev/null +++ b/app/assets/javascripts/ui_models/app_state/actions_menu_state.ts @@ -0,0 +1,22 @@ +import { UuidString } from "@standardnotes/snjs"; +import { action, makeObservable, observable } from "mobx"; + +export class ActionsMenuState { + hiddenExtensions: Record = {}; + + constructor() { + makeObservable(this, { + hiddenExtensions: observable, + toggleExtensionVisibility: action, + reset: action, + }); + } + + toggleExtensionVisibility = (uuid: UuidString): void => { + this.hiddenExtensions[uuid] = !this.hiddenExtensions[uuid]; + } + + reset = (): void => { + this.hiddenExtensions = {}; + } +} diff --git a/app/assets/javascripts/ui_models/app_state.ts b/app/assets/javascripts/ui_models/app_state/app_state.ts similarity index 77% rename from app/assets/javascripts/ui_models/app_state.ts rename to app/assets/javascripts/ui_models/app_state/app_state.ts index 7b48a0ffbf5..55024497f73 100644 --- a/app/assets/javascripts/ui_models/app_state.ts +++ b/app/assets/javascripts/ui_models/app_state/app_state.ts @@ -7,16 +7,18 @@ import { ContentType, PayloadSource, DeinitSource, - UuidString, - SyncOpStatus, PrefKey, - SNApplication, } from '@standardnotes/snjs'; import { WebApplication } from '@/ui_models/application'; import { Editor } from '@/ui_models/editor'; -import { action, makeObservable, observable, runInAction } from 'mobx'; +import { action, makeObservable, observable } from 'mobx'; import { Bridge } from '@/services/bridge'; import { storage, StorageKey } from '@/services/localStorage'; +import { AccountMenuState } from './account_menu_state'; +import { ActionsMenuState } from './actions_menu_state'; +import { NoAccountWarningState } from './no_account_warning_state'; +import { SyncState } from './sync_state'; +import { SearchOptionsState } from './search_options_state'; export enum AppStateEvent { TagChanged, @@ -41,113 +43,6 @@ export enum EventSource { type ObserverCallback = (event: AppStateEvent, data?: any) => Promise; -class ActionsMenuState { - hiddenExtensions: Record = {}; - - constructor() { - makeObservable(this, { - hiddenExtensions: observable, - toggleExtensionVisibility: action, - reset: action, - }); - } - - toggleExtensionVisibility(uuid: UuidString) { - this.hiddenExtensions[uuid] = !this.hiddenExtensions[uuid]; - } - - reset() { - this.hiddenExtensions = {}; - } -} - -export class SyncState { - inProgress = false; - errorMessage?: string = undefined; - humanReadablePercentage?: string = undefined; - - constructor() { - makeObservable(this, { - inProgress: observable, - errorMessage: observable, - humanReadablePercentage: observable, - update: action, - }); - } - - update(status: SyncOpStatus): void { - this.errorMessage = status.error?.message; - this.inProgress = status.syncInProgress; - const stats = status.getStats(); - const completionPercentage = - stats.uploadCompletionCount === 0 - ? 0 - : stats.uploadCompletionCount / stats.uploadTotalCount; - - if (completionPercentage === 0) { - this.humanReadablePercentage = undefined; - } else { - this.humanReadablePercentage = completionPercentage.toLocaleString( - undefined, - { style: 'percent' } - ); - } - } -} - -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(application: SNApplication, appObservers: (() => void)[]) { - this.show = application.hasAccount() - ? false - : storage.get(StorageKey.ShowNoAccountWarning) ?? true; - - appObservers.push( - application.addEventObserver(async () => { - runInAction(() => { - this.show = false; - }); - }, ApplicationEvent.SignedIn), - application.addEventObserver(async () => { - if (application.hasAccount()) { - runInAction(() => { - this.show = false; - }); - } - }, ApplicationEvent.Started) - ); - - 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'); @@ -167,8 +62,8 @@ export class AppState { readonly actionsMenu = new ActionsMenuState(); readonly noAccountWarning: NoAccountWarningState; readonly sync = new SyncState(); + readonly searchOptions; isSessionsModalVisible = false; - mouseUp = Promise.resolve(); private appEventObserverRemovers: (() => void)[] = []; @@ -186,6 +81,10 @@ export class AppState { application, this.appEventObserverRemovers ); + this.searchOptions = new SearchOptionsState( + application, + this.appEventObserverRemovers + ); this.addAppEventObserver(); this.streamNotesAndTags(); this.onVisibilityChange = () => { @@ -196,7 +95,6 @@ export class AppState { this.notifyEvent(event); }; this.registerVisibilityObservers(); - document.addEventListener('mousedown', this.onMouseDown); if (this.bridge.appVersion.includes('-beta')) { this.showBetaWarning = storage.get(StorageKey.ShowBetaWarning) ?? true; @@ -233,16 +131,9 @@ export class AppState { this.rootScopeCleanup2 = undefined; } document.removeEventListener('visibilitychange', this.onVisibilityChange); - document.removeEventListener('mousedown', this.onMouseDown); this.onVisibilityChange = undefined; } - onMouseDown = (): void => { - this.mouseUp = new Promise((resolve) => { - document.addEventListener('mouseup', () => resolve(), { once: true }); - }); - }; - openSessionsModal() { this.isSessionsModalVisible = true; } diff --git a/app/assets/javascripts/ui_models/app_state/index.ts b/app/assets/javascripts/ui_models/app_state/index.ts new file mode 100644 index 00000000000..e5ecceda861 --- /dev/null +++ b/app/assets/javascripts/ui_models/app_state/index.ts @@ -0,0 +1,6 @@ +export { + AppState, + AppStateEvent, + EventSource, + PanelResizedData, +} from './app_state'; diff --git a/app/assets/javascripts/ui_models/app_state/no_account_warning_state.ts b/app/assets/javascripts/ui_models/app_state/no_account_warning_state.ts new file mode 100644 index 00000000000..63b17f7aba6 --- /dev/null +++ b/app/assets/javascripts/ui_models/app_state/no_account_warning_state.ts @@ -0,0 +1,41 @@ +import { storage, StorageKey } from "@/services/localStorage"; +import { SNApplication, ApplicationEvent } from "@standardnotes/snjs"; +import { runInAction, makeObservable, observable, action } from "mobx"; + +export class NoAccountWarningState { + show: boolean; + constructor(application: SNApplication, appObservers: (() => void)[]) { + this.show = application.hasAccount() + ? false + : storage.get(StorageKey.ShowNoAccountWarning) ?? true; + + appObservers.push( + application.addEventObserver(async () => { + runInAction(() => { + this.show = false; + }); + }, ApplicationEvent.SignedIn), + application.addEventObserver(async () => { + if (application.hasAccount()) { + runInAction(() => { + this.show = false; + }); + } + }, ApplicationEvent.Started) + ); + + makeObservable(this, { + show: observable, + hide: action, + }); + } + + hide = (): void => { + this.show = false; + storage.set(StorageKey.ShowNoAccountWarning, false); + } + + reset = (): void => { + storage.remove(StorageKey.ShowNoAccountWarning); + } +} diff --git a/app/assets/javascripts/ui_models/app_state/search_options_state.ts b/app/assets/javascripts/ui_models/app_state/search_options_state.ts new file mode 100644 index 00000000000..7be4be6d2be --- /dev/null +++ b/app/assets/javascripts/ui_models/app_state/search_options_state.ts @@ -0,0 +1,59 @@ +import { ApplicationEvent } from "@standardnotes/snjs"; +import { makeObservable, observable, action, runInAction } from "mobx"; +import { WebApplication } from "../application"; + +export class SearchOptionsState { + includeProtectedContents = false; + includeArchived = false; + includeTrashed = false; + + constructor( + private application: WebApplication, + appObservers: (() => void)[] + ) { + makeObservable(this, { + includeProtectedContents: observable, + includeTrashed: observable, + includeArchived: observable, + + toggleIncludeArchived: action, + toggleIncludeTrashed: action, + toggleIncludeProtectedContents: action, + refreshIncludeProtectedContents: action, + }); + + appObservers.push( + this.application.addEventObserver(async () => { + this.refreshIncludeProtectedContents(); + }, ApplicationEvent.ProtectionSessionExpiryDateChanged) + ); + } + + toggleIncludeArchived = (): void => { + this.includeArchived = !this.includeArchived; + }; + + toggleIncludeTrashed = (): void => { + this.includeTrashed = !this.includeTrashed; + }; + + refreshIncludeProtectedContents = (): void => { + if ( + this.includeProtectedContents && + this.application.areProtectionsEnabled() + ) { + this.includeProtectedContents = false; + } + }; + + toggleIncludeProtectedContents = async (): Promise => { + if (this.includeProtectedContents) { + this.includeProtectedContents = false; + } else { + const authorized = await this.application.authorizeSearchingProtectedNotesText(); + runInAction(() => { + this.includeProtectedContents = authorized; + }); + } + }; +} diff --git a/app/assets/javascripts/ui_models/app_state/sync_state.ts b/app/assets/javascripts/ui_models/app_state/sync_state.ts new file mode 100644 index 00000000000..7bc06645415 --- /dev/null +++ b/app/assets/javascripts/ui_models/app_state/sync_state.ts @@ -0,0 +1,36 @@ +import { SyncOpStatus } from "@standardnotes/snjs"; +import { action, makeObservable, observable } from "mobx"; + +export class SyncState { + inProgress = false; + errorMessage?: string = undefined; + humanReadablePercentage?: string = undefined; + + constructor() { + makeObservable(this, { + inProgress: observable, + errorMessage: observable, + humanReadablePercentage: observable, + update: action, + }); + } + + update = (status: SyncOpStatus): void => { + this.errorMessage = status.error?.message; + this.inProgress = status.syncInProgress; + const stats = status.getStats(); + const completionPercentage = + stats.uploadCompletionCount === 0 + ? 0 + : stats.uploadCompletionCount / stats.uploadTotalCount; + + if (completionPercentage === 0) { + this.humanReadablePercentage = undefined; + } else { + this.humanReadablePercentage = completionPercentage.toLocaleString( + undefined, + { style: 'percent' } + ); + } + } +} diff --git a/app/assets/javascripts/views/editor/editor_view.ts b/app/assets/javascripts/views/editor/editor_view.ts index c99bb099189..96aa4fc0460 100644 --- a/app/assets/javascripts/views/editor/editor_view.ts +++ b/app/assets/javascripts/views/editor/editor_view.ts @@ -54,7 +54,7 @@ const ElementIds = { type NoteStatus = { message?: string; - date?: Date; + desc?: string; }; type EditorState = { @@ -541,11 +541,11 @@ class EditorViewCtrl extends PureViewCtrl { syncTakingTooLong: false, }); this.setStatus({ - message: 'All changes saved', + message: 'All changes saved' + (this.application.noAccount() ? ' offline' : ''), }); } - showErrorStatus(error?: any) { + showErrorStatus(error?: NoteStatus) { if (!error) { error = { message: 'Sync Unreachable', @@ -559,7 +559,7 @@ class EditorViewCtrl extends PureViewCtrl { this.setStatus(error); } - setStatus(status: { message: string }, wait = true) { + setStatus(status: NoteStatus, wait = true) { if (this.statusTimeout) { this.$timeout.cancel(this.statusTimeout); } diff --git a/app/assets/javascripts/views/notes/notes-view.pug b/app/assets/javascripts/views/notes/notes-view.pug index 2439b9c8e90..1b1e3efc794 100644 --- a/app/assets/javascripts/views/notes/notes-view.pug +++ b/app/assets/javascripts/views/notes/notes-view.pug @@ -12,6 +12,7 @@ i.icon.ion-plus.add-button .filter-section(role='search') input#search-bar.filter-bar( + type="text" ng-ref='self.searchBarInput' ng-focus='self.onSearchInputFocus()' ng-blur='self.onSearchInputBlur()', @@ -25,21 +26,12 @@ #search-clear-button( ng-click='self.clearFilterText();', ng-show='self.state.noteFilter.text' + aria-role="button" ) ✕ - label.sk-panel-row.justify-left.mt-2.animate-slide-in-top( - ng-if='self.state.searchIsFocused || self.state.searchOptionsAreFocused || self.state.authorizingSearchOptions' - style="padding-bottom: 0" - ) - .sk-horizontal-group.tight - input( - ng-ref='self.searchOptionsInput' - ng-focus="self.onSearchOptionsFocus()" - ng-blur="self.onSearchOptionsBlur()" - type="checkbox" - ng-checked="self.state.noteFilter.includeProtectedNoteText" - ng-on-click="self.onIncludeProtectedNoteTextChange($event)" - ) - p.sk-p.capitalize Include protected contents + search-options( + class="ml-2" + app-state='self.appState' + ) no-account-warning( application='self.application' app-state='self.appState' diff --git a/app/assets/javascripts/views/notes/notes_view.ts b/app/assets/javascripts/views/notes/notes_view.ts index 5eee017f73c..7d04358a617 100644 --- a/app/assets/javascripts/views/notes/notes_view.ts +++ b/app/assets/javascripts/views/notes/notes_view.ts @@ -18,10 +18,11 @@ import { KeyboardModifier, KeyboardKey } from '@/services/keyboardManager'; import { PANEL_NAME_NOTES } from '@/views/constants'; +import { autorun, IReactionDisposer } from 'mobx'; type NotesState = { panelTitle: string - notes?: SNNote[] + notes: SNNote[] renderedNotes: SNNote[] renderedNotesTags: string[], sortBy?: string @@ -33,11 +34,12 @@ type NotesState = { hideTags: boolean noteFilter: { text: string; - includeProtectedNoteText: boolean; } - searchIsFocused: boolean; - searchOptionsAreFocused: boolean; - authorizingSearchOptions: boolean; + searchOptions: { + includeProtectedContents: boolean; + includeArchived: boolean; + includeTrashed: boolean; + } mutable: { showMenu: boolean } completedFullSync: boolean [PrefKey.TagsPanelWidth]?: number @@ -76,8 +78,7 @@ class NotesViewCtrl extends PureViewCtrl { private searchKeyObserver: any private noteFlags: Partial> = {} private removeObservers: Array<() => void> = []; - private searchBarInput?: JQLite; - private searchOptionsInput?: JQLite; + private appStateObserver?: IReactionDisposer; /* @ngInject */ constructor($timeout: ng.ITimeoutService,) { @@ -94,6 +95,24 @@ class NotesViewCtrl extends PureViewCtrl { this.onPanelResize = this.onPanelResize.bind(this); window.addEventListener('resize', this.onWindowResize, true); this.registerKeyboardShortcuts(); + this.appStateObserver = autorun(async () => { + const { + includeProtectedContents, + includeArchived, + includeTrashed, + } = this.appState.searchOptions; + await this.setState({ + searchOptions: { + includeProtectedContents, + includeArchived, + includeTrashed, + } + }); + if (this.state.noteFilter.text) { + this.reloadNotesDisplayOptions(); + this.reloadNotes(); + } + }); } onWindowResize() { @@ -112,6 +131,7 @@ class NotesViewCtrl extends PureViewCtrl { this.nextNoteKeyObserver(); this.previousNoteKeyObserver(); this.searchKeyObserver(); + this.appStateObserver?.(); this.newNoteKeyObserver = undefined; this.nextNoteKeyObserver = undefined; this.previousNoteKeyObserver = undefined; @@ -119,10 +139,6 @@ class NotesViewCtrl extends PureViewCtrl { super.deinit(); } - getState() { - return this.state as NotesState; - } - async setNotesState(state: Partial) { return this.setState(state); } @@ -135,14 +151,15 @@ class NotesViewCtrl extends PureViewCtrl { mutable: { showMenu: false }, noteFilter: { text: '', - includeProtectedNoteText: false + }, + searchOptions: { + includeArchived: false, + includeProtectedContents: false, + includeTrashed: false, }, panelTitle: '', completedFullSync: false, - hideTags: true, - searchIsFocused: false, - searchOptionsAreFocused: false, - authorizingSearchOptions: false + hideTags: true }; } @@ -203,7 +220,7 @@ class NotesViewCtrl extends PureViewCtrl { * that may be in progress. This is the sync alternative to `async getMostValidNotes` */ private getPossiblyStaleNotes() { - return this.getState().notes!; + return this.state.notes; } /** @@ -230,7 +247,7 @@ class NotesViewCtrl extends PureViewCtrl { } streamNotesAndTags() { - this.removeObservers.push(this.application!.streamItems( + this.removeObservers.push(this.application.streamItems( [ContentType.Note], async (items) => { const notes = items as SNNote[]; @@ -256,7 +273,7 @@ class NotesViewCtrl extends PureViewCtrl { } )); - this.removeObservers.push(this.application!.streamItems( + this.removeObservers.push(this.application.streamItems( [ContentType.Tag], async (items) => { const tags = items as SNTag[]; @@ -280,9 +297,9 @@ class NotesViewCtrl extends PureViewCtrl { } async createNewNote() { - let title = `Note ${this.getState().notes!.length + 1}`; + let title = `Note ${this.state.notes.length + 1}`; if (this.isFiltering()) { - title = this.getState().noteFilter.text; + title = this.state.noteFilter.text; } await this.appState.createEditor(title); await this.flushUI(); @@ -293,21 +310,21 @@ class NotesViewCtrl extends PureViewCtrl { this.resetScrollPosition(); this.setShowMenuFalse(); await this.setNoteFilterText(''); - this.application!.getDesktopService().searchText(); + this.application.getDesktopService().searchText(); this.resetPagination(); /* Capture db load state before beginning reloadNotes, since this status may change during reload */ - const dbLoaded = this.application!.isDatabaseLoaded(); + const dbLoaded = this.application.isDatabaseLoaded(); this.reloadNotesDisplayOptions(); await this.reloadNotes(); - if (this.getState().notes!.length > 0) { + if (this.state.notes.length > 0) { this.selectFirstNote(); } else if (dbLoaded) { if ( this.activeEditorNote && - !this.getState().notes!.includes(this.activeEditorNote!) + !this.state.notes.includes(this.activeEditorNote!) ) { this.appState.closeActiveEditor(); } @@ -323,7 +340,7 @@ class NotesViewCtrl extends PureViewCtrl { } async removeNoteFromList(note: SNNote) { - const notes = this.getState().notes!; + const notes = this.state.notes; removeFromArray(notes, note); await this.setNotesState({ notes: notes, @@ -343,23 +360,37 @@ class NotesViewCtrl extends PureViewCtrl { */ private reloadNotesDisplayOptions() { const tag = this.appState.selectedTag; - const searchText = this.getState().noteFilter.text.toLowerCase(); + + const searchText = this.state.noteFilter.text.toLowerCase(); + const isSearching = searchText.length; + let includeArchived: boolean; + let includeTrashed: boolean; + + if (isSearching) { + includeArchived = this.state.searchOptions.includeArchived; + includeTrashed = this.state.searchOptions.includeTrashed; + } else { + includeArchived = this.state.showArchived ?? false; + includeTrashed = false; + } + const criteria = NotesDisplayCriteria.Create({ - sortProperty: this.state.sortBy! as CollectionSort, - sortDirection: this.state.sortReverse! ? 'asc' : 'dsc', + sortProperty: this.state.sortBy as CollectionSort, + sortDirection: this.state.sortReverse ? 'asc' : 'dsc', tags: tag ? [tag] : [], - includeArchived: this.getState().showArchived!, - includePinned: !this.getState().hidePinned!, + includeArchived, + includeTrashed, + includePinned: !this.state.hidePinned, searchQuery: { - query: searchText ?? '', - includeProtectedNoteText: this.state.noteFilter.includeProtectedNoteText + query: searchText, + includeProtectedNoteText: this.state.searchOptions.includeProtectedContents } }); - this.application!.setNotesDisplayCriteria(criteria); + this.application.setNotesDisplayCriteria(criteria); } private get selectedTag() { - return this.application!.getAppState().getSelectedTag(); + return this.application.getAppState().getSelectedTag(); } private async performReloadNotes() { @@ -411,7 +442,7 @@ class NotesViewCtrl extends PureViewCtrl { setShowMenuFalse() { this.setNotesState({ mutable: { - ...this.getState().mutable, + ...this.state.mutable, showMenu: false } }); @@ -420,19 +451,19 @@ class NotesViewCtrl extends PureViewCtrl { async handleEditorChange() { const activeNote = this.appState.getActiveEditor()?.note; if (activeNote && activeNote.conflictOf) { - this.application!.changeAndSaveItem(activeNote.uuid, (mutator) => { + this.application.changeAndSaveItem(activeNote.uuid, (mutator) => { mutator.conflictOf = undefined; }); } if (this.isFiltering()) { - this.application!.getDesktopService().searchText(this.getState().noteFilter.text); + this.application.getDesktopService().searchText(this.state.noteFilter.text); } } async reloadPreferences() { const viewOptions = {} as NotesState; - const prevSortValue = this.getState().sortBy; - let sortBy = this.application!.getPreference( + const prevSortValue = this.state.sortBy; + let sortBy = this.application.getPreference( PrefKey.SortNotesBy, CollectionSort.CreatedAt ); @@ -444,23 +475,23 @@ class NotesViewCtrl extends PureViewCtrl { sortBy = CollectionSort.UpdatedAt; } viewOptions.sortBy = sortBy; - viewOptions.sortReverse = this.application!.getPreference( + viewOptions.sortReverse = this.application.getPreference( PrefKey.SortNotesReverse, false ); - viewOptions.showArchived = this.application!.getPreference( + viewOptions.showArchived = this.application.getPreference( PrefKey.NotesShowArchived, false ); - viewOptions.hidePinned = this.application!.getPreference( + viewOptions.hidePinned = this.application.getPreference( PrefKey.NotesHidePinned, false ); - viewOptions.hideNotePreview = this.application!.getPreference( + viewOptions.hideNotePreview = this.application.getPreference( PrefKey.NotesHideNotePreview, false ); - viewOptions.hideDate = this.application!.getPreference( + viewOptions.hideDate = this.application.getPreference( PrefKey.NotesHideDate, false ); @@ -468,7 +499,7 @@ class NotesViewCtrl extends PureViewCtrl { PrefKey.NotesHideTags, true, ); - const state = this.getState(); + const state = this.state; const displayOptionsChanged = ( viewOptions.sortBy !== state.sortBy || viewOptions.sortReverse !== state.sortReverse || @@ -490,13 +521,13 @@ class NotesViewCtrl extends PureViewCtrl { } reloadPanelWidth() { - const width = this.application!.getPreference( + const width = this.application.getPreference( PrefKey.NotesPanelWidth ); if (width && this.panelPuppet!.ready) { this.panelPuppet!.setWidth!(width); if (this.panelPuppet!.isCollapsed!()) { - this.application!.getAppState().panelDidResize( + this.application.getAppState().panelDidResize( PANEL_NAME_NOTES, this.panelPuppet!.isCollapsed!() ); @@ -510,11 +541,11 @@ class NotesViewCtrl extends PureViewCtrl { __: boolean, isCollapsed: boolean ) { - this.application!.setPreference( + this.application.setPreference( PrefKey.NotesPanelWidth, newWidth ); - this.application!.getAppState().panelDidResize( + this.application.getAppState().panelDidResize( PANEL_NAME_NOTES, isCollapsed ); @@ -524,7 +555,7 @@ class NotesViewCtrl extends PureViewCtrl { this.notesToDisplay += this.pageSize; this.reloadNotes(); if (this.searchSubmitted) { - this.application!.getDesktopService().searchText(this.getState().noteFilter.text); + this.application.getDesktopService().searchText(this.state.noteFilter.text); } } @@ -543,7 +574,7 @@ class NotesViewCtrl extends PureViewCtrl { reloadPanelTitle() { let title; if (this.isFiltering()) { - const resultCount = this.getState().notes!.length; + const resultCount = this.state.notes.length; title = `${resultCount} search results`; } else if (this.appState.selectedTag) { title = `${this.appState.selectedTag.title}`; @@ -555,20 +586,20 @@ class NotesViewCtrl extends PureViewCtrl { optionsSubtitle() { let base = ""; - if (this.getState().sortBy === CollectionSort.CreatedAt) { + if (this.state.sortBy === CollectionSort.CreatedAt) { base += " Date Added"; - } else if (this.getState().sortBy === CollectionSort.UpdatedAt) { + } else if (this.state.sortBy === CollectionSort.UpdatedAt) { base += " Date Modified"; - } else if (this.getState().sortBy === CollectionSort.Title) { + } else if (this.state.sortBy === CollectionSort.Title) { base += " Title"; } - if (this.getState().showArchived) { + if (this.state.showArchived) { base += " | + Archived"; } - if (this.getState().hidePinned) { + if (this.state.hidePinned) { base += " | – Pinned"; } - if (this.getState().sortReverse) { + if (this.state.sortReverse) { base += " | Reversed"; } return base; @@ -628,13 +659,8 @@ class NotesViewCtrl extends PureViewCtrl { this.noteFlags[note.uuid] = flags; } - displayableNotes() { - return this.getState().notes!; - } - getFirstNonProtectedNote() { - const displayableNotes = this.displayableNotes(); - return displayableNotes.find(note => !note.protected); + return this.state.notes.find(note => !note.protected); } selectFirstNote() { @@ -645,9 +671,9 @@ class NotesViewCtrl extends PureViewCtrl { } selectNextNote() { - const displayableNotes = this.displayableNotes(); + const displayableNotes = this.state.notes; const currentIndex = displayableNotes.findIndex((candidate) => { - return candidate.uuid === this.activeEditorNote!.uuid; + return candidate.uuid === this.activeEditorNote.uuid; }); if (currentIndex + 1 < displayableNotes.length) { this.selectNote(displayableNotes[currentIndex + 1]); @@ -664,7 +690,7 @@ class NotesViewCtrl extends PureViewCtrl { } selectPreviousNote() { - const displayableNotes = this.displayableNotes(); + const displayableNotes = this.state.notes; const currentIndex = displayableNotes.indexOf(this.activeEditorNote!); if (currentIndex - 1 >= 0) { this.selectNote(displayableNotes[currentIndex - 1]); @@ -675,14 +701,14 @@ class NotesViewCtrl extends PureViewCtrl { } isFiltering() { - return this.getState().noteFilter.text && - this.getState().noteFilter.text.length > 0; + return this.state.noteFilter.text && + this.state.noteFilter.text.length > 0; } async setNoteFilterText(text: string) { await this.setNotesState({ noteFilter: { - ...this.getState().noteFilter, + ...this.state.noteFilter, text: text } }); @@ -703,72 +729,8 @@ class NotesViewCtrl extends PureViewCtrl { await this.reloadNotes(); } - async onIncludeProtectedNoteTextChange(event: Event) { - this.searchBarInput?.[0].focus(); - if (this.state.noteFilter.includeProtectedNoteText) { - await this.setState({ - noteFilter: { - ...this.state.noteFilter, - includeProtectedNoteText: false, - }, - }); - this.reloadNotesDisplayOptions(); - await this.reloadNotes(); - } else { - this.setState({ - authorizingSearchOptions: true, - }); - event.preventDefault(); - if (await this.application.authorizeSearchingProtectedNotesText()) { - await this.setState({ - noteFilter: { - ...this.state.noteFilter, - includeProtectedNoteText: true, - }, - }); - this.reloadNotesDisplayOptions(); - await this.reloadNotes(); - } - await this.$timeout(50); - await this.setState({ - authorizingSearchOptions: false, - }); - } - } - - onSearchInputFocus() { - this.setState({ - searchIsFocused: true, - }); - } - async onSearchInputBlur() { - await this.appState.mouseUp; - /** - * Wait a non-zero amount of time so the newly-focused element can have - * enough time to set its state - */ - await this.$timeout(50); - await this.setState({ - searchIsFocused: - this.searchBarInput?.[0] === document.activeElement, - }); - this.onFilterEnter(); - } - - onSearchOptionsFocus() { - this.setState({ - searchOptionsAreFocused: true, - }); - } - - async onSearchOptionsBlur() { - await this.appState.mouseUp; - await this.$timeout(50); - this.setState({ - searchOptionsAreFocused: - this.searchOptionsInput?.[0] === document.activeElement, - }); + this.appState.searchOptions.refreshIncludeProtectedContents(); } onFilterEnter() { @@ -778,7 +740,7 @@ class NotesViewCtrl extends PureViewCtrl { * enter before highlighting desktop search results. */ this.searchSubmitted = true; - this.application!.getDesktopService().searchText(this.getState().noteFilter.text); + this.application.getDesktopService().searchText(this.state.noteFilter.text); } selectedMenuItem() { @@ -786,7 +748,7 @@ class NotesViewCtrl extends PureViewCtrl { } togglePrefKey(key: PrefKey) { - this.application!.setPreference( + this.application.setPreference( key, !this.state[key] ); @@ -806,14 +768,14 @@ class NotesViewCtrl extends PureViewCtrl { toggleReverseSort() { this.selectedMenuItem(); - this.application!.setPreference( + this.application.setPreference( PrefKey.SortNotesReverse, - !this.getState().sortReverse + !this.state.sortReverse ); } setSortBy(type: CollectionSort) { - this.application!.setPreference( + this.application.setPreference( PrefKey.SortNotesBy, type ); @@ -829,7 +791,7 @@ class NotesViewCtrl extends PureViewCtrl { * use Control modifier as well. These rules don't apply to desktop, but * probably better to be consistent. */ - this.newNoteKeyObserver = this.application!.getKeyboardService().addKeyObserver({ + this.newNoteKeyObserver = this.application.getKeyboardService().addKeyObserver({ key: 'n', modifiers: [ KeyboardModifier.Meta, @@ -841,7 +803,7 @@ class NotesViewCtrl extends PureViewCtrl { } }); - this.nextNoteKeyObserver = this.application!.getKeyboardService().addKeyObserver({ + this.nextNoteKeyObserver = this.application.getKeyboardService().addKeyObserver({ key: KeyboardKey.Down, elements: [ document.body, @@ -856,7 +818,7 @@ class NotesViewCtrl extends PureViewCtrl { } }); - this.previousNoteKeyObserver = this.application!.getKeyboardService().addKeyObserver({ + this.previousNoteKeyObserver = this.application.getKeyboardService().addKeyObserver({ key: KeyboardKey.Up, element: document.body, onKeyDown: () => { @@ -864,7 +826,7 @@ class NotesViewCtrl extends PureViewCtrl { } }); - this.searchKeyObserver = this.application!.getKeyboardService().addKeyObserver({ + this.searchKeyObserver = this.application.getKeyboardService().addKeyObserver({ key: "f", modifiers: [ KeyboardModifier.Meta, diff --git a/app/assets/stylesheets/_notes.scss b/app/assets/stylesheets/_notes.scss index 02a8184648d..e66e8d54c22 100644 --- a/app/assets/stylesheets/_notes.scss +++ b/app/assets/stylesheets/_notes.scss @@ -53,6 +53,8 @@ height: 28px; margin-top: 14px; position: relative; + display: flex; + align-items: center; .filter-bar { background-color: var(--sn-stylekit-contrast-background-color); @@ -82,7 +84,8 @@ position: absolute; top: 50%; transform: translateY(-50%); - right: 8px; + right: 32px; + cursor: pointer; transition: background-color 0.15s linear; diff --git a/app/assets/stylesheets/_sn.scss b/app/assets/stylesheets/_sn.scss new file mode 100644 index 00000000000..6d74b17bc7f --- /dev/null +++ b/app/assets/stylesheets/_sn.scss @@ -0,0 +1,127 @@ +/* Components and utilities that are good candidates for extraction to StyleKit. */ + +.outline-none { + outline: none; +} + +.border-2 { + border-width: 2px; +} + +.border-background { + border-color: var(--sn-stylekit-background-color); +} + +.focus-within\:border-background:focus-within { + border-color: var(--sn-stylekit-background-color); +} + +.border-transparent { + border-color: var(--sn-stylekit-background-color); +} + +.bg-clip-padding { + background-clip: padding-box; +} + +.ring-info { + box-shadow: 0 0 0 2px var(--sn-stylekit-info-color); +} + +.focus\:ring-info:focus { + @extend .ring-info; +} + +.focus-within\:ring-info:focus-within { + @extend .ring-info; +} + +.border-transparent { + border-color: transparent; +} + +/** + * A button that is just an icon. Separated from .sn-button because there + * is almost no style overlap. + */ +.sn-icon-button { + @extend .border-2; + @extend .border-transparent; + @extend .bg-clip-padding; + @extend .m-0; + @extend .p-0; + @extend .bg-transparent; + @extend .cursor-pointer; + @extend .rounded-full; + @extend .color-neutral; + @extend .focus\:outline-none; + @extend .focus\:ring-info; +} + +.sn-dropdown { + @extend .absolute; + @extend .bg-default; + @extend .min-w-80; + @extend .duration-150; + @extend .grid; + @extend .gap-2; + @extend .slide-down-animation; + @extend .rounded; + @extend .box-shadow; + + z-index: $z-index-dropdown-menu; + + &.sn-dropdown-anchor-right { + right: 0; + } + + &[data-state='collapsed'] { + display: none; + } +} + +$switch-width: 35px; +$switch-handle-size: 14px; +$border-width: 2px; + +/** Lesser specificity will give priority to reach's styles */ +[data-reach-custom-checkbox-container].sn-switch { + @extend .duration-150; + @extend .ease-out; + @extend .rounded-full; + @extend .transition-background; + @extend .bg-clip-padding; + @extend .cursor-pointer; + @extend .border-transparent; + width: $switch-width; + height: 22px; + border-style: solid; + border-width: $border-width; + @extend .focus-within\:ring-info; + @extend .focus-within\:outline-none; + @extend .focus-within\:border-background; +} + +.sn-switch-handle { + @extend .absolute; + @extend .block; + @extend .bg-default; + @extend .rounded-full; + + @extend .ease-out; + @extend .transition-transform; + @extend .duration-150; + + left: $border-width; + width: $switch-handle-size; + height: $switch-handle-size; + top: 50%; + transform: translate(0px, -50%); + + &.sn-switch-handle-right { + transform: translate( + $switch-width - $switch-handle-size - ($border-width * 4), + -50% + ); + } +} diff --git a/app/assets/stylesheets/_stylekit-sub.scss b/app/assets/stylesheets/_stylekit-sub.scss index 7515853e5e3..6de7a670242 100644 --- a/app/assets/stylesheets/_stylekit-sub.scss +++ b/app/assets/stylesheets/_stylekit-sub.scss @@ -92,6 +92,10 @@ button.sk-a { min-height: 24px; } +*:focus-visible { + outline: none; +} + *:focus { outline: none; box-shadow: 0 0 0 2px var(--sn-stylekit-info-color); diff --git a/app/assets/stylesheets/_ui.scss b/app/assets/stylesheets/_ui.scss index e4785998d81..e71c8810d75 100644 --- a/app/assets/stylesheets/_ui.scss +++ b/app/assets/stylesheets/_ui.scss @@ -183,9 +183,6 @@ $screen-md-max: ($screen-lg-min - 1) !default; grid-column-end: 3; } -.color-neutral { - color: var(--sn-stylekit-neutral-color) -} .hover\:color-info:hover { color: var(--sn-stylekit-info-color) } diff --git a/app/assets/stylesheets/index.css.scss b/app/assets/stylesheets/index.css.scss index 52ca8b997ff..fa0deecc949 100644 --- a/app/assets/stylesheets/index.css.scss +++ b/app/assets/stylesheets/index.css.scss @@ -1,3 +1,4 @@ +@import "sn-stylekit/dist/stylekit"; @import "main"; @import "ui"; @import "footer"; @@ -11,3 +12,4 @@ @import "ionicons"; @import "reach-sub"; @import "sessions-modal"; +@import "sn"; diff --git a/app/assets/templates/directives/account-menu.pug b/app/assets/templates/directives/account-menu.pug index 65433ea0e40..97f0a49d862 100644 --- a/app/assets/templates/directives/account-menu.pug +++ b/app/assets/templates/directives/account-menu.pug @@ -99,7 +99,7 @@ ) (Learn more) .sk-panel-section.form-submit(ng-if='!self.state.formData.authenticating') button.sn-button.info.text-base.py-3.text-center( - ng-click='self.submitAuthForm()', + type="submit" ng-disabled='self.state.formData.authenticating' ) {{self.state.formData.showLogin ? "Sign In" : "Register"}} .sk-notification.neutral(ng-if='self.state.formData.showRegister') diff --git a/app/assets/templates/directives/editor-menu.pug b/app/assets/templates/directives/editor-menu.pug index c5536e4291b..d7e8efe6523 100644 --- a/app/assets/templates/directives/editor-menu.pug +++ b/app/assets/templates/directives/editor-menu.pug @@ -4,19 +4,20 @@ .sk-menu-panel-header .sk-menu-panel-header-title Note Editor menu-row( - action='self.selectComponent(null)', - circle="!self.selectedEditorUuid && 'success'", + action='self.selectComponent(null)', + circle="!self.selectedEditorUuid && 'success'", label="'Plain Editor'" ) menu-row( ng-repeat='editor in self.state.editors track by editor.uuid' - action='self.selectComponent(editor)', - button-action='self.toggleDefaultForEditor(editor)', - button-class="self.isEditorSelected(editor) ? 'warning' : 'info'", - button-text="self.isEditorDefault(editor) ? 'Undefault' : 'Set Default'", - circle="self.isEditorSelected(editor) && 'success'", - has-button='self.isEditorSelected(editor) || isEditorDefault(editor)', - label='editor.name', + action='self.selectComponent(editor)', + button-action='self.toggleDefaultForEditor(editor)', + button-class="self.isEditorSelected(editor) ? 'warning' : 'info'", + button-text="self.isEditorDefault(editor) ? 'Undefault' : 'Set Default'", + circle="self.isEditorSelected(editor) && 'success'", + has-button='self.isEditorSelected(editor) || isEditorDefault(editor)', + label='editor.name', + subtitle="self.isEditorSelected(editor) && 'Version ' + editor.package_info.version", ) .sk-menu-panel-column( ng-if='editor.conflictOf' @@ -25,9 +26,9 @@ ng-if='editor.conflictOf' ) Conflicted copy a.no-decoration( - href='https://standardnotes.org/extensions', - ng-if='self.state.editors.length == 0', - rel='noopener', + href='https://standardnotes.org/extensions', + ng-if='self.state.editors.length == 0', + rel='noopener', target='blank' ) menu-row(label="'Download More Editors'") diff --git a/app/assets/templates/directives/history-menu.pug b/app/assets/templates/directives/history-menu.pug index b45f8ed81e0..39b43a9fec4 100644 --- a/app/assets/templates/directives/history-menu.pug +++ b/app/assets/templates/directives/history-menu.pug @@ -2,7 +2,7 @@ .sk-menu-panel.dropdown-menu .sk-menu-panel-header .sk-menu-panel-header-title Session - .sk-menu-panel-header-subtitle {{ctrl.sessionHistoryEntries.length || 'No'}} revisions + .sk-menu-panel-header-subtitle {{ctrl.state.sessionHistory.length || 'No'}} revisions a.sk-a.info.sk-h5( ng-click='ctrl.showSessionOptions = !ctrl.showSessionOptions; $event.stopPropagation();' ) Options @@ -17,18 +17,18 @@ ) menu-row( action='ctrl.toggleSessionHistoryAutoOptimize()' - label="(ctrl.autoOptimize ? 'Disable' : 'Enable') + ' auto cleanup'") + label="(ctrl.state.autoOptimize ? 'Disable' : 'Enable') + ' auto cleanup'") .sk-sublabel | Automatically cleans up small revisions to conserve space. menu-row( action='ctrl.toggleSessionHistoryDiskSaving()' - label="(ctrl.diskEnabled ? 'Disable' : 'Enable') + ' saving history to disk'" + label="(ctrl.state.diskEnabled ? 'Disable' : 'Enable') + ' saving history to disk'" ) .sk-sublabel | Saving to disk is not recommended. Decreases performance and increases app | loading time and memory footprint. menu-row( - ng-repeat='revision in ctrl.sessionHistoryEntries track by $index' + ng-repeat='revision in ctrl.state.sessionHistory track by $index' action='ctrl.openSessionRevision(revision);' label='revision.previewTitle()' ) @@ -36,7 +36,7 @@ | {{revision.previewSubTitle()}} .sk-menu-panel-header .sk-menu-panel-header-title Remote - .sk-menu-panel-header-subtitle {{ctrl.remoteHistoryEntries.length || 'No'}} revisions + .sk-menu-panel-header-subtitle {{ctrl.state.remoteHistory.length || 'No'}} revisions a.sk-a.info.sk-h5( ng-click='ctrl.showRemoteOptions = !ctrl.showRemoteOptions; $event.stopPropagation();' ) Options @@ -49,7 +49,7 @@ .sk-sublabel | Fetch history from server. menu-row( - ng-repeat='revision in ctrl.remoteHistoryEntries track by $index' + ng-repeat='revision in ctrl.state.remoteHistory track by $index' action='ctrl.openRemoteRevision(revision);' label='ctrl.previewRemoteHistoryTitle(revision);' ) diff --git a/package.json b/package.json index adebcb3fc35..0be76053361 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "3.6.4", + "version": "3.6.6", "license": "AGPL-3.0-or-later", "repository": { "type": "git", @@ -24,6 +24,8 @@ "@babel/plugin-transform-react-jsx": "^7.12.16", "@babel/preset-env": "^7.12.16", "@babel/preset-typescript": "^7.12.16", + "@reach/disclosure": "^0.14.0", + "@reach/visually-hidden": "^0.14.0", "@svgr/webpack": "^5.5.0", "@types/angular": "^1.8.0", "@types/lodash": "^4.14.168", @@ -49,26 +51,27 @@ "mini-css-extract-plugin": "^0.9.0", "ng-cache-loader": "0.0.26", "node-sass": "^4.14.1", - "pug": "^2.0.4", + "pug": "^3.0.1", "pug-loader": "^2.4.0", "sass-loader": "^8.0.2", "serve-static": "^1.14.1", - "sn-stylekit": "github:standardnotes/StyleKit#1ec13454cc6d8cf97651263a039de8872be527b8", + "sn-stylekit": "github:standardnotes/StyleKit#c64573b229ac9154e480cde3b5fdab78c75b3530", "ts-loader": "^8.0.17", "typescript": "^4.1.5", "typescript-eslint": "0.0.1-alpha.0", "webpack": "^4.44.1", "webpack-cli": "^3.3.12", "webpack-dev-server": "^3.11.2", - "webpack-merge": "^4.2.2" + "webpack-merge": "^5.7.3" }, "dependencies": { "@bugsnag/js": "^7.6.0", "@reach/alert": "^0.13.0", "@reach/alert-dialog": "^0.13.0", + "@reach/checkbox": "^0.13.2", "@reach/dialog": "^0.13.0", "@standardnotes/sncrypto-web": "^1.2.10", - "@standardnotes/snjs": "^2.0.70", + "@standardnotes/snjs": "^2.0.74", "mobx": "^6.1.6", "preact": "^10.5.12" } diff --git a/webpack.dev.js b/webpack.dev.js index b5605f807f5..f793c8a0031 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -1,4 +1,4 @@ -const merge = require('webpack-merge'); +const { merge } = require('webpack-merge'); const config = require('./webpack.config.js'); const HtmlWebpackPlugin = require('html-webpack-plugin'); diff --git a/webpack.prod.js b/webpack.prod.js index bd075035448..855097710f7 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -1,7 +1,9 @@ -const merge = require('webpack-merge'); +const { merge } = require('webpack-merge'); const config = require('./webpack.config.js'); -module.exports = (env, argv) => merge(config(env, argv), { - mode: 'production', - devtool: 'source-map', -}); +module.exports = (env, argv) => { + return merge(config(env, argv), { + mode: 'production', + devtool: 'source-map', + }); +}; diff --git a/yarn.lock b/yarn.lock index b2ccc02d95b..7fa840f873a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -510,6 +510,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.7.tgz#fee7b39fe809d0e73e5b25eecaf5780ef3d73056" integrity sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg== +"@babel/parser@^7.6.0", "@babel/parser@^7.9.6": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.12.tgz#ba320059420774394d3b0c0233ba40e4250b81d1" + integrity sha512-4T7Pb244rxH24yR116LAuJ+adxXXnHhZaLJjegJVKSdoNCe4x1eDBaud5YIcQFcqzsaD5BHvJw5BQ0AZapdCRw== + "@babel/plugin-proposal-async-generator-functions@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz#dc6c1170e27d8aca99ff65f4925bd06b1c90550e" @@ -1681,6 +1686,15 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.6.1", "@babel/types@^7.9.6": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.12.tgz#edbf99208ef48852acdff1c8a681a1e4ade580cd" + integrity sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + "@bugsnag/browser@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@bugsnag/browser/-/browser-7.6.0.tgz#3a34a1e8e151d09b3bf8cdd9d1358abc102db792" @@ -1796,6 +1810,33 @@ "@reach/utils" "0.13.0" tslib "^2.0.0" +"@reach/auto-id@0.13.2": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@reach/auto-id/-/auto-id-0.13.2.tgz#6c7fe7142285707b0f38b2f556f32accb467df32" + integrity sha512-dWeXt6xxjN+NPRoZFXgmNkF89t8MEPsWLYjIIDf3gNXA/Dxaoytc9YBOIfVGpDSpdOwxPpxOu8rH+4Y3Jk2gHA== + dependencies: + "@reach/utils" "0.13.2" + tslib "^2.1.0" + +"@reach/auto-id@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@reach/auto-id/-/auto-id-0.14.0.tgz#1edfdeddb8fad656ec894a934c78f20c3b341416" + integrity sha512-Ym8PBXubuXP7m8CFReqHIH8iXOTcZ3PuAjtHHGuc2EToCwhbbFSf1OouWMUdr6S6vZmu0pOnhOgIE1QGw+dEpw== + dependencies: + "@reach/utils" "0.14.0" + tslib "^2.1.0" + +"@reach/checkbox@^0.13.2": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@reach/checkbox/-/checkbox-0.13.2.tgz#b972b922cf6cea0c2bbabca0129c58307b566a4e" + integrity sha512-PffLj9G7y7cnm53/Ni52DrbHUGbB2ohhe3KVQH6CMY3fuRAN00kJEkIoWR2Yh5VON3lxS9E6vEFn4c+3F6dYYA== + dependencies: + "@reach/auto-id" "0.13.2" + "@reach/machine" "0.13.2" + "@reach/utils" "0.13.2" + prop-types "^15.7.2" + tslib "^2.1.0" + "@reach/dialog@0.13.0", "@reach/dialog@^0.13.0": version "0.13.0" resolved "https://registry.yarnpkg.com/@reach/dialog/-/dialog-0.13.0.tgz#2110725c3b8a3c64685834cdc9f3ce5c15617809" @@ -1808,6 +1849,25 @@ react-remove-scroll "^2.4.1" tslib "^2.0.0" +"@reach/disclosure@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@reach/disclosure/-/disclosure-0.14.0.tgz#0b1a4df7f8c407cb08b6ae71615bb096fb87b6f7" + integrity sha512-J6OJouJiuA71k07LGLqARV6bigxOjxOMCvQbXzvT1ppVH6rWU6nFhX/gweCUxUv5BwrWYQp51omVoSHClI3TRg== + dependencies: + "@reach/auto-id" "0.14.0" + "@reach/utils" "0.14.0" + prop-types "^15.7.2" + tslib "^2.1.0" + +"@reach/machine@0.13.2": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@reach/machine/-/machine-0.13.2.tgz#744302f5ce2d4e5fd0527ae0baa60d325b2325d8" + integrity sha512-sYwkap6s4Rh2Uvs1IwMH537UJ1lHalMjjQlIV1cgruvOSVLvEB4WiGZpiKU6OS4WPVFW+iYuJwNW1mbGGSJkQg== + dependencies: + "@reach/utils" "0.13.2" + "@xstate/fsm" "1.4.0" + tslib "^2.1.0" + "@reach/portal@0.13.0": version "0.13.0" resolved "https://registry.yarnpkg.com/@reach/portal/-/portal-0.13.0.tgz#bed220d41097deb1454a7928b22529ba10d3ea2b" @@ -1825,6 +1885,24 @@ tslib "^2.0.0" warning "^4.0.3" +"@reach/utils@0.13.2": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.13.2.tgz#87e8fef8ebfe583fa48250238a1a3ed03189fcc8" + integrity sha512-3ir6cN60zvUrwjOJu7C6jec/samqAeyAB12ZADK+qjnmQPdzSYldrFWwDVV5H0WkhbYXR3uh+eImu13hCetNPQ== + dependencies: + "@types/warning" "^3.0.0" + tslib "^2.1.0" + warning "^4.0.3" + +"@reach/utils@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.14.0.tgz#f3ff579c737c3e9528f6f940bc518452f2636810" + integrity sha512-QbSFO5p44qUCkOllJM06Lt5A/EsoVIYlB9Ij1vKEezy53keaa5bc879dD2Ahv+mMf+E1VppCeiL6YYvdpJmVVQ== + dependencies: + "@types/warning" "^3.0.0" + tslib "^2.1.0" + warning "^4.0.3" + "@reach/visually-hidden@0.13.0": version "0.13.0" resolved "https://registry.yarnpkg.com/@reach/visually-hidden/-/visually-hidden-0.13.0.tgz#cace36d9bb80ffb797374fcaea989391b881038f" @@ -1832,6 +1910,14 @@ dependencies: tslib "^2.0.0" +"@reach/visually-hidden@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@reach/visually-hidden/-/visually-hidden-0.14.0.tgz#04df6dff0da1180ab85b8548c9a2113a7f01ebd0" + integrity sha512-vyZNj8p1piBY6FR280dHRQxjZGyFVRXYQY7yxvEIe251EZib6C0jc66YlcA/+om4gEhVcJ17/O/bHnKV7GRIig== + dependencies: + prop-types "^15.7.2" + tslib "^2.1.0" + "@standardnotes/auth@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@standardnotes/auth/-/auth-2.0.0.tgz#93f633fd40855f87843f911109e92b29dcbc5a04" @@ -1850,10 +1936,10 @@ "@standardnotes/sncrypto-common" "^1.2.7" libsodium-wrappers "^0.7.8" -"@standardnotes/snjs@^2.0.70": - version "2.0.70" - resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.0.70.tgz#259a4fadc4f9b360f35a399b674b921179bd5768" - integrity sha512-D11E+sCeoram2+NhQuFmn333JoHr1kGjVZrkRmZlfhGi+dYXJqZuDDDHbRn5WEJQneDg43Z8DjjAlxL+Mqhp6w== +"@standardnotes/snjs@^2.0.74": + version "2.0.74" + resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.0.74.tgz#042c3dcf5447006cdfc70b8cfcacf7ded92cea91" + integrity sha512-2G0jw1n4GgOnSkpXDXvrJp9R8xsImVrfNRjKNBE7RqzBg2WFynF5xt0bfqzLdRFZyA5oeuEkTG1CAU4nNPy0xw== dependencies: "@standardnotes/auth" "^2.0.0" "@standardnotes/sncrypto-common" "^1.2.9" @@ -1971,18 +2057,6 @@ resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== -"@types/babel-types@*", "@types/babel-types@^7.0.0": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.9.tgz#01d7b86949f455402a94c788883fe4ba574cad41" - integrity sha512-qZLoYeXSTgQuK1h7QQS16hqLGdmqtRmN8w/rl3Au/l5x/zkHx+a4VHrHyBsi1I1vtK2oBHxSzKIu0R5p6spdOA== - -"@types/babylon@^6.16.2": - version "6.16.5" - resolved "https://registry.yarnpkg.com/@types/babylon/-/babylon-6.16.5.tgz#1c5641db69eb8cdf378edd25b4be7754beeb48b4" - integrity sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w== - dependencies: - "@types/babel-types" "*" - "@types/glob@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" @@ -2303,6 +2377,11 @@ "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" +"@xstate/fsm@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@xstate/fsm/-/fsm-1.4.0.tgz#6fd082336fde4d026e9e448576189ee5265fa51a" + integrity sha512-uTHDeu2xI5E1IFwf37JFQM31RrH7mY7877RqPBS4ZqSNUwoLDuct8AhBWaXGnVizBAYyimVwgCyGa9z/NiRhXA== + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -2326,34 +2405,17 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" -acorn-globals@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf" - integrity sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8= - dependencies: - acorn "^4.0.4" - acorn-jsx@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== -acorn@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= - -acorn@^4.0.4, acorn@~4.0.2: - version "4.0.13" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" - integrity sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c= - acorn@^6.4.1: version "6.4.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -acorn@^7.4.0: +acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== @@ -2388,15 +2450,6 @@ ajv@^7.0.2: require-from-string "^2.0.2" uri-js "^4.2.2" -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc= - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" @@ -2599,6 +2652,11 @@ asn1@~0.2.3: dependencies: safer-buffer "~2.1.0" +assert-never@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe" + integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw== + assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" @@ -2702,28 +2760,12 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= +babel-walk@3.0.0-canary-5: + version "3.0.0-canary-5" + resolved "https://registry.yarnpkg.com/babel-walk/-/babel-walk-3.0.0-canary-5.tgz#f66ecd7298357aee44955f235a6ef54219104b11" + integrity sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw== dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + "@babel/types" "^7.9.6" balanced-match@^1.0.0: version "1.0.0" @@ -2794,10 +2836,10 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: - version "4.11.9" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" - integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== bn.js@^5.0.0, bn.js@^5.1.1: version "5.1.3" @@ -2868,7 +2910,7 @@ braces@^3.0.1, braces@~3.0.2: dependencies: fill-range "^7.0.1" -brorand@^1.0.1: +brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= @@ -3070,11 +3112,6 @@ camelcase-keys@^2.0.0: camelcase "^2.0.0" map-obj "^1.0.0" -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= - camelcase@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" @@ -3100,14 +3137,6 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60= - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - chalk@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -3136,7 +3165,7 @@ chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -character-parser@^2.1.1: +character-parser@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" integrity sha1-x84o821LzZdE5f/CxfzeHHMmH8A= @@ -3207,22 +3236,13 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -clean-css@4.2.x, clean-css@^4.1.11, clean-css@^4.2.3: +clean-css@4.2.x, clean-css@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== dependencies: source-map "~0.6.0" -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE= - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - cliui@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" @@ -3389,15 +3409,13 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -constantinople@^3.0.1, constantinople@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.1.2.tgz#d45ed724f57d3d10500017a7d3a889c1381ae647" - integrity sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw== +constantinople@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151" + integrity sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw== dependencies: - "@types/babel-types" "^7.0.0" - "@types/babylon" "^6.16.2" - babel-types "^6.26.0" - babylon "^6.18.0" + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.1" constants-browserify@^1.0.0: version "1.0.0" @@ -3458,11 +3476,6 @@ core-js-compat@^3.8.0: browserslist "^4.15.0" semver "7.0.0" -core-js@^2.4.0: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -3682,7 +3695,7 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" -decamelize@^1.0.0, decamelize@^1.1.2, decamelize@^1.2.0: +decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -3957,17 +3970,17 @@ electron-to-chromium@^1.3.612: integrity sha512-WFGatwtk7Fw0QcKCZzfGD72hvbcXV8kLY8aFuj0Ip0QRnOtyLYMsc+wXbSjb2w4lk1gcAeNU1/lQ20A+tvuypQ== elliptic@^6.5.3: - version "6.5.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" - integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" + bn.js "^4.11.9" + brorand "^1.1.0" hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" emoji-regex@^7.0.1: version "7.0.3" @@ -4963,7 +4976,7 @@ he@1.2.x, he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hmac-drbg@^1.0.0: +hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= @@ -5339,7 +5352,7 @@ is-callable@^1.1.4, is-callable@^1.2.2: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== -is-core-module@^2.1.0: +is-core-module@^2.1.0, is-core-module@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== @@ -5383,13 +5396,13 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-expression@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-3.0.0.tgz#39acaa6be7fd1f3471dc42c7416e61c24317ac9f" - integrity sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8= +is-expression@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab" + integrity sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A== dependencies: - acorn "~4.0.2" - object-assign "^4.0.1" + acorn "^7.1.1" + object-assign "^4.1.1" is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" @@ -5578,7 +5591,7 @@ js-base64@^2.1.8: resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== -js-stringify@^1.0.1: +js-stringify@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" integrity sha1-Fzb939lyTyijaCrcYjCufk6Weds= @@ -5720,11 +5733,6 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= - levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -5799,7 +5807,7 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@~4.17.10: +lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@~4.17.10: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -5809,11 +5817,6 @@ loglevel@^1.6.8: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= - loose-envify@^1.0.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -6043,7 +6046,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: +minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= @@ -6947,71 +6950,69 @@ public-encrypt@^4.0.0: randombytes "^2.0.1" safe-buffer "^5.1.2" -pug-attrs@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-2.0.4.tgz#b2f44c439e4eb4ad5d4ef25cac20d18ad28cc336" - integrity sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ== +pug-attrs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-3.0.0.tgz#b10451e0348165e31fad1cc23ebddd9dc7347c41" + integrity sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA== dependencies: - constantinople "^3.0.1" - js-stringify "^1.0.1" - pug-runtime "^2.0.5" + constantinople "^4.0.1" + js-stringify "^1.0.2" + pug-runtime "^3.0.0" -pug-code-gen@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-2.0.2.tgz#ad0967162aea077dcf787838d94ed14acb0217c2" - integrity sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw== +pug-code-gen@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-3.0.2.tgz#ad190f4943133bf186b60b80de483100e132e2ce" + integrity sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg== dependencies: - constantinople "^3.1.2" + constantinople "^4.0.1" doctypes "^1.1.0" - js-stringify "^1.0.1" - pug-attrs "^2.0.4" - pug-error "^1.3.3" - pug-runtime "^2.0.5" - void-elements "^2.0.1" - with "^5.0.0" - -pug-error@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-1.3.3.tgz#f342fb008752d58034c185de03602dd9ffe15fa6" - integrity sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ== + js-stringify "^1.0.2" + pug-attrs "^3.0.0" + pug-error "^2.0.0" + pug-runtime "^3.0.0" + void-elements "^3.1.0" + with "^7.0.0" + +pug-error@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-2.0.0.tgz#5c62173cb09c34de2a2ce04f17b8adfec74d8ca5" + integrity sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ== -pug-filters@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-3.1.1.tgz#ab2cc82db9eeccf578bda89130e252a0db026aa7" - integrity sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg== +pug-filters@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-4.0.0.tgz#d3e49af5ba8472e9b7a66d980e707ce9d2cc9b5e" + integrity sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A== dependencies: - clean-css "^4.1.11" - constantinople "^3.0.1" + constantinople "^4.0.1" jstransformer "1.0.0" - pug-error "^1.3.3" - pug-walk "^1.1.8" - resolve "^1.1.6" - uglify-js "^2.6.1" + pug-error "^2.0.0" + pug-walk "^2.0.0" + resolve "^1.15.1" -pug-lexer@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-4.1.0.tgz#531cde48c7c0b1fcbbc2b85485c8665e31489cfd" - integrity sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA== +pug-lexer@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-5.0.1.tgz#ae44628c5bef9b190b665683b288ca9024b8b0d5" + integrity sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w== dependencies: - character-parser "^2.1.1" - is-expression "^3.0.0" - pug-error "^1.3.3" + character-parser "^2.2.0" + is-expression "^4.0.0" + pug-error "^2.0.0" -pug-linker@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-3.0.6.tgz#f5bf218b0efd65ce6670f7afc51658d0f82989fb" - integrity sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg== +pug-linker@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-4.0.0.tgz#12cbc0594fc5a3e06b9fc59e6f93c146962a7708" + integrity sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw== dependencies: - pug-error "^1.3.3" - pug-walk "^1.1.8" + pug-error "^2.0.0" + pug-walk "^2.0.0" -pug-load@^2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-2.0.12.tgz#d38c85eb85f6e2f704dea14dcca94144d35d3e7b" - integrity sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg== +pug-load@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-3.0.0.tgz#9fd9cda52202b08adb11d25681fb9f34bd41b662" + integrity sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ== dependencies: - object-assign "^4.1.0" - pug-walk "^1.1.8" + object-assign "^4.1.1" + pug-walk "^2.0.0" pug-loader@^2.4.0: version "2.4.0" @@ -7022,44 +7023,49 @@ pug-loader@^2.4.0: pug-walk "^1.0.0" resolve "^1.1.7" -pug-parser@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-5.0.1.tgz#03e7ada48b6840bd3822f867d7d90f842d0ffdc9" - integrity sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA== +pug-parser@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-6.0.0.tgz#a8fdc035863a95b2c1dc5ebf4ecf80b4e76a1260" + integrity sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw== dependencies: - pug-error "^1.3.3" - token-stream "0.0.1" + pug-error "^2.0.0" + token-stream "1.0.0" -pug-runtime@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.5.tgz#6da7976c36bf22f68e733c359240d8ae7a32953a" - integrity sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw== +pug-runtime@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-3.0.1.tgz#f636976204723f35a8c5f6fad6acda2a191b83d7" + integrity sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg== -pug-strip-comments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz#cc1b6de1f6e8f5931cf02ec66cdffd3f50eaf8a8" - integrity sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw== +pug-strip-comments@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz#f94b07fd6b495523330f490a7f554b4ff876303e" + integrity sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ== dependencies: - pug-error "^1.3.3" + pug-error "^2.0.0" -pug-walk@^1.0.0, pug-walk@^1.1.8: +pug-walk@^1.0.0: version "1.1.8" resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.8.tgz#b408f67f27912f8c21da2f45b7230c4bd2a5ea7a" integrity sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA== -pug@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.4.tgz#ee7682ec0a60494b38d48a88f05f3b0ac931377d" - integrity sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw== - dependencies: - pug-code-gen "^2.0.2" - pug-filters "^3.1.1" - pug-lexer "^4.1.0" - pug-linker "^3.0.6" - pug-load "^2.0.12" - pug-parser "^5.0.1" - pug-runtime "^2.0.5" - pug-strip-comments "^1.0.4" +pug-walk@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-2.0.0.tgz#417aabc29232bb4499b5b5069a2b2d2a24d5f5fe" + integrity sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ== + +pug@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/pug/-/pug-3.0.1.tgz#9b287554043e6d18852673a382b0350595bdc067" + integrity sha512-9v1o2yXMfSKJy2PykKyWUhpgx9Pf9D/UlPgIs2pTTxR6DQZ0oivy4I9f8PlWXRY4sjIhDU4TMJ7hQmYnNJc2bw== + dependencies: + pug-code-gen "^3.0.2" + pug-filters "^4.0.0" + pug-lexer "^5.0.0" + pug-linker "^4.0.0" + pug-load "^3.0.0" + pug-parser "^6.0.0" + pug-runtime "^3.0.0" + pug-strip-comments "^2.0.0" pump@^2.0.0: version "2.0.1" @@ -7296,11 +7302,6 @@ regenerate@^1.4.0: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - regenerator-runtime@^0.13.4: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" @@ -7392,7 +7393,7 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.5.2, repeat-string@^1.6.1: +repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -7480,7 +7481,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.18.1: +resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.18.1: version "1.19.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== @@ -7488,6 +7489,14 @@ resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.18. is-core-module "^2.1.0" path-parse "^1.0.6" +resolve@^1.15.1: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -7503,13 +7512,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8= - dependencies: - align-text "^0.1.1" - rimraf@2, rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" @@ -7808,9 +7810,9 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -"sn-stylekit@github:standardnotes/StyleKit#1ec13454cc6d8cf97651263a039de8872be527b8": - version "3.0.1" - resolved "https://codeload.github.com/standardnotes/StyleKit/tar.gz/1ec13454cc6d8cf97651263a039de8872be527b8" +"sn-stylekit@github:standardnotes/StyleKit#c64573b229ac9154e480cde3b5fdab78c75b3530": + version "4.0.2" + resolved "https://codeload.github.com/standardnotes/StyleKit/tar.gz/c64573b229ac9154e480cde3b5fdab78c75b3530" snapdragon-node@^2.0.1: version "2.1.1" @@ -7906,7 +7908,7 @@ source-map@^0.4.2: dependencies: amdefine ">=0.0.4" -source-map@^0.5.0, source-map@^0.5.6, source-map@~0.5.1: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -8336,11 +8338,6 @@ to-arraybuffer@^1.0.0: resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -8383,10 +8380,10 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== -token-stream@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a" - integrity sha1-zu78cXp2xDFvEm0LnbqlXX598Bo= +token-stream@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4" + integrity sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ= tough-cookie@~2.5.0: version "2.5.0" @@ -8429,6 +8426,11 @@ tslib@^2.0.0, tslib@^2.0.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== +tslib@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + tsutils@^3.17.1: version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" @@ -8496,21 +8498,6 @@ uglify-js@3.4.x: commander "~2.19.0" source-map "~0.6.1" -uglify-js@^2.6.1: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0= - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= - unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -8721,10 +8708,10 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -void-elements@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" - integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= +void-elements@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= warning@^4.0.3: version "4.0.3" @@ -8833,12 +8820,13 @@ webpack-log@^2.0.0: ansi-colors "^3.0.0" uuid "^3.3.2" -webpack-merge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" - integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== +webpack-merge@^5.7.3: + version "5.7.3" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.7.3.tgz#2a0754e1877a25a8bbab3d2475ca70a052708213" + integrity sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA== dependencies: - lodash "^4.17.15" + clone-deep "^4.0.1" + wildcard "^2.0.0" webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: version "1.4.3" @@ -8917,29 +8905,26 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== -with@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/with/-/with-5.1.1.tgz#fa4daa92daf32c4ea94ed453c81f04686b575dfe" - integrity sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4= +with@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" + integrity sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w== dependencies: - acorn "^3.1.0" - acorn-globals "^3.0.0" + "@babel/parser" "^7.9.6" + "@babel/types" "^7.9.6" + assert-never "^1.2.1" + babel-walk "3.0.0-canary-5" word-wrap@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8= - worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" @@ -9021,13 +9006,3 @@ yargs@^13.3.2: which-module "^2.0.0" y18n "^4.0.0" yargs-parser "^13.1.2" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E= - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0"