From 67f0739d3c97509e8e650edcb59b24066485d961 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 13 Nov 2020 17:09:28 +0000 Subject: [PATCH 01/11] Desktop: Allow customising application layout --- .eslintignore | 69 +- .eslintrc.js | 3 + .gitignore | 69 +- joplin.code-workspace | 1 + package.json | 1 - .../app-cli/tests/services_CommandService.ts | 3 +- .../plugins/content_script/api/Global.d.ts | 2 +- .../plugins/content_script/api/Joplin.d.ts | 2 +- .../content_script/api/JoplinCommands.d.ts | 32 +- .../content_script/api/JoplinData.d.ts | 2 +- .../content_script/api/JoplinInterop.d.ts | 2 +- .../content_script/api/JoplinPlugins.d.ts | 4 +- .../content_script/api/JoplinSettings.d.ts | 4 +- .../api/JoplinViewsDialogs.d.ts | 4 +- .../api/JoplinViewsMenuItems.d.ts | 4 +- .../content_script/api/JoplinViewsMenus.d.ts | 4 +- .../content_script/api/JoplinViewsPanels.d.ts | 11 +- .../api/JoplinViewsToolbarButtons.d.ts | 4 +- .../content_script/api/JoplinWorkspace.d.ts | 2 +- .../plugins/content_script/api/types.ts | 154 +- .../support/plugins/dialog/api/Global.d.ts | 2 +- .../support/plugins/dialog/api/Joplin.d.ts | 2 +- .../plugins/dialog/api/JoplinCommands.d.ts | 32 +- .../plugins/dialog/api/JoplinData.d.ts | 2 +- .../plugins/dialog/api/JoplinInterop.d.ts | 2 +- .../plugins/dialog/api/JoplinPlugins.d.ts | 4 +- .../plugins/dialog/api/JoplinSettings.d.ts | 4 +- .../dialog/api/JoplinViewsDialogs.d.ts | 4 +- .../dialog/api/JoplinViewsMenuItems.d.ts | 4 +- .../plugins/dialog/api/JoplinViewsMenus.d.ts | 4 +- .../plugins/dialog/api/JoplinViewsPanels.d.ts | 11 +- .../dialog/api/JoplinViewsToolbarButtons.d.ts | 4 +- .../plugins/dialog/api/JoplinWorkspace.d.ts | 2 +- .../tests/support/plugins/dialog/api/types.ts | 154 +- .../tests/support/plugins/dialog/src/index.ts | 4 +- .../support/plugins/events/api/Global.d.ts | 2 +- .../support/plugins/events/api/Joplin.d.ts | 2 +- .../plugins/events/api/JoplinCommands.d.ts | 32 +- .../plugins/events/api/JoplinData.d.ts | 2 +- .../plugins/events/api/JoplinInterop.d.ts | 2 +- .../plugins/events/api/JoplinPlugins.d.ts | 4 +- .../plugins/events/api/JoplinSettings.d.ts | 4 +- .../events/api/JoplinViewsDialogs.d.ts | 4 +- .../events/api/JoplinViewsMenuItems.d.ts | 4 +- .../plugins/events/api/JoplinViewsMenus.d.ts | 4 +- .../plugins/events/api/JoplinViewsPanels.d.ts | 11 +- .../events/api/JoplinViewsToolbarButtons.d.ts | 4 +- .../plugins/events/api/JoplinWorkspace.d.ts | 2 +- .../tests/support/plugins/events/api/types.ts | 154 +- .../plugins/json_export/api/Global.d.ts | 2 +- .../plugins/json_export/api/Joplin.d.ts | 2 +- .../json_export/api/JoplinCommands.d.ts | 32 +- .../plugins/json_export/api/JoplinData.d.ts | 2 +- .../json_export/api/JoplinInterop.d.ts | 2 +- .../json_export/api/JoplinPlugins.d.ts | 4 +- .../json_export/api/JoplinSettings.d.ts | 4 +- .../json_export/api/JoplinViewsDialogs.d.ts | 4 +- .../json_export/api/JoplinViewsMenuItems.d.ts | 4 +- .../json_export/api/JoplinViewsMenus.d.ts | 4 +- .../json_export/api/JoplinViewsPanels.d.ts | 11 +- .../api/JoplinViewsToolbarButtons.d.ts | 4 +- .../json_export/api/JoplinWorkspace.d.ts | 2 +- .../support/plugins/json_export/api/types.ts | 154 +- .../support/plugins/menu/api/Global.d.ts | 2 +- .../support/plugins/menu/api/Joplin.d.ts | 2 +- .../plugins/menu/api/JoplinCommands.d.ts | 36 +- .../support/plugins/menu/api/JoplinData.d.ts | 2 +- .../plugins/menu/api/JoplinInterop.d.ts | 2 +- .../plugins/menu/api/JoplinPlugins.d.ts | 18 +- .../plugins/menu/api/JoplinSettings.d.ts | 4 +- .../plugins/menu/api/JoplinViewsDialogs.d.ts | 4 +- .../menu/api/JoplinViewsMenuItems.d.ts | 4 +- .../plugins/menu/api/JoplinViewsMenus.d.ts | 4 +- .../plugins/menu/api/JoplinViewsPanels.d.ts | 11 +- .../menu/api/JoplinViewsToolbarButtons.d.ts | 4 +- .../plugins/menu/api/JoplinWorkspace.d.ts | 2 +- .../tests/support/plugins/menu/api/types.ts | 221 +- .../tests/support/plugins/menu/src/index.ts | 2 +- .../plugins/multi_selection/api/Global.d.ts | 2 +- .../plugins/multi_selection/api/Joplin.d.ts | 2 +- .../multi_selection/api/JoplinCommands.d.ts | 32 +- .../multi_selection/api/JoplinData.d.ts | 2 +- .../multi_selection/api/JoplinInterop.d.ts | 2 +- .../multi_selection/api/JoplinPlugins.d.ts | 4 +- .../multi_selection/api/JoplinSettings.d.ts | 4 +- .../api/JoplinViewsDialogs.d.ts | 4 +- .../api/JoplinViewsMenuItems.d.ts | 4 +- .../multi_selection/api/JoplinViewsMenus.d.ts | 4 +- .../api/JoplinViewsPanels.d.ts | 11 +- .../api/JoplinViewsToolbarButtons.d.ts | 4 +- .../multi_selection/api/JoplinWorkspace.d.ts | 2 +- .../plugins/multi_selection/api/types.ts | 154 +- .../plugins/register_command/api/Global.d.ts | 2 +- .../plugins/register_command/api/Joplin.d.ts | 2 +- .../register_command/api/JoplinCommands.d.ts | 32 +- .../register_command/api/JoplinData.d.ts | 2 +- .../register_command/api/JoplinInterop.d.ts | 2 +- .../register_command/api/JoplinPlugins.d.ts | 4 +- .../register_command/api/JoplinSettings.d.ts | 4 +- .../api/JoplinViewsDialogs.d.ts | 4 +- .../api/JoplinViewsMenuItems.d.ts | 4 +- .../api/JoplinViewsMenus.d.ts | 4 +- .../api/JoplinViewsPanels.d.ts | 11 +- .../api/JoplinViewsToolbarButtons.d.ts | 4 +- .../register_command/api/JoplinWorkspace.d.ts | 2 +- .../plugins/register_command/api/types.ts | 154 +- .../plugins/register_command/src/index.ts | 8 +- .../plugins/selected_text/api/Global.d.ts | 2 +- .../plugins/selected_text/api/Joplin.d.ts | 2 +- .../selected_text/api/JoplinCommands.d.ts | 32 +- .../plugins/selected_text/api/JoplinData.d.ts | 2 +- .../selected_text/api/JoplinInterop.d.ts | 2 +- .../selected_text/api/JoplinPlugins.d.ts | 4 +- .../selected_text/api/JoplinSettings.d.ts | 4 +- .../selected_text/api/JoplinViewsDialogs.d.ts | 4 +- .../api/JoplinViewsMenuItems.d.ts | 4 +- .../selected_text/api/JoplinViewsMenus.d.ts | 4 +- .../selected_text/api/JoplinViewsPanels.d.ts | 11 +- .../api/JoplinViewsToolbarButtons.d.ts | 4 +- .../selected_text/api/JoplinWorkspace.d.ts | 2 +- .../plugins/selected_text/api/types.ts | 154 +- .../support/plugins/settings/api/Global.d.ts | 2 +- .../support/plugins/settings/api/Joplin.d.ts | 2 +- .../plugins/settings/api/JoplinCommands.d.ts | 32 +- .../plugins/settings/api/JoplinData.d.ts | 2 +- .../plugins/settings/api/JoplinInterop.d.ts | 2 +- .../plugins/settings/api/JoplinPlugins.d.ts | 4 +- .../plugins/settings/api/JoplinSettings.d.ts | 4 +- .../settings/api/JoplinViewsDialogs.d.ts | 4 +- .../settings/api/JoplinViewsMenuItems.d.ts | 4 +- .../settings/api/JoplinViewsMenus.d.ts | 4 +- .../settings/api/JoplinViewsPanels.d.ts | 11 +- .../api/JoplinViewsToolbarButtons.d.ts | 4 +- .../plugins/settings/api/JoplinWorkspace.d.ts | 2 +- .../support/plugins/settings/api/types.ts | 154 +- .../tests/support/plugins/toc/api/Global.d.ts | 2 +- .../tests/support/plugins/toc/api/Joplin.d.ts | 2 +- .../plugins/toc/api/JoplinCommands.d.ts | 32 +- .../support/plugins/toc/api/JoplinData.d.ts | 2 +- .../plugins/toc/api/JoplinInterop.d.ts | 2 +- .../plugins/toc/api/JoplinPlugins.d.ts | 4 +- .../plugins/toc/api/JoplinSettings.d.ts | 4 +- .../plugins/toc/api/JoplinViewsDialogs.d.ts | 4 +- .../plugins/toc/api/JoplinViewsMenuItems.d.ts | 4 +- .../plugins/toc/api/JoplinViewsMenus.d.ts | 4 +- .../plugins/toc/api/JoplinViewsPanels.d.ts | 11 +- .../toc/api/JoplinViewsToolbarButtons.d.ts | 4 +- .../plugins/toc/api/JoplinWorkspace.d.ts | 2 +- .../tests/support/plugins/toc/api/types.ts | 154 +- .../tests/support/plugins/toc/src/index.ts | 2 +- .../tests/support/plugins/updatePlugins.sh | 1 + .../withExternalModules/api/Global.d.ts | 2 +- .../withExternalModules/api/Joplin.d.ts | 2 +- .../api/JoplinCommands.d.ts | 32 +- .../withExternalModules/api/JoplinData.d.ts | 2 +- .../api/JoplinInterop.d.ts | 2 +- .../api/JoplinPlugins.d.ts | 4 +- .../api/JoplinSettings.d.ts | 4 +- .../api/JoplinViewsDialogs.d.ts | 4 +- .../api/JoplinViewsMenuItems.d.ts | 4 +- .../api/JoplinViewsMenus.d.ts | 4 +- .../api/JoplinViewsPanels.d.ts | 11 +- .../api/JoplinViewsToolbarButtons.d.ts | 4 +- .../api/JoplinWorkspace.d.ts | 2 +- .../plugins/withExternalModules/api/types.ts | 154 +- packages/app-desktop/app.ts | 114 +- packages/app-desktop/gui/Button/Button.tsx | 26 +- .../app-desktop/gui/MainScreen/MainScreen.tsx | 390 +- .../commands/toggleLayoutMoveMode.ts | 20 + .../gui/MainScreen/commands/toggleNoteList.ts | 20 +- .../gui/MainScreen/commands/toggleSideBar.ts | 20 +- packages/app-desktop/gui/MenuBar.tsx | 4 +- .../NoteBody/CodeMirror/Toolbar.tsx | 2 +- .../app-desktop/gui/NoteEditor/NoteEditor.tsx | 2 +- .../gui/NoteListControls/NoteListControls.tsx | 5 +- .../gui/NoteListWrapper/NoteListWrapper.tsx | 39 + .../gui/NoteToolbar/NoteToolbar.tsx | 2 +- .../gui/ResizableLayout/MoveButtons.tsx | 80 + .../gui/ResizableLayout/ResizableLayout.tsx | 212 +- .../hooks/useLayoutItemSizes.ts | 83 - .../ResizableLayout/utils/findItemByKey.ts | 23 + .../ResizableLayout/utils/isTempContainer.ts | 5 + .../gui/ResizableLayout/utils/iterateItems.ts | 21 + .../ResizableLayout/utils/layoutItemProp.ts | 8 + .../ResizableLayout/utils/movements.test.ts | 228 + .../gui/ResizableLayout/utils/movements.ts | 190 + .../gui/ResizableLayout/utils/persist.test.ts | 77 + .../gui/ResizableLayout/utils/persist.ts | 41 + .../gui/ResizableLayout/utils/removeItem.ts | 18 + .../utils/setLayoutItemProps.ts | 23 + .../gui/ResizableLayout/utils/style.ts | 38 + .../gui/ResizableLayout/utils/types.ts | 26 + .../utils/useLayoutItemSizes.test.ts | 89 + .../utils/useLayoutItemSizes.ts | 95 + .../{hooks => utils}/useWindowResizeEvent.ts | 0 .../ResizableLayout/utils/validateLayout.ts | 103 + packages/app-desktop/gui/Root.tsx | 16 +- packages/app-desktop/gui/SideBar/SideBar.tsx | 2 - .../SideBar/commands/focusElementSideBar.ts | 8 +- packages/app-desktop/gui/menuCommandNames.ts | 1 + packages/app-desktop/jest.config.js | 191 + packages/app-desktop/package-lock.json | 4539 ++++++++++++++++- packages/app-desktop/package.json | 10 +- .../commands/stateToWhenClauseContext.ts | 23 + packages/app-desktop/testPluginDemo.sh | 2 +- packages/lib/.gitignore | 1 + packages/lib/models/Setting.ts | 5 - packages/lib/package.json | 3 +- packages/lib/services/CommandService.ts | 7 +- .../commands/stateToWhenClauseContext.ts | 13 +- packages/lib/services/plugins/Plugin.ts | 10 +- .../lib/services/plugins/PluginService.ts | 17 + .../lib/services/plugins/WebviewController.ts | 8 +- .../lib/services/plugins/api/JoplinPlugins.ts | 2 +- .../lib/services/plugins/api/JoplinUtils.js | 11 - .../plugins/api/JoplinViewsDialogs.ts | 12 +- .../plugins/api/JoplinViewsMenuItems.ts | 12 +- .../services/plugins/api/JoplinViewsMenus.ts | 12 +- .../services/plugins/api/JoplinViewsPanels.ts | 20 +- .../plugins/api/JoplinViewsToolbarButtons.ts | 11 +- packages/lib/services/plugins/reducer.ts | 42 +- .../plugins/utils/createViewHandle.ts | 6 +- 222 files changed, 7967 insertions(+), 1810 deletions(-) create mode 100644 packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.ts create mode 100644 packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.tsx create mode 100644 packages/app-desktop/gui/ResizableLayout/MoveButtons.tsx delete mode 100644 packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/findItemByKey.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/isTempContainer.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/iterateItems.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/layoutItemProp.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/movements.test.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/movements.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/persist.test.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/persist.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/removeItem.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/setLayoutItemProps.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/style.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/types.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.ts rename packages/app-desktop/gui/ResizableLayout/{hooks => utils}/useWindowResizeEvent.ts (100%) create mode 100644 packages/app-desktop/gui/ResizableLayout/utils/validateLayout.ts create mode 100644 packages/app-desktop/jest.config.js create mode 100644 packages/app-desktop/services/commands/stateToWhenClauseContext.ts create mode 100644 packages/lib/.gitignore delete mode 100644 packages/lib/services/plugins/api/JoplinUtils.js diff --git a/.eslintignore b/.eslintignore index 566b64755b..5544ec6d35 100644 --- a/.eslintignore +++ b/.eslintignore @@ -433,6 +433,9 @@ packages/app-desktop/gui/MainScreen/commands/showSpellCheckerMenu.js.map packages/app-desktop/gui/MainScreen/commands/toggleEditors.d.ts packages/app-desktop/gui/MainScreen/commands/toggleEditors.js packages/app-desktop/gui/MainScreen/commands/toggleEditors.js.map +packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.d.ts +packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.js +packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.js.map packages/app-desktop/gui/MainScreen/commands/toggleNoteList.d.ts packages/app-desktop/gui/MainScreen/commands/toggleNoteList.js packages/app-desktop/gui/MainScreen/commands/toggleNoteList.js.map @@ -580,6 +583,9 @@ packages/app-desktop/gui/NoteListControls/commands/focusSearch.js.map packages/app-desktop/gui/NoteListItem.d.ts packages/app-desktop/gui/NoteListItem.js packages/app-desktop/gui/NoteListItem.js.map +packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.d.ts +packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.js +packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.js.map packages/app-desktop/gui/NoteTextViewer.d.ts packages/app-desktop/gui/NoteTextViewer.js packages/app-desktop/gui/NoteTextViewer.js.map @@ -589,15 +595,60 @@ packages/app-desktop/gui/NoteToolbar/NoteToolbar.js.map packages/app-desktop/gui/OneDriveLoginScreen.d.ts packages/app-desktop/gui/OneDriveLoginScreen.js packages/app-desktop/gui/OneDriveLoginScreen.js.map +packages/app-desktop/gui/ResizableLayout/MoveButtons.d.ts +packages/app-desktop/gui/ResizableLayout/MoveButtons.js +packages/app-desktop/gui/ResizableLayout/MoveButtons.js.map packages/app-desktop/gui/ResizableLayout/ResizableLayout.d.ts packages/app-desktop/gui/ResizableLayout/ResizableLayout.js packages/app-desktop/gui/ResizableLayout/ResizableLayout.js.map -packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.d.ts -packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.js -packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.js.map -packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.d.ts -packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.js -packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.js.map +packages/app-desktop/gui/ResizableLayout/utils/findItemByKey.d.ts +packages/app-desktop/gui/ResizableLayout/utils/findItemByKey.js +packages/app-desktop/gui/ResizableLayout/utils/findItemByKey.js.map +packages/app-desktop/gui/ResizableLayout/utils/isTempContainer.d.ts +packages/app-desktop/gui/ResizableLayout/utils/isTempContainer.js +packages/app-desktop/gui/ResizableLayout/utils/isTempContainer.js.map +packages/app-desktop/gui/ResizableLayout/utils/iterateItems.d.ts +packages/app-desktop/gui/ResizableLayout/utils/iterateItems.js +packages/app-desktop/gui/ResizableLayout/utils/iterateItems.js.map +packages/app-desktop/gui/ResizableLayout/utils/layoutItemProp.d.ts +packages/app-desktop/gui/ResizableLayout/utils/layoutItemProp.js +packages/app-desktop/gui/ResizableLayout/utils/layoutItemProp.js.map +packages/app-desktop/gui/ResizableLayout/utils/movements.d.ts +packages/app-desktop/gui/ResizableLayout/utils/movements.js +packages/app-desktop/gui/ResizableLayout/utils/movements.js.map +packages/app-desktop/gui/ResizableLayout/utils/movements.test.d.ts +packages/app-desktop/gui/ResizableLayout/utils/movements.test.js +packages/app-desktop/gui/ResizableLayout/utils/movements.test.js.map +packages/app-desktop/gui/ResizableLayout/utils/persist.d.ts +packages/app-desktop/gui/ResizableLayout/utils/persist.js +packages/app-desktop/gui/ResizableLayout/utils/persist.js.map +packages/app-desktop/gui/ResizableLayout/utils/persist.test.d.ts +packages/app-desktop/gui/ResizableLayout/utils/persist.test.js +packages/app-desktop/gui/ResizableLayout/utils/persist.test.js.map +packages/app-desktop/gui/ResizableLayout/utils/removeItem.d.ts +packages/app-desktop/gui/ResizableLayout/utils/removeItem.js +packages/app-desktop/gui/ResizableLayout/utils/removeItem.js.map +packages/app-desktop/gui/ResizableLayout/utils/setLayoutItemProps.d.ts +packages/app-desktop/gui/ResizableLayout/utils/setLayoutItemProps.js +packages/app-desktop/gui/ResizableLayout/utils/setLayoutItemProps.js.map +packages/app-desktop/gui/ResizableLayout/utils/style.d.ts +packages/app-desktop/gui/ResizableLayout/utils/style.js +packages/app-desktop/gui/ResizableLayout/utils/style.js.map +packages/app-desktop/gui/ResizableLayout/utils/types.d.ts +packages/app-desktop/gui/ResizableLayout/utils/types.js +packages/app-desktop/gui/ResizableLayout/utils/types.js.map +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.d.ts +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.js +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.js.map +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.d.ts +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.js +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.js.map +packages/app-desktop/gui/ResizableLayout/utils/useWindowResizeEvent.d.ts +packages/app-desktop/gui/ResizableLayout/utils/useWindowResizeEvent.js +packages/app-desktop/gui/ResizableLayout/utils/useWindowResizeEvent.js.map +packages/app-desktop/gui/ResizableLayout/utils/validateLayout.d.ts +packages/app-desktop/gui/ResizableLayout/utils/validateLayout.js +packages/app-desktop/gui/ResizableLayout/utils/validateLayout.js.map packages/app-desktop/gui/ResourceScreen.d.ts packages/app-desktop/gui/ResourceScreen.js packages/app-desktop/gui/ResourceScreen.js.map @@ -676,6 +727,9 @@ packages/app-desktop/plugins/GotoAnything.js.map packages/app-desktop/services/bridge.d.ts packages/app-desktop/services/bridge.js packages/app-desktop/services/bridge.js.map +packages/app-desktop/services/commands/stateToWhenClauseContext.d.ts +packages/app-desktop/services/commands/stateToWhenClauseContext.js +packages/app-desktop/services/commands/stateToWhenClauseContext.js.map packages/app-desktop/services/commands/types.d.ts packages/app-desktop/services/commands/types.js packages/app-desktop/services/commands/types.js.map @@ -1144,9 +1198,6 @@ packages/lib/services/rest/utils/requestFields.js.map packages/lib/services/rest/utils/requestPaginationOptions.d.ts packages/lib/services/rest/utils/requestPaginationOptions.js packages/lib/services/rest/utils/requestPaginationOptions.js.map -packages/lib/services/rest/utils/types.d.ts -packages/lib/services/rest/utils/types.js -packages/lib/services/rest/utils/types.js.map packages/lib/services/searchengine/filterParser.d.ts packages/lib/services/searchengine/filterParser.js packages/lib/services/searchengine/filterParser.js.map diff --git a/.eslintrc.js b/.eslintrc.js index 71b84d8da5..3094918b24 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -25,6 +25,9 @@ module.exports = { 'afterEach': 'readonly', 'jasmine': 'readonly', + // Jest variables + 'test': 'readonly', + // React Native variables '__DEV__': 'readonly', diff --git a/.gitignore b/.gitignore index 255a0df49c..ce533605be 100644 --- a/.gitignore +++ b/.gitignore @@ -425,6 +425,9 @@ packages/app-desktop/gui/MainScreen/commands/showSpellCheckerMenu.js.map packages/app-desktop/gui/MainScreen/commands/toggleEditors.d.ts packages/app-desktop/gui/MainScreen/commands/toggleEditors.js packages/app-desktop/gui/MainScreen/commands/toggleEditors.js.map +packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.d.ts +packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.js +packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.js.map packages/app-desktop/gui/MainScreen/commands/toggleNoteList.d.ts packages/app-desktop/gui/MainScreen/commands/toggleNoteList.js packages/app-desktop/gui/MainScreen/commands/toggleNoteList.js.map @@ -572,6 +575,9 @@ packages/app-desktop/gui/NoteListControls/commands/focusSearch.js.map packages/app-desktop/gui/NoteListItem.d.ts packages/app-desktop/gui/NoteListItem.js packages/app-desktop/gui/NoteListItem.js.map +packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.d.ts +packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.js +packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.js.map packages/app-desktop/gui/NoteTextViewer.d.ts packages/app-desktop/gui/NoteTextViewer.js packages/app-desktop/gui/NoteTextViewer.js.map @@ -581,15 +587,60 @@ packages/app-desktop/gui/NoteToolbar/NoteToolbar.js.map packages/app-desktop/gui/OneDriveLoginScreen.d.ts packages/app-desktop/gui/OneDriveLoginScreen.js packages/app-desktop/gui/OneDriveLoginScreen.js.map +packages/app-desktop/gui/ResizableLayout/MoveButtons.d.ts +packages/app-desktop/gui/ResizableLayout/MoveButtons.js +packages/app-desktop/gui/ResizableLayout/MoveButtons.js.map packages/app-desktop/gui/ResizableLayout/ResizableLayout.d.ts packages/app-desktop/gui/ResizableLayout/ResizableLayout.js packages/app-desktop/gui/ResizableLayout/ResizableLayout.js.map -packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.d.ts -packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.js -packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.js.map -packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.d.ts -packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.js -packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.js.map +packages/app-desktop/gui/ResizableLayout/utils/findItemByKey.d.ts +packages/app-desktop/gui/ResizableLayout/utils/findItemByKey.js +packages/app-desktop/gui/ResizableLayout/utils/findItemByKey.js.map +packages/app-desktop/gui/ResizableLayout/utils/isTempContainer.d.ts +packages/app-desktop/gui/ResizableLayout/utils/isTempContainer.js +packages/app-desktop/gui/ResizableLayout/utils/isTempContainer.js.map +packages/app-desktop/gui/ResizableLayout/utils/iterateItems.d.ts +packages/app-desktop/gui/ResizableLayout/utils/iterateItems.js +packages/app-desktop/gui/ResizableLayout/utils/iterateItems.js.map +packages/app-desktop/gui/ResizableLayout/utils/layoutItemProp.d.ts +packages/app-desktop/gui/ResizableLayout/utils/layoutItemProp.js +packages/app-desktop/gui/ResizableLayout/utils/layoutItemProp.js.map +packages/app-desktop/gui/ResizableLayout/utils/movements.d.ts +packages/app-desktop/gui/ResizableLayout/utils/movements.js +packages/app-desktop/gui/ResizableLayout/utils/movements.js.map +packages/app-desktop/gui/ResizableLayout/utils/movements.test.d.ts +packages/app-desktop/gui/ResizableLayout/utils/movements.test.js +packages/app-desktop/gui/ResizableLayout/utils/movements.test.js.map +packages/app-desktop/gui/ResizableLayout/utils/persist.d.ts +packages/app-desktop/gui/ResizableLayout/utils/persist.js +packages/app-desktop/gui/ResizableLayout/utils/persist.js.map +packages/app-desktop/gui/ResizableLayout/utils/persist.test.d.ts +packages/app-desktop/gui/ResizableLayout/utils/persist.test.js +packages/app-desktop/gui/ResizableLayout/utils/persist.test.js.map +packages/app-desktop/gui/ResizableLayout/utils/removeItem.d.ts +packages/app-desktop/gui/ResizableLayout/utils/removeItem.js +packages/app-desktop/gui/ResizableLayout/utils/removeItem.js.map +packages/app-desktop/gui/ResizableLayout/utils/setLayoutItemProps.d.ts +packages/app-desktop/gui/ResizableLayout/utils/setLayoutItemProps.js +packages/app-desktop/gui/ResizableLayout/utils/setLayoutItemProps.js.map +packages/app-desktop/gui/ResizableLayout/utils/style.d.ts +packages/app-desktop/gui/ResizableLayout/utils/style.js +packages/app-desktop/gui/ResizableLayout/utils/style.js.map +packages/app-desktop/gui/ResizableLayout/utils/types.d.ts +packages/app-desktop/gui/ResizableLayout/utils/types.js +packages/app-desktop/gui/ResizableLayout/utils/types.js.map +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.d.ts +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.js +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.js.map +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.d.ts +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.js +packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.js.map +packages/app-desktop/gui/ResizableLayout/utils/useWindowResizeEvent.d.ts +packages/app-desktop/gui/ResizableLayout/utils/useWindowResizeEvent.js +packages/app-desktop/gui/ResizableLayout/utils/useWindowResizeEvent.js.map +packages/app-desktop/gui/ResizableLayout/utils/validateLayout.d.ts +packages/app-desktop/gui/ResizableLayout/utils/validateLayout.js +packages/app-desktop/gui/ResizableLayout/utils/validateLayout.js.map packages/app-desktop/gui/ResourceScreen.d.ts packages/app-desktop/gui/ResourceScreen.js packages/app-desktop/gui/ResourceScreen.js.map @@ -668,6 +719,9 @@ packages/app-desktop/plugins/GotoAnything.js.map packages/app-desktop/services/bridge.d.ts packages/app-desktop/services/bridge.js packages/app-desktop/services/bridge.js.map +packages/app-desktop/services/commands/stateToWhenClauseContext.d.ts +packages/app-desktop/services/commands/stateToWhenClauseContext.js +packages/app-desktop/services/commands/stateToWhenClauseContext.js.map packages/app-desktop/services/commands/types.d.ts packages/app-desktop/services/commands/types.js packages/app-desktop/services/commands/types.js.map @@ -1136,9 +1190,6 @@ packages/lib/services/rest/utils/requestFields.js.map packages/lib/services/rest/utils/requestPaginationOptions.d.ts packages/lib/services/rest/utils/requestPaginationOptions.js packages/lib/services/rest/utils/requestPaginationOptions.js.map -packages/lib/services/rest/utils/types.d.ts -packages/lib/services/rest/utils/types.js -packages/lib/services/rest/utils/types.js.map packages/lib/services/searchengine/filterParser.d.ts packages/lib/services/searchengine/filterParser.js packages/lib/services/searchengine/filterParser.js.map diff --git a/joplin.code-workspace b/joplin.code-workspace index bf09fcce86..a1724691dc 100644 --- a/joplin.code-workspace +++ b/joplin.code-workspace @@ -8,6 +8,7 @@ "files.exclude": { "lerna-debug.log": true, "_mydocs/mdtest/": true, + "./packages/lib/plugin_types": true, "_releases/": true, "_vieux/": true, ".gitignore": true, diff --git a/package.json b/package.json index c55a42bd2e..2f57a0a9d3 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "buildWebsite": "npm run buildApiDoc && node ./packages/tools/build-website.js && npm run buildPluginDoc", "clean": "lerna clean -y && lerna run clean", "generateDatabaseTypes": "node packages/tools/generate-database-types", - "generatePluginTypes": "rm -rf ./plugin_types && node node_modules/typescript/bin/tsc --declaration --declarationDir ./plugin_types --project tsconfig.json", "linkChecker": "linkchecker https://joplinapp.org", "linter-ci": "./node_modules/.bin/eslint --resolve-plugins-relative-to . --quiet --ext .js --ext .jsx --ext .ts --ext .tsx", "linter-precommit": "./node_modules/.bin/eslint --resolve-plugins-relative-to . --fix --ext .js --ext .jsx --ext .ts --ext .tsx", diff --git a/packages/app-cli/tests/services_CommandService.ts b/packages/app-cli/tests/services_CommandService.ts index 0453fea14f..b723c38e89 100644 --- a/packages/app-cli/tests/services_CommandService.ts +++ b/packages/app-cli/tests/services_CommandService.ts @@ -1,6 +1,7 @@ import MenuUtils from '@joplin/lib/services/commands/MenuUtils'; import ToolbarButtonUtils from '@joplin/lib/services/commands/ToolbarButtonUtils'; import CommandService, { CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService'; +import stateToWhenClauseContext from '@joplin/lib/services/commands/stateToWhenClauseContext'; import KeymapService from '@joplin/lib/services/KeymapService'; const { asyncTest, setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow } = require('./test-utils.js'); @@ -17,7 +18,7 @@ function newService(): CommandService { return {}; }, }; - service.initialize(mockStore, true); + service.initialize(mockStore, true, stateToWhenClauseContext); return service; } diff --git a/packages/app-cli/tests/support/plugins/content_script/api/Global.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/content_script/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinCommands.d.ts index 0dc680e3b3..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinPlugins.d.ts index 4b7d0c72ec..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinPlugins.d.ts @@ -1,5 +1,5 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. @@ -28,7 +28,7 @@ export default class JoplinPlugins { * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/content_script) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) * * @param type Defines how the script will be used. See the type definition for more information about each supported type. * @param id A unique ID for the content script. diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/content_script/api/types.ts b/packages/app-cli/tests/support/plugins/content_script/api/types.ts index a0636920c1..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/types.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/types.ts @@ -6,7 +6,7 @@ export interface Command { /** * Name of command - must be globally unique */ - name: string + name: string; /** * Label to be displayed on menu items or keyboard shortcut editor for example. @@ -14,17 +14,17 @@ export interface Command { * In that case the command will not appear in the shortcut editor or command panel, and logically * should not be used as a menu item. */ - label?: string + label?: string; /** * Icon to be used on toolbar buttons for example */ - iconName?: string, + iconName?: string; /** * Code to be ran when the command is executed. It may return a result. */ - execute(...args:any[]):Promise + execute(...args: any[]): Promise; /** * Defines whether the command should be enabled or disabled, which in turns affects @@ -40,13 +40,11 @@ export interface Command { * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" * And | && | "oneNoteSelected && !inConflictFolder" * - * Currently the supported context variables aren't documented, but you can find the list there: - * - * https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/services/commands/stateToWhenClauseContext.ts + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). * * Note: Commands are enabled by default unless you use this property. */ - enabledCondition?: string + enabledCondition?: string; } // ================================================================= @@ -64,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -74,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -188,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -196,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -214,22 +212,22 @@ export interface MenuItem { * Command that should be associated with the menu item. All menu item should * have a command associated with them unless they are a sub-menu. */ - commandName?: string, + commandName?: string; /** * Accelerator associated with the menu item */ - accelerator?: string, + accelerator?: string; /** * Menu items that should appear below this menu item. Allows creating a menu tree. */ - submenu?: MenuItem[], + submenu?: MenuItem[]; /** * Menu item label. If not specified, the command label will be used instead. */ - label?: string, + label?: string; } // ================================================================= @@ -237,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -279,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -322,36 +320,30 @@ export type Path = string[]; export enum ContentScriptType { /** - * Registers a new Markdown-It plugin, which should follow this template: + * Registers a new Markdown-It plugin, which should follow the template below. * * ```javascript - * // The module should export an object as below: - * * module.exports = { - * - * // The "context" variable is currently unused but could be used later on to provide - * // access to your own plugin so that the content script and plugin can communicate. * default: function(context) { * return { - * - * // This is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information - * // The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml.ts), which - * // contains a number of options, mostly useful for Joplin's internal code. * plugin: function(markdownIt, options) { * // ... * }, - * - * // You may also specify additional assets such as JS or CSS that should be loaded in the rendered HTML document. - * // Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to - * // see how the data should be structured. - * assets: {}, + * assets: { + * // ... + * }, * } * } * } * ``` * - * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific feature, you - * would simply create a file such as this: + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: * * ```javascript * module.exports = { diff --git a/packages/app-cli/tests/support/plugins/dialog/api/Global.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/dialog/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinCommands.d.ts index 0dc680e3b3..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinPlugins.d.ts index 4b7d0c72ec..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinPlugins.d.ts @@ -1,5 +1,5 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. @@ -28,7 +28,7 @@ export default class JoplinPlugins { * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/content_script) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) * * @param type Defines how the script will be used. See the type definition for more information about each supported type. * @param id A unique ID for the content script. diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/dialog/api/types.ts b/packages/app-cli/tests/support/plugins/dialog/api/types.ts index a0636920c1..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/types.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/types.ts @@ -6,7 +6,7 @@ export interface Command { /** * Name of command - must be globally unique */ - name: string + name: string; /** * Label to be displayed on menu items or keyboard shortcut editor for example. @@ -14,17 +14,17 @@ export interface Command { * In that case the command will not appear in the shortcut editor or command panel, and logically * should not be used as a menu item. */ - label?: string + label?: string; /** * Icon to be used on toolbar buttons for example */ - iconName?: string, + iconName?: string; /** * Code to be ran when the command is executed. It may return a result. */ - execute(...args:any[]):Promise + execute(...args: any[]): Promise; /** * Defines whether the command should be enabled or disabled, which in turns affects @@ -40,13 +40,11 @@ export interface Command { * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" * And | && | "oneNoteSelected && !inConflictFolder" * - * Currently the supported context variables aren't documented, but you can find the list there: - * - * https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/services/commands/stateToWhenClauseContext.ts + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). * * Note: Commands are enabled by default unless you use this property. */ - enabledCondition?: string + enabledCondition?: string; } // ================================================================= @@ -64,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -74,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -188,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -196,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -214,22 +212,22 @@ export interface MenuItem { * Command that should be associated with the menu item. All menu item should * have a command associated with them unless they are a sub-menu. */ - commandName?: string, + commandName?: string; /** * Accelerator associated with the menu item */ - accelerator?: string, + accelerator?: string; /** * Menu items that should appear below this menu item. Allows creating a menu tree. */ - submenu?: MenuItem[], + submenu?: MenuItem[]; /** * Menu item label. If not specified, the command label will be used instead. */ - label?: string, + label?: string; } // ================================================================= @@ -237,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -279,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -322,36 +320,30 @@ export type Path = string[]; export enum ContentScriptType { /** - * Registers a new Markdown-It plugin, which should follow this template: + * Registers a new Markdown-It plugin, which should follow the template below. * * ```javascript - * // The module should export an object as below: - * * module.exports = { - * - * // The "context" variable is currently unused but could be used later on to provide - * // access to your own plugin so that the content script and plugin can communicate. * default: function(context) { * return { - * - * // This is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information - * // The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml.ts), which - * // contains a number of options, mostly useful for Joplin's internal code. * plugin: function(markdownIt, options) { * // ... * }, - * - * // You may also specify additional assets such as JS or CSS that should be loaded in the rendered HTML document. - * // Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to - * // see how the data should be structured. - * assets: {}, + * assets: { + * // ... + * }, * } * } * } * ``` * - * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific feature, you - * would simply create a file such as this: + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: * * ```javascript * module.exports = { diff --git a/packages/app-cli/tests/support/plugins/dialog/src/index.ts b/packages/app-cli/tests/support/plugins/dialog/src/index.ts index 6ee5b1db5a..814d25716a 100644 --- a/packages/app-cli/tests/support/plugins/dialog/src/index.ts +++ b/packages/app-cli/tests/support/plugins/dialog/src/index.ts @@ -4,12 +4,12 @@ joplin.plugins.register({ onStart: async function() { const dialogs = joplin.views.dialogs; - const handle = await dialogs.create(); + const handle = await dialogs.create('myDialog1'); await dialogs.setHtml(handle, '

Testing dialog with default buttons

Second line

Third line

'); const result = await dialogs.open(handle); alert('This button was clicked: ' + result); - const handle2 = await dialogs.create(); + const handle2 = await dialogs.create('myDialog2'); await dialogs.setHtml(handle2, '

Testing dialog with custom buttons

Second line

Third line

'); await dialogs.setButtons(handle2, [ { diff --git a/packages/app-cli/tests/support/plugins/events/api/Global.d.ts b/packages/app-cli/tests/support/plugins/events/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/events/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/events/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/events/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/events/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinCommands.d.ts index 0dc680e3b3..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinPlugins.d.ts index 4b7d0c72ec..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinPlugins.d.ts @@ -1,5 +1,5 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. @@ -28,7 +28,7 @@ export default class JoplinPlugins { * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/content_script) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) * * @param type Defines how the script will be used. See the type definition for more information about each supported type. * @param id A unique ID for the content script. diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/events/api/types.ts b/packages/app-cli/tests/support/plugins/events/api/types.ts index a0636920c1..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/events/api/types.ts +++ b/packages/app-cli/tests/support/plugins/events/api/types.ts @@ -6,7 +6,7 @@ export interface Command { /** * Name of command - must be globally unique */ - name: string + name: string; /** * Label to be displayed on menu items or keyboard shortcut editor for example. @@ -14,17 +14,17 @@ export interface Command { * In that case the command will not appear in the shortcut editor or command panel, and logically * should not be used as a menu item. */ - label?: string + label?: string; /** * Icon to be used on toolbar buttons for example */ - iconName?: string, + iconName?: string; /** * Code to be ran when the command is executed. It may return a result. */ - execute(...args:any[]):Promise + execute(...args: any[]): Promise; /** * Defines whether the command should be enabled or disabled, which in turns affects @@ -40,13 +40,11 @@ export interface Command { * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" * And | && | "oneNoteSelected && !inConflictFolder" * - * Currently the supported context variables aren't documented, but you can find the list there: - * - * https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/services/commands/stateToWhenClauseContext.ts + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). * * Note: Commands are enabled by default unless you use this property. */ - enabledCondition?: string + enabledCondition?: string; } // ================================================================= @@ -64,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -74,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -188,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -196,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -214,22 +212,22 @@ export interface MenuItem { * Command that should be associated with the menu item. All menu item should * have a command associated with them unless they are a sub-menu. */ - commandName?: string, + commandName?: string; /** * Accelerator associated with the menu item */ - accelerator?: string, + accelerator?: string; /** * Menu items that should appear below this menu item. Allows creating a menu tree. */ - submenu?: MenuItem[], + submenu?: MenuItem[]; /** * Menu item label. If not specified, the command label will be used instead. */ - label?: string, + label?: string; } // ================================================================= @@ -237,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -279,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -322,36 +320,30 @@ export type Path = string[]; export enum ContentScriptType { /** - * Registers a new Markdown-It plugin, which should follow this template: + * Registers a new Markdown-It plugin, which should follow the template below. * * ```javascript - * // The module should export an object as below: - * * module.exports = { - * - * // The "context" variable is currently unused but could be used later on to provide - * // access to your own plugin so that the content script and plugin can communicate. * default: function(context) { * return { - * - * // This is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information - * // The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml.ts), which - * // contains a number of options, mostly useful for Joplin's internal code. * plugin: function(markdownIt, options) { * // ... * }, - * - * // You may also specify additional assets such as JS or CSS that should be loaded in the rendered HTML document. - * // Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to - * // see how the data should be structured. - * assets: {}, + * assets: { + * // ... + * }, * } * } * } * ``` * - * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific feature, you - * would simply create a file such as this: + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: * * ```javascript * module.exports = { diff --git a/packages/app-cli/tests/support/plugins/json_export/api/Global.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/json_export/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinCommands.d.ts index 0dc680e3b3..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinPlugins.d.ts index 4b7d0c72ec..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinPlugins.d.ts @@ -1,5 +1,5 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. @@ -28,7 +28,7 @@ export default class JoplinPlugins { * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/content_script) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) * * @param type Defines how the script will be used. See the type definition for more information about each supported type. * @param id A unique ID for the content script. diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/json_export/api/types.ts b/packages/app-cli/tests/support/plugins/json_export/api/types.ts index a0636920c1..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/types.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/types.ts @@ -6,7 +6,7 @@ export interface Command { /** * Name of command - must be globally unique */ - name: string + name: string; /** * Label to be displayed on menu items or keyboard shortcut editor for example. @@ -14,17 +14,17 @@ export interface Command { * In that case the command will not appear in the shortcut editor or command panel, and logically * should not be used as a menu item. */ - label?: string + label?: string; /** * Icon to be used on toolbar buttons for example */ - iconName?: string, + iconName?: string; /** * Code to be ran when the command is executed. It may return a result. */ - execute(...args:any[]):Promise + execute(...args: any[]): Promise; /** * Defines whether the command should be enabled or disabled, which in turns affects @@ -40,13 +40,11 @@ export interface Command { * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" * And | && | "oneNoteSelected && !inConflictFolder" * - * Currently the supported context variables aren't documented, but you can find the list there: - * - * https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/services/commands/stateToWhenClauseContext.ts + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). * * Note: Commands are enabled by default unless you use this property. */ - enabledCondition?: string + enabledCondition?: string; } // ================================================================= @@ -64,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -74,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -188,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -196,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -214,22 +212,22 @@ export interface MenuItem { * Command that should be associated with the menu item. All menu item should * have a command associated with them unless they are a sub-menu. */ - commandName?: string, + commandName?: string; /** * Accelerator associated with the menu item */ - accelerator?: string, + accelerator?: string; /** * Menu items that should appear below this menu item. Allows creating a menu tree. */ - submenu?: MenuItem[], + submenu?: MenuItem[]; /** * Menu item label. If not specified, the command label will be used instead. */ - label?: string, + label?: string; } // ================================================================= @@ -237,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -279,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -322,36 +320,30 @@ export type Path = string[]; export enum ContentScriptType { /** - * Registers a new Markdown-It plugin, which should follow this template: + * Registers a new Markdown-It plugin, which should follow the template below. * * ```javascript - * // The module should export an object as below: - * * module.exports = { - * - * // The "context" variable is currently unused but could be used later on to provide - * // access to your own plugin so that the content script and plugin can communicate. * default: function(context) { * return { - * - * // This is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information - * // The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml.ts), which - * // contains a number of options, mostly useful for Joplin's internal code. * plugin: function(markdownIt, options) { * // ... * }, - * - * // You may also specify additional assets such as JS or CSS that should be loaded in the rendered HTML document. - * // Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to - * // see how the data should be structured. - * assets: {}, + * assets: { + * // ... + * }, * } * } * } * ``` * - * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific feature, you - * would simply create a file such as this: + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: * * ```javascript * module.exports = { diff --git a/packages/app-cli/tests/support/plugins/menu/api/Global.d.ts b/packages/app-cli/tests/support/plugins/menu/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/menu/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/menu/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinCommands.d.ts index 677e6d5b0f..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: @@ -27,10 +37,10 @@ export default class JoplinCommands { * * // Create a new sub-notebook under the provided notebook * // Note: internally, notebooks are called "folders". - * await joplin.commands.execute('newFolder', { parent_id: "SOME_FOLDER_ID" }); + * await joplin.commands.execute('newFolder', "SOME_FOLDER_ID"); * ``` */ - execute(commandName: string, props?: any): Promise; + execute(commandName: string, ...args: any[]): Promise; /** * desktop Registers a new command. * diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinPlugins.d.ts index aa561f1dac..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinPlugins.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; -import { Script } from './types'; +import Logger from '../../../Logger'; +import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. */ @@ -21,4 +21,18 @@ export default class JoplinPlugins { * ``` */ register(script: Script): Promise; + /** + * Registers a new content script. Unlike regular plugin code, which runs in a separate process, content scripts run within the main process code + * and thus allow improved performances and more customisations in specific cases. It can be used for example to load a Markdown or editor plugin. + * + * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules + * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) + * + * @param type Defines how the script will be used. See the type definition for more information about each supported type. + * @param id A unique ID for the content script. + * @param scriptPath Must be a path relative to the plugin main script. For example, if your file content_script.js is next to your index.ts file, you would set `scriptPath` to `"./content_script.js`. + */ + registerContentScript(type: ContentScriptType, id: string, scriptPath: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/menu/api/types.ts b/packages/app-cli/tests/support/plugins/menu/api/types.ts index ef16847f68..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/types.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/types.ts @@ -3,12 +3,48 @@ // ================================================================= export interface Command { - name: string - label: string - iconName?: string, - execute(props:any):Promise - isEnabled?(props:any):boolean - mapStateToProps?(state:any):any + /** + * Name of command - must be globally unique + */ + name: string; + + /** + * Label to be displayed on menu items or keyboard shortcut editor for example. + * If it is missing, it's assumed it's a private command, to be called programmatically only. + * In that case the command will not appear in the shortcut editor or command panel, and logically + * should not be used as a menu item. + */ + label?: string; + + /** + * Icon to be used on toolbar buttons for example + */ + iconName?: string; + + /** + * Code to be ran when the command is executed. It may return a result. + */ + execute(...args: any[]): Promise; + + /** + * Defines whether the command should be enabled or disabled, which in turns affects + * the enabled state of any associated button or menu item. + * + * The condition should be expressed as a "when-clause" (as in Visual Studio Code). It's a simple boolean expression that evaluates to + * `true` or `false`. It supports the following operators: + * + * Operator | Symbol | Example + * -- | -- | -- + * Equality | == | "editorType == markdown" + * Inequality | != | "currentScreen != config" + * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" + * And | && | "oneNoteSelected && !inConflictFolder" + * + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). + * + * Note: Commands are enabled by default unless you use this property. + */ + enabledCondition?: string; } // ================================================================= @@ -26,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -36,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -150,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -158,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -172,10 +208,26 @@ export enum MenuItemLocation { } export interface MenuItem { - commandName?: string, - accelerator?: string, - submenu?: MenuItem[], - label?: string, + /** + * Command that should be associated with the menu item. All menu item should + * have a command associated with them unless they are a sub-menu. + */ + commandName?: string; + + /** + * Accelerator associated with the menu item + */ + accelerator?: string; + + /** + * Menu items that should appear below this menu item. Allows creating a menu tree. + */ + submenu?: MenuItem[]; + + /** + * Menu item label. If not specified, the command label will be used instead. + */ + label?: string; } // ================================================================= @@ -183,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -225,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -261,3 +313,48 @@ export interface SettingSection { * [2]: (Optional) Resource link. */ export type Path = string[]; + +// ================================================================= +// Plugins type +// ================================================================= + +export enum ContentScriptType { + /** + * Registers a new Markdown-It plugin, which should follow the template below. + * + * ```javascript + * module.exports = { + * default: function(context) { + * return { + * plugin: function(markdownIt, options) { + * // ... + * }, + * assets: { + * // ... + * }, + * } + * } + * } + * ``` + * + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: + * + * ```javascript + * module.exports = { + * default: function(context) { + * return { + * plugin: require('markdown-it-toc-done-right'); + * } + * } + * } + * ``` + */ + MarkdownItPlugin = 'markdownItPlugin', + CodeMirrorPlugin = 'codeMirrorPlugin', +} diff --git a/packages/app-cli/tests/support/plugins/menu/src/index.ts b/packages/app-cli/tests/support/plugins/menu/src/index.ts index f59055909f..4d2e976299 100644 --- a/packages/app-cli/tests/support/plugins/menu/src/index.ts +++ b/packages/app-cli/tests/support/plugins/menu/src/index.ts @@ -2,7 +2,7 @@ import joplin from 'api'; joplin.plugins.register({ onStart: async function() { - await joplin.views.menus.create('My Menu', [ + await joplin.views.menus.create('myMenu', 'My Menu', [ { commandName: "newNote", }, diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/Global.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinCommands.d.ts index 0dc680e3b3..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinPlugins.d.ts index 4b7d0c72ec..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinPlugins.d.ts @@ -1,5 +1,5 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. @@ -28,7 +28,7 @@ export default class JoplinPlugins { * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/content_script) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) * * @param type Defines how the script will be used. See the type definition for more information about each supported type. * @param id A unique ID for the content script. diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/types.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/types.ts index a0636920c1..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/types.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/types.ts @@ -6,7 +6,7 @@ export interface Command { /** * Name of command - must be globally unique */ - name: string + name: string; /** * Label to be displayed on menu items or keyboard shortcut editor for example. @@ -14,17 +14,17 @@ export interface Command { * In that case the command will not appear in the shortcut editor or command panel, and logically * should not be used as a menu item. */ - label?: string + label?: string; /** * Icon to be used on toolbar buttons for example */ - iconName?: string, + iconName?: string; /** * Code to be ran when the command is executed. It may return a result. */ - execute(...args:any[]):Promise + execute(...args: any[]): Promise; /** * Defines whether the command should be enabled or disabled, which in turns affects @@ -40,13 +40,11 @@ export interface Command { * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" * And | && | "oneNoteSelected && !inConflictFolder" * - * Currently the supported context variables aren't documented, but you can find the list there: - * - * https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/services/commands/stateToWhenClauseContext.ts + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). * * Note: Commands are enabled by default unless you use this property. */ - enabledCondition?: string + enabledCondition?: string; } // ================================================================= @@ -64,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -74,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -188,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -196,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -214,22 +212,22 @@ export interface MenuItem { * Command that should be associated with the menu item. All menu item should * have a command associated with them unless they are a sub-menu. */ - commandName?: string, + commandName?: string; /** * Accelerator associated with the menu item */ - accelerator?: string, + accelerator?: string; /** * Menu items that should appear below this menu item. Allows creating a menu tree. */ - submenu?: MenuItem[], + submenu?: MenuItem[]; /** * Menu item label. If not specified, the command label will be used instead. */ - label?: string, + label?: string; } // ================================================================= @@ -237,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -279,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -322,36 +320,30 @@ export type Path = string[]; export enum ContentScriptType { /** - * Registers a new Markdown-It plugin, which should follow this template: + * Registers a new Markdown-It plugin, which should follow the template below. * * ```javascript - * // The module should export an object as below: - * * module.exports = { - * - * // The "context" variable is currently unused but could be used later on to provide - * // access to your own plugin so that the content script and plugin can communicate. * default: function(context) { * return { - * - * // This is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information - * // The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml.ts), which - * // contains a number of options, mostly useful for Joplin's internal code. * plugin: function(markdownIt, options) { * // ... * }, - * - * // You may also specify additional assets such as JS or CSS that should be loaded in the rendered HTML document. - * // Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to - * // see how the data should be structured. - * assets: {}, + * assets: { + * // ... + * }, * } * } * } * ``` * - * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific feature, you - * would simply create a file such as this: + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: * * ```javascript * module.exports = { diff --git a/packages/app-cli/tests/support/plugins/register_command/api/Global.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/register_command/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinCommands.d.ts index 0dc680e3b3..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinPlugins.d.ts index 4b7d0c72ec..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinPlugins.d.ts @@ -1,5 +1,5 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. @@ -28,7 +28,7 @@ export default class JoplinPlugins { * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/content_script) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) * * @param type Defines how the script will be used. See the type definition for more information about each supported type. * @param id A unique ID for the content script. diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/register_command/api/types.ts b/packages/app-cli/tests/support/plugins/register_command/api/types.ts index a0636920c1..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/types.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/types.ts @@ -6,7 +6,7 @@ export interface Command { /** * Name of command - must be globally unique */ - name: string + name: string; /** * Label to be displayed on menu items or keyboard shortcut editor for example. @@ -14,17 +14,17 @@ export interface Command { * In that case the command will not appear in the shortcut editor or command panel, and logically * should not be used as a menu item. */ - label?: string + label?: string; /** * Icon to be used on toolbar buttons for example */ - iconName?: string, + iconName?: string; /** * Code to be ran when the command is executed. It may return a result. */ - execute(...args:any[]):Promise + execute(...args: any[]): Promise; /** * Defines whether the command should be enabled or disabled, which in turns affects @@ -40,13 +40,11 @@ export interface Command { * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" * And | && | "oneNoteSelected && !inConflictFolder" * - * Currently the supported context variables aren't documented, but you can find the list there: - * - * https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/services/commands/stateToWhenClauseContext.ts + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). * * Note: Commands are enabled by default unless you use this property. */ - enabledCondition?: string + enabledCondition?: string; } // ================================================================= @@ -64,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -74,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -188,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -196,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -214,22 +212,22 @@ export interface MenuItem { * Command that should be associated with the menu item. All menu item should * have a command associated with them unless they are a sub-menu. */ - commandName?: string, + commandName?: string; /** * Accelerator associated with the menu item */ - accelerator?: string, + accelerator?: string; /** * Menu items that should appear below this menu item. Allows creating a menu tree. */ - submenu?: MenuItem[], + submenu?: MenuItem[]; /** * Menu item label. If not specified, the command label will be used instead. */ - label?: string, + label?: string; } // ================================================================= @@ -237,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -279,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -322,36 +320,30 @@ export type Path = string[]; export enum ContentScriptType { /** - * Registers a new Markdown-It plugin, which should follow this template: + * Registers a new Markdown-It plugin, which should follow the template below. * * ```javascript - * // The module should export an object as below: - * * module.exports = { - * - * // The "context" variable is currently unused but could be used later on to provide - * // access to your own plugin so that the content script and plugin can communicate. * default: function(context) { * return { - * - * // This is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information - * // The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml.ts), which - * // contains a number of options, mostly useful for Joplin's internal code. * plugin: function(markdownIt, options) { * // ... * }, - * - * // You may also specify additional assets such as JS or CSS that should be loaded in the rendered HTML document. - * // Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to - * // see how the data should be structured. - * assets: {}, + * assets: { + * // ... + * }, * } * } * } * ``` * - * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific feature, you - * would simply create a file such as this: + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: * * ```javascript * module.exports = { diff --git a/packages/app-cli/tests/support/plugins/register_command/src/index.ts b/packages/app-cli/tests/support/plugins/register_command/src/index.ts index 37ed5613a3..276081ca5f 100644 --- a/packages/app-cli/tests/support/plugins/register_command/src/index.ts +++ b/packages/app-cli/tests/support/plugins/register_command/src/index.ts @@ -31,14 +31,14 @@ joplin.plugins.register({ }); // Add the first command to the note toolbar - await joplin.views.toolbarButtons.create('testCommand1', ToolbarButtonLocation.NoteToolbar); + await joplin.views.toolbarButtons.create('myButton1', 'testCommand1', ToolbarButtonLocation.NoteToolbar); // Add the second command to the editor toolbar - await joplin.views.toolbarButtons.create('testCommand2', ToolbarButtonLocation.EditorToolbar); + await joplin.views.toolbarButtons.create('myButton2', 'testCommand2', ToolbarButtonLocation.EditorToolbar); // Also add the commands to the menu - await joplin.views.menuItems.create('testCommand1', MenuItemLocation.Tools, { accelerator: 'CmdOrCtrl+Alt+Shift+B' }); - await joplin.views.menuItems.create('testCommand2', MenuItemLocation.Tools); + await joplin.views.menuItems.create('myMenuItem1', 'testCommand1', MenuItemLocation.Tools, { accelerator: 'CmdOrCtrl+Alt+Shift+B' }); + await joplin.views.menuItems.create('myMenuItem2', 'testCommand2', MenuItemLocation.Tools); console.info('Running command with arguments...'); const result = await joplin.commands.execute('commandWithResult', 'abcd', 123); diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/Global.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinCommands.d.ts index 0dc680e3b3..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinPlugins.d.ts index 4b7d0c72ec..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinPlugins.d.ts @@ -1,5 +1,5 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. @@ -28,7 +28,7 @@ export default class JoplinPlugins { * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/content_script) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) * * @param type Defines how the script will be used. See the type definition for more information about each supported type. * @param id A unique ID for the content script. diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/types.ts b/packages/app-cli/tests/support/plugins/selected_text/api/types.ts index a0636920c1..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/types.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/types.ts @@ -6,7 +6,7 @@ export interface Command { /** * Name of command - must be globally unique */ - name: string + name: string; /** * Label to be displayed on menu items or keyboard shortcut editor for example. @@ -14,17 +14,17 @@ export interface Command { * In that case the command will not appear in the shortcut editor or command panel, and logically * should not be used as a menu item. */ - label?: string + label?: string; /** * Icon to be used on toolbar buttons for example */ - iconName?: string, + iconName?: string; /** * Code to be ran when the command is executed. It may return a result. */ - execute(...args:any[]):Promise + execute(...args: any[]): Promise; /** * Defines whether the command should be enabled or disabled, which in turns affects @@ -40,13 +40,11 @@ export interface Command { * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" * And | && | "oneNoteSelected && !inConflictFolder" * - * Currently the supported context variables aren't documented, but you can find the list there: - * - * https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/services/commands/stateToWhenClauseContext.ts + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). * * Note: Commands are enabled by default unless you use this property. */ - enabledCondition?: string + enabledCondition?: string; } // ================================================================= @@ -64,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -74,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -188,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -196,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -214,22 +212,22 @@ export interface MenuItem { * Command that should be associated with the menu item. All menu item should * have a command associated with them unless they are a sub-menu. */ - commandName?: string, + commandName?: string; /** * Accelerator associated with the menu item */ - accelerator?: string, + accelerator?: string; /** * Menu items that should appear below this menu item. Allows creating a menu tree. */ - submenu?: MenuItem[], + submenu?: MenuItem[]; /** * Menu item label. If not specified, the command label will be used instead. */ - label?: string, + label?: string; } // ================================================================= @@ -237,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -279,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -322,36 +320,30 @@ export type Path = string[]; export enum ContentScriptType { /** - * Registers a new Markdown-It plugin, which should follow this template: + * Registers a new Markdown-It plugin, which should follow the template below. * * ```javascript - * // The module should export an object as below: - * * module.exports = { - * - * // The "context" variable is currently unused but could be used later on to provide - * // access to your own plugin so that the content script and plugin can communicate. * default: function(context) { * return { - * - * // This is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information - * // The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml.ts), which - * // contains a number of options, mostly useful for Joplin's internal code. * plugin: function(markdownIt, options) { * // ... * }, - * - * // You may also specify additional assets such as JS or CSS that should be loaded in the rendered HTML document. - * // Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to - * // see how the data should be structured. - * assets: {}, + * assets: { + * // ... + * }, * } * } * } * ``` * - * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific feature, you - * would simply create a file such as this: + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: * * ```javascript * module.exports = { diff --git a/packages/app-cli/tests/support/plugins/settings/api/Global.d.ts b/packages/app-cli/tests/support/plugins/settings/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/settings/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/settings/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinCommands.d.ts index 0dc680e3b3..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinPlugins.d.ts index 4b7d0c72ec..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinPlugins.d.ts @@ -1,5 +1,5 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. @@ -28,7 +28,7 @@ export default class JoplinPlugins { * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/content_script) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) * * @param type Defines how the script will be used. See the type definition for more information about each supported type. * @param id A unique ID for the content script. diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/settings/api/types.ts b/packages/app-cli/tests/support/plugins/settings/api/types.ts index a0636920c1..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/types.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/types.ts @@ -6,7 +6,7 @@ export interface Command { /** * Name of command - must be globally unique */ - name: string + name: string; /** * Label to be displayed on menu items or keyboard shortcut editor for example. @@ -14,17 +14,17 @@ export interface Command { * In that case the command will not appear in the shortcut editor or command panel, and logically * should not be used as a menu item. */ - label?: string + label?: string; /** * Icon to be used on toolbar buttons for example */ - iconName?: string, + iconName?: string; /** * Code to be ran when the command is executed. It may return a result. */ - execute(...args:any[]):Promise + execute(...args: any[]): Promise; /** * Defines whether the command should be enabled or disabled, which in turns affects @@ -40,13 +40,11 @@ export interface Command { * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" * And | && | "oneNoteSelected && !inConflictFolder" * - * Currently the supported context variables aren't documented, but you can find the list there: - * - * https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/services/commands/stateToWhenClauseContext.ts + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). * * Note: Commands are enabled by default unless you use this property. */ - enabledCondition?: string + enabledCondition?: string; } // ================================================================= @@ -64,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -74,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -188,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -196,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -214,22 +212,22 @@ export interface MenuItem { * Command that should be associated with the menu item. All menu item should * have a command associated with them unless they are a sub-menu. */ - commandName?: string, + commandName?: string; /** * Accelerator associated with the menu item */ - accelerator?: string, + accelerator?: string; /** * Menu items that should appear below this menu item. Allows creating a menu tree. */ - submenu?: MenuItem[], + submenu?: MenuItem[]; /** * Menu item label. If not specified, the command label will be used instead. */ - label?: string, + label?: string; } // ================================================================= @@ -237,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -279,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -322,36 +320,30 @@ export type Path = string[]; export enum ContentScriptType { /** - * Registers a new Markdown-It plugin, which should follow this template: + * Registers a new Markdown-It plugin, which should follow the template below. * * ```javascript - * // The module should export an object as below: - * * module.exports = { - * - * // The "context" variable is currently unused but could be used later on to provide - * // access to your own plugin so that the content script and plugin can communicate. * default: function(context) { * return { - * - * // This is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information - * // The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml.ts), which - * // contains a number of options, mostly useful for Joplin's internal code. * plugin: function(markdownIt, options) { * // ... * }, - * - * // You may also specify additional assets such as JS or CSS that should be loaded in the rendered HTML document. - * // Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to - * // see how the data should be structured. - * assets: {}, + * assets: { + * // ... + * }, * } * } * } * ``` * - * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific feature, you - * would simply create a file such as this: + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: * * ```javascript * module.exports = { diff --git a/packages/app-cli/tests/support/plugins/toc/api/Global.d.ts b/packages/app-cli/tests/support/plugins/toc/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/toc/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/toc/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinCommands.d.ts index 0dc680e3b3..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinPlugins.d.ts index 4b7d0c72ec..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinPlugins.d.ts @@ -1,5 +1,5 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. @@ -28,7 +28,7 @@ export default class JoplinPlugins { * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/content_script) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) * * @param type Defines how the script will be used. See the type definition for more information about each supported type. * @param id A unique ID for the content script. diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/toc/api/types.ts b/packages/app-cli/tests/support/plugins/toc/api/types.ts index a0636920c1..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/types.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/types.ts @@ -6,7 +6,7 @@ export interface Command { /** * Name of command - must be globally unique */ - name: string + name: string; /** * Label to be displayed on menu items or keyboard shortcut editor for example. @@ -14,17 +14,17 @@ export interface Command { * In that case the command will not appear in the shortcut editor or command panel, and logically * should not be used as a menu item. */ - label?: string + label?: string; /** * Icon to be used on toolbar buttons for example */ - iconName?: string, + iconName?: string; /** * Code to be ran when the command is executed. It may return a result. */ - execute(...args:any[]):Promise + execute(...args: any[]): Promise; /** * Defines whether the command should be enabled or disabled, which in turns affects @@ -40,13 +40,11 @@ export interface Command { * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" * And | && | "oneNoteSelected && !inConflictFolder" * - * Currently the supported context variables aren't documented, but you can find the list there: - * - * https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/services/commands/stateToWhenClauseContext.ts + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). * * Note: Commands are enabled by default unless you use this property. */ - enabledCondition?: string + enabledCondition?: string; } // ================================================================= @@ -64,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -74,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -188,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -196,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -214,22 +212,22 @@ export interface MenuItem { * Command that should be associated with the menu item. All menu item should * have a command associated with them unless they are a sub-menu. */ - commandName?: string, + commandName?: string; /** * Accelerator associated with the menu item */ - accelerator?: string, + accelerator?: string; /** * Menu items that should appear below this menu item. Allows creating a menu tree. */ - submenu?: MenuItem[], + submenu?: MenuItem[]; /** * Menu item label. If not specified, the command label will be used instead. */ - label?: string, + label?: string; } // ================================================================= @@ -237,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -279,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -322,36 +320,30 @@ export type Path = string[]; export enum ContentScriptType { /** - * Registers a new Markdown-It plugin, which should follow this template: + * Registers a new Markdown-It plugin, which should follow the template below. * * ```javascript - * // The module should export an object as below: - * * module.exports = { - * - * // The "context" variable is currently unused but could be used later on to provide - * // access to your own plugin so that the content script and plugin can communicate. * default: function(context) { * return { - * - * // This is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information - * // The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml.ts), which - * // contains a number of options, mostly useful for Joplin's internal code. * plugin: function(markdownIt, options) { * // ... * }, - * - * // You may also specify additional assets such as JS or CSS that should be loaded in the rendered HTML document. - * // Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to - * // see how the data should be structured. - * assets: {}, + * assets: { + * // ... + * }, * } * } * } * ``` * - * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific feature, you - * would simply create a file such as this: + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: * * ```javascript * module.exports = { diff --git a/packages/app-cli/tests/support/plugins/toc/src/index.ts b/packages/app-cli/tests/support/plugins/toc/src/index.ts index ece86933dd..3fd104c962 100644 --- a/packages/app-cli/tests/support/plugins/toc/src/index.ts +++ b/packages/app-cli/tests/support/plugins/toc/src/index.ts @@ -41,7 +41,7 @@ joplin.plugins.register({ onStart: async function() { const panels = joplin.views.panels; - const view = await panels.create(); + const view = await (panels as any).create(); await panels.setHtml(view, 'Loading...'); await panels.addScript(view, './webview.js'); diff --git a/packages/app-cli/tests/support/plugins/updatePlugins.sh b/packages/app-cli/tests/support/plugins/updatePlugins.sh index 2722e1c08c..842da54a57 100755 --- a/packages/app-cli/tests/support/plugins/updatePlugins.sh +++ b/packages/app-cli/tests/support/plugins/updatePlugins.sh @@ -11,6 +11,7 @@ yo joplin rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/dialog/" rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/events/" rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/json_export/" +rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/menu/" rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/multi_selection/" rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/register_command/" rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/selected_text/" diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/Global.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/Global.d.ts index 011fe0dafd..f6a0078fa2 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/Global.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/Global.d.ts @@ -1,6 +1,6 @@ import Plugin from '../Plugin'; import Joplin from './Joplin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * @ignore */ diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/Joplin.d.ts index e12babda23..b6ed5824ce 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/Joplin.d.ts @@ -7,7 +7,7 @@ import JoplinCommands from './JoplinCommands'; import JoplinViews from './JoplinViews'; import JoplinInterop from './JoplinInterop'; import JoplinSettings from './JoplinSettings'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. */ diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinCommands.d.ts index 0dc680e3b3..8a9f30451c 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinCommands.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinCommands.d.ts @@ -1,25 +1,35 @@ import { Command } from './types'; /** - * This class allows executing or registering new Joplin commands. Commands can be executed or associated with - * {@link JoplinViewsToolbarButtons | toolbar buttons} or {@link JoplinViewsMenuItems | menu items}. + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) * * ## Executing Joplin's internal commands * - * It is also possible to execute internal Joplin's commands which, as of now, are not well documented. - * You can find the list directly on GitHub though at the following locations: + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: * - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/MainScreen/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/commands - * https://github.com/laurent22/joplin/tree/dev/ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.ts + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) * - * To view what arguments are supported, you can open any of these files and look at the `execute()` command. + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. */ export default class JoplinCommands { /** - * desktop Executes the given command. - * The `props` are the arguments passed to the command, and they vary based on the command + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. * * ```typescript * // Create a new note in the current notebook: diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinData.d.ts index 213d576ed8..fbde6ff9a0 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinData.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinData.d.ts @@ -6,7 +6,7 @@ import { Path } from './types'; * * This is also what you would use to search notes, via the `search` endpoint. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/simple) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) * * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. * And each method takes these parameters: diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinInterop.d.ts index 142c01ddfc..8de655c83a 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinInterop.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinInterop.d.ts @@ -2,7 +2,7 @@ import { ExportModule, ImportModule } from './types'; /** * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) * * To implement an import or export module, you would simply define an object with various event handlers that are called * by the application during the import/export process. diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinPlugins.d.ts index 4b7d0c72ec..fc9fda6a36 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinPlugins.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinPlugins.d.ts @@ -1,5 +1,5 @@ import Plugin from '../Plugin'; -import Logger from 'lib/Logger'; +import Logger from '../../../Logger'; import { ContentScriptType, Script } from './types'; /** * This class provides access to plugin-related features. @@ -28,7 +28,7 @@ export default class JoplinPlugins { * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/content_script) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) * * @param type Defines how the script will be used. See the type definition for more information about each supported type. * @param id A unique ID for the content script. diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinSettings.d.ts index 4deaae636c..0fa39d9640 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinSettings.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinSettings.d.ts @@ -7,7 +7,7 @@ import { SettingItem, SettingSection } from './types'; * * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/settings) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) */ export default class JoplinSettings { private plugin_; @@ -37,7 +37,7 @@ export default class JoplinSettings { * * The list of available settings is not documented yet, but can be found by looking at the source code: * - * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/ReactNativeClient/lib/models/Setting.ts#L142 + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 */ globalValue(key: string): Promise; } diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsDialogs.d.ts index e76f8a41bc..7a9f8e941f 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsDialogs.d.ts @@ -5,7 +5,7 @@ import { ButtonSpec, ViewHandle, ButtonId } from './types'; * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/dialog) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ export default class JoplinViewsDialogs { private store; @@ -16,7 +16,7 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - create(): Promise; + create(id: string): Promise; /** * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" */ diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsMenuItems.d.ts index d2fb8d9949..69e2a8f181 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsMenuItems.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsMenuItems.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing menu items. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsMenuItems { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - create(commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; } diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsMenus.d.ts index 866486a080..f5f803cb1b 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsMenus.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsMenus.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating menus. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/menu) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) */ export default class JoplinViewsMenus { private store; @@ -14,5 +14,5 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - create(label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsPanels.d.ts index 98458e401d..3646269eeb 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsPanels.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsPanels.d.ts @@ -1,10 +1,13 @@ import Plugin from '../Plugin'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/toc) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ export default class JoplinViewsPanels { private store; @@ -14,7 +17,7 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - create(): Promise; + create(id: string): Promise; /** * Sets the panel webview HTML */ diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsToolbarButtons.d.ts index d937b50b43..ba17c83e34 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsToolbarButtons.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsToolbarButtons.d.ts @@ -3,7 +3,7 @@ import Plugin from '../Plugin'; /** * Allows creating and managing toolbar buttons. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/register_command) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) */ export default class JoplinViewsToolbarButtons { private store; @@ -12,5 +12,5 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - create(commandName: string, location: ToolbarButtonLocation): Promise; + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; } diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinWorkspace.d.ts index 361eb3a675..0686d32a9c 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinWorkspace.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinWorkspace.d.ts @@ -2,7 +2,7 @@ * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well * as various related events, such as when a new note is selected, or when the note content changes. * - * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins) + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) */ export default class JoplinWorkspace { private store; diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/types.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/types.ts index a0636920c1..e4da323694 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/types.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/types.ts @@ -6,7 +6,7 @@ export interface Command { /** * Name of command - must be globally unique */ - name: string + name: string; /** * Label to be displayed on menu items or keyboard shortcut editor for example. @@ -14,17 +14,17 @@ export interface Command { * In that case the command will not appear in the shortcut editor or command panel, and logically * should not be used as a menu item. */ - label?: string + label?: string; /** * Icon to be used on toolbar buttons for example */ - iconName?: string, + iconName?: string; /** * Code to be ran when the command is executed. It may return a result. */ - execute(...args:any[]):Promise + execute(...args: any[]): Promise; /** * Defines whether the command should be enabled or disabled, which in turns affects @@ -40,13 +40,11 @@ export interface Command { * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" * And | && | "oneNoteSelected && !inConflictFolder" * - * Currently the supported context variables aren't documented, but you can find the list there: - * - * https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/services/commands/stateToWhenClauseContext.ts + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). * * Note: Commands are enabled by default unless you use this property. */ - enabledCondition?: string + enabledCondition?: string; } // ================================================================= @@ -64,7 +62,7 @@ export enum ImportModuleOutputFormat { } /** - * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/CliClient/tests/support/plugins/json_export) for an example. + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. * * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. * @@ -74,113 +72,113 @@ export interface ExportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. */ - target: FileSystemItem, + target: FileSystemItem; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Called when the export process starts. */ - onInit(context:ExportContext): Promise; + onInit(context: ExportContext): Promise; /** * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. */ - onProcessItem(context:ExportContext, itemType:number, item:any):Promise; + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; /** * Called when a resource file needs to be exported. */ - onProcessResource(context:ExportContext, resource:any, filePath:string):Promise; + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; /** * Called when the export process is done. */ - onClose(context:ExportContext):Promise; + onClose(context: ExportContext): Promise; } export interface ImportModule { /** * The format to be exported, eg "enex", "jex", "json", etc. */ - format: string, + format: string; /** * The description that will appear in the UI, for example in the menu item. */ - description: string, + description: string; /** * Only applies to single file exporters or importers * It tells whether the format can package multiple notes into one file. * For example JEX or ENEX can, but HTML cannot. */ - isNoteArchive: boolean, + isNoteArchive: boolean; /** * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. */ - sources: FileSystemItem[], + sources: FileSystemItem[]; /** * Tells the file extensions of the exported files. */ - fileExtensions?: string[], + fileExtensions?: string[]; /** * Tells the type of notes that will be generated, either HTML or Markdown (default). */ - outputFormat?: ImportModuleOutputFormat, + outputFormat?: ImportModuleOutputFormat; /** * Called when the import process starts. There is only one event handler within which you should import the complete data. */ - onExec(context:ImportContext): Promise; + onExec(context: ImportContext): Promise; } export interface ExportOptions { - format?: string, - path?:string, - sourceFolderIds?: string[], - sourceNoteIds?: string[], - modulePath?:string, - target?:FileSystemItem, + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; } export interface ExportContext { - destPath: string, - options: ExportOptions, + destPath: string; + options: ExportOptions; /** * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. */ - userData?: any, + userData?: any; } export interface ImportContext { - sourcePath: string, - options: any, - warnings: string[], + sourcePath: string; + options: any; + warnings: string[]; } // ================================================================= @@ -188,7 +186,7 @@ export interface ImportContext { // ================================================================= export interface Script { - onStart?(event:any):Promise, + onStart?(event: any): Promise; } // ================================================================= @@ -196,7 +194,7 @@ export interface Script { // ================================================================= export interface CreateMenuItemOptions { - accelerator: string, + accelerator: string; } export enum MenuItemLocation { @@ -214,22 +212,22 @@ export interface MenuItem { * Command that should be associated with the menu item. All menu item should * have a command associated with them unless they are a sub-menu. */ - commandName?: string, + commandName?: string; /** * Accelerator associated with the menu item */ - accelerator?: string, + accelerator?: string; /** * Menu items that should appear below this menu item. Allows creating a menu tree. */ - submenu?: MenuItem[], + submenu?: MenuItem[]; /** * Menu item label. If not specified, the command label will be used instead. */ - label?: string, + label?: string; } // ================================================================= @@ -237,9 +235,9 @@ export interface MenuItem { // ================================================================= export interface ButtonSpec { - id: ButtonId, - title?: string, - onClick?():void, + id: ButtonId; + title?: string; + onClick?(): void; } export type ButtonId = string; @@ -279,28 +277,28 @@ export enum SettingItemType { // Redefine a simplified interface to mask internal details // and to remove function calls as they would have to be async. export interface SettingItem { - value: any, - type: SettingItemType, - public: boolean, - label:string, + value: any; + type: SettingItemType; + public: boolean; + label: string; - description?:string, - isEnum?: boolean, - section?: string, - options?:any, - appTypes?:string[], - secure?: boolean, - advanced?: boolean, - minimum?: number, - maximum?: number, - step?: number, + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; } export interface SettingSection { - label: string, - iconName?: string, - description?: string, - name?: string, + label: string; + iconName?: string; + description?: string; + name?: string; } // ================================================================= @@ -322,36 +320,30 @@ export type Path = string[]; export enum ContentScriptType { /** - * Registers a new Markdown-It plugin, which should follow this template: + * Registers a new Markdown-It plugin, which should follow the template below. * * ```javascript - * // The module should export an object as below: - * * module.exports = { - * - * // The "context" variable is currently unused but could be used later on to provide - * // access to your own plugin so that the content script and plugin can communicate. * default: function(context) { * return { - * - * // This is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information - * // The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml.ts), which - * // contains a number of options, mostly useful for Joplin's internal code. * plugin: function(markdownIt, options) { * // ... * }, - * - * // You may also specify additional assets such as JS or CSS that should be loaded in the rendered HTML document. - * // Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to - * // see how the data should be structured. - * assets: {}, + * assets: { + * // ... + * }, * } * } * } * ``` * - * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific feature, you - * would simply create a file such as this: + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: * * ```javascript * module.exports = { diff --git a/packages/app-desktop/app.ts b/packages/app-desktop/app.ts index 000a08014f..3894b66b26 100644 --- a/packages/app-desktop/app.ts +++ b/packages/app-desktop/app.ts @@ -18,6 +18,9 @@ import SpellCheckerService from '@joplin/lib/services/spellChecker/SpellCheckerS import SpellCheckerServiceDriverNative from './services/spellChecker/SpellCheckerServiceDriverNative'; import bridge from './services/bridge'; import menuCommandNames from './gui/menuCommandNames'; +import { LayoutItem } from './gui/ResizableLayout/utils/types'; +import stateToWhenClauseContext from './services/commands/stateToWhenClauseContext'; +import ResourceService from '@joplin/lib/services/ResourceService'; const { FoldersScreenUtils } = require('@joplin/lib/folders-screen-utils.js'); const MasterKey = require('@joplin/lib/models/MasterKey'); @@ -27,7 +30,6 @@ const Tag = require('@joplin/lib/models/Tag.js'); const { reg } = require('@joplin/lib/registry.js'); const packageInfo = require('./packageInfo.js'); const DecryptionWorker = require('@joplin/lib/services/DecryptionWorker'); -const ResourceService = require('@joplin/lib/services/ResourceService').default; const ClipperServer = require('@joplin/lib/ClipperServer'); const ExternalEditWatcher = require('@joplin/lib/services/ExternalEditWatcher'); const { webFrame } = require('electron'); @@ -67,6 +69,7 @@ const commands = [ require('./gui/MainScreen/commands/openNote'), require('./gui/MainScreen/commands/openFolder'), require('./gui/MainScreen/commands/openTag'), + require('./gui/MainScreen/commands/toggleLayoutMoveMode'), require('./gui/NoteEditor/commands/focusElementNoteBody'), require('./gui/NoteEditor/commands/focusElementNoteTitle'), require('./gui/NoteEditor/commands/showLocalSearch'), @@ -105,17 +108,17 @@ export interface AppState extends State { route: AppStateRoute; navHistory: any[]; noteVisiblePanes: string[]; - sidebarVisibility: boolean; - noteListVisibility: boolean; windowContentSize: any; watchedNoteFiles: string[]; lastEditorScrollPercents: any; devToolsVisible: boolean; visibleDialogs: any; // empty object if no dialog is visible. Otherwise contains the list of visible dialogs. focusedField: string; + layoutMoveMode: boolean; // Extra reducer keys go here watchedResources: any; + mainLayout: LayoutItem; } const appDefaultState: AppState = { @@ -127,14 +130,14 @@ const appDefaultState: AppState = { }, navHistory: [], noteVisiblePanes: ['editor', 'viewer'], - sidebarVisibility: true, - noteListVisibility: true, windowContentSize: bridge().windowContentSize(), watchedNoteFiles: [], lastEditorScrollPercents: {}, devToolsVisible: false, visibleDialogs: {}, // empty object if no dialog is visible. Otherwise contains the list of visible dialogs. focusedField: null, + layoutMoveMode: false, + mainLayout: null, ...resourceEditWatcherDefaultState, }; @@ -234,25 +237,12 @@ class Application extends BaseApplication { newState.noteVisiblePanes = action.panes; break; - case 'SIDEBAR_VISIBILITY_TOGGLE': + case 'MAIN_LAYOUT_SET': - newState = Object.assign({}, state); - newState.sidebarVisibility = !state.sidebarVisibility; - break; - - case 'SIDEBAR_VISIBILITY_SET': - newState = Object.assign({}, state); - newState.sidebarVisibility = action.visibility; - break; - - case 'NOTELIST_VISIBILITY_TOGGLE': - newState = Object.assign({}, state); - newState.noteListVisibility = !state.noteListVisibility; - break; - - case 'NOTELIST_VISIBILITY_SET': - newState = Object.assign({}, state); - newState.noteListVisibility = action.visibility; + newState = { + ...state, + mainLayout: action.value, + }; break; case 'NOTE_FILE_WATCHER_ADD': @@ -333,6 +323,14 @@ class Application extends BaseApplication { } break; + case 'LAYOUT_MOVE_MODE_SET': + + newState = { + ...state, + layoutMoveMode: action.value, + }; + break; + } } catch (error) { error.message = `In reducer: ${error.message} Action: ${JSON.stringify(action)}`; @@ -384,14 +382,6 @@ class Application extends BaseApplication { Setting.setValue('noteVisiblePanes', newState.noteVisiblePanes); } - if (['SIDEBAR_VISIBILITY_TOGGLE', 'SIDEBAR_VISIBILITY_SET'].indexOf(action.type) >= 0) { - Setting.setValue('sidebarVisibility', newState.sidebarVisibility); - } - - if (['NOTELIST_VISIBILITY_TOGGLE', 'NOTELIST_VISIBILITY_SET'].indexOf(action.type) >= 0) { - Setting.setValue('noteListVisibility', newState.noteListVisibility); - } - if (['NOTE_DEVTOOLS_TOGGLE', 'NOTE_DEVTOOLS_SET'].indexOf(action.type) >= 0) { this.toggleDevTools(newState.devToolsVisible); } @@ -497,6 +487,37 @@ class Application extends BaseApplication { return cssString; } + private async initPluginService() { + const pluginLogger = new Logger(); + pluginLogger.addTarget(TargetType.File, { path: `${Setting.value('profileDir')}/log-plugins.txt` }); + pluginLogger.addTarget(TargetType.Console, { prefix: 'Plugin Service:' }); + pluginLogger.setLevel(Setting.value('env') == 'dev' ? Logger.LEVEL_DEBUG : Logger.LEVEL_INFO); + + const pluginRunner = new PluginRunner(); + PluginService.instance().setLogger(pluginLogger); + PluginService.instance().initialize(PlatformImplementation.instance(), pluginRunner, this.store()); + + try { + if (await shim.fsDriver().exists(Setting.value('pluginDir'))) await PluginService.instance().loadAndRunPlugins(Setting.value('pluginDir')); + } catch (error) { + this.logger().error(`There was an error loading plugins from ${Setting.value('pluginDir')}:`, error); + } + + try { + if (Setting.value('plugins.devPluginPaths')) { + const paths = Setting.value('plugins.devPluginPaths').split(',').map((p: string) => p.trim()); + await PluginService.instance().loadAndRunPlugins(paths); + } + + // Also load dev plugins that have passed via command line arguments + if (Setting.value('startupDevPlugins')) { + await PluginService.instance().loadAndRunPlugins(Setting.value('startupDevPlugins')); + } + } catch (error) { + this.logger().error(`There was an error loading plugins from ${Setting.value('plugins.devPluginPaths')}:`, error); + } + } + async start(argv: string[]): Promise { const electronIsDev = require('electron-is-dev'); @@ -539,7 +560,7 @@ class Application extends BaseApplication { this.initRedux(); - CommandService.instance().initialize(this.store(), Setting.value('env') == 'dev'); + CommandService.instance().initialize(this.store(), Setting.value('env') == 'dev', stateToWhenClauseContext); for (const command of commands) { CommandService.instance().registerDeclaration(command.declaration); @@ -688,34 +709,7 @@ class Application extends BaseApplication { bridge().addEventListener('nativeThemeUpdated', this.bridge_nativeThemeUpdated); - const pluginLogger = new Logger(); - pluginLogger.addTarget(TargetType.File, { path: `${Setting.value('profileDir')}/log-plugins.txt` }); - pluginLogger.addTarget(TargetType.Console, { prefix: 'Plugin Service:' }); - pluginLogger.setLevel(Setting.value('env') == 'dev' ? Logger.LEVEL_DEBUG : Logger.LEVEL_INFO); - - const pluginRunner = new PluginRunner(); - PluginService.instance().setLogger(pluginLogger); - PluginService.instance().initialize(PlatformImplementation.instance(), pluginRunner, this.store()); - - try { - if (await shim.fsDriver().exists(Setting.value('pluginDir'))) await PluginService.instance().loadAndRunPlugins(Setting.value('pluginDir')); - } catch (error) { - this.logger().error(`There was an error loading plugins from ${Setting.value('pluginDir')}:`, error); - } - - try { - if (Setting.value('plugins.devPluginPaths')) { - const paths = Setting.value('plugins.devPluginPaths').split(',').map((p: string) => p.trim()); - await PluginService.instance().loadAndRunPlugins(paths); - } - - // Also load dev plugins that have passed via command line arguments - if (Setting.value('startupDevPlugins')) { - await PluginService.instance().loadAndRunPlugins(Setting.value('startupDevPlugins')); - } - } catch (error) { - this.logger().error(`There was an error loading plugins from ${Setting.value('plugins.devPluginPaths')}:`, error); - } + await this.initPluginService(); this.setupContextMenu(); diff --git a/packages/app-desktop/gui/Button/Button.tsx b/packages/app-desktop/gui/Button/Button.tsx index 6f6686baf5..8b7c71abe2 100644 --- a/packages/app-desktop/gui/Button/Button.tsx +++ b/packages/app-desktop/gui/Button/Button.tsx @@ -14,7 +14,7 @@ interface Props { iconName?: string; level?: ButtonLevel; className?: string; - onClick: Function; + onClick?: Function; color?: string; iconAnimation?: string; tooltip?: string; @@ -57,12 +57,14 @@ const StyledButtonPrimary = styled(StyledButtonBase)` border: none; background-color: ${(props: any) => props.theme.backgroundColor5}; - &:hover { - background-color: ${(props: any) => props.theme.backgroundColorHover5}; - } + ${(props: any) => props.disabled} { + &:hover { + background-color: ${(props: any) => props.theme.backgroundColorHover5}; + } - &:active { - background-color: ${(props: any) => props.theme.backgroundColorActive5}; + &:active { + background-color: ${(props: any) => props.theme.backgroundColorActive5}; + } } ${StyledIcon} { @@ -78,12 +80,14 @@ const StyledButtonSecondary = styled(StyledButtonBase)` border: 1px solid ${(props: any) => props.theme.borderColor4}; background-color: ${(props: any) => props.theme.backgroundColor4}; - &:hover { - background-color: ${(props: any) => props.theme.backgroundColorHover4}; - } + ${(props: any) => props.disabled} { + &:hover { + background-color: ${(props: any) => props.theme.backgroundColorHover4}; + } - &:active { - background-color: ${(props: any) => props.theme.backgroundColorActive4}; + &:active { + background-color: ${(props: any) => props.theme.backgroundColorActive4}; + } } ${StyledIcon} { diff --git a/packages/app-desktop/gui/MainScreen/MainScreen.tsx b/packages/app-desktop/gui/MainScreen/MainScreen.tsx index bf3190ddad..37e185c67e 100644 --- a/packages/app-desktop/gui/MainScreen/MainScreen.tsx +++ b/packages/app-desktop/gui/MainScreen/MainScreen.tsx @@ -1,13 +1,15 @@ import * as React from 'react'; -import ResizableLayout, { findItemByKey, LayoutItem, LayoutItemDirection, allDynamicSizes } from '../ResizableLayout/ResizableLayout'; -import NoteList from '../NoteList/NoteList'; +import ResizableLayout from '../ResizableLayout/ResizableLayout'; +import findItemByKey from '../ResizableLayout/utils/findItemByKey'; +import { MoveButtonClickEvent } from '../ResizableLayout/MoveButtons'; +import { move } from '../ResizableLayout/utils/movements'; +import { LayoutItem } from '../ResizableLayout/utils/types'; import NoteEditor from '../NoteEditor/NoteEditor'; import NoteContentPropertiesDialog from '../NoteContentPropertiesDialog'; import ShareNoteDialog from '../ShareNoteDialog'; -import NoteListControls from '../NoteListControls/NoteListControls'; import CommandService from '@joplin/lib/services/CommandService'; import PluginService from '@joplin/lib/services/plugins/PluginService'; -import { utils as pluginUtils } from '@joplin/lib/services/plugins/reducer'; +import { PluginStates, utils as pluginUtils } from '@joplin/lib/services/plugins/reducer'; import SideBar from '../SideBar/SideBar'; import UserWebview from '../../services/plugins/UserWebview'; import UserWebviewDialog from '../../services/plugins/UserWebviewDialog'; @@ -15,20 +17,61 @@ import { ContainerType } from '@joplin/lib/services/plugins/WebviewController'; import { stateUtils } from '@joplin/lib/reducer'; import InteropServiceHelper from '../../InteropServiceHelper'; import { _ } from '@joplin/lib/locale'; +import NoteListWrapper from '../NoteListWrapper/NoteListWrapper'; +import { AppState } from '../../app'; +import { saveLayout, loadLayout } from '../ResizableLayout/utils/persist'; +import Setting from '@joplin/lib/models/Setting'; +import produce from 'immer'; +import shim from '@joplin/lib/shim'; +import bridge from '../../services/bridge'; +import time from '@joplin/lib/time'; +import styled from 'styled-components'; +import { themeStyle } from '@joplin/lib/theme'; +import validateLayout from '../ResizableLayout/utils/validateLayout'; +import iterateItems from '../ResizableLayout/utils/iterateItems'; +import removeItem from '../ResizableLayout/utils/removeItem'; -const produce = require('immer').default; const { connect } = require('react-redux'); const { PromptDialog } = require('../PromptDialog.min.js'); const NotePropertiesDialog = require('../NotePropertiesDialog.min.js'); -const Setting = require('@joplin/lib/models/Setting').default; -const shim = require('@joplin/lib/shim').default; -const { themeStyle } = require('@joplin/lib/theme.js'); -const bridge = require('electron').remote.require('./bridge').default; const PluginManager = require('@joplin/lib/services/PluginManager'); const EncryptionService = require('@joplin/lib/services/EncryptionService'); const ipcRenderer = require('electron').ipcRenderer; -const time = require('@joplin/lib/time').default; -const styled = require('styled-components').default; + +interface LayerModalState { + visible: boolean; + message: string; +} + +interface Props { + plugins: PluginStates; + pluginsLoaded: boolean; + hasNotesBeingSaved: boolean; + dispatch: Function; + mainLayout: LayoutItem; + style: any; + layoutMoveMode: boolean; + editorNoteStatuses: any; + customCss: string; + shouldUpgradeSyncTarget: boolean; + hasDisabledSyncItems: boolean; + hasDisabledEncryptionItems: boolean; + showMissingMasterKeyMessage: boolean; + showNeedUpgradingMasterKeyMessage: boolean; + showShouldReencryptMessage: boolean; + focusedField: string; + themeId: number; + settingEditorCodeView: boolean; + pluginsLegacy: any; +} + +interface State { + promptOptions: any; + modalLayer: LayerModalState; + notePropertiesDialogOptions: any; + noteContentPropertiesDialogOptions: any; + shareNoteDialogOptions: any; +} const StyledUserWebviewDialogContainer = styled.div` display: flex; @@ -41,6 +84,15 @@ const StyledUserWebviewDialogContainer = styled.div` box-sizing: border-box; `; +const defaultLayout: LayoutItem = { + key: 'root', + children: [ + { key: 'sideBar', width: 250 }, + { key: 'noteList', width: 250 }, + { key: 'editor' }, + ], +}; + const commands = [ require('./commands/editAlarm'), require('./commands/exportPdf'), @@ -65,20 +117,21 @@ const commands = [ require('./commands/toggleNoteList'), require('./commands/toggleSideBar'), require('./commands/toggleVisiblePanes'), + require('./commands/toggleLayoutMoveMode'), require('./commands/openNote'), require('./commands/openFolder'), require('./commands/openTag'), ]; -class MainScreenComponent extends React.Component { +class MainScreenComponent extends React.Component { - waitForNotesSavedIID_: any; - isPrinting_: boolean; - styleKey_: string; - styles_: any; - promptOnClose_: Function; + private waitForNotesSavedIID_: any; + private isPrinting_: boolean; + private styleKey_: string; + private styles_: any; + private promptOnClose_: Function; - constructor(props: any) { + constructor(props: Props) { super(props); this.state = { @@ -90,9 +143,10 @@ class MainScreenComponent extends React.Component { notePropertiesDialogOptions: {}, noteContentPropertiesDialogOptions: {}, shareNoteDialogOptions: {}, - layout: this.buildLayout(props.plugins), }; + this.updateMainLayout(this.buildLayout(props.plugins)); + this.registerCommands(); this.setupAppCloseHandling(); @@ -103,117 +157,72 @@ class MainScreenComponent extends React.Component { this.userWebview_message = this.userWebview_message.bind(this); this.resizableLayout_resize = this.resizableLayout_resize.bind(this); this.resizableLayout_renderItem = this.resizableLayout_renderItem.bind(this); + this.resizableLayout_moveButtonClick = this.resizableLayout_moveButtonClick.bind(this); this.window_resize = this.window_resize.bind(this); this.rowHeight = this.rowHeight.bind(this); + this.layoutModeListenerKeyDown = this.layoutModeListenerKeyDown.bind(this); window.addEventListener('resize', this.window_resize); } - buildLayout(plugins: any): LayoutItem { - const rootLayoutSize = this.rootLayoutSize(); - const theme = themeStyle(this.props.themeId); - const sideBarMinWidth = 200; - - const sizes = { - sideBarColumn: { - width: 150, - }, - noteListColumn: { - width: 150, - }, - pluginColumn: { - width: 150, - }, - ...Setting.value('ui.layout'), - }; - - for (const k in sizes) { - if (sizes[k].width < sideBarMinWidth) sizes[k].width = sideBarMinWidth; - } - - const pluginColumnChildren: LayoutItem[] = []; - + private updateLayoutPluginViews(layout: LayoutItem, plugins: PluginStates) { const infos = pluginUtils.viewInfosByType(plugins, 'webview'); - for (const info of infos) { - if (info.view.containerType !== ContainerType.Panel) continue; + let newLayout = produce(layout, (draftLayout: LayoutItem) => { + for (const info of infos) { + if (info.view.containerType !== ContainerType.Panel) continue; - // For now it's assumed all views go in the "pluginColumn" so they are - // resizable vertically. But horizontally they stretch 100% - const viewId = info.view.id; + const viewId = info.view.id; + const existingItem = findItemByKey(draftLayout, viewId); - const size = { - ...(sizes[viewId] ? sizes[viewId] : null), - width: '100%', - }; + if (!existingItem) { + draftLayout.children.push({ + key: viewId, + context: { + pluginId: info.plugin.id, + }, + }); + } + } + }); - pluginColumnChildren.push({ - key: viewId, - resizableBottom: true, - context: { - plugin: info.plugin, - control: info.view, - }, - ...size, - }); + // Remove layout items that belong to plugins that are no longer + // active. + const pluginIds = Object.keys(plugins); + const itemsToRemove: string[] = []; + iterateItems(newLayout, (_itemIndex: number, item: LayoutItem, _parent: LayoutItem) => { + if (item.context && item.context.pluginId && !pluginIds.includes(item.context.pluginId)) { + itemsToRemove.push(item.key); + } + return true; + }); + + for (const itemKey of itemsToRemove) { + newLayout = removeItem(newLayout, itemKey); } - return { - key: 'root', - direction: LayoutItemDirection.Row, - width: rootLayoutSize.width, - height: rootLayoutSize.height, - children: [ - { - key: 'sideBarColumn', - direction: LayoutItemDirection.Column, - resizableRight: true, - width: sizes.sideBarColumn.width, - visible: Setting.value('sidebarVisibility'), - minWidth: sideBarMinWidth, - children: [ - { - key: 'sideBar', - }, - ], - }, - { - key: 'noteListColumn', - direction: LayoutItemDirection.Column, - resizableRight: true, - width: sizes.noteListColumn.width, - visible: Setting.value('noteListVisibility'), - minWidth: sideBarMinWidth, - children: [ - { - height: theme.topRowHeight, - key: 'noteListControls', - }, - { - key: 'noteList', - }, - ], - }, - { - key: 'pluginColumn', - direction: LayoutItemDirection.Column, - resizableRight: true, - width: sizes.pluginColumn.width, - visible: !!pluginColumnChildren.length, - minWidth: sideBarMinWidth, - children: pluginColumnChildren, - }, - { - key: 'editorColumn', - direction: LayoutItemDirection.Column, - children: [ - { - key: 'editor', - }, - ], - }, - ], - }; + return newLayout !== layout ? validateLayout(newLayout) : layout; + } + + private buildLayout(plugins: PluginStates): LayoutItem { + const rootLayoutSize = this.rootLayoutSize(); + + const userLayout = Setting.value('ui.layout'); + let output = null; + + try { + output = loadLayout(userLayout, defaultLayout, rootLayoutSize); + + if (!findItemByKey(output, 'sideBar') || !findItemByKey(output, 'noteList') || !findItemByKey(output, 'editor')) { + throw new Error('"sideBar", "noteList" and "editor" must be present in the layout'); + } + } catch (error) { + console.warn('Could not load layout - restoring default layout:', error); + console.warn('Layout was:', userLayout); + output = loadLayout(null, defaultLayout, rootLayoutSize); + } + + return this.updateLayoutPluginViews(output, plugins); } window_resize() { @@ -263,25 +272,22 @@ class MainScreenComponent extends React.Component { this.setState({ shareNoteDialogOptions: {} }); } + updateMainLayout(layout: LayoutItem) { + this.props.dispatch({ + type: 'MAIN_LAYOUT_SET', + value: layout, + }); + } + updateRootLayoutSize() { - this.setState({ layout: produce(this.state.layout, (draft: any) => { + this.updateMainLayout(produce(this.props.mainLayout, (draft: any) => { const s = this.rootLayoutSize(); draft.width = s.width; draft.height = s.height; - }) }); + })); } - componentDidUpdate(prevProps: any, prevState: any) { - if (this.props.noteListVisibility !== prevProps.noteListVisibility || this.props.sidebarVisibility !== prevProps.sidebarVisibility) { - this.setState({ layout: produce(this.state.layout, (draft: any) => { - const noteListColumn = findItemByKey(draft, 'noteListColumn'); - noteListColumn.visible = this.props.noteListVisibility; - - const sideBarColumn = findItemByKey(draft, 'sideBarColumn'); - sideBarColumn.visible = this.props.sidebarVisibility; - }) }); - } - + componentDidUpdate(prevProps: Props, prevState: State) { if (prevProps.style.width !== this.props.style.width || prevProps.style.height !== this.props.style.height || this.messageBoxVisible(prevProps) !== this.messageBoxVisible(this.props) @@ -290,7 +296,8 @@ class MainScreenComponent extends React.Component { } if (prevProps.plugins !== this.props.plugins) { - this.setState({ layout: this.buildLayout(this.props.plugins) }); + this.updateMainLayout(this.updateLayoutPluginViews(this.props.mainLayout, this.props.plugins)); + // this.setState({ layout: this.buildLayout(this.props.plugins) }); } if (this.state.notePropertiesDialogOptions !== prevState.notePropertiesDialogOptions) { @@ -313,28 +320,28 @@ class MainScreenComponent extends React.Component { name: 'shareNote', }); } + + if (this.props.mainLayout !== prevProps.mainLayout) { + const toSave = saveLayout(this.props.mainLayout); + Setting.setValue('ui.layout', toSave); + } + } + + layoutModeListenerKeyDown(event: any) { + if (event.key !== 'Escape') return; + if (!this.props.layoutMoveMode) return; + CommandService.instance().execute('toggleLayoutMoveMode'); } componentDidMount() { - this.updateRootLayoutSize(); + window.addEventListener('keydown', this.layoutModeListenerKeyDown); } componentWillUnmount() { this.unregisterCommands(); window.removeEventListener('resize', this.window_resize); - } - - toggleSideBar() { - this.props.dispatch({ - type: 'SIDEBAR_VISIBILITY_TOGGLE', - }); - } - - toggleNoteList() { - this.props.dispatch({ - type: 'NOTELIST_VISIBILITY_TOGGLE', - }); + window.removeEventListener('keydown', this.layoutModeListenerKeyDown); } async waitForNoteToSaved(noteId: string) { @@ -399,8 +406,8 @@ class MainScreenComponent extends React.Component { return 50; } - styles(themeId: number, width: number, height: number, messageBoxVisible: boolean, isSidebarVisible: any, isNoteListVisible: any) { - const styleKey = [themeId, width, height, messageBoxVisible, +isSidebarVisible, +isNoteListVisible].join('_'); + styles(themeId: number, width: number, height: number, messageBoxVisible: boolean) { + const styleKey = [themeId, width, height, messageBoxVisible].join('_'); if (styleKey === this.styleKey_) return this.styles_; const theme = themeStyle(themeId); @@ -561,30 +568,57 @@ class MainScreenComponent extends React.Component { } resizableLayout_resize(event: any) { - this.setState({ layout: event.layout }); - Setting.setValue('ui.layout', allDynamicSizes(event.layout)); + this.updateMainLayout(event.layout); + } + + resizableLayout_moveButtonClick(event: MoveButtonClickEvent) { + const newLayout = move(this.props.mainLayout, event.itemKey, event.direction); + this.updateMainLayout(newLayout); } resizableLayout_renderItem(key: string, event: any) { const eventEmitter = event.eventEmitter; - if (key === 'sideBar') { - return ; - } else if (key === 'noteList') { - return ; - } else if (key === 'editor') { - const bodyEditor = this.props.settingEditorCodeView ? 'CodeMirror' : 'TinyMCE'; - return ; - } else if (key === 'noteListControls') { - return ; - } else if (key.indexOf('plugin-view') === 0) { - const { control, plugin } = event.item.context; + const components: any = { + sideBar: () => { + return ; + }, + + noteList: () => { + return ; + }, + + editor: () => { + const bodyEditor = this.props.settingEditorCodeView ? 'CodeMirror' : 'TinyMCE'; + return ; + }, + }; + + if (components[key]) return components[key](); + + if (key.indexOf('plugin-view') === 0) { + const viewInfo = pluginUtils.viewInfoByViewId(this.props.plugins, event.item.key); + + if (!viewInfo) { + console.warn(`Could not find plugin associated with view: ${event.item.key}`); + return null; + } + + const { view, plugin } = viewInfo; + return { this.props.style ); const promptOptions = this.state.promptOptions; - const sidebarVisibility = this.props.sidebarVisibility; - const noteListVisibility = this.props.noteListVisibility; - const styles = this.styles(this.props.themeId, style.width, style.height, this.messageBoxVisible(), sidebarVisibility, noteListVisibility); + const styles = this.styles(this.props.themeId, style.width, style.height, this.messageBoxVisible()); if (!this.promptOnClose_) { this.promptOnClose_ = (answer: any, buttonType: any) => { @@ -656,6 +688,18 @@ class MainScreenComponent extends React.Component { const noteContentPropertiesDialogOptions = this.state.noteContentPropertiesDialogOptions; const shareNoteDialogOptions = this.state.shareNoteDialogOptions; + const layoutComp = this.props.mainLayout ? ( + + ) : null; + return (
{this.state.modalLayer.message}
@@ -667,25 +711,17 @@ class MainScreenComponent extends React.Component { {messageComp} - + {layoutComp} {pluginDialog}
); } } -const mapStateToProps = (state: any) => { +const mapStateToProps = (state: AppState) => { return { themeId: state.settings.theme, settingEditorCodeView: state.settings['editor.codeView'], - sidebarVisibility: state.sidebarVisibility, - noteListVisibility: state.noteListVisibility, folders: state.folders, notes: state.notes, hasDisabledSyncItems: state.hasDisabledSyncItems, @@ -703,6 +739,8 @@ const mapStateToProps = (state: any) => { editorNoteStatuses: state.editorNoteStatuses, hasNotesBeingSaved: stateUtils.hasNotesBeingSaved(state), focusedField: state.focusedField, + layoutMoveMode: state.layoutMoveMode, + mainLayout: state.mainLayout, }; }; diff --git a/packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.ts b/packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.ts new file mode 100644 index 0000000000..5609f251f1 --- /dev/null +++ b/packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.ts @@ -0,0 +1,20 @@ +import { CommandDeclaration, CommandRuntime, CommandContext } from '@joplin/lib/services/CommandService'; +import { _ } from '@joplin/lib/locale'; +import { AppState } from '../../../app'; + +export const declaration: CommandDeclaration = { + name: 'toggleLayoutMoveMode', + label: () => _('Change application layout'), +}; + +export const runtime = (): CommandRuntime => { + return { + execute: async (context: CommandContext, value: boolean = null) => { + const newValue = value !== null ? value : !(context.state as AppState).layoutMoveMode; + context.dispatch({ + type: 'LAYOUT_MOVE_MODE_SET', + value: newValue, + }); + }, + }; +}; diff --git a/packages/app-desktop/gui/MainScreen/commands/toggleNoteList.ts b/packages/app-desktop/gui/MainScreen/commands/toggleNoteList.ts index 396aa09b6f..3c11c88850 100644 --- a/packages/app-desktop/gui/MainScreen/commands/toggleNoteList.ts +++ b/packages/app-desktop/gui/MainScreen/commands/toggleNoteList.ts @@ -1,5 +1,8 @@ -import { CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService'; +import { CommandContext, CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService'; import { _ } from '@joplin/lib/locale'; +import setLayoutItemProps from '../../ResizableLayout/utils/setLayoutItemProps'; +import layoutItemProp from '../../ResizableLayout/utils/layoutItemProp'; +import { AppState } from '../../../app'; export const declaration: CommandDeclaration = { name: 'toggleNoteList', @@ -7,11 +10,18 @@ export const declaration: CommandDeclaration = { iconName: 'fas fa-align-justify', }; -export const runtime = (comp: any): CommandRuntime => { +export const runtime = (): CommandRuntime => { return { - execute: async () => { - comp.props.dispatch({ - type: 'NOTELIST_VISIBILITY_TOGGLE', + execute: async (context: CommandContext) => { + const layout = (context.state as AppState).mainLayout; + + const newLayout = setLayoutItemProps(layout, 'noteList', { + visible: !layoutItemProp(layout, 'noteList', 'visible'), + }); + + context.dispatch({ + type: 'MAIN_LAYOUT_SET', + value: newLayout, }); }, }; diff --git a/packages/app-desktop/gui/MainScreen/commands/toggleSideBar.ts b/packages/app-desktop/gui/MainScreen/commands/toggleSideBar.ts index 7a6c4e311e..b5bb24e51b 100644 --- a/packages/app-desktop/gui/MainScreen/commands/toggleSideBar.ts +++ b/packages/app-desktop/gui/MainScreen/commands/toggleSideBar.ts @@ -1,5 +1,8 @@ -import { CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService'; +import { CommandContext, CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService'; import { _ } from '@joplin/lib/locale'; +import setLayoutItemProps from '../../ResizableLayout/utils/setLayoutItemProps'; +import layoutItemProp from '../../ResizableLayout/utils/layoutItemProp'; +import { AppState } from '../../../app'; export const declaration: CommandDeclaration = { name: 'toggleSideBar', @@ -7,11 +10,18 @@ export const declaration: CommandDeclaration = { iconName: 'fas fa-bars', }; -export const runtime = (comp: any): CommandRuntime => { +export const runtime = (): CommandRuntime => { return { - execute: async () => { - comp.props.dispatch({ - type: 'SIDEBAR_VISIBILITY_TOGGLE', + execute: async (context: CommandContext) => { + const layout = (context.state as AppState).mainLayout; + + const newLayout = setLayoutItemProps(layout, 'sideBar', { + visible: !layoutItemProp(layout, 'sideBar', 'visible'), + }); + + context.dispatch({ + type: 'MAIN_LAYOUT_SET', + value: newLayout, }); }, }; diff --git a/packages/app-desktop/gui/MenuBar.tsx b/packages/app-desktop/gui/MenuBar.tsx index 14fbae7092..afa6ef9c4e 100644 --- a/packages/app-desktop/gui/MenuBar.tsx +++ b/packages/app-desktop/gui/MenuBar.tsx @@ -13,9 +13,9 @@ import { Module } from '@joplin/lib/services/interop/types'; import InteropServiceHelper from '../InteropServiceHelper'; import { _ } from '@joplin/lib/locale'; import { MenuItem, MenuItemLocation } from '@joplin/lib/services/plugins/api/types'; -import stateToWhenClauseContext from '@joplin/lib/services/commands/stateToWhenClauseContext'; import SpellCheckerService from '@joplin/lib/services/spellChecker/SpellCheckerService'; import menuCommandNames from './menuCommandNames'; +import stateToWhenClauseContext from '../services/commands/stateToWhenClauseContext'; const { connect } = require('react-redux'); const { reg } = require('@joplin/lib/registry.js'); @@ -519,6 +519,8 @@ function useMenu(props: Props) { view: { label: _('&View'), submenu: [ + menuItemDic.toggleLayoutMoveMode, + separator(), menuItemDic.toggleSideBar, menuItemDic.toggleNoteList, menuItemDic.toggleVisiblePanes, diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/Toolbar.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/Toolbar.tsx index d26becf2ac..75332ce065 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/Toolbar.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/Toolbar.tsx @@ -5,7 +5,7 @@ import { utils as pluginUtils } from '@joplin/lib/services/plugins/reducer'; import { connect } from 'react-redux'; import { AppState } from '../../../../app'; import ToolbarButtonUtils, { ToolbarButtonInfo } from '@joplin/lib/services/commands/ToolbarButtonUtils'; -import stateToWhenClauseContext from '@joplin/lib/services/commands/stateToWhenClauseContext'; +import stateToWhenClauseContext from '../../../../services/commands/stateToWhenClauseContext'; const { buildStyle } = require('@joplin/lib/theme'); interface ToolbarProps { diff --git a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx index ad6819fe94..bb18d13477 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx @@ -23,12 +23,12 @@ import eventManager from '@joplin/lib/eventManager'; import { AppState } from '../../app'; import ToolbarButtonUtils from '@joplin/lib/services/commands/ToolbarButtonUtils'; import { _ } from '@joplin/lib/locale'; -import stateToWhenClauseContext from '@joplin/lib/services/commands/stateToWhenClauseContext'; import TagList from '../TagList'; import NoteTitleBar from './NoteTitle/NoteTitleBar'; import markupLanguageUtils from '@joplin/lib/markupLanguageUtils'; import usePrevious from '../hooks/usePrevious'; import Setting from '@joplin/lib/models/Setting'; +import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext'; const { themeStyle } = require('@joplin/lib/theme'); const { substrWithEllipsis } = require('@joplin/lib/string-utils'); diff --git a/packages/app-desktop/gui/NoteListControls/NoteListControls.tsx b/packages/app-desktop/gui/NoteListControls/NoteListControls.tsx index bf47c6aebc..561bd39659 100644 --- a/packages/app-desktop/gui/NoteListControls/NoteListControls.tsx +++ b/packages/app-desktop/gui/NoteListControls/NoteListControls.tsx @@ -8,10 +8,11 @@ const styled = require('styled-components').default; interface Props { showNewNoteButtons: boolean; + height: number; } const StyledRoot = styled.div` - width: 100%; + height: ${(props: any) => props.height}px; display: flex; flex-direction: row; padding: ${(props: any) => props.theme.mainPadding}px; @@ -68,7 +69,7 @@ export default function NoteListControls(props: Props) { } return ( - + {renderNewNoteButtons()} diff --git a/packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.tsx b/packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.tsx new file mode 100644 index 0000000000..a513f53701 --- /dev/null +++ b/packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.tsx @@ -0,0 +1,39 @@ +import { themeStyle } from '@joplin/lib/theme'; +import * as React from 'react'; +import { useMemo } from 'react'; +import NoteList from '../NoteList/NoteList'; +import NoteListControls from '../NoteListControls/NoteListControls'; +import { Size } from '../ResizableLayout/utils/types'; +import styled from 'styled-components'; + +interface Props { + resizableLayoutEventEmitter: any; + size: Size; + visible: boolean; + focusedField: string; + themeId: number; +} + +const StyledRoot = styled.div` + display: flex; + flex-direction: column; +`; + +export default function NoteListWrapper(props: Props) { + const theme = themeStyle(props.themeId); + const controlHeight = theme.topRowHeight; + + const noteListSize = useMemo(() => { + return { + width: props.size.width, + height: props.size.height - controlHeight, + }; + }, [props.size, controlHeight]); + + return ( + + + + + ); +} diff --git a/packages/app-desktop/gui/NoteToolbar/NoteToolbar.tsx b/packages/app-desktop/gui/NoteToolbar/NoteToolbar.tsx index 6487bfe6df..333344516c 100644 --- a/packages/app-desktop/gui/NoteToolbar/NoteToolbar.tsx +++ b/packages/app-desktop/gui/NoteToolbar/NoteToolbar.tsx @@ -3,7 +3,7 @@ import CommandService from '@joplin/lib/services/CommandService'; import ToolbarBase from '../ToolbarBase'; import { utils as pluginUtils } from '@joplin/lib/services/plugins/reducer'; import ToolbarButtonUtils, { ToolbarButtonInfo } from '@joplin/lib/services/commands/ToolbarButtonUtils'; -import stateToWhenClauseContext from '@joplin/lib/services/commands/stateToWhenClauseContext'; +import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext'; const { connect } = require('react-redux'); const { buildStyle } = require('@joplin/lib/theme'); diff --git a/packages/app-desktop/gui/ResizableLayout/MoveButtons.tsx b/packages/app-desktop/gui/ResizableLayout/MoveButtons.tsx new file mode 100644 index 0000000000..26905c67fd --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/MoveButtons.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; +import { useCallback } from 'react'; +import Button, { ButtonLevel } from '../Button/Button'; +import { MoveDirection } from './utils/movements'; +import styled from 'styled-components'; + +const StyledRoot = styled.div` + display: flex; + flex-direction: column; + padding: 5px; + background-color: ${props => props.theme.backgroundColor}; + border-radius: 5px; +`; + +const ButtonRow = styled.div` + display: flex; + flex-direction: row; + justify-content: center; +`; + +const EmptyButton = styled(Button)` + visibility: hidden; +`; + +const ArrowButton = styled(Button)` + opacity: ${props => props.disabled ? 0.2 : 1}; +`; + +export interface MoveButtonClickEvent { + direction: MoveDirection; + itemKey: string; +} + +interface Props { + onClick(event: MoveButtonClickEvent): void; + itemKey: string; + canMoveLeft: boolean; + canMoveRight: boolean; + canMoveUp: boolean; + canMoveDown: boolean; +} + +export default function MoveButtons(props: Props) { + const onButtonClick = useCallback((direction: MoveDirection) => { + props.onClick({ direction, itemKey: props.itemKey }); + }, [props.onClick, props.itemKey]); + + function canMove(dir: MoveDirection) { + if (dir === MoveDirection.Up) return props.canMoveUp; + if (dir === MoveDirection.Down) return props.canMoveDown; + if (dir === MoveDirection.Left) return props.canMoveLeft; + if (dir === MoveDirection.Right) return props.canMoveRight; + throw new Error('Unreachable'); + } + + function renderButton(dir: MoveDirection) { + return onButtonClick(dir)} + />; + } + + return ( + + + {renderButton(MoveDirection.Up)} + + + {renderButton(MoveDirection.Left)} + + {renderButton(MoveDirection.Right)} + + + {renderButton(MoveDirection.Down)} + + + ); +} diff --git a/packages/app-desktop/gui/ResizableLayout/ResizableLayout.tsx b/packages/app-desktop/gui/ResizableLayout/ResizableLayout.tsx index f5591d75d2..a469ba7352 100644 --- a/packages/app-desktop/gui/ResizableLayout/ResizableLayout.tsx +++ b/packages/app-desktop/gui/ResizableLayout/ResizableLayout.tsx @@ -1,36 +1,18 @@ import * as React from 'react'; -import { useRef, useState } from 'react'; -import produce from 'immer'; -import useWindowResizeEvent from './hooks/useWindowResizeEvent'; -import useLayoutItemSizes, { LayoutItemSizes, itemSize } from './hooks/useLayoutItemSizes'; -const { Resizable } = require('re-resizable'); +import { useRef, useState, useEffect } from 'react'; +import useWindowResizeEvent from './utils/useWindowResizeEvent'; +import setLayoutItemProps from './utils/setLayoutItemProps'; +import useLayoutItemSizes, { LayoutItemSizes, itemSize } from './utils/useLayoutItemSizes'; +import validateLayout from './utils/validateLayout'; +import { Size, LayoutItem } from './utils/types'; +import { canMove, MoveDirection } from './utils/movements'; +import MoveButtons, { MoveButtonClickEvent } from './MoveButtons'; +import { StyledWrapperRoot, StyledMoveOverlay, MoveModeRootWrapper, MoveModeRootMessage } from './utils/style'; +import { Resizable } from 're-resizable'; const EventEmitter = require('events'); -export const dragBarThickness = 5; - -export enum LayoutItemDirection { - Row = 'row', - Column = 'column', -} - -export interface Size { - width: number; - height: number; -} - -export interface LayoutItem { - key: string; - width?: number; - height?: number; - minWidth?: number; - minHeight?: number; - children?: LayoutItem[]; - direction?: LayoutItemDirection; - resizableRight?: boolean; - resizableBottom?: boolean; - visible?: boolean; - context?: any; -} +const itemMinWidth = 20; +const itemMinHeight = 20; interface onResizeEvent { layout: LayoutItem; @@ -42,78 +24,24 @@ interface Props { width?: number; height?: number; renderItem: Function; + onMoveButtonClick(event: MoveButtonClickEvent): void; + moveMode: boolean; + moveModeMessage: string; } -export function allDynamicSizes(layout: LayoutItem): any { - const output: any = {}; - - function recurseProcess(item: LayoutItem) { - if (item.resizableBottom || item.resizableRight) { - if ('width' in item || 'height' in item) { - const size: any = {}; - if ('width' in item) size.width = item.width; - if ('height' in item) size.height = item.height; - output[item.key] = size; - } - } - - if (item.children) { - for (const child of item.children) { - recurseProcess(child); - } - } - } - - recurseProcess(layout); - - return output; +function itemVisible(item: LayoutItem, moveMode: boolean) { + if (moveMode) return true; + if (item.children && !item.children.length) return false; + return item.visible !== false; } -export function findItemByKey(layout: LayoutItem, key: string): LayoutItem { - function recurseFind(item: LayoutItem): LayoutItem { - if (item.key === key) return item; - - if (item.children) { - for (const child of item.children) { - const found = recurseFind(child); - if (found) return found; - } - } - return null; - } - - const output = recurseFind(layout); - if (!output) throw new Error(`Invalid item key: ${key}`); - return output; -} - -function updateLayoutItem(layout: LayoutItem, key: string, props: any) { - return produce(layout, (draftState: LayoutItem) => { - function recurseFind(item: LayoutItem) { - if (item.key === key) { - for (const n in props) { - (item as any)[n] = props[n]; - } - } else { - if (item.children) { - for (const child of item.children) { - recurseFind(child); - } - } - } - } - - recurseFind(draftState); - }); -} - -function renderContainer(item: LayoutItem, sizes: LayoutItemSizes, onResizeStart: Function, onResize: Function, onResizeStop: Function, children: any[], isLastChild: boolean): any { +function renderContainer(item: LayoutItem, parent: LayoutItem | null, sizes: LayoutItemSizes, onResizeStart: Function, onResize: Function, onResizeStop: Function, children: any[], isLastChild: boolean, moveMode: boolean): any { const style: any = { - display: item.visible !== false ? 'flex' : 'none', + display: itemVisible(item, moveMode) ? 'flex' : 'none', flexDirection: item.direction, }; - const size: Size = itemSize(item, sizes); + const size: Size = itemSize(item, parent, sizes, true); const className = `resizableLayoutItem rli-${item.key}`; if (item.resizableRight || item.resizableBottom) { @@ -128,21 +56,18 @@ function renderContainer(item: LayoutItem, sizes: LayoutItemSizes, onResizeStart topLeft: false, }; - if (item.resizableRight) style.paddingRight = dragBarThickness; - if (item.resizableBottom) style.paddingBottom = dragBarThickness; - return ( {children} @@ -161,8 +86,29 @@ function ResizableLayout(props: Props) { const [resizedItem, setResizedItem] = useState(null); - function renderLayoutItem(item: LayoutItem, sizes: LayoutItemSizes, isVisible: boolean, isLastChild: boolean): any { + function renderItemWrapper(comp: any, item: LayoutItem, parent: LayoutItem | null, size: Size, moveMode: boolean) { + const moveOverlay = moveMode ? ( + + + + ) : null; + return ( + + {moveOverlay} + {comp} + + ); + } + + function renderLayoutItem(item: LayoutItem, parent: LayoutItem | null, sizes: LayoutItemSizes, isVisible: boolean, isLastChild: boolean): any { function onResizeStart() { setResizedItem({ key: item.key, @@ -171,45 +117,79 @@ function ResizableLayout(props: Props) { }); } - function onResize(_event: any, _direction: any, _refToElement: HTMLDivElement, delta: any) { - const newLayout = updateLayoutItem(props.layout, item.key, { - width: resizedItem.initialWidth + delta.width, - height: resizedItem.initialHeight + delta.height, - }); + function onResize(_event: any, direction: string, _refToElement: any, delta: any) { + const newWidth = Math.max(itemMinWidth, resizedItem.initialWidth + delta.width); + const newHeight = Math.max(itemMinHeight, resizedItem.initialHeight + delta.height); + + const newSize: any = {}; + + if (item.width) newSize.width = item.width; + if (item.height) newSize.height = item.height; + + if (direction === 'bottom') { + newSize.height = newHeight; + } else { + newSize.width = newWidth; + } + + const newLayout = setLayoutItemProps(props.layout, item.key, newSize); props.onResize({ layout: newLayout }); eventEmitter.current.emit('resize'); } - function onResizeStop(_event: any, _direction: any, _refToElement: HTMLDivElement, delta: any) { + function onResizeStop(_event: any, _direction: any, _refToElement: any, delta: any) { onResize(_event, _direction, _refToElement, delta); setResizedItem(null); } if (!item.children) { + const size = itemSize(item, parent, sizes, false); + const comp = props.renderItem(item.key, { item: item, eventEmitter: eventEmitter.current, - size: sizes[item.key], + size: size, visible: isVisible, }); - return renderContainer(item, sizes, onResizeStart, onResize, onResizeStop, [comp], isLastChild); + const wrapper = renderItemWrapper(comp, item, parent, size, props.moveMode); + + return renderContainer(item, parent, sizes, onResizeStart, onResize, onResizeStop, [wrapper], isLastChild, props.moveMode); } else { const childrenComponents = []; for (let i = 0; i < item.children.length; i++) { const child = item.children[i]; - childrenComponents.push(renderLayoutItem(child, sizes, isVisible && child.visible !== false, i === item.children.length - 1)); + childrenComponents.push(renderLayoutItem(child, item, sizes, isVisible && itemVisible(child, props.moveMode), i === item.children.length - 1)); } - return renderContainer(item, sizes, onResizeStart, onResize, onResizeStop, childrenComponents, isLastChild); + return renderContainer(item, parent, sizes, onResizeStart, onResize, onResizeStop, childrenComponents, isLastChild, props.moveMode); } } - useWindowResizeEvent(eventEmitter); - const sizes = useLayoutItemSizes(props.layout); + useEffect(() => { + validateLayout(props.layout); + }, [props.layout]); - return renderLayoutItem(props.layout, sizes, props.layout.visible !== false, true); + useWindowResizeEvent(eventEmitter); + const sizes = useLayoutItemSizes(props.layout, props.moveMode); + + function renderMoveModeBox(rootComp: any) { + return ( + + {props.moveModeMessage} + {rootComp} + + ); + } + + const rootComp = renderLayoutItem(props.layout, null, sizes, itemVisible(props.layout, props.moveMode), true); + + if (props.moveMode) { + return renderMoveModeBox(rootComp); + } else { + return rootComp; + } } export default ResizableLayout; diff --git a/packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.ts b/packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.ts deleted file mode 100644 index 3bcefd71df..0000000000 --- a/packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { useMemo } from 'react'; -import { LayoutItem, Size, dragBarThickness } from '../ResizableLayout'; - -export interface LayoutItemSizes { - [key: string]: Size; -} - -export function itemSize(item: LayoutItem, sizes: LayoutItemSizes): Size { - return { - width: 'width' in item ? item.width : sizes[item.key].width, - height: 'height' in item ? item.height : sizes[item.key].height, - }; -} - -function calculateChildrenSizes(item: LayoutItem, sizes: LayoutItemSizes): LayoutItemSizes { - if (!item.children) return sizes; - - const parentSize = itemSize(item, sizes); - - const remainingSize: Size = { - width: parentSize.width, - height: parentSize.height, - }; - - const noWidthChildren: LayoutItem[] = []; - const noHeightChildren: LayoutItem[] = []; - - for (const child of item.children) { - let w = 'width' in child ? child.width : null; - let h = 'height' in child ? child.height : null; - if (child.visible === false) { - w = 0; - h = 0; - } - - if (item.resizableRight) w -= dragBarThickness; - if (item.resizableBottom) h -= dragBarThickness; - - sizes[child.key] = { width: w, height: h }; - if (w !== null) remainingSize.width -= w; - if (h !== null) remainingSize.height -= h; - if (w === null) noWidthChildren.push(child); - if (h === null) noHeightChildren.push(child); - } - - if (noWidthChildren.length) { - const w = item.direction === 'row' ? remainingSize.width / noWidthChildren.length : parentSize.width; - for (const child of noWidthChildren) { - sizes[child.key].width = w; - } - } - - if (noHeightChildren.length) { - const h = item.direction === 'column' ? remainingSize.height / noHeightChildren.length : parentSize.height; - for (const child of noHeightChildren) { - sizes[child.key].height = h; - } - } - - for (const child of item.children) { - const childrenSizes = calculateChildrenSizes(child, sizes); - sizes = { ...sizes, ...childrenSizes }; - } - - return sizes; -} - -export default function useLayoutItemSizes(layout: LayoutItem) { - return useMemo(() => { - let sizes: LayoutItemSizes = {}; - - if (!('width' in layout) || !('height' in layout)) throw new Error('width and height are required on layout root'); - - sizes[layout.key] = { - width: layout.width, - height: layout.height, - }; - - sizes = calculateChildrenSizes(layout, sizes); - - return sizes; - }, [layout]); -} diff --git a/packages/app-desktop/gui/ResizableLayout/utils/findItemByKey.ts b/packages/app-desktop/gui/ResizableLayout/utils/findItemByKey.ts new file mode 100644 index 0000000000..9238cdc2a1 --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/findItemByKey.ts @@ -0,0 +1,23 @@ +import { LayoutItem } from './types'; + +export default function findItemByKey(layout: LayoutItem, key: string): LayoutItem { + if (!layout) throw new Error('Layout cannot be null'); + + function recurseFind(item: LayoutItem): LayoutItem { + if (item.key === key) return item; + + if (item.children) { + for (const child of item.children) { + const found = recurseFind(child); + if (found) return found; + } + } + return null; + } + + return recurseFind(layout); + + // const output = recurseFind(layout); + // if (!output) throw new Error(`Could not find item "${key}"`); + // return output; +} diff --git a/packages/app-desktop/gui/ResizableLayout/utils/isTempContainer.ts b/packages/app-desktop/gui/ResizableLayout/utils/isTempContainer.ts new file mode 100644 index 0000000000..d9dca0a63a --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/isTempContainer.ts @@ -0,0 +1,5 @@ +import { tempContainerPrefix } from './types'; + +export default function(itemKey: string): boolean { + return itemKey.indexOf(tempContainerPrefix) === 0; +} diff --git a/packages/app-desktop/gui/ResizableLayout/utils/iterateItems.ts b/packages/app-desktop/gui/ResizableLayout/utils/iterateItems.ts new file mode 100644 index 0000000000..1a40de9361 --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/iterateItems.ts @@ -0,0 +1,21 @@ +import { LayoutItem } from './types'; + +type ItemItemCallback = (itemIndex: number, item: LayoutItem, parent: LayoutItem)=> boolean; + +export default function iterateItems(layout: LayoutItem, callback: ItemItemCallback) { + const result = callback(0, layout, null); + if (result === false) return; + + function recurseFind(item: LayoutItem, callback: Function): boolean { + if (item.children) { + for (let childIndex = 0; childIndex < item.children.length; childIndex++) { + const child = item.children[childIndex]; + if (callback(childIndex, child, item) === false) return false; + if (recurseFind(child, callback) === false) return false; + } + } + return true; + } + + if (recurseFind(layout, callback) === false) return; +} diff --git a/packages/app-desktop/gui/ResizableLayout/utils/layoutItemProp.ts b/packages/app-desktop/gui/ResizableLayout/utils/layoutItemProp.ts new file mode 100644 index 0000000000..df64dcdf78 --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/layoutItemProp.ts @@ -0,0 +1,8 @@ +import findItemByKey from './findItemByKey'; +import { LayoutItem } from './types'; + +export default function layoutItemProp(layout: LayoutItem, key: string, propName: string) { + const item = findItemByKey(layout, key); + if (!item) throw new Error(`Could not find layout item: ${key}`); + return (item as any)[propName]; +} diff --git a/packages/app-desktop/gui/ResizableLayout/utils/movements.test.ts b/packages/app-desktop/gui/ResizableLayout/utils/movements.test.ts new file mode 100644 index 0000000000..805464982d --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/movements.test.ts @@ -0,0 +1,228 @@ +import { LayoutItem, LayoutItemDirection } from './types'; +import validateLayout from './validateLayout'; +import { canMove, MoveDirection, moveHorizontal, moveVertical } from './movements'; +import findItemByKey from './findItemByKey'; + +describe('movements', () => { + + test('should move items horizontally to the right', () => { + let layout: LayoutItem = validateLayout({ + key: 'root', + width: 100, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { + key: 'col1', + }, + { + key: 'col2', + }, + { + key: 'col3', + }, + ], + }); + + expect(() => moveHorizontal(layout, 'col1', -1)).toThrow(); + + layout = moveHorizontal(layout, 'col1', 1); + + expect(layout.children[0].children[0].key).toBe('col2'); + expect(layout.children[0].children[1].key).toBe('col1'); + expect(layout.children[1].key).toBe('col3'); + + layout = moveHorizontal(layout, 'col1', 1); + + expect(layout.children[0].key).toBe('col2'); + expect(layout.children[1].key).toBe('col1'); + expect(layout.children[2].key).toBe('col3'); + + layout = moveHorizontal(layout, 'col1', 1); + layout = moveHorizontal(layout, 'col1', 1); + + expect(() => moveHorizontal(layout, 'col1', 1)).toThrow(); + }); + + test('should move items horizontally to the left', () => { + let layout: LayoutItem = validateLayout({ + key: 'root', + width: 100, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { + key: 'col1', + direction: LayoutItemDirection.Column, + children: [ + { key: 'item1' }, + { key: 'item2' }, + ], + }, + { + key: 'col2', + }, + ], + }); + + layout = moveHorizontal(layout, 'item2', -1); + + expect(layout.children[0].key).toBe('item2'); + expect(layout.children[1].key).toBe('item1'); + expect(layout.children[2].key).toBe('col2'); + }); + + test('should move items vertically', () => { + let layout: LayoutItem = validateLayout({ + key: 'root', + width: 100, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { + key: 'col1', + }, + { + key: 'col2', + direction: LayoutItemDirection.Column, + children: [ + { key: 'row1' }, + { key: 'row2' }, + { key: 'row3' }, + ], + }, + { + key: 'col3', + }, + ], + }); + + layout = moveVertical(layout, 'row3', -1); + + expect(layout.children[1].children[0].key).toBe('row1'); + expect(layout.children[1].children[1].key).toBe('row3'); + expect(layout.children[1].children[2].key).toBe('row2'); + }); + + test('should tell if item can be moved', () => { + const layout: LayoutItem = validateLayout({ + key: 'root', + width: 200, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { + key: 'col1', + resizableRight: true, + direction: LayoutItemDirection.Column, + children: [ + { key: 'row1' }, + { key: 'row2' }, + ], + }, + { + key: 'col2', + }, + ], + }); + + expect(canMove(MoveDirection.Up, findItemByKey(layout, 'col1'), findItemByKey(layout, 'root'))).toBe(false); + expect(canMove(MoveDirection.Down, findItemByKey(layout, 'col1'), findItemByKey(layout, 'root'))).toBe(false); + expect(canMove(MoveDirection.Left, findItemByKey(layout, 'col1'), findItemByKey(layout, 'root'))).toBe(false); + expect(canMove(MoveDirection.Right, findItemByKey(layout, 'col1'), findItemByKey(layout, 'root'))).toBe(true); + + expect(canMove(MoveDirection.Up, findItemByKey(layout, 'row1'), findItemByKey(layout, 'col1'))).toBe(false); + expect(canMove(MoveDirection.Down, findItemByKey(layout, 'row1'), findItemByKey(layout, 'col1'))).toBe(true); + expect(canMove(MoveDirection.Left, findItemByKey(layout, 'row1'), findItemByKey(layout, 'col1'))).toBe(true); + expect(canMove(MoveDirection.Right, findItemByKey(layout, 'row1'), findItemByKey(layout, 'col1'))).toBe(true); + + expect(canMove(MoveDirection.Up, findItemByKey(layout, 'row2'), findItemByKey(layout, 'col1'))).toBe(true); + expect(canMove(MoveDirection.Down, findItemByKey(layout, 'row2'), findItemByKey(layout, 'col1'))).toBe(false); + expect(canMove(MoveDirection.Left, findItemByKey(layout, 'row2'), findItemByKey(layout, 'col1'))).toBe(true); + expect(canMove(MoveDirection.Right, findItemByKey(layout, 'row2'), findItemByKey(layout, 'col1'))).toBe(true); + + expect(canMove(MoveDirection.Up, findItemByKey(layout, 'col2'), findItemByKey(layout, 'root'))).toBe(false); + expect(canMove(MoveDirection.Down, findItemByKey(layout, 'col2'), findItemByKey(layout, 'root'))).toBe(false); + expect(canMove(MoveDirection.Left, findItemByKey(layout, 'col2'), findItemByKey(layout, 'root'))).toBe(true); + expect(canMove(MoveDirection.Right, findItemByKey(layout, 'col2'), findItemByKey(layout, 'root'))).toBe(false); + }); + + test('Container with only one child should take the width of its parent', () => { + let layout: LayoutItem = validateLayout({ + key: 'root', + width: 100, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { + key: 'col1', + width: 50, + }, + { + key: 'col2', + }, + ], + }); + + layout = moveHorizontal(layout, 'col2', -1); + + expect(layout.children[0].children[0].key).toBe('col1'); + expect(layout.children[0].children[0].width).toBe(undefined); + }); + + test('Temp container should take the width of the child it replaces', () => { + let layout: LayoutItem = validateLayout({ + key: 'root', + width: 100, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { + key: 'col1', + width: 20, + }, + { + key: 'col2', + width: 80, + }, + { + key: 'col3', + }, + ], + }); + + layout = moveHorizontal(layout, 'col2', -1); + + expect(layout.children[0].width).toBe(20); + expect(layout.children[0].children[0].width).toBe(undefined); + expect(layout.children[0].children[1].width).toBe(undefined); + }); + + test('Last child should have flexible width if all siblings have fixed width', () => { + let layout: LayoutItem = validateLayout({ + key: 'root', + width: 100, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { + key: 'col1', + width: 20, + }, + { + key: 'col2', + width: 20, + }, + { + key: 'col3', + }, + ], + }); + + layout = moveHorizontal(layout, 'col3', -1); + + expect(layout.children[0].width).toBe(20); + expect(layout.children[1].width).toBe(undefined); + }); + +}); diff --git a/packages/app-desktop/gui/ResizableLayout/utils/movements.ts b/packages/app-desktop/gui/ResizableLayout/utils/movements.ts new file mode 100644 index 0000000000..eee79ca20d --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/movements.ts @@ -0,0 +1,190 @@ +import iterateItems from './iterateItems'; +import { LayoutItem, LayoutItemDirection, tempContainerPrefix } from './types'; +import produce from 'immer'; +import uuid from '@joplin/lib/uuid'; +import validateLayout from './validateLayout'; + +export enum MoveDirection { + Up = 'up', + Down = 'down', + Left = 'left', + Right = 'right', +} + +enum MovementDirection { + Horizontal = 1, + Vertical = 2, +} + +function array_move(arr: any[], old_index: number, new_index: number) { + arr = arr.slice(); + if (new_index >= arr.length) { + let k = new_index - arr.length + 1; + while (k--) { + arr.push(undefined); + } + } + arr.splice(new_index, 0, arr.splice(old_index, 1)[0]); + return arr; +} + +function findItemIndex(siblings: LayoutItem[], key: string) { + return siblings.findIndex((value: LayoutItem) => { + return value.key === key; + }); +} + +function isHorizontalMove(direction: MoveDirection) { + return direction === MoveDirection.Left || direction === MoveDirection.Right; +} + +function resetItemSizes(items: LayoutItem[]) { + return items.map((item: LayoutItem) => { + const newItem = { ...item }; + delete newItem.width; + delete newItem.height; + return newItem; + }); +} + +export function canMove(direction: MoveDirection, item: LayoutItem, parent: LayoutItem) { + if (!parent) return false; + + if (isHorizontalMove(direction)) { + if (parent.isRoot) { + const idx = direction === MoveDirection.Left ? 0 : parent.children.length - 1; + return parent.children[idx] !== item; + } else if (parent.direction === LayoutItemDirection.Column) { + return true; + } + } else { + if (parent.isRoot) { + return false; + } else if (parent.direction === LayoutItemDirection.Column) { + const idx = direction === MoveDirection.Up ? 0 : parent.children.length - 1; + return parent.children[idx] !== item; + } + } + + throw new Error('Unhandled case'); +} + +// For all movements we make the assumption that there's a root container, +// which is a row of multiple columns. Within each of these columns there +// can be multiple rows (one item per row). Items cannot be more deeply +// nested. +function moveItem(direction: MovementDirection, layout: LayoutItem, key: string, inc: number): LayoutItem { + const itemParents: Record = {}; + + const itemIsRoot = (item: LayoutItem) => { + return !itemParents[item.key]; + }; + + const updatedLayout = produce(layout, (draft: any) => { + iterateItems(draft, (itemIndex: number, item: LayoutItem, parent: LayoutItem) => { + itemParents[item.key] = parent; + + if (item.key !== key || !parent) return true; + + // - "flow" means we are moving an item horizontally within a + // row + // - "contrary" means we are moving an item horizontally within + // a column. Sicen it can't move horizontally, it is moved + // out of its container. And vice-versa for vertical + // movements. + let moveType = null; + + if (direction === MovementDirection.Horizontal && parent.direction === LayoutItemDirection.Row) moveType = 'flow'; + if (direction === MovementDirection.Horizontal && parent.direction === LayoutItemDirection.Column) moveType = 'contrary'; + if (direction === MovementDirection.Vertical && parent.direction === LayoutItemDirection.Column) moveType = 'flow'; + if (direction === MovementDirection.Vertical && parent.direction === LayoutItemDirection.Row) moveType = 'contrary'; + + if (moveType === 'flow') { + const newIndex = itemIndex + inc; + + if (newIndex >= parent.children.length || newIndex < 0) throw new Error(`Cannot move item "${key}" from position ${itemIndex} to ${newIndex}`); + + // If the item next to it is a container (has children), + // move the item inside the container + if (parent.children[newIndex].children) { + const newParent = parent.children[newIndex]; + parent.children.splice(itemIndex, 1); + newParent.children.push(item); + newParent.children = resetItemSizes(newParent.children); + } else { + // If the item is a child of the root container, create + // a new column at `newIndex` and move the item that + // was there, as well as the current item, in this + // container. + if (itemIsRoot(parent)) { + const targetChild = parent.children[newIndex]; + + // The new container takes the size of the item it + // replaces. + const newSize: any = {}; + if (direction === MovementDirection.Horizontal) { + if ('width' in targetChild) newSize.width = targetChild.width; + } else { + if ('height' in targetChild) newSize.height = targetChild.height; + } + + const newParent: LayoutItem = { + key: `${tempContainerPrefix}${uuid.createNano()}`, + direction: LayoutItemDirection.Column, + children: [ + targetChild, + item, + ], + ...newSize, + }; + + parent.children[newIndex] = newParent; + parent.children.splice(itemIndex, 1); + + newParent.children = resetItemSizes(newParent.children); + } else { + // Otherwise the default case is simply to move the + // item left/right + parent.children = array_move(parent.children, itemIndex, newIndex); + } + } + } else { + const parentParent = itemParents[parent.key]; + const parentIndex = findItemIndex(parentParent.children, parent.key); + + parent.children.splice(itemIndex, 1); + + let newInc = inc; + if (parent.children.length <= 1) { + parentParent.children[parentIndex] = parent.children[0]; + newInc = inc < 0 ? inc + 1 : inc; + } + + const newItemIndex = parentIndex + newInc; + + parentParent.children.splice(newItemIndex, 0, item); + parentParent.children = resetItemSizes(parentParent.children); + } + + return false; + }); + }); + + return validateLayout(updatedLayout); +} + +export function moveHorizontal(layout: LayoutItem, key: string, inc: number): LayoutItem { + return moveItem(MovementDirection.Horizontal, layout, key, inc); +} + +export function moveVertical(layout: LayoutItem, key: string, inc: number): LayoutItem { + return moveItem(MovementDirection.Vertical, layout, key, inc); +} + +export function move(layout: LayoutItem, key: string, direction: MoveDirection): LayoutItem { + if (direction === MoveDirection.Up) return moveVertical(layout, key, -1); + if (direction === MoveDirection.Down) return moveVertical(layout, key, +1); + if (direction === MoveDirection.Left) return moveHorizontal(layout, key, -1); + if (direction === MoveDirection.Right) return moveHorizontal(layout, key, +1); + throw new Error('Unreachable'); +} diff --git a/packages/app-desktop/gui/ResizableLayout/utils/persist.test.ts b/packages/app-desktop/gui/ResizableLayout/utils/persist.test.ts new file mode 100644 index 0000000000..015e8d854b --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/persist.test.ts @@ -0,0 +1,77 @@ +import { loadLayout, saveLayout } from './persist'; +import { LayoutItem, LayoutItemDirection } from './types'; +import validateLayout from './validateLayout'; + +describe('persist', () => { + + test('should save layout and filter out non-user properties', () => { + const layout: LayoutItem = validateLayout({ + key: 'root', + width: 100, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { + key: 'col1', + width: 50, + }, + { + key: 'col2', + direction: LayoutItemDirection.Column, + children: [ + { key: 'item1', height: 20 }, + { key: 'item2' }, + ], + }, + { + key: 'col3', + }, + ], + }); + + const toSave = saveLayout(layout); + + expect(toSave.key).toBe('root'); + expect(toSave.width).toBeUndefined(); + expect(toSave.height).toBeUndefined(); + expect(toSave.direction).toBeUndefined(); + expect(toSave.children.length).toBe(3); + + expect(toSave.children[1].key).toBe('col2'); + expect(toSave.children[1].direction).toBeUndefined(); + }); + + test('should load a layout', () => { + const layout: any = { + key: 'root', + children: [ + { + key: 'col1', + width: 50, + }, + { + key: 'col2', + children: [ + { key: 'item1', height: 20 }, + { key: 'item2' }, + ], + }, + { + key: 'col3', + }, + ], + }; + + const loaded = loadLayout(layout, null, { width: 100, height: 200 }); + + expect(loaded.key).toBe('root'); + expect(loaded.width).toBe(100); + expect(loaded.height).toBe(200); + expect(loaded.direction).toBe(LayoutItemDirection.Row); + expect(loaded.children.length).toBe(3); + + expect(loaded.children[1].key).toBe('col2'); + expect(loaded.children[1].direction).toBe(LayoutItemDirection.Column); + }); + +}); diff --git a/packages/app-desktop/gui/ResizableLayout/utils/persist.ts b/packages/app-desktop/gui/ResizableLayout/utils/persist.ts new file mode 100644 index 0000000000..98292efc9b --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/persist.ts @@ -0,0 +1,41 @@ +import { LayoutItem, Size } from './types'; +import produce from 'immer'; +import iterateItems from './iterateItems'; +import validateLayout from './validateLayout'; + +export function saveLayout(layout: LayoutItem): any { + const propertyWhiteList = [ + 'visible', + 'width', + 'height', + 'children', + 'key', + 'context', + ]; + + return produce(layout, (draft: any) => { + delete draft.width; + delete draft.height; + iterateItems(draft, (_itemIndex: number, item: LayoutItem, _parent: LayoutItem) => { + for (const k of Object.keys(item)) { + if (!propertyWhiteList.includes(k)) delete (item as any)[k]; + } + return true; + }); + }); +} + +export function loadLayout(layout: any, defaultLayout: LayoutItem, rootSize: Size): LayoutItem { + let output: LayoutItem = null; + + if (layout) { + output = { ...layout }; + } else { + output = { ...defaultLayout }; + } + + output.width = rootSize.width; + output.height = rootSize.height; + + return validateLayout(output); +} diff --git a/packages/app-desktop/gui/ResizableLayout/utils/removeItem.ts b/packages/app-desktop/gui/ResizableLayout/utils/removeItem.ts new file mode 100644 index 0000000000..2f067c3356 --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/removeItem.ts @@ -0,0 +1,18 @@ +import produce from 'immer'; +import iterateItems from './iterateItems'; +import { LayoutItem } from './types'; +import validateLayout from './validateLayout'; + +export default function(layout: LayoutItem, itemKey: string): LayoutItem { + const output = produce(layout, (layoutDraft: LayoutItem) => { + iterateItems(layoutDraft, (itemIndex: number, item: LayoutItem, parent: LayoutItem) => { + if (item.key === itemKey) { + parent.children.splice(itemIndex, 1); + return false; + } + return true; + }); + }); + + return output !== layout ? validateLayout(output) : layout; +} diff --git a/packages/app-desktop/gui/ResizableLayout/utils/setLayoutItemProps.ts b/packages/app-desktop/gui/ResizableLayout/utils/setLayoutItemProps.ts new file mode 100644 index 0000000000..8cf7cfa714 --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/setLayoutItemProps.ts @@ -0,0 +1,23 @@ +import produce from 'immer'; +import { LayoutItem } from './types'; +import validateLayout from './validateLayout'; + +export default function setLayoutItemProps(layout: LayoutItem, key: string, props: any) { + return validateLayout(produce(layout, (draftState: LayoutItem) => { + function recurseFind(item: LayoutItem) { + if (item.key === key) { + for (const n in props) { + (item as any)[n] = props[n]; + } + } else { + if (item.children) { + for (const child of item.children) { + recurseFind(child); + } + } + } + } + + recurseFind(draftState); + })); +} diff --git a/packages/app-desktop/gui/ResizableLayout/utils/style.ts b/packages/app-desktop/gui/ResizableLayout/utils/style.ts new file mode 100644 index 0000000000..023b17153e --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/style.ts @@ -0,0 +1,38 @@ +import { ThemeAppearance } from '@joplin/lib/themes/type'; +import styled from 'styled-components'; + +export const StyledWrapperRoot = styled.div` + position: relative; + display: flex; + width: ${props => props.size.width}px; + height: ${props => props.size.height}px; +`; + +export const StyledMoveOverlay = styled.div` + display: flex; + justify-content: center; + align-items: center; + z-index: 100; + background-color: ${props => props.theme.appearance === ThemeAppearance.Light ? 'rgba(0,0,0,0.5)' : 'rgba(255,255,255,0.5)'}; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +`; + +export const MoveModeRootWrapper = styled.div` + position:relative; + display: flex; + align-items: center; + justify-content: center; +`; + +export const MoveModeRootMessage = styled.div` + position:absolute; + bottom: 10px; + z-index:200; + background-color: ${props => props.theme.backgroundColor}; + padding: 10px; + border-radius: 5; +`; diff --git a/packages/app-desktop/gui/ResizableLayout/utils/types.ts b/packages/app-desktop/gui/ResizableLayout/utils/types.ts new file mode 100644 index 0000000000..e9e3b5a410 --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/types.ts @@ -0,0 +1,26 @@ +export enum LayoutItemDirection { + Row = 'row', + Column = 'column', +} + +export interface Size { + width: number; + height: number; +} + +export interface LayoutItem { + key: string; + isRoot?: boolean; + width?: number; + height?: number; + minWidth?: number; + minHeight?: number; + children?: LayoutItem[]; + direction?: LayoutItemDirection; + resizableRight?: boolean; + resizableBottom?: boolean; + visible?: boolean; + context?: any; +} + +export const tempContainerPrefix = 'tempContainer-'; diff --git a/packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.ts b/packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.ts new file mode 100644 index 0000000000..13e0f4821f --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.ts @@ -0,0 +1,89 @@ +import useLayoutItemSizes, { itemSize } from './useLayoutItemSizes'; +import { LayoutItem, LayoutItemDirection } from './types'; +import { renderHook } from '@testing-library/react-hooks'; +import validateLayout from './validateLayout'; + +describe('useLayoutItemSizes', () => { + + test('should validate the layout', () => { + const layout: LayoutItem = validateLayout({ + key: 'root', + width: 200, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { key: 'col1' }, + { key: 'col2' }, + ], + }); + + expect(layout.isRoot).toBe(true); + }); + + test('should give item sizes', () => { + const layout: LayoutItem = validateLayout({ + key: 'root', + width: 200, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { + key: 'col1', + width: 50, + }, + { + key: 'col2', + }, + ], + }); + + const { result } = renderHook(() => useLayoutItemSizes(layout)); + const sizes = result.current; + + expect(sizes.root).toEqual({ width: 200, height: 100 }); + expect(sizes.col1).toEqual({ width: 50, height: 100 }); + expect(sizes.col2).toEqual({ width: 150, height: 100 }); + }); + + test('should leave room for the resizer controls', () => { + const layout: LayoutItem = validateLayout({ + key: 'root', + width: 200, + height: 100, + direction: LayoutItemDirection.Row, + children: [ + { + key: 'col1', + resizableRight: true, + direction: LayoutItemDirection.Column, + children: [ + { key: 'row1', resizableBottom: true }, + { key: 'row2' }, + ], + }, + { + key: 'col2', + }, + ], + }); + + const { result } = renderHook(() => useLayoutItemSizes(layout)); + + const sizes = result.current; + + expect(sizes).toEqual({ + root: { width: 200, height: 100 }, + col1: { width: 100, height: 100 }, + col2: { width: 100, height: 100 }, + row1: { width: 100, height: 50 }, + row2: { width: 100, height: 50 }, + }); + + expect(itemSize(layout.children[0], layout, sizes, true)).toEqual({ width: 100, height: 100 }); + + const parent = layout.children[0]; + expect(itemSize(parent.children[0], parent, sizes, false)).toEqual({ width: 95, height: 45 }); + expect(itemSize(parent.children[1], parent, sizes, false)).toEqual({ width: 95, height: 50 }); + }); + +}); diff --git a/packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.ts b/packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.ts new file mode 100644 index 0000000000..b0a6a6dc01 --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.ts @@ -0,0 +1,95 @@ +import { useMemo } from 'react'; +import { LayoutItem, Size } from './types'; + +const dragBarThickness = 5; + +export interface LayoutItemSizes { + [key: string]: Size; +} + +// Container always take the full space while the items within it need to +// accomodate for the resize handle. +export function itemSize(item: LayoutItem, parent: LayoutItem | null, sizes: LayoutItemSizes, isContainer: boolean): Size { + const parentResizableRight = !!parent && parent.resizableRight; + const parentResizableBottom = !!parent && parent.resizableBottom; + + const rightGap = !isContainer && (item.resizableRight || parentResizableRight) ? dragBarThickness : 0; + const bottomGap = !isContainer && (item.resizableBottom || parentResizableBottom) ? dragBarThickness : 0; + + return { + width: ('width' in item ? item.width : sizes[item.key].width) - rightGap, + height: ('height' in item ? item.height : sizes[item.key].height) - bottomGap, + }; +} + +// This calculate the size of each item within the layout. However +// the final size, as rendered by the component is determined by +// `itemSize()`, as it takes into account the resizer handle +function calculateChildrenSizes(item: LayoutItem, parent: LayoutItem | null, sizes: LayoutItemSizes, makeAllVisible: boolean): LayoutItemSizes { + if (!item.children) return sizes; + + const parentSize = itemSize(item, parent, sizes, true); + + const remainingSize: Size = { + width: parentSize.width, + height: parentSize.height, + }; + + const noWidthChildren: any[] = []; + const noHeightChildren: any[] = []; + + for (const child of item.children) { + let w = 'width' in child ? child.width : null; + let h = 'height' in child ? child.height : null; + if (!makeAllVisible && child.visible === false) { + w = 0; + h = 0; + } + + sizes[child.key] = { width: w, height: h }; + if (w !== null) remainingSize.width -= w; + if (h !== null) remainingSize.height -= h; + if (w === null) noWidthChildren.push({ item: child, parent: item }); + if (h === null) noHeightChildren.push({ item: child, parent: item }); + } + + if (noWidthChildren.length) { + const w = item.direction === 'row' ? Math.floor(remainingSize.width / noWidthChildren.length) : parentSize.width; + for (const child of noWidthChildren) { + const finalWidth = w; + sizes[child.item.key].width = finalWidth; + } + } + + if (noHeightChildren.length) { + const h = item.direction === 'column' ? Math.floor(remainingSize.height / noHeightChildren.length) : parentSize.height; + for (const child of noHeightChildren) { + const finalHeight = h; + sizes[child.item.key].height = finalHeight; + } + } + + for (const child of item.children) { + const childrenSizes = calculateChildrenSizes(child, parent, sizes, makeAllVisible); + sizes = { ...sizes, ...childrenSizes }; + } + + return sizes; +} + +export default function useLayoutItemSizes(layout: LayoutItem, makeAllVisible: boolean = false) { + return useMemo(() => { + let sizes: LayoutItemSizes = {}; + + if (!('width' in layout) || !('height' in layout)) throw new Error('width and height are required on layout root'); + + sizes[layout.key] = { + width: layout.width, + height: layout.height, + }; + + sizes = calculateChildrenSizes(layout, null, sizes, makeAllVisible); + + return sizes; + }, [layout, makeAllVisible]); +} diff --git a/packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.ts b/packages/app-desktop/gui/ResizableLayout/utils/useWindowResizeEvent.ts similarity index 100% rename from packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.ts rename to packages/app-desktop/gui/ResizableLayout/utils/useWindowResizeEvent.ts diff --git a/packages/app-desktop/gui/ResizableLayout/utils/validateLayout.ts b/packages/app-desktop/gui/ResizableLayout/utils/validateLayout.ts new file mode 100644 index 0000000000..9a248acac4 --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/utils/validateLayout.ts @@ -0,0 +1,103 @@ +import produce from 'immer'; +import iterateItems from './iterateItems'; +import { LayoutItem, LayoutItemDirection } from './types'; + +function updateItemSize(itemIndex: number, itemDraft: LayoutItem, parent: LayoutItem) { + if (!parent) return; + + // If a container has only one child, this child should not + // have a width and height, and simply fill up the container + if (parent.children.length === 1) { + delete itemDraft.width; + delete itemDraft.height; + } + + // If all children of a container have a fixed width, the + // latest child should have a flexible width (i.e. no "width" + // property), so that it fills up the remaining space + if (itemIndex === parent.children.length - 1) { + let allChildrenAreSized = true; + for (const child of parent.children) { + if (parent.direction === LayoutItemDirection.Row) { + if (!child.width) { + allChildrenAreSized = false; + break; + } + } else { + if (!child.height) { + allChildrenAreSized = false; + break; + } + } + } + + if (allChildrenAreSized) { + if (parent.direction === LayoutItemDirection.Row) { + delete itemDraft.width; + } else { + delete itemDraft.height; + } + } + } +} + +// All items should be resizable, except for the root and the latest child +// of a container. +function updateResizeRules(itemIndex: number, itemDraft: LayoutItem, parent: LayoutItem) { + if (!parent) return; + const isLastChild = itemIndex === parent.children.length - 1; + itemDraft.resizableRight = parent.direction === LayoutItemDirection.Row && !isLastChild; + itemDraft.resizableBottom = parent.direction === LayoutItemDirection.Column && !isLastChild; +} + +// Container direction should alternate between row (for the root) and +// columns, then rows again. +function updateDirection(_itemIndex: number, itemDraft: LayoutItem, parent: LayoutItem) { + if (!parent) { + itemDraft.direction = LayoutItemDirection.Row; + } else { + itemDraft.direction = parent.direction === LayoutItemDirection.Row ? LayoutItemDirection.Column : LayoutItemDirection.Row; + } +} + +function itemShouldBeVisible(item: LayoutItem): boolean { + if (!item.children) return item.visible !== false; + + let oneIsVisible = false; + + for (const child of item.children) { + if (itemShouldBeVisible(child)) { + oneIsVisible = true; + break; + } + } + + return oneIsVisible; +} + +// If all children of a container are hidden, the container should be +// hidden too. A container visiblity cannot be changed by the user. +function updateContainerVisibility(_itemIndex: number, itemDraft: LayoutItem, _parent: LayoutItem) { + if (itemDraft.children) { + itemDraft.visible = itemShouldBeVisible(itemDraft); + } else { + itemDraft.visible = itemDraft.visible !== false; + } +} + +export default function validateLayout(layout: LayoutItem): LayoutItem { + if (!layout) throw new Error('Layout is null'); + if (!layout.children || !layout.children.length) throw new Error('Root does not have children'); + + return produce(layout, (draft: LayoutItem) => { + draft.isRoot = true; + + iterateItems(draft, (itemIndex: number, itemDraft: LayoutItem, parent: LayoutItem) => { + updateItemSize(itemIndex, itemDraft, parent); + updateResizeRules(itemIndex, itemDraft, parent); + updateDirection(itemIndex, itemDraft, parent); + updateContainerVisibility(itemIndex, itemDraft, parent); + return true; + }); + }); +} diff --git a/packages/app-desktop/gui/Root.tsx b/packages/app-desktop/gui/Root.tsx index 72d8f0a023..642ea718e1 100644 --- a/packages/app-desktop/gui/Root.tsx +++ b/packages/app-desktop/gui/Root.tsx @@ -6,7 +6,7 @@ import OneDriveLoginScreen from './OneDriveLoginScreen'; import DropboxLoginScreen from './DropboxLoginScreen'; import ErrorBoundary from './ErrorBoundary'; import { themeStyle } from '@joplin/lib/theme'; -import { Size } from './ResizableLayout/ResizableLayout'; +import { Size } from './ResizableLayout/utils/types'; import MenuBar from './MenuBar'; import { _ } from '@joplin/lib/locale'; const React = require('react'); @@ -67,20 +67,10 @@ async function initialize() { type: 'NOTE_VISIBLE_PANES_SET', panes: Setting.value('noteVisiblePanes'), }); - - store.dispatch({ - type: 'SIDEBAR_VISIBILITY_SET', - visibility: Setting.value('sidebarVisibility'), - }); - - store.dispatch({ - type: 'NOTELIST_VISIBILITY_SET', - visibility: Setting.value('noteListVisibility'), - }); } class RootComponent extends React.Component { - async componentDidMount() { + public async componentDidMount() { if (this.props.appState == 'starting') { this.props.dispatch({ type: 'APP_STATE_SET', @@ -98,7 +88,7 @@ class RootComponent extends React.Component { await WelcomeUtils.install(this.props.dispatch); } - render() { + public render() { const navigatorStyle = { width: this.props.size.width / this.props.zoomFactor, height: this.props.size.height / this.props.zoomFactor, diff --git a/packages/app-desktop/gui/SideBar/SideBar.tsx b/packages/app-desktop/gui/SideBar/SideBar.tsx index e745f800fb..4d5f580507 100644 --- a/packages/app-desktop/gui/SideBar/SideBar.tsx +++ b/packages/app-desktop/gui/SideBar/SideBar.tsx @@ -685,8 +685,6 @@ const mapStateToProps = (state: any) => { collapsedFolderIds: state.collapsedFolderIds, decryptionWorker: state.decryptionWorker, resourceFetcher: state.resourceFetcher, - sidebarVisibility: state.sidebarVisibility, - noteListVisibility: state.noteListVisibility, }; }; diff --git a/packages/app-desktop/gui/SideBar/commands/focusElementSideBar.ts b/packages/app-desktop/gui/SideBar/commands/focusElementSideBar.ts index f9061f7625..986e14aa58 100644 --- a/packages/app-desktop/gui/SideBar/commands/focusElementSideBar.ts +++ b/packages/app-desktop/gui/SideBar/commands/focusElementSideBar.ts @@ -1,5 +1,7 @@ -import { CommandRuntime, CommandDeclaration } from '@joplin/lib/services/CommandService'; +import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService'; import { _ } from '@joplin/lib/locale'; +import layoutItemProp from '../../ResizableLayout/utils/layoutItemProp'; +import { AppState } from '../../../app'; export const declaration: CommandDeclaration = { name: 'focusElementSideBar', @@ -9,8 +11,8 @@ export const declaration: CommandDeclaration = { export const runtime = (comp: any): CommandRuntime => { return { - execute: async (context: any) => { - const sideBarVisible = !!context.state.sidebarVisibility; + execute: async (context: CommandContext) => { + const sideBarVisible = layoutItemProp((context.state as AppState).mainLayout, 'sideBar', 'visible'); if (sideBarVisible) { const item = comp.selectedItem(); diff --git a/packages/app-desktop/gui/menuCommandNames.ts b/packages/app-desktop/gui/menuCommandNames.ts index af34d9c96b..468cab5f35 100644 --- a/packages/app-desktop/gui/menuCommandNames.ts +++ b/packages/app-desktop/gui/menuCommandNames.ts @@ -30,6 +30,7 @@ export default function() { 'textPaste', 'textSelectAll', 'toggleExternalEditing', + 'toggleLayoutMoveMode', 'toggleNoteList', 'toggleSideBar', 'toggleVisiblePanes', diff --git a/packages/app-desktop/jest.config.js b/packages/app-desktop/jest.config.js new file mode 100644 index 0000000000..e047fa0bbc --- /dev/null +++ b/packages/app-desktop/jest.config.js @@ -0,0 +1,191 @@ +// For a detailed explanation regarding each configuration property, visit: +// https://jestjs.io/docs/en/configuration.html + +module.exports = { + // All imported modules in your tests should be mocked automatically + // automock: false, + + // Stop running tests after `n` failures + // bail: 0, + + // The directory where Jest should store its cached dependency information + // cacheDirectory: "/tmp/jest_rs", + + // Automatically clear mock calls and instances between every test + // clearMocks: false, + + // Indicates whether the coverage information should be collected while executing the test + // collectCoverage: false, + + // An array of glob patterns indicating a set of files for which coverage information should be collected + // collectCoverageFrom: undefined, + + // The directory where Jest should output its coverage files + // coverageDirectory: undefined, + + // An array of regexp pattern strings used to skip coverage collection + // coveragePathIgnorePatterns: [ + // "/node_modules/" + // ], + + // Indicates which provider should be used to instrument code for coverage + coverageProvider: 'v8', + + // A list of reporter names that Jest uses when writing coverage reports + // coverageReporters: [ + // "json", + // "text", + // "lcov", + // "clover" + // ], + + // An object that configures minimum threshold enforcement for coverage results + // coverageThreshold: undefined, + + // A path to a custom dependency extractor + // dependencyExtractor: undefined, + + // Make calling deprecated APIs throw helpful error messages + // errorOnDeprecated: false, + + // Force coverage collection from ignored files using an array of glob patterns + // forceCoverageMatch: [], + + // A path to a module which exports an async function that is triggered once before all test suites + // globalSetup: undefined, + + // A path to a module which exports an async function that is triggered once after all test suites + // globalTeardown: undefined, + + // A set of global variables that need to be available in all test environments + // globals: {}, + + // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. + // maxWorkers: "50%", + + // An array of directory names to be searched recursively up from the requiring module's location + // moduleDirectories: [ + // "node_modules" + // ], + + // An array of file extensions your modules use + // moduleFileExtensions: [ + // "js", + // "json", + // "jsx", + // "ts", + // "tsx", + // "node" + // ], + + // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module + // moduleNameMapper: {}, + + // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader + // modulePathIgnorePatterns: [], + + // Activates notifications for test results + // notify: false, + + // An enum that specifies notification mode. Requires { notify: true } + // notifyMode: "failure-change", + + // A preset that is used as a base for Jest's configuration + // preset: undefined, + + // Run tests from one or more projects + // projects: undefined, + + // Use this configuration option to add custom reporters to Jest + // reporters: undefined, + + // Automatically reset mock state between every test + // resetMocks: false, + + // Reset the module registry before running each individual test + // resetModules: false, + + // A path to a custom resolver + // resolver: undefined, + + // Automatically restore mock state between every test + // restoreMocks: false, + + // The root directory that Jest should scan for tests and modules within + // rootDir: undefined, + + // A list of paths to directories that Jest should use to search for files in + // roots: [ + // "" + // ], + + // Allows you to use a custom runner instead of Jest's default test runner + // runner: "jest-runner", + + // The paths to modules that run some code to configure or set up the testing environment before each test + // setupFiles: [], + + // A list of paths to modules that run some code to configure or set up the testing framework before each test + // setupFilesAfterEnv: [], + + // The number of seconds after which a test is considered as slow and reported as such in the results. + // slowTestThreshold: 5, + + // A list of paths to snapshot serializer modules Jest should use for snapshot testing + // snapshotSerializers: [], + + // The test environment that will be used for testing + testEnvironment: 'node', + + // Options that will be passed to the testEnvironment + // testEnvironmentOptions: {}, + + // Adds a location field to test results + // testLocationInResults: false, + + // The glob patterns Jest uses to detect test files + testMatch: [ + '**/*.test.js', + ], + + // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped + // testPathIgnorePatterns: [ + // "/node_modules/" + // ], + + // The regexp pattern or array of patterns that Jest uses to detect test files + // testRegex: [], + + // This option allows the use of a custom results processor + // testResultsProcessor: undefined, + + // This option allows use of a custom test runner + // testRunner: "jasmine2", + + // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href + // testURL: "http://localhost", + + // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" + // timers: "real", + + // A map from regular expressions to paths to transformers + // transform: undefined, + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + // transformIgnorePatterns: [ + // "/node_modules/", + // "\\.pnp\\.[^\\/]+$" + // ], + + // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them + // unmockedModulePathPatterns: undefined, + + // Indicates whether each individual test should be reported during the run + // verbose: undefined, + + // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode + // watchPathIgnorePatterns: [], + + // Whether to use watchman for file crawling + // watchman: true, +}; diff --git a/packages/app-desktop/package-lock.json b/packages/app-desktop/package-lock.json index 66e7e0c231..73212e3431 100644 --- a/packages/app-desktop/package-lock.json +++ b/packages/app-desktop/package-lock.json @@ -36,6 +36,128 @@ "@babel/highlight": "^7.10.4" } }, + "@babel/core": { + "version": "7.12.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz", + "integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.1", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.1", + "@babel/parser": "^7.12.3", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/generator": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/parser": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", + "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "dev": true + }, + "@babel/traverse": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", + "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.12.5", + "@babel/types": "^7.12.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", + "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, "@babel/generator": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", @@ -145,6 +267,34 @@ } } }, + "@babel/helper-member-expression-to-functions": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", + "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + }, + "dependencies": { + "@babel/types": { + "version": "7.12.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", + "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, "@babel/helper-module-imports": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", @@ -153,6 +303,266 @@ "@babel/types": "^7.0.0" } }, + "@babel/helper-module-transforms": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/generator": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5" + } + }, + "@babel/parser": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", + "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "dev": true + }, + "@babel/traverse": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", + "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.12.5", + "@babel/types": "^7.12.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", + "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/types": { + "version": "7.12.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", + "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", + "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.1", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" + }, + "dependencies": { + "@babel/generator": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/parser": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", + "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "dev": true + }, + "@babel/traverse": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", + "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.12.5", + "@babel/types": "^7.12.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", + "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-simple-access": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + }, + "dependencies": { + "@babel/types": { + "version": "7.12.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", + "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, "@babel/helper-split-export-declaration": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", @@ -183,6 +593,97 @@ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" }, + "@babel/helpers": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" + }, + "dependencies": { + "@babel/generator": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/parser": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", + "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", + "dev": true + }, + "@babel/traverse": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", + "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.12.5", + "@babel/types": "^7.12.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", + "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", @@ -231,6 +732,114 @@ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==" }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", + "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", + "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@babel/runtime": { "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", @@ -346,6 +955,22 @@ } } }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, "@develar/schema-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.1.0.tgz", @@ -491,12 +1116,706 @@ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.13.0.tgz", "integrity": "sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg==" }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/core": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.3", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" + } + }, + "@jest/reporters": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "node-notifier": "^8.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^7.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "node-notifier": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz", + "integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "optional": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + } + } + }, + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "dev": true }, + "@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "@styled-system/background": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@styled-system/background/-/background-5.1.2.tgz", @@ -608,6 +1927,74 @@ "defer-to-connect": "^1.0.1" } }, + "@testing-library/react-hooks": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-3.4.2.tgz", + "integrity": "sha512-RfPG0ckOzUIVeIqlOc1YztKgFW+ON8Y5xaSPbiBkfj9nMkkiLhLeBXT5icfPX65oJV/zCZu4z8EVnUc6GY9C5A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.4", + "@types/testing-library__react-hooks": "^3.4.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + } + } + }, + "@types/babel__core": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", + "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.3.tgz", + "integrity": "sha512-uCoznIPDmnickEi6D0v11SBpW0OuVqHJCa7syXqQHy5uktSCreIlt0iglsCnmvz8yCb38hGcWeseA8cWJSwv5Q==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.15.tgz", + "integrity": "sha512-Pzh9O3sTK8V6I1olsXpCfj2k/ygO2q1X0vhhnDrEQyYLHZesWz+zMZMVcwXLCYf0U36EtmyYaFGPfXlTtDHe3A==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -620,11 +2007,19 @@ "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", "dev": true }, + "@types/graceful-fs": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", + "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "dev": true, "requires": { "@types/react": "*", "hoist-non-react-statics": "^3.3.0" @@ -634,36 +2029,79 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dev": true, "requires": { "react-is": "^16.7.0" } } } }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "@types/jasmine": { "version": "3.5.11", "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.5.11.tgz", "integrity": "sha512-fg1rOd/DehQTIJTifGqGVY6q92lDgnLfs7C6t1ccSwQrMyoTGSoH6wWzhJDZb6ezhsdwAX4EIBLe8w5fXWmEng==", "dev": true }, + "@types/jest": { + "version": "26.0.15", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.15.tgz", + "integrity": "sha512-s2VMReFXRg9XXxV+CW9e5Nz8fH2K1aEhwgjUqPPbQd7g95T0laAcvLv032EhFHIa5GHsZ8W7iJEQVaJq6k3Gog==", + "dev": true, + "requires": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" + } + }, "@types/node": { "version": "14.14.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz", "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==", "dev": true }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/prettier": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.5.tgz", + "integrity": "sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==", + "dev": true + }, "@types/prop-types": { "version": "15.7.3", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", - "dev": true + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "@types/react": { "version": "16.9.55", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.55.tgz", "integrity": "sha512-6KLe6lkILeRwyyy7yG9rULKJ0sXplUsl98MGoCfpteXf9sPWFWWMknDcsvubcpaTdBuxtsLF6HDUwdApZL/xIg==", - "dev": true, "requires": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -672,11 +2110,18 @@ "csstype": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.4.tgz", - "integrity": "sha512-xc8DUsCLmjvCfoD7LTGE0ou2MIWLx0K9RCZwSHMOdynqRsP4MtUcLeqh1HcQ2dInwDTqn+3CE0/FZh1et+p4jA==", - "dev": true + "integrity": "sha512-xc8DUsCLmjvCfoD7LTGE0ou2MIWLx0K9RCZwSHMOdynqRsP4MtUcLeqh1HcQ2dInwDTqn+3CE0/FZh1et+p4jA==" } } }, + "@types/react-native": { + "version": "0.63.34", + "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.63.34.tgz", + "integrity": "sha512-6syTIfUt+DY4mJBoO0Y5i4jsDg0I7v31XIPRgsJZAlHeMY9p9GehtGd4VpQKB/NgzLiGzx9ahJPE8w+0lt/WxA==", + "requires": { + "@types/react": "*" + } + }, "@types/react-redux": { "version": "7.1.9", "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.9.tgz", @@ -725,11 +2170,96 @@ } } }, + "@types/react-test-renderer": { + "version": "16.9.3", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-16.9.3.tgz", + "integrity": "sha512-wJ7IlN5NI82XMLOyHSa+cNN4Z0I+8/YaLl04uDgcZ+W+ExWCmCiVTLT/7fRNqzy4OhStZcUwIqLNF7q+AdW43Q==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, + "@types/styled-components": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.4.tgz", + "integrity": "sha512-78f5Zuy0v/LTQNOYfpH+CINHpchzMMmAt9amY2YNtSgsk1TmlKm8L2Wijss/mtTrsUAVTm2CdGB8VOM65vA8xg==", + "requires": { + "@types/hoist-non-react-statics": "*", + "@types/react": "*", + "@types/react-native": "*", + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.4.tgz", + "integrity": "sha512-xc8DUsCLmjvCfoD7LTGE0ou2MIWLx0K9RCZwSHMOdynqRsP4MtUcLeqh1HcQ2dInwDTqn+3CE0/FZh1et+p4jA==" + } + } + }, + "@types/testing-library__react-hooks": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@types/testing-library__react-hooks/-/testing-library__react-hooks-3.4.1.tgz", + "integrity": "sha512-G4JdzEcq61fUyV6wVW9ebHWEiLK2iQvaBuCHHn9eMSbZzVh4Z4wHnUGIvQOYCCYeu5DnUtFyNYuAAgbSaO/43Q==", + "dev": true, + "requires": { + "@types/react-test-renderer": "*" + } + }, + "@types/yargs": { + "version": "15.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.9.tgz", + "integrity": "sha512-HmU8SeIRhZCWcnRskCs36Q1Q00KBV6Cqh/ora8WN1+22dY07AZdn6Gel8QZ3t26XYPImtcL8WV/eqjhVmMEw4g==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, "ajv": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz", @@ -800,6 +2330,23 @@ "ansi-wrap": "^0.1.0" } }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, "ansi-gray": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", @@ -826,6 +2373,24 @@ "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", "dev": true }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + } + } + }, "app-builder-bin": { "version": "1.9.11", "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-1.9.11.tgz", @@ -1146,6 +2711,12 @@ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, "babel-cli": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", @@ -2004,6 +3575,85 @@ "babel-template": "^6.24.1" } }, + "babel-jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "dev": true, + "requires": { + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "babel-messages": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", @@ -2032,6 +3682,31 @@ "touch": "^2.0.1" } }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, "babel-plugin-macros": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.5.1.tgz", @@ -2139,6 +3814,26 @@ } } }, + "babel-preset-current-node-syntax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.0.tgz", + "integrity": "sha512-mGkvkpocWJes1CmMKtgGUwCeeq0pOhALyymozzDWYomHTbDLwueDYG6p4TK1YOeYHCzBzYPsWkgTto10JubI1Q==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, "babel-preset-flow": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", @@ -2148,6 +3843,16 @@ "babel-plugin-transform-flow-strip-types": "^6.22.0" } }, + "babel-preset-jest": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, "babel-preset-react": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", @@ -2538,6 +4243,30 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, "buffer": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.0.tgz", @@ -2800,6 +4529,15 @@ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -2819,6 +4557,12 @@ "supports-color": "^2.0.0" } }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", @@ -2841,6 +4585,12 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -3055,6 +4805,12 @@ } } }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -3065,6 +4821,12 @@ "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.56.0.tgz", "integrity": "sha512-MfKVmYgifXjQpLSgpETuih7A7WTTIsxvKfSLGseTY5+qt0E1UD1wblZGM6WLenORo8sgmf+3X+WTe2WF7mufyw==" }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, "collection-map": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", @@ -3305,6 +5067,19 @@ "object-assign": "^4.1.1" } }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, "crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", @@ -3331,6 +5106,29 @@ "postcss-value-parser": "^4.0.2" } }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, "csstype": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.4.tgz", @@ -3360,6 +5158,17 @@ "assert-plus": "^1.0.0" } }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, "debounce": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz", @@ -3380,6 +5189,12 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", + "dev": true + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -3405,6 +5220,18 @@ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, "default-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", @@ -3524,6 +5351,12 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, "detect-node": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", @@ -3531,6 +5364,12 @@ "dev": true, "optional": true }, + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true + }, "dmg-builder": { "version": "22.3.2", "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.3.2.tgz", @@ -3582,6 +5421,23 @@ "@babel/runtime": "^7.1.2" } }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } + } + }, "dot-prop": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", @@ -4035,6 +5891,12 @@ } } }, + "emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "dev": true + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -4148,16 +6010,71 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -4263,6 +6180,46 @@ "homedir-polyfill": "^1.0.1" } }, + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "ext": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", @@ -4448,11 +6405,26 @@ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, "fast-memoize": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==" }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, "fbjs": { "version": "0.8.16", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", @@ -4500,6 +6472,15 @@ "dev": true, "optional": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -4680,6 +6661,13 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.2.1.tgz", + "integrity": "sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA==", + "dev": true, + "optional": true + }, "fullstore": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fullstore/-/fullstore-1.1.0.tgz", @@ -4706,12 +6694,33 @@ "wide-align": "^1.1.0" } }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -5898,6 +7907,51 @@ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -6019,6 +8073,21 @@ "lru-cache": "^5.1.1" } }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "http-cache-semantics": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz", @@ -6036,6 +8105,12 @@ "sshpk": "^1.7.0" } }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", @@ -6066,6 +8141,16 @@ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6112,6 +8197,12 @@ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", @@ -6170,6 +8261,15 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -6214,6 +8314,13 @@ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" }, + "is-docker": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "dev": true, + "optional": true + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -6260,6 +8367,12 @@ "number-is-nan": "^1.0.0" } }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -6291,6 +8404,12 @@ "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", @@ -6324,6 +8443,12 @@ "dev": true, "optional": true }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", @@ -6426,6 +8551,1602 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", + "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "dev": true, + "requires": { + "@jest/core": "^26.6.3", + "import-local": "^3.0.2", + "jest-cli": "^26.6.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "jest-cli": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", + "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "dev": true, + "requires": { + "@jest/core": "^26.6.3", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.6.3", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "prompts": "^2.0.1", + "yargs": "^15.4.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-changed-files": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-environment-jsdom": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" + } + }, + "jest-environment-node": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + } + } + }, + "jest-jasmine2": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.6.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-leak-detector": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "dev": true, + "requires": { + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", + "dev": true, + "requires": { + "is-core-module": "^2.0.0", + "path-parse": "^1.0.6" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-resolve-dependencies": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", + "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.6.2" + } + }, + "jest-runner": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-runtime": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + } + } + }, + "jest-snapshot": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-watcher": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.6.2", + "string-length": "^4.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "js-sha512": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", @@ -6454,6 +10175,40 @@ "dev": true, "optional": true }, + "jsdom": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", + "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + } + }, "jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", @@ -6471,6 +10226,12 @@ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -6551,6 +10312,12 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, "last-run": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", @@ -6603,6 +10370,22 @@ "flush-write-stream": "^1.0.2" } }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, "liftoff": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", @@ -6619,6 +10402,12 @@ "resolve": "^1.1.7" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -6666,6 +10455,12 @@ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -6755,6 +10550,15 @@ "kind-of": "^6.0.2" } }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -6851,6 +10655,12 @@ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.0.4.tgz", "integrity": "sha512-P0z5IeAH6qHHGkJIXWw0xC2HNEgkx/9uWWBQw64FJj3/ol14VYdfVGWWr0fXfjhhv3TKVIqUq65os6O4GUNksA==" }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -7128,12 +10938,24 @@ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "node-abi": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.16.0.tgz", @@ -7340,6 +11162,18 @@ } } }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, "node-notifier": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", @@ -7429,6 +11263,15 @@ "pify": "^3.0.0" } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", @@ -7445,6 +11288,18 @@ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -7610,6 +11465,20 @@ "mimic-fn": "^1.0.0" } }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, "ora": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", @@ -7727,6 +11596,18 @@ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "dev": true }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -7835,6 +11716,12 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -7858,6 +11745,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -7908,6 +11801,12 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -7930,6 +11829,60 @@ "pinkie": "^2.0.0" } }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -7963,6 +11916,12 @@ "which-pm-runs": "^1.0.0" } }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", @@ -7981,6 +11940,56 @@ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==" }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", + "dev": true + } + } + }, "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -8004,6 +12013,16 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "prompts": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", + "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, "prop-types": { "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", @@ -8259,6 +12278,30 @@ "react-transition-group": "^2.2.1" } }, + "react-test-renderer": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.14.0.tgz", + "integrity": "sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "react-is": "^16.8.6", + "scheduler": "^0.19.1" + }, + "dependencies": { + "scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } + } + }, "react-tooltip": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-3.10.0.tgz", @@ -8545,6 +12588,105 @@ "remove-trailing-separator": "^1.1.0" } }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8570,6 +12712,23 @@ "path-parse": "^1.0.6" } }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, "resolve-dir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", @@ -8679,6 +12838,12 @@ "resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz", "integrity": "sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g==" }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, "rxjs": { "version": "6.5.5", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", @@ -8708,6 +12873,35 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + } + } + }, "sanitize-filename": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", @@ -8723,6 +12917,15 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, "scheduler": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", @@ -8825,6 +13028,21 @@ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "shellwords": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", @@ -8880,6 +13098,12 @@ } } }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -9158,6 +13382,23 @@ "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", "dev": true }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, "stat-mode": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", @@ -9185,6 +13426,12 @@ } } }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, "stream-exhaust": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", @@ -9197,6 +13444,33 @@ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, + "string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -9232,6 +13506,18 @@ "is-utf8": "^0.2.0" } }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -9344,6 +13630,33 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "sver-compat": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", @@ -9359,6 +13672,12 @@ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=" }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "taboverride": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/taboverride/-/taboverride-4.0.3.tgz", @@ -9447,6 +13766,33 @@ "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", "dev": true }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -9510,6 +13856,12 @@ "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.2.0.tgz", "integrity": "sha512-Q7KAu9sLB6TBhKFdb2LHPGy770zkSEjpN1VRqZ6pxNuVQ0mbGWgMocHDvM9XL9yJaOhFrJP6s9XM7zG2gapGpA==" }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, "to-absolute-glob": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", @@ -9564,6 +13916,15 @@ "safe-regex": "^1.1.0" } }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "to-through": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", @@ -9591,6 +13952,26 @@ } } }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", @@ -9640,6 +14021,21 @@ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", "dev": true }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -9911,6 +14307,41 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", + "dev": true, + "optional": true + }, + "v8-to-istanbul": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.0.0.tgz", + "integrity": "sha512-fLL2rFuQpMtm9r8hrAV2apXX/WqHJ6+IC4/eQVdMDGBUgH/YMV4Gv3duk3kjmyg6uiQWBAA9nJwue4iJUOkHeA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, "v8flags": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", @@ -10009,6 +14440,33 @@ "vinyl": "^2.0.0" } }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -10018,11 +14476,54 @@ "defaults": "^1.0.3" } }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, "whatwg-fetch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz", + "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^6.1.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -10099,6 +14600,12 @@ } } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -10192,12 +14699,30 @@ "typedarray-to-buffer": "^3.1.5" } }, + "ws": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz", + "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==", + "dev": true + }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/packages/app-desktop/package.json b/packages/app-desktop/package.json index c4a5b1c1a2..b9ad0b2532 100644 --- a/packages/app-desktop/package.json +++ b/packages/app-desktop/package.json @@ -10,7 +10,8 @@ "postinstall": "npm run build && gulp electronRebuild", "tsc": "node node_modules/typescript/bin/tsc --project tsconfig.json", "watch": "node node_modules/typescript/bin/tsc --watch --project tsconfig.json", - "start": "gulp build && electron . --env dev --log-level debug --no-welcome --open-dev-tools" + "start": "gulp build && electron . --env dev --log-level debug --no-welcome --open-dev-tools", + "test": "jest" }, "repository": { "type": "git", @@ -86,11 +87,13 @@ }, "homepage": "https://github.com/laurent22/joplin#readme", "devDependencies": { + "@joplin/tools": "^1.0.9", + "@testing-library/react-hooks": "^3.4.2", "@types/jasmine": "^3.5.11", + "@types/jest": "^26.0.15", "@types/node": "^14.14.6", "@types/react": "16.9.55", "@types/react-redux": "^7.1.9", - "@joplin/tools": "^1.0.9", "ajv": "^6.5.0", "app-builder-bin": "^1.9.11", "babel-cli": "^6.26.0", @@ -100,7 +103,9 @@ "electron-rebuild": "^1.10.1", "glob": "^7.1.6", "gulp": "^4.0.2", + "jest": "^26.6.3", "js-sha512": "^0.8.0", + "react-test-renderer": "^16.14.0", "typescript": "^4.0.5" }, "optionalDependencies": { @@ -112,6 +117,7 @@ "@fortawesome/fontawesome-free": "^5.13.0", "@joplin/lib": "^1.0.9", "@joplin/renderer": "^1.0.17", + "@types/styled-components": "^5.1.4", "async-mutex": "^0.1.3", "codemirror": "^5.56.0", "color": "^3.1.2", diff --git a/packages/app-desktop/services/commands/stateToWhenClauseContext.ts b/packages/app-desktop/services/commands/stateToWhenClauseContext.ts new file mode 100644 index 0000000000..4dbe1c26ab --- /dev/null +++ b/packages/app-desktop/services/commands/stateToWhenClauseContext.ts @@ -0,0 +1,23 @@ +// This extends the generic stateToWhenClauseContext (potentially shared by +// all apps) with additional properties specific to the desktop app. So in +// general, any desktop component should import this file, and not the lib +// one. + +import { AppState } from '../../app'; +import libStateToWhenClauseContext from '@joplin/lib/services/commands/stateToWhenClauseContext'; +import layoutItemProp from '../../gui/ResizableLayout/utils/layoutItemProp'; + +export default function stateToWhenClauseContext(state: AppState) { + return { + ...libStateToWhenClauseContext(state), + + // UI elements + markdownEditorVisible: !!state.settings['editor.codeView'], + richTextEditorVisible: !state.settings['editor.codeView'], + markdownEditorPaneVisible: state.settings['editor.codeView'] && state.noteVisiblePanes.includes('editor'), + markdownViewerPaneVisible: state.settings['editor.codeView'] && state.noteVisiblePanes.includes('viewer'), + modalDialogVisible: !!Object.keys(state.visibleDialogs).length, + sideBarVisible: !!state.mainLayout && layoutItemProp(state.mainLayout, 'sideBar', 'visible'), + noteListHasNotes: !!state.notes.length, + }; +} diff --git a/packages/app-desktop/testPluginDemo.sh b/packages/app-desktop/testPluginDemo.sh index 6a043fdb44..10b0bf7706 100755 --- a/packages/app-desktop/testPluginDemo.sh +++ b/packages/app-desktop/testPluginDemo.sh @@ -3,5 +3,5 @@ # This is a convenient way to build and test a plugin demo. # It could be used to develop plugins too. -PLUGIN_PATH=/home/laurent/source/joplin/packages/app-cli/tests/support/plugins/content_script +PLUGIN_PATH=/home/laurent/source/joplin/packages/app-cli/tests/support/plugins/register_command npm i --prefix="$PLUGIN_PATH" && npm start -- --dev-plugins "$PLUGIN_PATH" \ No newline at end of file diff --git a/packages/lib/.gitignore b/packages/lib/.gitignore new file mode 100644 index 0000000000..6a64b44e91 --- /dev/null +++ b/packages/lib/.gitignore @@ -0,0 +1 @@ +plugin_types/ diff --git a/packages/lib/models/Setting.ts b/packages/lib/models/Setting.ts index 37a5f52f31..44443e9d13 100644 --- a/packages/lib/models/Setting.ts +++ b/packages/lib/models/Setting.ts @@ -661,9 +661,6 @@ class Setting extends BaseModel { 'ui.layout': { value: {}, type: SettingItemType.Object, public: false, appTypes: ['desktop'] }, - 'style.sidebar.width': { value: 150, minimum: 80, maximum: 400, type: SettingItemType.Int, public: false, appTypes: ['desktop'] }, - 'style.noteList.width': { value: 150, minimum: 80, maximum: 400, type: SettingItemType.Int, public: false, appTypes: ['desktop'] }, - // TODO: Is there a better way to do this? The goal here is to simply have // a way to display a link to the customizable stylesheets, not for it to // serve as a customizable Setting. But because the Setting page is auto- @@ -728,8 +725,6 @@ class Setting extends BaseModel { }, }, noteVisiblePanes: { value: ['editor', 'viewer'], type: SettingItemType.Array, public: false, appTypes: ['desktop'] }, - sidebarVisibility: { value: true, type: SettingItemType.Bool, public: false, appTypes: ['desktop'] }, - noteListVisibility: { value: true, type: SettingItemType.Bool, public: false, appTypes: ['desktop'] }, tagHeaderIsExpanded: { value: true, type: SettingItemType.Bool, public: false, appTypes: ['desktop'] }, folderHeaderIsExpanded: { value: true, type: SettingItemType.Bool, public: false, appTypes: ['desktop'] }, editor: { value: '', type: SettingItemType.String, subType: 'file_path_and_args', public: true, appTypes: ['cli', 'desktop'], label: () => _('Text editor command'), description: () => _('The editor command (may include arguments) that will be used to open a note. If none is provided it will try to auto-detect the default editor.') }, diff --git a/packages/lib/package.json b/packages/lib/package.json index 50480de8ac..b221501851 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -10,7 +10,8 @@ }, "scripts": { "tsc": "node node_modules/typescript/bin/tsc --project tsconfig.json", - "watch": "node node_modules/typescript/bin/tsc --watch --project tsconfig.json" + "watch": "node node_modules/typescript/bin/tsc --watch --project tsconfig.json", + "generatePluginTypes": "rm -rf ./plugin_types && node node_modules/typescript/bin/tsc --declaration --declarationDir ./plugin_types --project tsconfig.json" }, "devDependencies": { "@types/node": "^14.14.6", diff --git a/packages/lib/services/CommandService.ts b/packages/lib/services/CommandService.ts index e117fad6b2..664a26ebcb 100644 --- a/packages/lib/services/CommandService.ts +++ b/packages/lib/services/CommandService.ts @@ -3,7 +3,6 @@ import eventManager from '../eventManager'; import BaseService from './BaseService'; import shim from '../shim'; import WhenClause from './WhenClause'; -import stateToWhenClauseContext from './commands/stateToWhenClauseContext'; type LabelFunction = ()=> string; type EnabledCondition = string; @@ -103,11 +102,13 @@ export default class CommandService extends BaseService { private commands_: Commands = {}; private store_: any; private devMode_: boolean; + private stateToWhenClauseContext_: Function; - public initialize(store: any, devMode: boolean) { + public initialize(store: any, devMode: boolean, stateToWhenClauseContext: Function) { utils.store = store; this.store_ = store; this.devMode_ = devMode; + this.stateToWhenClauseContext_ = stateToWhenClauseContext; } public on(eventName: string, callback: Function) { @@ -236,7 +237,7 @@ export default class CommandService extends BaseService { } public currentWhenClauseContext() { - return stateToWhenClauseContext(this.store_.getState()); + return this.stateToWhenClauseContext_(this.store_.getState()); } public isPublic(commandName: string) { diff --git a/packages/lib/services/commands/stateToWhenClauseContext.ts b/packages/lib/services/commands/stateToWhenClauseContext.ts index aa281083ef..84d97a25f0 100644 --- a/packages/lib/services/commands/stateToWhenClauseContext.ts +++ b/packages/lib/services/commands/stateToWhenClauseContext.ts @@ -1,23 +1,14 @@ -import { stateUtils } from '../../reducer'; +import { State, stateUtils } from '../../reducer'; const BaseModel = require('../../BaseModel').default; const Folder = require('../../models/Folder'); const MarkupToHtml = require('@joplin/renderer/MarkupToHtml').default; -export default function stateToWhenClauseContext(state: any) { +export default function stateToWhenClauseContext(state: State) { const noteId = state.selectedNoteIds.length === 1 ? state.selectedNoteIds[0] : null; const note = noteId ? BaseModel.byId(state.notes, noteId) : null; return { - // UI elements - markdownEditorVisible: !!state.settings['editor.codeView'], - richTextEditorVisible: !state.settings['editor.codeView'], - markdownEditorPaneVisible: state.settings['editor.codeView'] && state.noteVisiblePanes.includes('editor'), - markdownViewerPaneVisible: state.settings['editor.codeView'] && state.noteVisiblePanes.includes('viewer'), - modalDialogVisible: !!Object.keys(state.visibleDialogs).length, - sideBarVisible: !!state.sidebarVisibility, - noteListHasNotes: !!state.notes.length, - // Application state notesAreBeingSaved: stateUtils.hasNotesBeingSaved(state), syncStarted: state.syncStarted, diff --git a/packages/lib/services/plugins/Plugin.ts b/packages/lib/services/plugins/Plugin.ts index 028e601871..cf7d732175 100644 --- a/packages/lib/services/plugins/Plugin.ts +++ b/packages/lib/services/plugins/Plugin.ts @@ -62,6 +62,10 @@ export default class Plugin { return this.baseDir_; } + public get viewCount(): number { + return Object.keys(this.viewControllers_).length; + } + on(eventName: string, callback: Function) { return this.eventEmitter_.on(eventName, callback); } @@ -101,7 +105,7 @@ export default class Plugin { } public addViewController(v: ViewController) { - if (this.viewControllers_[v.handle]) throw new Error(`View already added: ${v.handle}`); + if (this.viewControllers_[v.handle]) throw new Error(`View already added or there is already a view with this ID: ${v.handle}`); this.viewControllers_[v.handle] = v; } @@ -110,4 +114,8 @@ export default class Plugin { return this.viewControllers_[handle]; } + public deprecationNotice(goneInVersion: string, message: string) { + this.logger_.warn(`Plugin: ${this.id}: DEPRECATION NOTICE: ${message} The current feature will stop working in version ${goneInVersion}.`); + } + } diff --git a/packages/lib/services/plugins/PluginService.ts b/packages/lib/services/plugins/PluginService.ts index 96f7a38e70..bb4cef0964 100644 --- a/packages/lib/services/plugins/PluginService.ts +++ b/packages/lib/services/plugins/PluginService.ts @@ -49,6 +49,10 @@ export default class PluginService extends BaseService { return this.plugins_[id]; } + public allPluginIds(): string[] { + return Object.keys(this.plugins_); + } + private async parsePluginJsBundle(jsBundleString: string) { const scriptText = jsBundleString; const lines = scriptText.split('\n'); @@ -163,4 +167,17 @@ export default class PluginService extends BaseService { return this.runner_.run(plugin, pluginApi); } + // public async handleDisabledPlugins() { + // const enabledPlugins = this.allPluginIds(); + // const v = await this.kvStore_.value('pluginService.lastEnabledPlugins'); + // const lastEnabledPlugins = v ? JSON.parse(v) : []; + + // const disabledPlugins = []; + // for (const id of lastEnabledPlugins) { + // if (!enabledPlugins.includes(id)) disabledPlugins.push(id); + // } + + // await this.kvStore_.setValue('pluginService.lastEnabledPlugins', JSON.stringify(enabledPlugins)); + // } + } diff --git a/packages/lib/services/plugins/WebviewController.ts b/packages/lib/services/plugins/WebviewController.ts index 30de94011d..8ccf6d1b14 100644 --- a/packages/lib/services/plugins/WebviewController.ts +++ b/packages/lib/services/plugins/WebviewController.ts @@ -23,7 +23,7 @@ export default class WebviewController extends ViewController { private messageListener_: Function = null; private closeResponse_: CloseResponse = null; - constructor(id: string, pluginId: string, store: any, baseDir: string) { + constructor(id: string, pluginId: string, store: any, baseDir: string, containerType: ContainerType) { super(id, pluginId, store); this.baseDir_ = toSystemSlashes(baseDir, 'linux'); @@ -33,7 +33,7 @@ export default class WebviewController extends ViewController { view: { id: this.handle, type: this.type, - containerType: ContainerType.Panel, + containerType: containerType, html: '', scripts: [], opened: false, @@ -68,10 +68,6 @@ export default class WebviewController extends ViewController { return this.storeView.containerType; } - public set containerType(containerType: ContainerType) { - this.setStoreProp('containerType', containerType); - } - public async addScript(path: string) { const fullPath = toSystemSlashes(shim.fsDriver().resolve(`${this.baseDir_}/${path}`), 'linux'); diff --git a/packages/lib/services/plugins/api/JoplinPlugins.ts b/packages/lib/services/plugins/api/JoplinPlugins.ts index ba48522ff1..a177af40fa 100644 --- a/packages/lib/services/plugins/api/JoplinPlugins.ts +++ b/packages/lib/services/plugins/api/JoplinPlugins.ts @@ -42,7 +42,7 @@ export default class JoplinPlugins { // be handled correctly by loggers, etc. const newError: Error = new Error(error.message); newError.stack = error.stack; - this.logger.error(`In plugin ${this.plugin.id}:`, newError); + this.logger.error(`Uncaught exception in plugin "${this.plugin.id}":`, newError); }).then(() => { this.logger.info(`Finished running onStart handler: ${this.plugin.id} (Took ${Date.now() - startTime}ms)`); this.plugin.emit('started'); diff --git a/packages/lib/services/plugins/api/JoplinUtils.js b/packages/lib/services/plugins/api/JoplinUtils.js deleted file mode 100644 index 1961c41c44..0000000000 --- a/packages/lib/services/plugins/api/JoplinUtils.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const Entities = require('html-entities').AllHtmlEntities; -const htmlentities = new Entities().encode; -class JoplinUtils { - escapeHtml(text) { - return htmlentities(text); - } -} -exports.default = JoplinUtils; -// # sourceMappingURL=JoplinUtils.js.map diff --git a/packages/lib/services/plugins/api/JoplinViewsDialogs.ts b/packages/lib/services/plugins/api/JoplinViewsDialogs.ts index 8abda423c5..9f908dc4dd 100644 --- a/packages/lib/services/plugins/api/JoplinViewsDialogs.ts +++ b/packages/lib/services/plugins/api/JoplinViewsDialogs.ts @@ -29,10 +29,14 @@ export default class JoplinViewsDialogs { /** * Creates a new dialog */ - async create(): Promise { - const handle = createViewHandle(this.plugin); - const controller = new WebviewController(handle, this.plugin.id, this.store, this.plugin.baseDir); - controller.containerType = ContainerType.Dialog; + async create(id: string): Promise { + if (!id) { + this.plugin.deprecationNotice('1.5', 'Creating a view without an ID is deprecated. To fix it, change your call to `joplin.views.dialogs.create("my-unique-id")`'); + id = `${this.plugin.viewCount}`; + } + + const handle = createViewHandle(this.plugin, id); + const controller = new WebviewController(handle, this.plugin.id, this.store, this.plugin.baseDir, ContainerType.Dialog); this.plugin.addViewController(controller); return handle; } diff --git a/packages/lib/services/plugins/api/JoplinViewsMenuItems.ts b/packages/lib/services/plugins/api/JoplinViewsMenuItems.ts index 2674742ecc..5997f157c8 100644 --- a/packages/lib/services/plugins/api/JoplinViewsMenuItems.ts +++ b/packages/lib/services/plugins/api/JoplinViewsMenuItems.ts @@ -22,8 +22,16 @@ export default class JoplinViewsMenuItems { /** * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. */ - async create(commandName: string, location: MenuItemLocation = MenuItemLocation.Tools, options: CreateMenuItemOptions = null) { - const handle = createViewHandle(this.plugin); + async create(id: string, commandName: string, location: MenuItemLocation = MenuItemLocation.Tools, options: CreateMenuItemOptions = null) { + if (typeof location !== 'string') { + this.plugin.deprecationNotice('1.5', 'Creating a view without an ID is deprecated. To fix it, change your call to `joplin.views.menuItem.create("my-unique-id", ...)`'); + options = location as any; + location = commandName as any || MenuItemLocation.Tools; + commandName = id as any; + id = `${this.plugin.viewCount}`; + } + + const handle = createViewHandle(this.plugin, id); const controller = new MenuItemController(handle, this.plugin.id, this.store, commandName, location); this.plugin.addViewController(controller); diff --git a/packages/lib/services/plugins/api/JoplinViewsMenus.ts b/packages/lib/services/plugins/api/JoplinViewsMenus.ts index d22a9b4ac9..487b421942 100644 --- a/packages/lib/services/plugins/api/JoplinViewsMenus.ts +++ b/packages/lib/services/plugins/api/JoplinViewsMenus.ts @@ -35,8 +35,16 @@ export default class JoplinViewsMenus { * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the * menu as a sub-menu of the application build-in menus. */ - public async create(label: string, menuItems: MenuItem[], location: MenuItemLocation = MenuItemLocation.Tools) { - const handle = createViewHandle(this.plugin); + public async create(id: string, label: string, menuItems: MenuItem[], location: MenuItemLocation = MenuItemLocation.Tools) { + if (!Array.isArray(menuItems)) { + this.plugin.deprecationNotice('1.5', 'Creating a view without an ID is deprecated. To fix it, change your call to `joplin.views.menus.create("my-unique-id", ...)`'); + location = menuItems as any || MenuItemLocation.Tools; + menuItems = label as any; + label = id as any; + id = `${this.plugin.viewCount}`; + } + + const handle = createViewHandle(this.plugin, id); const controller = new MenuController(handle, this.plugin.id, this.store, label, menuItems, location); this.plugin.addViewController(controller); this.registerCommandAccelerators(menuItems); diff --git a/packages/lib/services/plugins/api/JoplinViewsPanels.ts b/packages/lib/services/plugins/api/JoplinViewsPanels.ts index e159a890d5..60395b4a78 100644 --- a/packages/lib/services/plugins/api/JoplinViewsPanels.ts +++ b/packages/lib/services/plugins/api/JoplinViewsPanels.ts @@ -1,11 +1,14 @@ import Plugin from '../Plugin'; import createViewHandle from '../utils/createViewHandle'; -import WebviewController from '../WebviewController'; +import WebviewController, { ContainerType } from '../WebviewController'; import { ViewHandle } from './types'; /** - * Allows creating and managing view panels. View panels currently are displayed at the right of the sidebar and allows displaying any HTML content (within a webview) and update it in real-time. For example - * it could be used to display a table of content for the active note, or display various metadata or graph. + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) */ @@ -26,9 +29,14 @@ export default class JoplinViewsPanels { /** * Creates a new panel */ - async create(): Promise { - const handle = createViewHandle(this.plugin); - const controller = new WebviewController(handle, this.plugin.id, this.store, this.plugin.baseDir); + async create(id: string): Promise { + if (!id) { + this.plugin.deprecationNotice('1.5', 'Creating a view without an ID is deprecated. To fix it, change your call to `joplin.views.panels.create("my-unique-id")`'); + id = `${this.plugin.viewCount}`; + } + + const handle = createViewHandle(this.plugin, id); + const controller = new WebviewController(handle, this.plugin.id, this.store, this.plugin.baseDir, ContainerType.Panel); this.plugin.addViewController(controller); return handle; } diff --git a/packages/lib/services/plugins/api/JoplinViewsToolbarButtons.ts b/packages/lib/services/plugins/api/JoplinViewsToolbarButtons.ts index b1e07130e2..26d387229b 100644 --- a/packages/lib/services/plugins/api/JoplinViewsToolbarButtons.ts +++ b/packages/lib/services/plugins/api/JoplinViewsToolbarButtons.ts @@ -21,8 +21,15 @@ export default class JoplinViewsToolbarButtons { /** * Creates a new toolbar button and associate it with the given command. */ - async create(commandName: string, location: ToolbarButtonLocation) { - const handle = createViewHandle(this.plugin); + async create(id: string, commandName: string, location: ToolbarButtonLocation) { + if (arguments.length < 3) { + this.plugin.deprecationNotice('1.5', 'Creating a view without an ID is deprecated. To fix it, change your call to `joplin.views.toolbarButtons.create("my-unique-id", ...)`'); + location = commandName as any; + commandName = id as any; + id = `${this.plugin.viewCount}`; + } + + const handle = createViewHandle(this.plugin, id); const controller = new ToolbarButtonController(handle, this.plugin.id, this.store, commandName, location); this.plugin.addViewController(controller); } diff --git a/packages/lib/services/plugins/reducer.ts b/packages/lib/services/plugins/reducer.ts index 0eba22ea01..ea9e75aefc 100644 --- a/packages/lib/services/plugins/reducer.ts +++ b/packages/lib/services/plugins/reducer.ts @@ -82,6 +82,30 @@ export const utils = { return output; }, + viewInfoByViewId: function(plugins: PluginStates, viewId: string): ViewInfo { + for (const pluginId in plugins) { + const plugin = plugins[pluginId]; + if (plugin.views[viewId]) { + return { + plugin: plugin, + view: plugin.views[viewId], + }; + } + } + return null; + }, + + allViewIds: function(plugins: PluginStates): string[] { + const output = []; + for (const pluginId in plugins) { + const plugin = plugins[pluginId]; + for (const viewId in plugin.views) { + output.push(viewId); + } + } + return output; + }, + commandNamesFromViews: function(plugins: PluginStates, toolbarType: string): string[] { const infos = utils.viewInfosByType(plugins, 'toolbarButton'); @@ -91,42 +115,44 @@ export const utils = { }, }; -const reducer = (draft: Draft, action: any) => { +const reducer = (draftRoot: Draft, action: any) => { if (action.type.indexOf('PLUGIN_') !== 0) return; // All actions should be scoped to a plugin, except when adding a new plugin if (!action.pluginId && action.type !== 'PLUGIN_ADD') throw new Error(`action.pluginId is required. Action was: ${JSON.stringify(action)}`); + const draft = draftRoot.pluginService as State; + try { switch (action.type) { case 'PLUGIN_ADD': - if (draft.pluginService.plugins[action.plugin.id]) throw new Error(`Plugin is already loaded: ${JSON.stringify(action)}`); - draft.pluginService.plugins[action.plugin.id] = action.plugin; + if (draft.plugins[action.plugin.id]) throw new Error(`Plugin is already loaded: ${JSON.stringify(action)}`); + draft.plugins[action.plugin.id] = action.plugin; break; case 'PLUGIN_VIEW_ADD': - draft.pluginService.plugins[action.pluginId].views[action.view.id] = { ...action.view }; + draft.plugins[action.pluginId].views[action.view.id] = { ...action.view }; break; case 'PLUGIN_VIEW_PROP_SET': - draft.pluginService.plugins[action.pluginId].views[action.id][action.name] = action.value; + (draft.plugins[action.pluginId].views[action.id] as any)[action.name] = action.value; break; case 'PLUGIN_VIEW_PROP_PUSH': - draft.pluginService.plugins[action.pluginId].views[action.id][action.name].push(action.value); + (draft.plugins[action.pluginId].views[action.id] as any)[action.name].push(action.value); break; case 'PLUGIN_CONTENT_SCRIPTS_ADD': { const type = action.contentScript.type; - if (!draft.pluginService.plugins[action.pluginId].contentScripts[type]) draft.pluginService.plugins[action.pluginId].contentScripts[type] = []; + if (!draft.plugins[action.pluginId].contentScripts[type]) draft.plugins[action.pluginId].contentScripts[type] = []; - draft.pluginService.plugins[action.pluginId].contentScripts[type].push({ + draft.plugins[action.pluginId].contentScripts[type].push({ id: action.contentScript.id, path: action.contentScript.path, }); diff --git a/packages/lib/services/plugins/utils/createViewHandle.ts b/packages/lib/services/plugins/utils/createViewHandle.ts index f5476bab27..f58f267c63 100644 --- a/packages/lib/services/plugins/utils/createViewHandle.ts +++ b/packages/lib/services/plugins/utils/createViewHandle.ts @@ -1,8 +1,8 @@ -import uuid from '../../../uuid'; import Plugin from '../Plugin'; export type ViewHandle = string; -export default function createViewHandle(plugin: Plugin): ViewHandle { - return `plugin-view-${plugin.id}-${uuid.createNano()}`; +export default function createViewHandle(plugin: Plugin, id: string): ViewHandle { + if (!id) throw new Error('A view ID must be provided'); + return `plugin-view-${plugin.id}-${id}`; } From 72472c13c56951624f326edbfbc80cf3ea2472fd Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 13 Nov 2020 17:55:35 +0000 Subject: [PATCH 02/11] Desktop: Fixed issue with note being saved after word has been replaced by spell checker --- .../app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx index 8a940a48a2..be95987469 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx @@ -272,6 +272,8 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { }, replaceSelection: (value: any) => { editor.selection.setContent(value); + editor.fire('joplinChange'); + dispatchDidUpdate(editor); }, }; From a647272cf0205e7eda1b366f768c3ed26603631c Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 13 Nov 2020 18:48:42 +0000 Subject: [PATCH 03/11] Plugins: Allow retrieving form values from dialogs --- .../tests/support/plugins/dialog/src/index.ts | 17 +++++++- .../services/plugins/UserWebview.tsx | 40 ++++++++++++++++++- .../services/plugins/UserWebviewDialog.tsx | 11 ++++- packages/app-desktop/testPluginDemo.sh | 3 +- .../lib/services/plugins/WebviewController.ts | 6 +-- .../plugins/api/JoplinViewsDialogs.ts | 9 +++-- packages/lib/services/plugins/api/types.ts | 5 +++ 7 files changed, 77 insertions(+), 14 deletions(-) diff --git a/packages/app-cli/tests/support/plugins/dialog/src/index.ts b/packages/app-cli/tests/support/plugins/dialog/src/index.ts index 6ee5b1db5a..b1e6ed4a2f 100644 --- a/packages/app-cli/tests/support/plugins/dialog/src/index.ts +++ b/packages/app-cli/tests/support/plugins/dialog/src/index.ts @@ -7,7 +7,7 @@ joplin.plugins.register({ const handle = await dialogs.create(); await dialogs.setHtml(handle, '

Testing dialog with default buttons

Second line

Third line

'); const result = await dialogs.open(handle); - alert('This button was clicked: ' + result); + alert('Got result: ' + JSON.stringify(result)); const handle2 = await dialogs.create(); await dialogs.setHtml(handle2, '

Testing dialog with custom buttons

Second line

Third line

'); @@ -25,7 +25,20 @@ joplin.plugins.register({ ]); const result2 = await dialogs.open(handle2); - alert('This button was clicked: ' + result2); + alert('Got result: ' + JSON.stringify(result2)); + const handle3 = await dialogs.create(); + await dialogs.setHtml(handle3, ` +

Testing dialog with form elements

+
+ Name: +
+ Email: +
+ `); + + const result3 = await dialogs.open(handle3); + alert('Got result: ' + JSON.stringify(result3)); }, + }); diff --git a/packages/app-desktop/services/plugins/UserWebview.tsx b/packages/app-desktop/services/plugins/UserWebview.tsx index 6e23c518ac..7f0c228918 100644 --- a/packages/app-desktop/services/plugins/UserWebview.tsx +++ b/packages/app-desktop/services/plugins/UserWebview.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useRef, useEffect, useState } from 'react'; +import { useRef, useEffect, useState, useImperativeHandle, forwardRef } from 'react'; import useViewIsReady from './hooks/useViewIsReady'; import useThemeCss from './hooks/useThemeCss'; const styled = require('styled-components').default; @@ -32,7 +32,29 @@ const StyledFrame = styled.iframe` border-bottom: ${(props: Props) => props.borderBottom ? `1px solid ${props.theme.dividerColor}` : 'none'}; `; -export default function UserWebview(props: Props) { +function serializeForm(form: any) { + const output: any = {}; + const formData = new FormData(form); + for (const key of formData.keys()) { + output[key] = formData.get(key); + } + return output; +} + +function serializeForms(document: any) { + const forms = document.getElementsByTagName('form'); + const output: any = {}; + let untitledIndex = 0; + + for (const form of forms) { + const name = `${form.getAttribute('name')}` || (`form${untitledIndex++}`); + output[name] = serializeForm(form); + } + + return output; +} + +function UserWebview(props: Props, ref: any) { const minWidth = props.minWidth ? props.minWidth : 200; const minHeight = props.minHeight ? props.minHeight : 20; @@ -41,6 +63,18 @@ export default function UserWebview(props: Props) { const cssFilePath = useThemeCss({ pluginId: props.pluginId, themeId: props.themeId }); const [contentSize, setContentSize] = useState({ width: minWidth, height: minHeight }); + useImperativeHandle(ref, () => { + return { + formData: function() { + if (viewRef.current) { + return serializeForms(viewRef.current.contentWindow.document); + } else { + return null; + } + }, + }; + }); + function frameWindow() { if (!viewRef.current) return null; return viewRef.current.contentWindow; @@ -143,3 +177,5 @@ export default function UserWebview(props: Props) { borderBottom={props.borderBottom} >; } + +export default forwardRef(UserWebview); diff --git a/packages/app-desktop/services/plugins/UserWebviewDialog.tsx b/packages/app-desktop/services/plugins/UserWebviewDialog.tsx index c6882e6c3b..00a07d44c9 100644 --- a/packages/app-desktop/services/plugins/UserWebviewDialog.tsx +++ b/packages/app-desktop/services/plugins/UserWebviewDialog.tsx @@ -1,7 +1,8 @@ -import { ButtonSpec } from '@joplin/lib/services/plugins/api/types'; +import { ButtonSpec, DialogResult } from '@joplin/lib/services/plugins/api/types'; import PluginService from '@joplin/lib/services/plugins/PluginService'; import WebviewController from '@joplin/lib/services/plugins/WebviewController'; import * as React from 'react'; +import { useRef } from 'react'; import UserWebview, { Props as UserWebviewProps } from './UserWebview'; import UserWebviewDialogButtonBar from './UserWebviewDialogButtonBar'; const styled = require('styled-components').default; @@ -49,6 +50,8 @@ function defaultButtons(): ButtonSpec[] { } export default function UserWebviewDialog(props: Props) { + const webviewRef = useRef(null); + function viewController(): WebviewController { return PluginService.instance().pluginById(props.pluginId).viewController(props.viewId) as WebviewController; } @@ -57,7 +60,10 @@ export default function UserWebviewDialog(props: Props) { return { ...b, onClick: () => { - viewController().closeWithResponse(b.id); + const response: DialogResult = { id: b.id }; + const formData = webviewRef.current.formData(); + if (formData && Object.keys(formData).length) response.formData = formData; + viewController().closeWithResponse(response); }, }; }); @@ -67,6 +73,7 @@ export default function UserWebviewDialog(props: Props) { /dev/null 2>&1 && pwd )" +PLUGIN_PATH="$SCRIPT_DIR/../app-cli/tests/support/plugins/dialog" npm i --prefix="$PLUGIN_PATH" && npm start -- --dev-plugins "$PLUGIN_PATH" \ No newline at end of file diff --git a/packages/lib/services/plugins/WebviewController.ts b/packages/lib/services/plugins/WebviewController.ts index 30de94011d..ac85676f91 100644 --- a/packages/lib/services/plugins/WebviewController.ts +++ b/packages/lib/services/plugins/WebviewController.ts @@ -1,6 +1,6 @@ import ViewController from './ViewController'; import shim from '../../shim'; -import { ButtonId, ButtonSpec } from './api/types'; +import { ButtonSpec, DialogResult } from './api/types'; const { toSystemSlashes } = require('../../path-utils'); export enum ContainerType { @@ -99,7 +99,7 @@ export default class WebviewController extends ViewController { // Specific to dialogs // --------------------------------------------- - public async open(): Promise { + public async open(): Promise { this.setStoreProp('opened', true); return new Promise((resolve: Function, reject: Function) => { @@ -111,7 +111,7 @@ export default class WebviewController extends ViewController { this.setStoreProp('opened', false); } - public closeWithResponse(result: ButtonId) { + public closeWithResponse(result: DialogResult) { this.close(); this.closeResponse_.resolve(result); } diff --git a/packages/lib/services/plugins/api/JoplinViewsDialogs.ts b/packages/lib/services/plugins/api/JoplinViewsDialogs.ts index 8abda423c5..1fbabb9d8b 100644 --- a/packages/lib/services/plugins/api/JoplinViewsDialogs.ts +++ b/packages/lib/services/plugins/api/JoplinViewsDialogs.ts @@ -1,12 +1,13 @@ import Plugin from '../Plugin'; import createViewHandle from '../utils/createViewHandle'; import WebviewController, { ContainerType } from '../WebviewController'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -61,7 +62,7 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - async open(handle: ViewHandle): Promise { + async open(handle: ViewHandle): Promise { return this.controller(handle).open(); } diff --git a/packages/lib/services/plugins/api/types.ts b/packages/lib/services/plugins/api/types.ts index e4da323694..d5f0dad55a 100644 --- a/packages/lib/services/plugins/api/types.ts +++ b/packages/lib/services/plugins/api/types.ts @@ -261,6 +261,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= From 458ae3731db68e22720eff8ae209acf34afb3905 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 13 Nov 2020 19:12:49 +0000 Subject: [PATCH 04/11] Doc: Add beta banner for plugin API --- packages/lib/services/plugins/api/Joplin.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/lib/services/plugins/api/Joplin.ts b/packages/lib/services/plugins/api/Joplin.ts index 0a254284f2..0a782b1684 100644 --- a/packages/lib/services/plugins/api/Joplin.ts +++ b/packages/lib/services/plugins/api/Joplin.ts @@ -11,6 +11,18 @@ import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { From e392efc091f56ec2a894c83050c1b33cc274cb42 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 13 Nov 2020 21:19:02 +0000 Subject: [PATCH 05/11] ignored files --- .eslintignore | 3 --- .gitignore | 3 --- 2 files changed, 6 deletions(-) diff --git a/.eslintignore b/.eslintignore index 566b64755b..855ddc7519 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1144,9 +1144,6 @@ packages/lib/services/rest/utils/requestFields.js.map packages/lib/services/rest/utils/requestPaginationOptions.d.ts packages/lib/services/rest/utils/requestPaginationOptions.js packages/lib/services/rest/utils/requestPaginationOptions.js.map -packages/lib/services/rest/utils/types.d.ts -packages/lib/services/rest/utils/types.js -packages/lib/services/rest/utils/types.js.map packages/lib/services/searchengine/filterParser.d.ts packages/lib/services/searchengine/filterParser.js packages/lib/services/searchengine/filterParser.js.map diff --git a/.gitignore b/.gitignore index 255a0df49c..e5be36d758 100644 --- a/.gitignore +++ b/.gitignore @@ -1136,9 +1136,6 @@ packages/lib/services/rest/utils/requestFields.js.map packages/lib/services/rest/utils/requestPaginationOptions.d.ts packages/lib/services/rest/utils/requestPaginationOptions.js packages/lib/services/rest/utils/requestPaginationOptions.js.map -packages/lib/services/rest/utils/types.d.ts -packages/lib/services/rest/utils/types.js -packages/lib/services/rest/utils/types.js.map packages/lib/services/searchengine/filterParser.d.ts packages/lib/services/searchengine/filterParser.js packages/lib/services/searchengine/filterParser.js.map From 91e7c66f9e3c7bfeabb775da2c1be85788ad4d1d Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 13 Nov 2020 21:19:55 +0000 Subject: [PATCH 06/11] Update website --- docs/api/get_started/plugins/index.html | 2 +- .../plugin_api/assets/js/search.json | 2 +- .../references/plugin_api/classes/joplin.html | 12 + .../plugin_api/classes/joplincommands.html | 3 + .../plugin_api/classes/joplindata.html | 3 + .../plugin_api/classes/joplininterop.html | 3 + .../plugin_api/classes/joplinplugins.html | 3 + .../plugin_api/classes/joplinsettings.html | 3 + .../plugin_api/classes/joplinviews.html | 3 + .../classes/joplinviewsdialogs.html | 12 +- .../classes/joplinviewsmenuitems.html | 3 + .../plugin_api/classes/joplinviewsmenus.html | 3 + .../plugin_api/classes/joplinviewspanels.html | 3 + .../classes/joplinviewstoolbarbuttons.html | 3 + .../plugin_api/classes/joplinworkspace.html | 3 + .../plugin_api/enums/contentscripttype.html | 3 + .../plugin_api/enums/filesystemitem.html | 3 + .../enums/importmoduleoutputformat.html | 3 + .../plugin_api/enums/menuitemlocation.html | 3 + .../plugin_api/enums/settingitemtype.html | 3 + .../enums/toolbarbuttonlocation.html | 3 + docs/api/references/plugin_api/globals.html | 4 + docs/api/references/plugin_api/index.html | 3 + .../plugin_api/interfaces/buttonspec.html | 3 + .../plugin_api/interfaces/command.html | 3 + .../interfaces/createmenuitemoptions.html | 3 + .../plugin_api/interfaces/dialogresult.html | 272 ++++++++++++++++++ .../plugin_api/interfaces/editorcommand.html | 3 + .../plugin_api/interfaces/exportcontext.html | 3 + .../plugin_api/interfaces/exportmodule.html | 3 + .../plugin_api/interfaces/exportoptions.html | 3 + .../plugin_api/interfaces/importcontext.html | 3 + .../plugin_api/interfaces/importmodule.html | 3 + .../plugin_api/interfaces/menuitem.html | 3 + .../plugin_api/interfaces/script.html | 3 + .../plugin_api/interfaces/settingitem.html | 3 + .../plugin_api/interfaces/settingsection.html | 3 + docs/index.html | 10 + docs/stats/index.html | 210 +++++++------- readme/stats.md | 86 +++--- 40 files changed, 549 insertions(+), 154 deletions(-) create mode 100644 docs/api/references/plugin_api/interfaces/dialogresult.html diff --git a/docs/api/get_started/plugins/index.html b/docs/api/get_started/plugins/index.html index 2f8cae75a4..048690a88a 100644 --- a/docs/api/get_started/plugins/index.html +++ b/docs/api/get_started/plugins/index.html @@ -415,7 +415,7 @@ https://github.com/laurent22/joplin/blob/dev/readme/api/get_started/plugins.md

Doing so should compile all the files into the dist/ directory. This is from here that Joplin will load the plugin.

Testing the plugin🔗

-

In order to test the plugin, you might want to run Joplin in Development Mode. Doing so means that Joplin will run using a different profile, so you can experiment with the plugin without risking to accidentally change or delete your data.

+

In order to test the plugin, you might want to run Joplin in Development Mode. Doing so means that Joplin will run using a different profile, so you can experiment with the plugin without risking to accidentally change or delete your data.

Finally, in order to test the plugin, open the Setting screen, then navigate the the Plugins section, and add the plugin path in the Development plugins text field. For example, if your plugin project path is /home/user/src/joplin-plugin, add this in the text field.

Restart the app, and Joplin should load the plugin and execute its onStart handler. If all went well you should see the test message in the plugin console: "Test plugin started!".

Next steps🔗

diff --git a/docs/api/references/plugin_api/assets/js/search.json b/docs/api/references/plugin_api/assets/js/search.json index b8d161ff78..09b90841be 100644 --- a/docs/api/references/plugin_api/assets/js/search.json +++ b/docs/api/references/plugin_api/assets/js/search.json @@ -1 +1 @@ -{"kinds":{"4":"Enumeration","16":"Enumeration member","128":"Class","256":"Interface","512":"Constructor","1024":"Property","2048":"Method","262144":"Accessor","4194304":"Type alias"},"rows":[{"id":0,"kind":256,"name":"Command","url":"interfaces/command.html","classes":"tsd-kind-interface"},{"id":1,"kind":1024,"name":"name","url":"interfaces/command.html#name","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Command"},{"id":2,"kind":1024,"name":"label","url":"interfaces/command.html#label","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Command"},{"id":3,"kind":1024,"name":"iconName","url":"interfaces/command.html#iconname","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Command"},{"id":4,"kind":2048,"name":"execute","url":"interfaces/command.html#execute","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"Command"},{"id":5,"kind":1024,"name":"enabledCondition","url":"interfaces/command.html#enabledcondition","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Command"},{"id":6,"kind":4,"name":"FileSystemItem","url":"enums/filesystemitem.html","classes":"tsd-kind-enum"},{"id":7,"kind":16,"name":"File","url":"enums/filesystemitem.html#file","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"FileSystemItem"},{"id":8,"kind":16,"name":"Directory","url":"enums/filesystemitem.html#directory","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"FileSystemItem"},{"id":9,"kind":4,"name":"ImportModuleOutputFormat","url":"enums/importmoduleoutputformat.html","classes":"tsd-kind-enum"},{"id":10,"kind":16,"name":"Markdown","url":"enums/importmoduleoutputformat.html#markdown","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ImportModuleOutputFormat"},{"id":11,"kind":16,"name":"Html","url":"enums/importmoduleoutputformat.html#html","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ImportModuleOutputFormat"},{"id":12,"kind":256,"name":"ExportModule","url":"interfaces/exportmodule.html","classes":"tsd-kind-interface"},{"id":13,"kind":1024,"name":"format","url":"interfaces/exportmodule.html#format","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportModule"},{"id":14,"kind":1024,"name":"description","url":"interfaces/exportmodule.html#description","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportModule"},{"id":15,"kind":1024,"name":"target","url":"interfaces/exportmodule.html#target","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportModule"},{"id":16,"kind":1024,"name":"isNoteArchive","url":"interfaces/exportmodule.html#isnotearchive","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportModule"},{"id":17,"kind":1024,"name":"fileExtensions","url":"interfaces/exportmodule.html#fileextensions","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportModule"},{"id":18,"kind":2048,"name":"onInit","url":"interfaces/exportmodule.html#oninit","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ExportModule"},{"id":19,"kind":2048,"name":"onProcessItem","url":"interfaces/exportmodule.html#onprocessitem","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ExportModule"},{"id":20,"kind":2048,"name":"onProcessResource","url":"interfaces/exportmodule.html#onprocessresource","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ExportModule"},{"id":21,"kind":2048,"name":"onClose","url":"interfaces/exportmodule.html#onclose","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ExportModule"},{"id":22,"kind":256,"name":"ImportModule","url":"interfaces/importmodule.html","classes":"tsd-kind-interface"},{"id":23,"kind":1024,"name":"format","url":"interfaces/importmodule.html#format","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":24,"kind":1024,"name":"description","url":"interfaces/importmodule.html#description","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":25,"kind":1024,"name":"isNoteArchive","url":"interfaces/importmodule.html#isnotearchive","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":26,"kind":1024,"name":"sources","url":"interfaces/importmodule.html#sources","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":27,"kind":1024,"name":"fileExtensions","url":"interfaces/importmodule.html#fileextensions","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":28,"kind":1024,"name":"outputFormat","url":"interfaces/importmodule.html#outputformat","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":29,"kind":2048,"name":"onExec","url":"interfaces/importmodule.html#onexec","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ImportModule"},{"id":30,"kind":256,"name":"ExportOptions","url":"interfaces/exportoptions.html","classes":"tsd-kind-interface"},{"id":31,"kind":1024,"name":"format","url":"interfaces/exportoptions.html#format","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":32,"kind":1024,"name":"path","url":"interfaces/exportoptions.html#path","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":33,"kind":1024,"name":"sourceFolderIds","url":"interfaces/exportoptions.html#sourcefolderids","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":34,"kind":1024,"name":"sourceNoteIds","url":"interfaces/exportoptions.html#sourcenoteids","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":35,"kind":1024,"name":"modulePath","url":"interfaces/exportoptions.html#modulepath","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":36,"kind":1024,"name":"target","url":"interfaces/exportoptions.html#target","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":37,"kind":256,"name":"ExportContext","url":"interfaces/exportcontext.html","classes":"tsd-kind-interface"},{"id":38,"kind":1024,"name":"destPath","url":"interfaces/exportcontext.html#destpath","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportContext"},{"id":39,"kind":1024,"name":"options","url":"interfaces/exportcontext.html#options","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportContext"},{"id":40,"kind":1024,"name":"userData","url":"interfaces/exportcontext.html#userdata","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportContext"},{"id":41,"kind":256,"name":"ImportContext","url":"interfaces/importcontext.html","classes":"tsd-kind-interface"},{"id":42,"kind":1024,"name":"sourcePath","url":"interfaces/importcontext.html#sourcepath","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportContext"},{"id":43,"kind":1024,"name":"options","url":"interfaces/importcontext.html#options","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportContext"},{"id":44,"kind":1024,"name":"warnings","url":"interfaces/importcontext.html#warnings","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportContext"},{"id":45,"kind":256,"name":"Script","url":"interfaces/script.html","classes":"tsd-kind-interface"},{"id":46,"kind":2048,"name":"onStart","url":"interfaces/script.html#onstart","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"Script"},{"id":47,"kind":256,"name":"CreateMenuItemOptions","url":"interfaces/createmenuitemoptions.html","classes":"tsd-kind-interface"},{"id":48,"kind":1024,"name":"accelerator","url":"interfaces/createmenuitemoptions.html#accelerator","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"CreateMenuItemOptions"},{"id":49,"kind":4,"name":"MenuItemLocation","url":"enums/menuitemlocation.html","classes":"tsd-kind-enum"},{"id":50,"kind":16,"name":"File","url":"enums/menuitemlocation.html#file","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":51,"kind":16,"name":"Edit","url":"enums/menuitemlocation.html#edit","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":52,"kind":16,"name":"View","url":"enums/menuitemlocation.html#view","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":53,"kind":16,"name":"Note","url":"enums/menuitemlocation.html#note","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":54,"kind":16,"name":"Tools","url":"enums/menuitemlocation.html#tools","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":55,"kind":16,"name":"Help","url":"enums/menuitemlocation.html#help","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":56,"kind":16,"name":"Context","url":"enums/menuitemlocation.html#context","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":57,"kind":256,"name":"MenuItem","url":"interfaces/menuitem.html","classes":"tsd-kind-interface"},{"id":58,"kind":1024,"name":"commandName","url":"interfaces/menuitem.html#commandname","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MenuItem"},{"id":59,"kind":1024,"name":"accelerator","url":"interfaces/menuitem.html#accelerator","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MenuItem"},{"id":60,"kind":1024,"name":"submenu","url":"interfaces/menuitem.html#submenu","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MenuItem"},{"id":61,"kind":1024,"name":"label","url":"interfaces/menuitem.html#label","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MenuItem"},{"id":62,"kind":256,"name":"ButtonSpec","url":"interfaces/buttonspec.html","classes":"tsd-kind-interface"},{"id":63,"kind":1024,"name":"id","url":"interfaces/buttonspec.html#id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ButtonSpec"},{"id":64,"kind":1024,"name":"title","url":"interfaces/buttonspec.html#title","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ButtonSpec"},{"id":65,"kind":2048,"name":"onClick","url":"interfaces/buttonspec.html#onclick","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ButtonSpec"},{"id":66,"kind":4,"name":"ToolbarButtonLocation","url":"enums/toolbarbuttonlocation.html","classes":"tsd-kind-enum"},{"id":67,"kind":16,"name":"NoteToolbar","url":"enums/toolbarbuttonlocation.html#notetoolbar","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ToolbarButtonLocation"},{"id":68,"kind":16,"name":"EditorToolbar","url":"enums/toolbarbuttonlocation.html#editortoolbar","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ToolbarButtonLocation"},{"id":69,"kind":256,"name":"EditorCommand","url":"interfaces/editorcommand.html","classes":"tsd-kind-interface"},{"id":70,"kind":1024,"name":"name","url":"interfaces/editorcommand.html#name","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"EditorCommand"},{"id":71,"kind":1024,"name":"value","url":"interfaces/editorcommand.html#value","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"EditorCommand"},{"id":72,"kind":4,"name":"SettingItemType","url":"enums/settingitemtype.html","classes":"tsd-kind-enum"},{"id":73,"kind":16,"name":"Int","url":"enums/settingitemtype.html#int","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":74,"kind":16,"name":"String","url":"enums/settingitemtype.html#string","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":75,"kind":16,"name":"Bool","url":"enums/settingitemtype.html#bool","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":76,"kind":16,"name":"Array","url":"enums/settingitemtype.html#array","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":77,"kind":16,"name":"Object","url":"enums/settingitemtype.html#object","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":78,"kind":16,"name":"Button","url":"enums/settingitemtype.html#button","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":79,"kind":256,"name":"SettingItem","url":"interfaces/settingitem.html","classes":"tsd-kind-interface"},{"id":80,"kind":1024,"name":"value","url":"interfaces/settingitem.html#value","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":81,"kind":1024,"name":"type","url":"interfaces/settingitem.html#type","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":82,"kind":1024,"name":"public","url":"interfaces/settingitem.html#public","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":83,"kind":1024,"name":"label","url":"interfaces/settingitem.html#label","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":84,"kind":1024,"name":"description","url":"interfaces/settingitem.html#description","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":85,"kind":1024,"name":"isEnum","url":"interfaces/settingitem.html#isenum","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":86,"kind":1024,"name":"section","url":"interfaces/settingitem.html#section","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":87,"kind":1024,"name":"options","url":"interfaces/settingitem.html#options","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":88,"kind":1024,"name":"appTypes","url":"interfaces/settingitem.html#apptypes","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":89,"kind":1024,"name":"secure","url":"interfaces/settingitem.html#secure","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":90,"kind":1024,"name":"advanced","url":"interfaces/settingitem.html#advanced","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":91,"kind":1024,"name":"minimum","url":"interfaces/settingitem.html#minimum","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":92,"kind":1024,"name":"maximum","url":"interfaces/settingitem.html#maximum","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":93,"kind":1024,"name":"step","url":"interfaces/settingitem.html#step","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":94,"kind":256,"name":"SettingSection","url":"interfaces/settingsection.html","classes":"tsd-kind-interface"},{"id":95,"kind":1024,"name":"label","url":"interfaces/settingsection.html#label","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingSection"},{"id":96,"kind":1024,"name":"iconName","url":"interfaces/settingsection.html#iconname","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingSection"},{"id":97,"kind":1024,"name":"description","url":"interfaces/settingsection.html#description","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingSection"},{"id":98,"kind":1024,"name":"name","url":"interfaces/settingsection.html#name","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingSection"},{"id":99,"kind":4,"name":"ContentScriptType","url":"enums/contentscripttype.html","classes":"tsd-kind-enum"},{"id":100,"kind":16,"name":"MarkdownItPlugin","url":"enums/contentscripttype.html#markdownitplugin","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ContentScriptType"},{"id":101,"kind":16,"name":"CodeMirrorPlugin","url":"enums/contentscripttype.html#codemirrorplugin","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ContentScriptType"},{"id":102,"kind":4194304,"name":"ButtonId","url":"globals.html#buttonid","classes":"tsd-kind-type-alias"},{"id":103,"kind":4194304,"name":"ViewHandle","url":"globals.html#viewhandle","classes":"tsd-kind-type-alias"},{"id":104,"kind":4194304,"name":"Path","url":"globals.html#path","classes":"tsd-kind-type-alias"},{"id":105,"kind":128,"name":"JoplinData","url":"classes/joplindata.html","classes":"tsd-kind-class"},{"id":106,"kind":2048,"name":"get","url":"classes/joplindata.html#get","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinData"},{"id":107,"kind":2048,"name":"post","url":"classes/joplindata.html#post","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinData"},{"id":108,"kind":2048,"name":"put","url":"classes/joplindata.html#put","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinData"},{"id":109,"kind":2048,"name":"delete","url":"classes/joplindata.html#delete","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinData"},{"id":110,"kind":128,"name":"JoplinPlugins","url":"classes/joplinplugins.html","classes":"tsd-kind-class"},{"id":111,"kind":512,"name":"constructor","url":"classes/joplinplugins.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinPlugins"},{"id":112,"kind":2048,"name":"register","url":"classes/joplinplugins.html#register","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinPlugins"},{"id":113,"kind":2048,"name":"registerContentScript","url":"classes/joplinplugins.html#registercontentscript","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinPlugins"},{"id":114,"kind":128,"name":"JoplinWorkspace","url":"classes/joplinworkspace.html","classes":"tsd-kind-class"},{"id":115,"kind":512,"name":"constructor","url":"classes/joplinworkspace.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":116,"kind":2048,"name":"onNoteSelectionChange","url":"classes/joplinworkspace.html#onnoteselectionchange","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":117,"kind":2048,"name":"onNoteContentChange","url":"classes/joplinworkspace.html#onnotecontentchange","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":118,"kind":2048,"name":"onNoteAlarmTrigger","url":"classes/joplinworkspace.html#onnotealarmtrigger","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":119,"kind":2048,"name":"onSyncComplete","url":"classes/joplinworkspace.html#onsynccomplete","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":120,"kind":2048,"name":"selectedNote","url":"classes/joplinworkspace.html#selectednote","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":121,"kind":2048,"name":"selectedNoteIds","url":"classes/joplinworkspace.html#selectednoteids","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":122,"kind":128,"name":"JoplinCommands","url":"classes/joplincommands.html","classes":"tsd-kind-class"},{"id":123,"kind":2048,"name":"execute","url":"classes/joplincommands.html#execute","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinCommands"},{"id":124,"kind":2048,"name":"register","url":"classes/joplincommands.html#register","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinCommands"},{"id":125,"kind":128,"name":"JoplinViewsDialogs","url":"classes/joplinviewsdialogs.html","classes":"tsd-kind-class"},{"id":126,"kind":512,"name":"constructor","url":"classes/joplinviewsdialogs.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":127,"kind":2048,"name":"create","url":"classes/joplinviewsdialogs.html#create","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":128,"kind":2048,"name":"showMessageBox","url":"classes/joplinviewsdialogs.html#showmessagebox","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":129,"kind":2048,"name":"setHtml","url":"classes/joplinviewsdialogs.html#sethtml","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":130,"kind":2048,"name":"setButtons","url":"classes/joplinviewsdialogs.html#setbuttons","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":131,"kind":2048,"name":"open","url":"classes/joplinviewsdialogs.html#open","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":132,"kind":128,"name":"JoplinViewsMenuItems","url":"classes/joplinviewsmenuitems.html","classes":"tsd-kind-class"},{"id":133,"kind":512,"name":"constructor","url":"classes/joplinviewsmenuitems.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViewsMenuItems"},{"id":134,"kind":2048,"name":"create","url":"classes/joplinviewsmenuitems.html#create","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsMenuItems"},{"id":135,"kind":128,"name":"JoplinViewsMenus","url":"classes/joplinviewsmenus.html","classes":"tsd-kind-class"},{"id":136,"kind":512,"name":"constructor","url":"classes/joplinviewsmenus.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViewsMenus"},{"id":137,"kind":2048,"name":"create","url":"classes/joplinviewsmenus.html#create","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsMenus"},{"id":138,"kind":128,"name":"JoplinViewsToolbarButtons","url":"classes/joplinviewstoolbarbuttons.html","classes":"tsd-kind-class"},{"id":139,"kind":512,"name":"constructor","url":"classes/joplinviewstoolbarbuttons.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViewsToolbarButtons"},{"id":140,"kind":2048,"name":"create","url":"classes/joplinviewstoolbarbuttons.html#create","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsToolbarButtons"},{"id":141,"kind":128,"name":"JoplinViewsPanels","url":"classes/joplinviewspanels.html","classes":"tsd-kind-class"},{"id":142,"kind":512,"name":"constructor","url":"classes/joplinviewspanels.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViewsPanels"},{"id":143,"kind":2048,"name":"create","url":"classes/joplinviewspanels.html#create","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsPanels"},{"id":144,"kind":2048,"name":"setHtml","url":"classes/joplinviewspanels.html#sethtml","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsPanels"},{"id":145,"kind":2048,"name":"addScript","url":"classes/joplinviewspanels.html#addscript","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsPanels"},{"id":146,"kind":2048,"name":"onMessage","url":"classes/joplinviewspanels.html#onmessage","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsPanels"},{"id":147,"kind":128,"name":"JoplinViews","url":"classes/joplinviews.html","classes":"tsd-kind-class"},{"id":148,"kind":512,"name":"constructor","url":"classes/joplinviews.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViews"},{"id":149,"kind":262144,"name":"dialogs","url":"classes/joplinviews.html#dialogs","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"JoplinViews"},{"id":150,"kind":262144,"name":"panels","url":"classes/joplinviews.html#panels","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"JoplinViews"},{"id":151,"kind":262144,"name":"menuItems","url":"classes/joplinviews.html#menuitems","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"JoplinViews"},{"id":152,"kind":262144,"name":"menus","url":"classes/joplinviews.html#menus","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"JoplinViews"},{"id":153,"kind":262144,"name":"toolbarButtons","url":"classes/joplinviews.html#toolbarbuttons","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"JoplinViews"},{"id":154,"kind":128,"name":"JoplinInterop","url":"classes/joplininterop.html","classes":"tsd-kind-class"},{"id":155,"kind":2048,"name":"registerExportModule","url":"classes/joplininterop.html#registerexportmodule","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinInterop"},{"id":156,"kind":2048,"name":"registerImportModule","url":"classes/joplininterop.html#registerimportmodule","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinInterop"},{"id":157,"kind":128,"name":"JoplinSettings","url":"classes/joplinsettings.html","classes":"tsd-kind-class"},{"id":158,"kind":512,"name":"constructor","url":"classes/joplinsettings.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinSettings"},{"id":159,"kind":2048,"name":"registerSetting","url":"classes/joplinsettings.html#registersetting","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinSettings"},{"id":160,"kind":2048,"name":"registerSection","url":"classes/joplinsettings.html#registersection","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinSettings"},{"id":161,"kind":2048,"name":"value","url":"classes/joplinsettings.html#value","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinSettings"},{"id":162,"kind":2048,"name":"setValue","url":"classes/joplinsettings.html#setvalue","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinSettings"},{"id":163,"kind":2048,"name":"globalValue","url":"classes/joplinsettings.html#globalvalue","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinSettings"},{"id":164,"kind":128,"name":"Joplin","url":"classes/joplin.html","classes":"tsd-kind-class"},{"id":165,"kind":512,"name":"constructor","url":"classes/joplin.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"Joplin"},{"id":166,"kind":262144,"name":"data","url":"classes/joplin.html#data","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":167,"kind":262144,"name":"plugins","url":"classes/joplin.html#plugins","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":168,"kind":262144,"name":"workspace","url":"classes/joplin.html#workspace","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":169,"kind":262144,"name":"commands","url":"classes/joplin.html#commands","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":170,"kind":262144,"name":"views","url":"classes/joplin.html#views","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":171,"kind":262144,"name":"interop","url":"classes/joplin.html#interop","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":172,"kind":262144,"name":"settings","url":"classes/joplin.html#settings","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,32.873]],["parent/0",[]],["name/1",[1,39.063]],["parent/1",[0,2.978]],["name/2",[2,36.55]],["parent/2",[0,2.978]],["name/3",[3,42.428]],["parent/3",[0,2.978]],["name/4",[4,42.428]],["parent/4",[0,2.978]],["name/5",[5,47.536]],["parent/5",[0,2.978]],["name/6",[6,39.063]],["parent/6",[]],["name/7",[7,42.428]],["parent/7",[6,3.539]],["name/8",[8,47.536]],["parent/8",[6,3.539]],["name/9",[9,39.063]],["parent/9",[]],["name/10",[10,47.536]],["parent/10",[9,3.539]],["name/11",[11,47.536]],["parent/11",[9,3.539]],["name/12",[12,28.077]],["parent/12",[]],["name/13",[13,39.063]],["parent/13",[12,2.544]],["name/14",[14,36.55]],["parent/14",[12,2.544]],["name/15",[15,42.428]],["parent/15",[12,2.544]],["name/16",[16,42.428]],["parent/16",[12,2.544]],["name/17",[17,42.428]],["parent/17",[12,2.544]],["name/18",[18,47.536]],["parent/18",[12,2.544]],["name/19",[19,47.536]],["parent/19",[12,2.544]],["name/20",[20,47.536]],["parent/20",[12,2.544]],["name/21",[21,47.536]],["parent/21",[12,2.544]],["name/22",[22,30.19]],["parent/22",[]],["name/23",[13,39.063]],["parent/23",[22,2.735]],["name/24",[14,36.55]],["parent/24",[22,2.735]],["name/25",[16,42.428]],["parent/25",[22,2.735]],["name/26",[23,47.536]],["parent/26",[22,2.735]],["name/27",[17,42.428]],["parent/27",[22,2.735]],["name/28",[24,47.536]],["parent/28",[22,2.735]],["name/29",[25,47.536]],["parent/29",[22,2.735]],["name/30",[26,31.442]],["parent/30",[]],["name/31",[13,39.063]],["parent/31",[26,2.849]],["name/32",[27,42.428]],["parent/32",[26,2.849]],["name/33",[28,47.536]],["parent/33",[26,2.849]],["name/34",[29,47.536]],["parent/34",[26,2.849]],["name/35",[30,47.536]],["parent/35",[26,2.849]],["name/36",[15,42.428]],["parent/36",[26,2.849]],["name/37",[31,36.55]],["parent/37",[]],["name/38",[32,47.536]],["parent/38",[31,3.311]],["name/39",[33,39.063]],["parent/39",[31,3.311]],["name/40",[34,47.536]],["parent/40",[31,3.311]],["name/41",[35,36.55]],["parent/41",[]],["name/42",[36,47.536]],["parent/42",[35,3.311]],["name/43",[33,39.063]],["parent/43",[35,3.311]],["name/44",[37,47.536]],["parent/44",[35,3.311]],["name/45",[38,42.428]],["parent/45",[]],["name/46",[39,47.536]],["parent/46",[38,3.844]],["name/47",[40,42.428]],["parent/47",[]],["name/48",[41,42.428]],["parent/48",[40,3.844]],["name/49",[42,30.19]],["parent/49",[]],["name/50",[7,42.428]],["parent/50",[42,2.735]],["name/51",[43,47.536]],["parent/51",[42,2.735]],["name/52",[44,47.536]],["parent/52",[42,2.735]],["name/53",[45,47.536]],["parent/53",[42,2.735]],["name/54",[46,47.536]],["parent/54",[42,2.735]],["name/55",[47,47.536]],["parent/55",[42,2.735]],["name/56",[48,47.536]],["parent/56",[42,2.735]],["name/57",[49,34.543]],["parent/57",[]],["name/58",[50,47.536]],["parent/58",[49,3.13]],["name/59",[41,42.428]],["parent/59",[49,3.13]],["name/60",[51,47.536]],["parent/60",[49,3.13]],["name/61",[2,36.55]],["parent/61",[49,3.13]],["name/62",[52,36.55]],["parent/62",[]],["name/63",[53,47.536]],["parent/63",[52,3.311]],["name/64",[54,47.536]],["parent/64",[52,3.311]],["name/65",[55,47.536]],["parent/65",[52,3.311]],["name/66",[56,39.063]],["parent/66",[]],["name/67",[57,47.536]],["parent/67",[56,3.539]],["name/68",[58,47.536]],["parent/68",[56,3.539]],["name/69",[59,39.063]],["parent/69",[]],["name/70",[1,39.063]],["parent/70",[59,3.539]],["name/71",[60,39.063]],["parent/71",[59,3.539]],["name/72",[61,31.442]],["parent/72",[]],["name/73",[62,47.536]],["parent/73",[61,2.849]],["name/74",[63,47.536]],["parent/74",[61,2.849]],["name/75",[64,47.536]],["parent/75",[61,2.849]],["name/76",[65,47.536]],["parent/76",[61,2.849]],["name/77",[66,47.536]],["parent/77",[61,2.849]],["name/78",[67,47.536]],["parent/78",[61,2.849]],["name/79",[68,24.182]],["parent/79",[]],["name/80",[60,39.063]],["parent/80",[68,2.191]],["name/81",[69,47.536]],["parent/81",[68,2.191]],["name/82",[70,47.536]],["parent/82",[68,2.191]],["name/83",[2,36.55]],["parent/83",[68,2.191]],["name/84",[14,36.55]],["parent/84",[68,2.191]],["name/85",[71,47.536]],["parent/85",[68,2.191]],["name/86",[72,47.536]],["parent/86",[68,2.191]],["name/87",[33,39.063]],["parent/87",[68,2.191]],["name/88",[73,47.536]],["parent/88",[68,2.191]],["name/89",[74,47.536]],["parent/89",[68,2.191]],["name/90",[75,47.536]],["parent/90",[68,2.191]],["name/91",[76,47.536]],["parent/91",[68,2.191]],["name/92",[77,47.536]],["parent/92",[68,2.191]],["name/93",[78,47.536]],["parent/93",[68,2.191]],["name/94",[79,34.543]],["parent/94",[]],["name/95",[2,36.55]],["parent/95",[79,3.13]],["name/96",[3,42.428]],["parent/96",[79,3.13]],["name/97",[14,36.55]],["parent/97",[79,3.13]],["name/98",[1,39.063]],["parent/98",[79,3.13]],["name/99",[80,39.063]],["parent/99",[]],["name/100",[81,47.536]],["parent/100",[80,3.539]],["name/101",[82,47.536]],["parent/101",[80,3.539]],["name/102",[83,47.536]],["parent/102",[]],["name/103",[84,47.536]],["parent/103",[]],["name/104",[27,42.428]],["parent/104",[]],["name/105",[85,34.543]],["parent/105",[]],["name/106",[86,47.536]],["parent/106",[85,3.13]],["name/107",[87,47.536]],["parent/107",[85,3.13]],["name/108",[88,47.536]],["parent/108",[85,3.13]],["name/109",[89,47.536]],["parent/109",[85,3.13]],["name/110",[90,36.55]],["parent/110",[]],["name/111",[91,28.077]],["parent/111",[90,3.311]],["name/112",[92,42.428]],["parent/112",[90,3.311]],["name/113",[93,47.536]],["parent/113",[90,3.311]],["name/114",[94,30.19]],["parent/114",[]],["name/115",[91,28.077]],["parent/115",[94,2.735]],["name/116",[95,47.536]],["parent/116",[94,2.735]],["name/117",[96,47.536]],["parent/117",[94,2.735]],["name/118",[97,47.536]],["parent/118",[94,2.735]],["name/119",[98,47.536]],["parent/119",[94,2.735]],["name/120",[99,47.536]],["parent/120",[94,2.735]],["name/121",[100,47.536]],["parent/121",[94,2.735]],["name/122",[101,39.063]],["parent/122",[]],["name/123",[4,42.428]],["parent/123",[101,3.539]],["name/124",[92,42.428]],["parent/124",[101,3.539]],["name/125",[102,31.442]],["parent/125",[]],["name/126",[91,28.077]],["parent/126",[102,2.849]],["name/127",[103,34.543]],["parent/127",[102,2.849]],["name/128",[104,47.536]],["parent/128",[102,2.849]],["name/129",[105,42.428]],["parent/129",[102,2.849]],["name/130",[106,47.536]],["parent/130",[102,2.849]],["name/131",[107,47.536]],["parent/131",[102,2.849]],["name/132",[108,39.063]],["parent/132",[]],["name/133",[91,28.077]],["parent/133",[108,3.539]],["name/134",[103,34.543]],["parent/134",[108,3.539]],["name/135",[109,39.063]],["parent/135",[]],["name/136",[91,28.077]],["parent/136",[109,3.539]],["name/137",[103,34.543]],["parent/137",[109,3.539]],["name/138",[110,39.063]],["parent/138",[]],["name/139",[91,28.077]],["parent/139",[110,3.539]],["name/140",[103,34.543]],["parent/140",[110,3.539]],["name/141",[111,32.873]],["parent/141",[]],["name/142",[91,28.077]],["parent/142",[111,2.978]],["name/143",[103,34.543]],["parent/143",[111,2.978]],["name/144",[105,42.428]],["parent/144",[111,2.978]],["name/145",[112,47.536]],["parent/145",[111,2.978]],["name/146",[113,47.536]],["parent/146",[111,2.978]],["name/147",[114,31.442]],["parent/147",[]],["name/148",[91,28.077]],["parent/148",[114,2.849]],["name/149",[115,47.536]],["parent/149",[114,2.849]],["name/150",[116,47.536]],["parent/150",[114,2.849]],["name/151",[117,47.536]],["parent/151",[114,2.849]],["name/152",[118,47.536]],["parent/152",[114,2.849]],["name/153",[119,47.536]],["parent/153",[114,2.849]],["name/154",[120,39.063]],["parent/154",[]],["name/155",[121,47.536]],["parent/155",[120,3.539]],["name/156",[122,47.536]],["parent/156",[120,3.539]],["name/157",[123,31.442]],["parent/157",[]],["name/158",[91,28.077]],["parent/158",[123,2.849]],["name/159",[124,47.536]],["parent/159",[123,2.849]],["name/160",[125,47.536]],["parent/160",[123,2.849]],["name/161",[60,39.063]],["parent/161",[123,2.849]],["name/162",[126,47.536]],["parent/162",[123,2.849]],["name/163",[127,47.536]],["parent/163",[123,2.849]],["name/164",[128,29.078]],["parent/164",[]],["name/165",[91,28.077]],["parent/165",[128,2.634]],["name/166",[129,47.536]],["parent/166",[128,2.634]],["name/167",[130,47.536]],["parent/167",[128,2.634]],["name/168",[131,47.536]],["parent/168",[128,2.634]],["name/169",[132,47.536]],["parent/169",[128,2.634]],["name/170",[133,47.536]],["parent/170",[128,2.634]],["name/171",[134,47.536]],["parent/171",[128,2.634]],["name/172",[135,47.536]],["parent/172",[128,2.634]]],"invertedIndex":[["accelerator",{"_index":41,"name":{"48":{},"59":{}},"parent":{}}],["addscript",{"_index":112,"name":{"145":{}},"parent":{}}],["advanced",{"_index":75,"name":{"90":{}},"parent":{}}],["apptypes",{"_index":73,"name":{"88":{}},"parent":{}}],["array",{"_index":65,"name":{"76":{}},"parent":{}}],["bool",{"_index":64,"name":{"75":{}},"parent":{}}],["button",{"_index":67,"name":{"78":{}},"parent":{}}],["buttonid",{"_index":83,"name":{"102":{}},"parent":{}}],["buttonspec",{"_index":52,"name":{"62":{}},"parent":{"63":{},"64":{},"65":{}}}],["codemirrorplugin",{"_index":82,"name":{"101":{}},"parent":{}}],["command",{"_index":0,"name":{"0":{}},"parent":{"1":{},"2":{},"3":{},"4":{},"5":{}}}],["commandname",{"_index":50,"name":{"58":{}},"parent":{}}],["commands",{"_index":132,"name":{"169":{}},"parent":{}}],["constructor",{"_index":91,"name":{"111":{},"115":{},"126":{},"133":{},"136":{},"139":{},"142":{},"148":{},"158":{},"165":{}},"parent":{}}],["contentscripttype",{"_index":80,"name":{"99":{}},"parent":{"100":{},"101":{}}}],["context",{"_index":48,"name":{"56":{}},"parent":{}}],["create",{"_index":103,"name":{"127":{},"134":{},"137":{},"140":{},"143":{}},"parent":{}}],["createmenuitemoptions",{"_index":40,"name":{"47":{}},"parent":{"48":{}}}],["data",{"_index":129,"name":{"166":{}},"parent":{}}],["delete",{"_index":89,"name":{"109":{}},"parent":{}}],["description",{"_index":14,"name":{"14":{},"24":{},"84":{},"97":{}},"parent":{}}],["destpath",{"_index":32,"name":{"38":{}},"parent":{}}],["dialogs",{"_index":115,"name":{"149":{}},"parent":{}}],["directory",{"_index":8,"name":{"8":{}},"parent":{}}],["edit",{"_index":43,"name":{"51":{}},"parent":{}}],["editorcommand",{"_index":59,"name":{"69":{}},"parent":{"70":{},"71":{}}}],["editortoolbar",{"_index":58,"name":{"68":{}},"parent":{}}],["enabledcondition",{"_index":5,"name":{"5":{}},"parent":{}}],["execute",{"_index":4,"name":{"4":{},"123":{}},"parent":{}}],["exportcontext",{"_index":31,"name":{"37":{}},"parent":{"38":{},"39":{},"40":{}}}],["exportmodule",{"_index":12,"name":{"12":{}},"parent":{"13":{},"14":{},"15":{},"16":{},"17":{},"18":{},"19":{},"20":{},"21":{}}}],["exportoptions",{"_index":26,"name":{"30":{}},"parent":{"31":{},"32":{},"33":{},"34":{},"35":{},"36":{}}}],["file",{"_index":7,"name":{"7":{},"50":{}},"parent":{}}],["fileextensions",{"_index":17,"name":{"17":{},"27":{}},"parent":{}}],["filesystemitem",{"_index":6,"name":{"6":{}},"parent":{"7":{},"8":{}}}],["format",{"_index":13,"name":{"13":{},"23":{},"31":{}},"parent":{}}],["get",{"_index":86,"name":{"106":{}},"parent":{}}],["globalvalue",{"_index":127,"name":{"163":{}},"parent":{}}],["help",{"_index":47,"name":{"55":{}},"parent":{}}],["html",{"_index":11,"name":{"11":{}},"parent":{}}],["iconname",{"_index":3,"name":{"3":{},"96":{}},"parent":{}}],["id",{"_index":53,"name":{"63":{}},"parent":{}}],["importcontext",{"_index":35,"name":{"41":{}},"parent":{"42":{},"43":{},"44":{}}}],["importmodule",{"_index":22,"name":{"22":{}},"parent":{"23":{},"24":{},"25":{},"26":{},"27":{},"28":{},"29":{}}}],["importmoduleoutputformat",{"_index":9,"name":{"9":{}},"parent":{"10":{},"11":{}}}],["int",{"_index":62,"name":{"73":{}},"parent":{}}],["interop",{"_index":134,"name":{"171":{}},"parent":{}}],["isenum",{"_index":71,"name":{"85":{}},"parent":{}}],["isnotearchive",{"_index":16,"name":{"16":{},"25":{}},"parent":{}}],["joplin",{"_index":128,"name":{"164":{}},"parent":{"165":{},"166":{},"167":{},"168":{},"169":{},"170":{},"171":{},"172":{}}}],["joplincommands",{"_index":101,"name":{"122":{}},"parent":{"123":{},"124":{}}}],["joplindata",{"_index":85,"name":{"105":{}},"parent":{"106":{},"107":{},"108":{},"109":{}}}],["joplininterop",{"_index":120,"name":{"154":{}},"parent":{"155":{},"156":{}}}],["joplinplugins",{"_index":90,"name":{"110":{}},"parent":{"111":{},"112":{},"113":{}}}],["joplinsettings",{"_index":123,"name":{"157":{}},"parent":{"158":{},"159":{},"160":{},"161":{},"162":{},"163":{}}}],["joplinviews",{"_index":114,"name":{"147":{}},"parent":{"148":{},"149":{},"150":{},"151":{},"152":{},"153":{}}}],["joplinviewsdialogs",{"_index":102,"name":{"125":{}},"parent":{"126":{},"127":{},"128":{},"129":{},"130":{},"131":{}}}],["joplinviewsmenuitems",{"_index":108,"name":{"132":{}},"parent":{"133":{},"134":{}}}],["joplinviewsmenus",{"_index":109,"name":{"135":{}},"parent":{"136":{},"137":{}}}],["joplinviewspanels",{"_index":111,"name":{"141":{}},"parent":{"142":{},"143":{},"144":{},"145":{},"146":{}}}],["joplinviewstoolbarbuttons",{"_index":110,"name":{"138":{}},"parent":{"139":{},"140":{}}}],["joplinworkspace",{"_index":94,"name":{"114":{}},"parent":{"115":{},"116":{},"117":{},"118":{},"119":{},"120":{},"121":{}}}],["label",{"_index":2,"name":{"2":{},"61":{},"83":{},"95":{}},"parent":{}}],["markdown",{"_index":10,"name":{"10":{}},"parent":{}}],["markdownitplugin",{"_index":81,"name":{"100":{}},"parent":{}}],["maximum",{"_index":77,"name":{"92":{}},"parent":{}}],["menuitem",{"_index":49,"name":{"57":{}},"parent":{"58":{},"59":{},"60":{},"61":{}}}],["menuitemlocation",{"_index":42,"name":{"49":{}},"parent":{"50":{},"51":{},"52":{},"53":{},"54":{},"55":{},"56":{}}}],["menuitems",{"_index":117,"name":{"151":{}},"parent":{}}],["menus",{"_index":118,"name":{"152":{}},"parent":{}}],["minimum",{"_index":76,"name":{"91":{}},"parent":{}}],["modulepath",{"_index":30,"name":{"35":{}},"parent":{}}],["name",{"_index":1,"name":{"1":{},"70":{},"98":{}},"parent":{}}],["note",{"_index":45,"name":{"53":{}},"parent":{}}],["notetoolbar",{"_index":57,"name":{"67":{}},"parent":{}}],["object",{"_index":66,"name":{"77":{}},"parent":{}}],["onclick",{"_index":55,"name":{"65":{}},"parent":{}}],["onclose",{"_index":21,"name":{"21":{}},"parent":{}}],["onexec",{"_index":25,"name":{"29":{}},"parent":{}}],["oninit",{"_index":18,"name":{"18":{}},"parent":{}}],["onmessage",{"_index":113,"name":{"146":{}},"parent":{}}],["onnotealarmtrigger",{"_index":97,"name":{"118":{}},"parent":{}}],["onnotecontentchange",{"_index":96,"name":{"117":{}},"parent":{}}],["onnoteselectionchange",{"_index":95,"name":{"116":{}},"parent":{}}],["onprocessitem",{"_index":19,"name":{"19":{}},"parent":{}}],["onprocessresource",{"_index":20,"name":{"20":{}},"parent":{}}],["onstart",{"_index":39,"name":{"46":{}},"parent":{}}],["onsynccomplete",{"_index":98,"name":{"119":{}},"parent":{}}],["open",{"_index":107,"name":{"131":{}},"parent":{}}],["options",{"_index":33,"name":{"39":{},"43":{},"87":{}},"parent":{}}],["outputformat",{"_index":24,"name":{"28":{}},"parent":{}}],["panels",{"_index":116,"name":{"150":{}},"parent":{}}],["path",{"_index":27,"name":{"32":{},"104":{}},"parent":{}}],["plugins",{"_index":130,"name":{"167":{}},"parent":{}}],["post",{"_index":87,"name":{"107":{}},"parent":{}}],["public",{"_index":70,"name":{"82":{}},"parent":{}}],["put",{"_index":88,"name":{"108":{}},"parent":{}}],["register",{"_index":92,"name":{"112":{},"124":{}},"parent":{}}],["registercontentscript",{"_index":93,"name":{"113":{}},"parent":{}}],["registerexportmodule",{"_index":121,"name":{"155":{}},"parent":{}}],["registerimportmodule",{"_index":122,"name":{"156":{}},"parent":{}}],["registersection",{"_index":125,"name":{"160":{}},"parent":{}}],["registersetting",{"_index":124,"name":{"159":{}},"parent":{}}],["script",{"_index":38,"name":{"45":{}},"parent":{"46":{}}}],["section",{"_index":72,"name":{"86":{}},"parent":{}}],["secure",{"_index":74,"name":{"89":{}},"parent":{}}],["selectednote",{"_index":99,"name":{"120":{}},"parent":{}}],["selectednoteids",{"_index":100,"name":{"121":{}},"parent":{}}],["setbuttons",{"_index":106,"name":{"130":{}},"parent":{}}],["sethtml",{"_index":105,"name":{"129":{},"144":{}},"parent":{}}],["settingitem",{"_index":68,"name":{"79":{}},"parent":{"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{}}}],["settingitemtype",{"_index":61,"name":{"72":{}},"parent":{"73":{},"74":{},"75":{},"76":{},"77":{},"78":{}}}],["settings",{"_index":135,"name":{"172":{}},"parent":{}}],["settingsection",{"_index":79,"name":{"94":{}},"parent":{"95":{},"96":{},"97":{},"98":{}}}],["setvalue",{"_index":126,"name":{"162":{}},"parent":{}}],["showmessagebox",{"_index":104,"name":{"128":{}},"parent":{}}],["sourcefolderids",{"_index":28,"name":{"33":{}},"parent":{}}],["sourcenoteids",{"_index":29,"name":{"34":{}},"parent":{}}],["sourcepath",{"_index":36,"name":{"42":{}},"parent":{}}],["sources",{"_index":23,"name":{"26":{}},"parent":{}}],["step",{"_index":78,"name":{"93":{}},"parent":{}}],["string",{"_index":63,"name":{"74":{}},"parent":{}}],["submenu",{"_index":51,"name":{"60":{}},"parent":{}}],["target",{"_index":15,"name":{"15":{},"36":{}},"parent":{}}],["title",{"_index":54,"name":{"64":{}},"parent":{}}],["toolbarbuttonlocation",{"_index":56,"name":{"66":{}},"parent":{"67":{},"68":{}}}],["toolbarbuttons",{"_index":119,"name":{"153":{}},"parent":{}}],["tools",{"_index":46,"name":{"54":{}},"parent":{}}],["type",{"_index":69,"name":{"81":{}},"parent":{}}],["userdata",{"_index":34,"name":{"40":{}},"parent":{}}],["value",{"_index":60,"name":{"71":{},"80":{},"161":{}},"parent":{}}],["view",{"_index":44,"name":{"52":{}},"parent":{}}],["viewhandle",{"_index":84,"name":{"103":{}},"parent":{}}],["views",{"_index":133,"name":{"170":{}},"parent":{}}],["warnings",{"_index":37,"name":{"44":{}},"parent":{}}],["workspace",{"_index":131,"name":{"168":{}},"parent":{}}]],"pipeline":[]}} \ No newline at end of file +{"kinds":{"4":"Enumeration","16":"Enumeration member","128":"Class","256":"Interface","512":"Constructor","1024":"Property","2048":"Method","262144":"Accessor","4194304":"Type alias"},"rows":[{"id":0,"kind":256,"name":"Command","url":"interfaces/command.html","classes":"tsd-kind-interface"},{"id":1,"kind":1024,"name":"name","url":"interfaces/command.html#name","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Command"},{"id":2,"kind":1024,"name":"label","url":"interfaces/command.html#label","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Command"},{"id":3,"kind":1024,"name":"iconName","url":"interfaces/command.html#iconname","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Command"},{"id":4,"kind":2048,"name":"execute","url":"interfaces/command.html#execute","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"Command"},{"id":5,"kind":1024,"name":"enabledCondition","url":"interfaces/command.html#enabledcondition","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Command"},{"id":6,"kind":4,"name":"FileSystemItem","url":"enums/filesystemitem.html","classes":"tsd-kind-enum"},{"id":7,"kind":16,"name":"File","url":"enums/filesystemitem.html#file","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"FileSystemItem"},{"id":8,"kind":16,"name":"Directory","url":"enums/filesystemitem.html#directory","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"FileSystemItem"},{"id":9,"kind":4,"name":"ImportModuleOutputFormat","url":"enums/importmoduleoutputformat.html","classes":"tsd-kind-enum"},{"id":10,"kind":16,"name":"Markdown","url":"enums/importmoduleoutputformat.html#markdown","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ImportModuleOutputFormat"},{"id":11,"kind":16,"name":"Html","url":"enums/importmoduleoutputformat.html#html","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ImportModuleOutputFormat"},{"id":12,"kind":256,"name":"ExportModule","url":"interfaces/exportmodule.html","classes":"tsd-kind-interface"},{"id":13,"kind":1024,"name":"format","url":"interfaces/exportmodule.html#format","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportModule"},{"id":14,"kind":1024,"name":"description","url":"interfaces/exportmodule.html#description","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportModule"},{"id":15,"kind":1024,"name":"target","url":"interfaces/exportmodule.html#target","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportModule"},{"id":16,"kind":1024,"name":"isNoteArchive","url":"interfaces/exportmodule.html#isnotearchive","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportModule"},{"id":17,"kind":1024,"name":"fileExtensions","url":"interfaces/exportmodule.html#fileextensions","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportModule"},{"id":18,"kind":2048,"name":"onInit","url":"interfaces/exportmodule.html#oninit","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ExportModule"},{"id":19,"kind":2048,"name":"onProcessItem","url":"interfaces/exportmodule.html#onprocessitem","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ExportModule"},{"id":20,"kind":2048,"name":"onProcessResource","url":"interfaces/exportmodule.html#onprocessresource","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ExportModule"},{"id":21,"kind":2048,"name":"onClose","url":"interfaces/exportmodule.html#onclose","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ExportModule"},{"id":22,"kind":256,"name":"ImportModule","url":"interfaces/importmodule.html","classes":"tsd-kind-interface"},{"id":23,"kind":1024,"name":"format","url":"interfaces/importmodule.html#format","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":24,"kind":1024,"name":"description","url":"interfaces/importmodule.html#description","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":25,"kind":1024,"name":"isNoteArchive","url":"interfaces/importmodule.html#isnotearchive","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":26,"kind":1024,"name":"sources","url":"interfaces/importmodule.html#sources","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":27,"kind":1024,"name":"fileExtensions","url":"interfaces/importmodule.html#fileextensions","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":28,"kind":1024,"name":"outputFormat","url":"interfaces/importmodule.html#outputformat","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportModule"},{"id":29,"kind":2048,"name":"onExec","url":"interfaces/importmodule.html#onexec","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ImportModule"},{"id":30,"kind":256,"name":"ExportOptions","url":"interfaces/exportoptions.html","classes":"tsd-kind-interface"},{"id":31,"kind":1024,"name":"format","url":"interfaces/exportoptions.html#format","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":32,"kind":1024,"name":"path","url":"interfaces/exportoptions.html#path","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":33,"kind":1024,"name":"sourceFolderIds","url":"interfaces/exportoptions.html#sourcefolderids","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":34,"kind":1024,"name":"sourceNoteIds","url":"interfaces/exportoptions.html#sourcenoteids","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":35,"kind":1024,"name":"modulePath","url":"interfaces/exportoptions.html#modulepath","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":36,"kind":1024,"name":"target","url":"interfaces/exportoptions.html#target","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportOptions"},{"id":37,"kind":256,"name":"ExportContext","url":"interfaces/exportcontext.html","classes":"tsd-kind-interface"},{"id":38,"kind":1024,"name":"destPath","url":"interfaces/exportcontext.html#destpath","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportContext"},{"id":39,"kind":1024,"name":"options","url":"interfaces/exportcontext.html#options","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportContext"},{"id":40,"kind":1024,"name":"userData","url":"interfaces/exportcontext.html#userdata","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ExportContext"},{"id":41,"kind":256,"name":"ImportContext","url":"interfaces/importcontext.html","classes":"tsd-kind-interface"},{"id":42,"kind":1024,"name":"sourcePath","url":"interfaces/importcontext.html#sourcepath","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportContext"},{"id":43,"kind":1024,"name":"options","url":"interfaces/importcontext.html#options","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportContext"},{"id":44,"kind":1024,"name":"warnings","url":"interfaces/importcontext.html#warnings","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ImportContext"},{"id":45,"kind":256,"name":"Script","url":"interfaces/script.html","classes":"tsd-kind-interface"},{"id":46,"kind":2048,"name":"onStart","url":"interfaces/script.html#onstart","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"Script"},{"id":47,"kind":256,"name":"CreateMenuItemOptions","url":"interfaces/createmenuitemoptions.html","classes":"tsd-kind-interface"},{"id":48,"kind":1024,"name":"accelerator","url":"interfaces/createmenuitemoptions.html#accelerator","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"CreateMenuItemOptions"},{"id":49,"kind":4,"name":"MenuItemLocation","url":"enums/menuitemlocation.html","classes":"tsd-kind-enum"},{"id":50,"kind":16,"name":"File","url":"enums/menuitemlocation.html#file","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":51,"kind":16,"name":"Edit","url":"enums/menuitemlocation.html#edit","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":52,"kind":16,"name":"View","url":"enums/menuitemlocation.html#view","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":53,"kind":16,"name":"Note","url":"enums/menuitemlocation.html#note","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":54,"kind":16,"name":"Tools","url":"enums/menuitemlocation.html#tools","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":55,"kind":16,"name":"Help","url":"enums/menuitemlocation.html#help","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":56,"kind":16,"name":"Context","url":"enums/menuitemlocation.html#context","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"MenuItemLocation"},{"id":57,"kind":256,"name":"MenuItem","url":"interfaces/menuitem.html","classes":"tsd-kind-interface"},{"id":58,"kind":1024,"name":"commandName","url":"interfaces/menuitem.html#commandname","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MenuItem"},{"id":59,"kind":1024,"name":"accelerator","url":"interfaces/menuitem.html#accelerator","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MenuItem"},{"id":60,"kind":1024,"name":"submenu","url":"interfaces/menuitem.html#submenu","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MenuItem"},{"id":61,"kind":1024,"name":"label","url":"interfaces/menuitem.html#label","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MenuItem"},{"id":62,"kind":256,"name":"ButtonSpec","url":"interfaces/buttonspec.html","classes":"tsd-kind-interface"},{"id":63,"kind":1024,"name":"id","url":"interfaces/buttonspec.html#id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ButtonSpec"},{"id":64,"kind":1024,"name":"title","url":"interfaces/buttonspec.html#title","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ButtonSpec"},{"id":65,"kind":2048,"name":"onClick","url":"interfaces/buttonspec.html#onclick","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"ButtonSpec"},{"id":66,"kind":4,"name":"ToolbarButtonLocation","url":"enums/toolbarbuttonlocation.html","classes":"tsd-kind-enum"},{"id":67,"kind":16,"name":"NoteToolbar","url":"enums/toolbarbuttonlocation.html#notetoolbar","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ToolbarButtonLocation"},{"id":68,"kind":16,"name":"EditorToolbar","url":"enums/toolbarbuttonlocation.html#editortoolbar","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ToolbarButtonLocation"},{"id":69,"kind":256,"name":"EditorCommand","url":"interfaces/editorcommand.html","classes":"tsd-kind-interface"},{"id":70,"kind":1024,"name":"name","url":"interfaces/editorcommand.html#name","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"EditorCommand"},{"id":71,"kind":1024,"name":"value","url":"interfaces/editorcommand.html#value","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"EditorCommand"},{"id":72,"kind":256,"name":"DialogResult","url":"interfaces/dialogresult.html","classes":"tsd-kind-interface"},{"id":73,"kind":1024,"name":"id","url":"interfaces/dialogresult.html#id","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"DialogResult"},{"id":74,"kind":1024,"name":"formData","url":"interfaces/dialogresult.html#formdata","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"DialogResult"},{"id":75,"kind":4,"name":"SettingItemType","url":"enums/settingitemtype.html","classes":"tsd-kind-enum"},{"id":76,"kind":16,"name":"Int","url":"enums/settingitemtype.html#int","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":77,"kind":16,"name":"String","url":"enums/settingitemtype.html#string","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":78,"kind":16,"name":"Bool","url":"enums/settingitemtype.html#bool","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":79,"kind":16,"name":"Array","url":"enums/settingitemtype.html#array","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":80,"kind":16,"name":"Object","url":"enums/settingitemtype.html#object","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":81,"kind":16,"name":"Button","url":"enums/settingitemtype.html#button","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"SettingItemType"},{"id":82,"kind":256,"name":"SettingItem","url":"interfaces/settingitem.html","classes":"tsd-kind-interface"},{"id":83,"kind":1024,"name":"value","url":"interfaces/settingitem.html#value","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":84,"kind":1024,"name":"type","url":"interfaces/settingitem.html#type","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":85,"kind":1024,"name":"public","url":"interfaces/settingitem.html#public","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":86,"kind":1024,"name":"label","url":"interfaces/settingitem.html#label","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":87,"kind":1024,"name":"description","url":"interfaces/settingitem.html#description","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":88,"kind":1024,"name":"isEnum","url":"interfaces/settingitem.html#isenum","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":89,"kind":1024,"name":"section","url":"interfaces/settingitem.html#section","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":90,"kind":1024,"name":"options","url":"interfaces/settingitem.html#options","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":91,"kind":1024,"name":"appTypes","url":"interfaces/settingitem.html#apptypes","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":92,"kind":1024,"name":"secure","url":"interfaces/settingitem.html#secure","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":93,"kind":1024,"name":"advanced","url":"interfaces/settingitem.html#advanced","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":94,"kind":1024,"name":"minimum","url":"interfaces/settingitem.html#minimum","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":95,"kind":1024,"name":"maximum","url":"interfaces/settingitem.html#maximum","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":96,"kind":1024,"name":"step","url":"interfaces/settingitem.html#step","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingItem"},{"id":97,"kind":256,"name":"SettingSection","url":"interfaces/settingsection.html","classes":"tsd-kind-interface"},{"id":98,"kind":1024,"name":"label","url":"interfaces/settingsection.html#label","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingSection"},{"id":99,"kind":1024,"name":"iconName","url":"interfaces/settingsection.html#iconname","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingSection"},{"id":100,"kind":1024,"name":"description","url":"interfaces/settingsection.html#description","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingSection"},{"id":101,"kind":1024,"name":"name","url":"interfaces/settingsection.html#name","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SettingSection"},{"id":102,"kind":4,"name":"ContentScriptType","url":"enums/contentscripttype.html","classes":"tsd-kind-enum"},{"id":103,"kind":16,"name":"MarkdownItPlugin","url":"enums/contentscripttype.html#markdownitplugin","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ContentScriptType"},{"id":104,"kind":16,"name":"CodeMirrorPlugin","url":"enums/contentscripttype.html#codemirrorplugin","classes":"tsd-kind-enum-member tsd-parent-kind-enum","parent":"ContentScriptType"},{"id":105,"kind":4194304,"name":"ButtonId","url":"globals.html#buttonid","classes":"tsd-kind-type-alias"},{"id":106,"kind":4194304,"name":"ViewHandle","url":"globals.html#viewhandle","classes":"tsd-kind-type-alias"},{"id":107,"kind":4194304,"name":"Path","url":"globals.html#path","classes":"tsd-kind-type-alias"},{"id":108,"kind":128,"name":"JoplinData","url":"classes/joplindata.html","classes":"tsd-kind-class"},{"id":109,"kind":2048,"name":"get","url":"classes/joplindata.html#get","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinData"},{"id":110,"kind":2048,"name":"post","url":"classes/joplindata.html#post","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinData"},{"id":111,"kind":2048,"name":"put","url":"classes/joplindata.html#put","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinData"},{"id":112,"kind":2048,"name":"delete","url":"classes/joplindata.html#delete","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinData"},{"id":113,"kind":128,"name":"JoplinPlugins","url":"classes/joplinplugins.html","classes":"tsd-kind-class"},{"id":114,"kind":512,"name":"constructor","url":"classes/joplinplugins.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinPlugins"},{"id":115,"kind":2048,"name":"register","url":"classes/joplinplugins.html#register","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinPlugins"},{"id":116,"kind":2048,"name":"registerContentScript","url":"classes/joplinplugins.html#registercontentscript","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinPlugins"},{"id":117,"kind":128,"name":"JoplinWorkspace","url":"classes/joplinworkspace.html","classes":"tsd-kind-class"},{"id":118,"kind":512,"name":"constructor","url":"classes/joplinworkspace.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":119,"kind":2048,"name":"onNoteSelectionChange","url":"classes/joplinworkspace.html#onnoteselectionchange","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":120,"kind":2048,"name":"onNoteContentChange","url":"classes/joplinworkspace.html#onnotecontentchange","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":121,"kind":2048,"name":"onNoteAlarmTrigger","url":"classes/joplinworkspace.html#onnotealarmtrigger","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":122,"kind":2048,"name":"onSyncComplete","url":"classes/joplinworkspace.html#onsynccomplete","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":123,"kind":2048,"name":"selectedNote","url":"classes/joplinworkspace.html#selectednote","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":124,"kind":2048,"name":"selectedNoteIds","url":"classes/joplinworkspace.html#selectednoteids","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinWorkspace"},{"id":125,"kind":128,"name":"JoplinCommands","url":"classes/joplincommands.html","classes":"tsd-kind-class"},{"id":126,"kind":2048,"name":"execute","url":"classes/joplincommands.html#execute","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinCommands"},{"id":127,"kind":2048,"name":"register","url":"classes/joplincommands.html#register","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinCommands"},{"id":128,"kind":128,"name":"JoplinViewsDialogs","url":"classes/joplinviewsdialogs.html","classes":"tsd-kind-class"},{"id":129,"kind":512,"name":"constructor","url":"classes/joplinviewsdialogs.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":130,"kind":2048,"name":"create","url":"classes/joplinviewsdialogs.html#create","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":131,"kind":2048,"name":"showMessageBox","url":"classes/joplinviewsdialogs.html#showmessagebox","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":132,"kind":2048,"name":"setHtml","url":"classes/joplinviewsdialogs.html#sethtml","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":133,"kind":2048,"name":"setButtons","url":"classes/joplinviewsdialogs.html#setbuttons","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":134,"kind":2048,"name":"open","url":"classes/joplinviewsdialogs.html#open","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsDialogs"},{"id":135,"kind":128,"name":"JoplinViewsMenuItems","url":"classes/joplinviewsmenuitems.html","classes":"tsd-kind-class"},{"id":136,"kind":512,"name":"constructor","url":"classes/joplinviewsmenuitems.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViewsMenuItems"},{"id":137,"kind":2048,"name":"create","url":"classes/joplinviewsmenuitems.html#create","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsMenuItems"},{"id":138,"kind":128,"name":"JoplinViewsMenus","url":"classes/joplinviewsmenus.html","classes":"tsd-kind-class"},{"id":139,"kind":512,"name":"constructor","url":"classes/joplinviewsmenus.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViewsMenus"},{"id":140,"kind":2048,"name":"create","url":"classes/joplinviewsmenus.html#create","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsMenus"},{"id":141,"kind":128,"name":"JoplinViewsToolbarButtons","url":"classes/joplinviewstoolbarbuttons.html","classes":"tsd-kind-class"},{"id":142,"kind":512,"name":"constructor","url":"classes/joplinviewstoolbarbuttons.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViewsToolbarButtons"},{"id":143,"kind":2048,"name":"create","url":"classes/joplinviewstoolbarbuttons.html#create","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsToolbarButtons"},{"id":144,"kind":128,"name":"JoplinViewsPanels","url":"classes/joplinviewspanels.html","classes":"tsd-kind-class"},{"id":145,"kind":512,"name":"constructor","url":"classes/joplinviewspanels.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViewsPanels"},{"id":146,"kind":2048,"name":"create","url":"classes/joplinviewspanels.html#create","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsPanels"},{"id":147,"kind":2048,"name":"setHtml","url":"classes/joplinviewspanels.html#sethtml","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsPanels"},{"id":148,"kind":2048,"name":"addScript","url":"classes/joplinviewspanels.html#addscript","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsPanels"},{"id":149,"kind":2048,"name":"onMessage","url":"classes/joplinviewspanels.html#onmessage","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinViewsPanels"},{"id":150,"kind":128,"name":"JoplinViews","url":"classes/joplinviews.html","classes":"tsd-kind-class"},{"id":151,"kind":512,"name":"constructor","url":"classes/joplinviews.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinViews"},{"id":152,"kind":262144,"name":"dialogs","url":"classes/joplinviews.html#dialogs","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"JoplinViews"},{"id":153,"kind":262144,"name":"panels","url":"classes/joplinviews.html#panels","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"JoplinViews"},{"id":154,"kind":262144,"name":"menuItems","url":"classes/joplinviews.html#menuitems","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"JoplinViews"},{"id":155,"kind":262144,"name":"menus","url":"classes/joplinviews.html#menus","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"JoplinViews"},{"id":156,"kind":262144,"name":"toolbarButtons","url":"classes/joplinviews.html#toolbarbuttons","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"JoplinViews"},{"id":157,"kind":128,"name":"JoplinInterop","url":"classes/joplininterop.html","classes":"tsd-kind-class"},{"id":158,"kind":2048,"name":"registerExportModule","url":"classes/joplininterop.html#registerexportmodule","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinInterop"},{"id":159,"kind":2048,"name":"registerImportModule","url":"classes/joplininterop.html#registerimportmodule","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinInterop"},{"id":160,"kind":128,"name":"JoplinSettings","url":"classes/joplinsettings.html","classes":"tsd-kind-class"},{"id":161,"kind":512,"name":"constructor","url":"classes/joplinsettings.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"JoplinSettings"},{"id":162,"kind":2048,"name":"registerSetting","url":"classes/joplinsettings.html#registersetting","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinSettings"},{"id":163,"kind":2048,"name":"registerSection","url":"classes/joplinsettings.html#registersection","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinSettings"},{"id":164,"kind":2048,"name":"value","url":"classes/joplinsettings.html#value","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinSettings"},{"id":165,"kind":2048,"name":"setValue","url":"classes/joplinsettings.html#setvalue","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinSettings"},{"id":166,"kind":2048,"name":"globalValue","url":"classes/joplinsettings.html#globalvalue","classes":"tsd-kind-method tsd-parent-kind-class","parent":"JoplinSettings"},{"id":167,"kind":128,"name":"Joplin","url":"classes/joplin.html","classes":"tsd-kind-class"},{"id":168,"kind":512,"name":"constructor","url":"classes/joplin.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"Joplin"},{"id":169,"kind":262144,"name":"data","url":"classes/joplin.html#data","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":170,"kind":262144,"name":"plugins","url":"classes/joplin.html#plugins","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":171,"kind":262144,"name":"workspace","url":"classes/joplin.html#workspace","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":172,"kind":262144,"name":"commands","url":"classes/joplin.html#commands","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":173,"kind":262144,"name":"views","url":"classes/joplin.html#views","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":174,"kind":262144,"name":"interop","url":"classes/joplin.html#interop","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"},{"id":175,"kind":262144,"name":"settings","url":"classes/joplin.html#settings","classes":"tsd-kind-get-signature tsd-parent-kind-class","parent":"Joplin"}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,33.043]],["parent/0",[]],["name/1",[1,39.234]],["parent/1",[0,2.99]],["name/2",[2,36.721]],["parent/2",[0,2.99]],["name/3",[3,42.599]],["parent/3",[0,2.99]],["name/4",[4,42.599]],["parent/4",[0,2.99]],["name/5",[5,47.707]],["parent/5",[0,2.99]],["name/6",[6,39.234]],["parent/6",[]],["name/7",[7,42.599]],["parent/7",[6,3.55]],["name/8",[8,47.707]],["parent/8",[6,3.55]],["name/9",[9,39.234]],["parent/9",[]],["name/10",[10,47.707]],["parent/10",[9,3.55]],["name/11",[11,47.707]],["parent/11",[9,3.55]],["name/12",[12,28.248]],["parent/12",[]],["name/13",[13,39.234]],["parent/13",[12,2.556]],["name/14",[14,36.721]],["parent/14",[12,2.556]],["name/15",[15,42.599]],["parent/15",[12,2.556]],["name/16",[16,42.599]],["parent/16",[12,2.556]],["name/17",[17,42.599]],["parent/17",[12,2.556]],["name/18",[18,47.707]],["parent/18",[12,2.556]],["name/19",[19,47.707]],["parent/19",[12,2.556]],["name/20",[20,47.707]],["parent/20",[12,2.556]],["name/21",[21,47.707]],["parent/21",[12,2.556]],["name/22",[22,30.361]],["parent/22",[]],["name/23",[13,39.234]],["parent/23",[22,2.747]],["name/24",[14,36.721]],["parent/24",[22,2.747]],["name/25",[16,42.599]],["parent/25",[22,2.747]],["name/26",[23,47.707]],["parent/26",[22,2.747]],["name/27",[17,42.599]],["parent/27",[22,2.747]],["name/28",[24,47.707]],["parent/28",[22,2.747]],["name/29",[25,47.707]],["parent/29",[22,2.747]],["name/30",[26,31.612]],["parent/30",[]],["name/31",[13,39.234]],["parent/31",[26,2.86]],["name/32",[27,42.599]],["parent/32",[26,2.86]],["name/33",[28,47.707]],["parent/33",[26,2.86]],["name/34",[29,47.707]],["parent/34",[26,2.86]],["name/35",[30,47.707]],["parent/35",[26,2.86]],["name/36",[15,42.599]],["parent/36",[26,2.86]],["name/37",[31,36.721]],["parent/37",[]],["name/38",[32,47.707]],["parent/38",[31,3.323]],["name/39",[33,39.234]],["parent/39",[31,3.323]],["name/40",[34,47.707]],["parent/40",[31,3.323]],["name/41",[35,36.721]],["parent/41",[]],["name/42",[36,47.707]],["parent/42",[35,3.323]],["name/43",[33,39.234]],["parent/43",[35,3.323]],["name/44",[37,47.707]],["parent/44",[35,3.323]],["name/45",[38,42.599]],["parent/45",[]],["name/46",[39,47.707]],["parent/46",[38,3.854]],["name/47",[40,42.599]],["parent/47",[]],["name/48",[41,42.599]],["parent/48",[40,3.854]],["name/49",[42,30.361]],["parent/49",[]],["name/50",[7,42.599]],["parent/50",[42,2.747]],["name/51",[43,47.707]],["parent/51",[42,2.747]],["name/52",[44,47.707]],["parent/52",[42,2.747]],["name/53",[45,47.707]],["parent/53",[42,2.747]],["name/54",[46,47.707]],["parent/54",[42,2.747]],["name/55",[47,47.707]],["parent/55",[42,2.747]],["name/56",[48,47.707]],["parent/56",[42,2.747]],["name/57",[49,34.714]],["parent/57",[]],["name/58",[50,47.707]],["parent/58",[49,3.141]],["name/59",[41,42.599]],["parent/59",[49,3.141]],["name/60",[51,47.707]],["parent/60",[49,3.141]],["name/61",[2,36.721]],["parent/61",[49,3.141]],["name/62",[52,36.721]],["parent/62",[]],["name/63",[53,42.599]],["parent/63",[52,3.323]],["name/64",[54,47.707]],["parent/64",[52,3.323]],["name/65",[55,47.707]],["parent/65",[52,3.323]],["name/66",[56,39.234]],["parent/66",[]],["name/67",[57,47.707]],["parent/67",[56,3.55]],["name/68",[58,47.707]],["parent/68",[56,3.55]],["name/69",[59,39.234]],["parent/69",[]],["name/70",[1,39.234]],["parent/70",[59,3.55]],["name/71",[60,39.234]],["parent/71",[59,3.55]],["name/72",[61,39.234]],["parent/72",[]],["name/73",[53,42.599]],["parent/73",[61,3.55]],["name/74",[62,47.707]],["parent/74",[61,3.55]],["name/75",[63,31.612]],["parent/75",[]],["name/76",[64,47.707]],["parent/76",[63,2.86]],["name/77",[65,47.707]],["parent/77",[63,2.86]],["name/78",[66,47.707]],["parent/78",[63,2.86]],["name/79",[67,47.707]],["parent/79",[63,2.86]],["name/80",[68,47.707]],["parent/80",[63,2.86]],["name/81",[69,47.707]],["parent/81",[63,2.86]],["name/82",[70,24.353]],["parent/82",[]],["name/83",[60,39.234]],["parent/83",[70,2.204]],["name/84",[71,47.707]],["parent/84",[70,2.204]],["name/85",[72,47.707]],["parent/85",[70,2.204]],["name/86",[2,36.721]],["parent/86",[70,2.204]],["name/87",[14,36.721]],["parent/87",[70,2.204]],["name/88",[73,47.707]],["parent/88",[70,2.204]],["name/89",[74,47.707]],["parent/89",[70,2.204]],["name/90",[33,39.234]],["parent/90",[70,2.204]],["name/91",[75,47.707]],["parent/91",[70,2.204]],["name/92",[76,47.707]],["parent/92",[70,2.204]],["name/93",[77,47.707]],["parent/93",[70,2.204]],["name/94",[78,47.707]],["parent/94",[70,2.204]],["name/95",[79,47.707]],["parent/95",[70,2.204]],["name/96",[80,47.707]],["parent/96",[70,2.204]],["name/97",[81,34.714]],["parent/97",[]],["name/98",[2,36.721]],["parent/98",[81,3.141]],["name/99",[3,42.599]],["parent/99",[81,3.141]],["name/100",[14,36.721]],["parent/100",[81,3.141]],["name/101",[1,39.234]],["parent/101",[81,3.141]],["name/102",[82,39.234]],["parent/102",[]],["name/103",[83,47.707]],["parent/103",[82,3.55]],["name/104",[84,47.707]],["parent/104",[82,3.55]],["name/105",[85,47.707]],["parent/105",[]],["name/106",[86,47.707]],["parent/106",[]],["name/107",[27,42.599]],["parent/107",[]],["name/108",[87,34.714]],["parent/108",[]],["name/109",[88,47.707]],["parent/109",[87,3.141]],["name/110",[89,47.707]],["parent/110",[87,3.141]],["name/111",[90,47.707]],["parent/111",[87,3.141]],["name/112",[91,47.707]],["parent/112",[87,3.141]],["name/113",[92,36.721]],["parent/113",[]],["name/114",[93,28.248]],["parent/114",[92,3.323]],["name/115",[94,42.599]],["parent/115",[92,3.323]],["name/116",[95,47.707]],["parent/116",[92,3.323]],["name/117",[96,30.361]],["parent/117",[]],["name/118",[93,28.248]],["parent/118",[96,2.747]],["name/119",[97,47.707]],["parent/119",[96,2.747]],["name/120",[98,47.707]],["parent/120",[96,2.747]],["name/121",[99,47.707]],["parent/121",[96,2.747]],["name/122",[100,47.707]],["parent/122",[96,2.747]],["name/123",[101,47.707]],["parent/123",[96,2.747]],["name/124",[102,47.707]],["parent/124",[96,2.747]],["name/125",[103,39.234]],["parent/125",[]],["name/126",[4,42.599]],["parent/126",[103,3.55]],["name/127",[94,42.599]],["parent/127",[103,3.55]],["name/128",[104,31.612]],["parent/128",[]],["name/129",[93,28.248]],["parent/129",[104,2.86]],["name/130",[105,34.714]],["parent/130",[104,2.86]],["name/131",[106,47.707]],["parent/131",[104,2.86]],["name/132",[107,42.599]],["parent/132",[104,2.86]],["name/133",[108,47.707]],["parent/133",[104,2.86]],["name/134",[109,47.707]],["parent/134",[104,2.86]],["name/135",[110,39.234]],["parent/135",[]],["name/136",[93,28.248]],["parent/136",[110,3.55]],["name/137",[105,34.714]],["parent/137",[110,3.55]],["name/138",[111,39.234]],["parent/138",[]],["name/139",[93,28.248]],["parent/139",[111,3.55]],["name/140",[105,34.714]],["parent/140",[111,3.55]],["name/141",[112,39.234]],["parent/141",[]],["name/142",[93,28.248]],["parent/142",[112,3.55]],["name/143",[105,34.714]],["parent/143",[112,3.55]],["name/144",[113,33.043]],["parent/144",[]],["name/145",[93,28.248]],["parent/145",[113,2.99]],["name/146",[105,34.714]],["parent/146",[113,2.99]],["name/147",[107,42.599]],["parent/147",[113,2.99]],["name/148",[114,47.707]],["parent/148",[113,2.99]],["name/149",[115,47.707]],["parent/149",[113,2.99]],["name/150",[116,31.612]],["parent/150",[]],["name/151",[93,28.248]],["parent/151",[116,2.86]],["name/152",[117,47.707]],["parent/152",[116,2.86]],["name/153",[118,47.707]],["parent/153",[116,2.86]],["name/154",[119,47.707]],["parent/154",[116,2.86]],["name/155",[120,47.707]],["parent/155",[116,2.86]],["name/156",[121,47.707]],["parent/156",[116,2.86]],["name/157",[122,39.234]],["parent/157",[]],["name/158",[123,47.707]],["parent/158",[122,3.55]],["name/159",[124,47.707]],["parent/159",[122,3.55]],["name/160",[125,31.612]],["parent/160",[]],["name/161",[93,28.248]],["parent/161",[125,2.86]],["name/162",[126,47.707]],["parent/162",[125,2.86]],["name/163",[127,47.707]],["parent/163",[125,2.86]],["name/164",[60,39.234]],["parent/164",[125,2.86]],["name/165",[128,47.707]],["parent/165",[125,2.86]],["name/166",[129,47.707]],["parent/166",[125,2.86]],["name/167",[130,29.249]],["parent/167",[]],["name/168",[93,28.248]],["parent/168",[130,2.646]],["name/169",[131,47.707]],["parent/169",[130,2.646]],["name/170",[132,47.707]],["parent/170",[130,2.646]],["name/171",[133,47.707]],["parent/171",[130,2.646]],["name/172",[134,47.707]],["parent/172",[130,2.646]],["name/173",[135,47.707]],["parent/173",[130,2.646]],["name/174",[136,47.707]],["parent/174",[130,2.646]],["name/175",[137,47.707]],["parent/175",[130,2.646]]],"invertedIndex":[["accelerator",{"_index":41,"name":{"48":{},"59":{}},"parent":{}}],["addscript",{"_index":114,"name":{"148":{}},"parent":{}}],["advanced",{"_index":77,"name":{"93":{}},"parent":{}}],["apptypes",{"_index":75,"name":{"91":{}},"parent":{}}],["array",{"_index":67,"name":{"79":{}},"parent":{}}],["bool",{"_index":66,"name":{"78":{}},"parent":{}}],["button",{"_index":69,"name":{"81":{}},"parent":{}}],["buttonid",{"_index":85,"name":{"105":{}},"parent":{}}],["buttonspec",{"_index":52,"name":{"62":{}},"parent":{"63":{},"64":{},"65":{}}}],["codemirrorplugin",{"_index":84,"name":{"104":{}},"parent":{}}],["command",{"_index":0,"name":{"0":{}},"parent":{"1":{},"2":{},"3":{},"4":{},"5":{}}}],["commandname",{"_index":50,"name":{"58":{}},"parent":{}}],["commands",{"_index":134,"name":{"172":{}},"parent":{}}],["constructor",{"_index":93,"name":{"114":{},"118":{},"129":{},"136":{},"139":{},"142":{},"145":{},"151":{},"161":{},"168":{}},"parent":{}}],["contentscripttype",{"_index":82,"name":{"102":{}},"parent":{"103":{},"104":{}}}],["context",{"_index":48,"name":{"56":{}},"parent":{}}],["create",{"_index":105,"name":{"130":{},"137":{},"140":{},"143":{},"146":{}},"parent":{}}],["createmenuitemoptions",{"_index":40,"name":{"47":{}},"parent":{"48":{}}}],["data",{"_index":131,"name":{"169":{}},"parent":{}}],["delete",{"_index":91,"name":{"112":{}},"parent":{}}],["description",{"_index":14,"name":{"14":{},"24":{},"87":{},"100":{}},"parent":{}}],["destpath",{"_index":32,"name":{"38":{}},"parent":{}}],["dialogresult",{"_index":61,"name":{"72":{}},"parent":{"73":{},"74":{}}}],["dialogs",{"_index":117,"name":{"152":{}},"parent":{}}],["directory",{"_index":8,"name":{"8":{}},"parent":{}}],["edit",{"_index":43,"name":{"51":{}},"parent":{}}],["editorcommand",{"_index":59,"name":{"69":{}},"parent":{"70":{},"71":{}}}],["editortoolbar",{"_index":58,"name":{"68":{}},"parent":{}}],["enabledcondition",{"_index":5,"name":{"5":{}},"parent":{}}],["execute",{"_index":4,"name":{"4":{},"126":{}},"parent":{}}],["exportcontext",{"_index":31,"name":{"37":{}},"parent":{"38":{},"39":{},"40":{}}}],["exportmodule",{"_index":12,"name":{"12":{}},"parent":{"13":{},"14":{},"15":{},"16":{},"17":{},"18":{},"19":{},"20":{},"21":{}}}],["exportoptions",{"_index":26,"name":{"30":{}},"parent":{"31":{},"32":{},"33":{},"34":{},"35":{},"36":{}}}],["file",{"_index":7,"name":{"7":{},"50":{}},"parent":{}}],["fileextensions",{"_index":17,"name":{"17":{},"27":{}},"parent":{}}],["filesystemitem",{"_index":6,"name":{"6":{}},"parent":{"7":{},"8":{}}}],["format",{"_index":13,"name":{"13":{},"23":{},"31":{}},"parent":{}}],["formdata",{"_index":62,"name":{"74":{}},"parent":{}}],["get",{"_index":88,"name":{"109":{}},"parent":{}}],["globalvalue",{"_index":129,"name":{"166":{}},"parent":{}}],["help",{"_index":47,"name":{"55":{}},"parent":{}}],["html",{"_index":11,"name":{"11":{}},"parent":{}}],["iconname",{"_index":3,"name":{"3":{},"99":{}},"parent":{}}],["id",{"_index":53,"name":{"63":{},"73":{}},"parent":{}}],["importcontext",{"_index":35,"name":{"41":{}},"parent":{"42":{},"43":{},"44":{}}}],["importmodule",{"_index":22,"name":{"22":{}},"parent":{"23":{},"24":{},"25":{},"26":{},"27":{},"28":{},"29":{}}}],["importmoduleoutputformat",{"_index":9,"name":{"9":{}},"parent":{"10":{},"11":{}}}],["int",{"_index":64,"name":{"76":{}},"parent":{}}],["interop",{"_index":136,"name":{"174":{}},"parent":{}}],["isenum",{"_index":73,"name":{"88":{}},"parent":{}}],["isnotearchive",{"_index":16,"name":{"16":{},"25":{}},"parent":{}}],["joplin",{"_index":130,"name":{"167":{}},"parent":{"168":{},"169":{},"170":{},"171":{},"172":{},"173":{},"174":{},"175":{}}}],["joplincommands",{"_index":103,"name":{"125":{}},"parent":{"126":{},"127":{}}}],["joplindata",{"_index":87,"name":{"108":{}},"parent":{"109":{},"110":{},"111":{},"112":{}}}],["joplininterop",{"_index":122,"name":{"157":{}},"parent":{"158":{},"159":{}}}],["joplinplugins",{"_index":92,"name":{"113":{}},"parent":{"114":{},"115":{},"116":{}}}],["joplinsettings",{"_index":125,"name":{"160":{}},"parent":{"161":{},"162":{},"163":{},"164":{},"165":{},"166":{}}}],["joplinviews",{"_index":116,"name":{"150":{}},"parent":{"151":{},"152":{},"153":{},"154":{},"155":{},"156":{}}}],["joplinviewsdialogs",{"_index":104,"name":{"128":{}},"parent":{"129":{},"130":{},"131":{},"132":{},"133":{},"134":{}}}],["joplinviewsmenuitems",{"_index":110,"name":{"135":{}},"parent":{"136":{},"137":{}}}],["joplinviewsmenus",{"_index":111,"name":{"138":{}},"parent":{"139":{},"140":{}}}],["joplinviewspanels",{"_index":113,"name":{"144":{}},"parent":{"145":{},"146":{},"147":{},"148":{},"149":{}}}],["joplinviewstoolbarbuttons",{"_index":112,"name":{"141":{}},"parent":{"142":{},"143":{}}}],["joplinworkspace",{"_index":96,"name":{"117":{}},"parent":{"118":{},"119":{},"120":{},"121":{},"122":{},"123":{},"124":{}}}],["label",{"_index":2,"name":{"2":{},"61":{},"86":{},"98":{}},"parent":{}}],["markdown",{"_index":10,"name":{"10":{}},"parent":{}}],["markdownitplugin",{"_index":83,"name":{"103":{}},"parent":{}}],["maximum",{"_index":79,"name":{"95":{}},"parent":{}}],["menuitem",{"_index":49,"name":{"57":{}},"parent":{"58":{},"59":{},"60":{},"61":{}}}],["menuitemlocation",{"_index":42,"name":{"49":{}},"parent":{"50":{},"51":{},"52":{},"53":{},"54":{},"55":{},"56":{}}}],["menuitems",{"_index":119,"name":{"154":{}},"parent":{}}],["menus",{"_index":120,"name":{"155":{}},"parent":{}}],["minimum",{"_index":78,"name":{"94":{}},"parent":{}}],["modulepath",{"_index":30,"name":{"35":{}},"parent":{}}],["name",{"_index":1,"name":{"1":{},"70":{},"101":{}},"parent":{}}],["note",{"_index":45,"name":{"53":{}},"parent":{}}],["notetoolbar",{"_index":57,"name":{"67":{}},"parent":{}}],["object",{"_index":68,"name":{"80":{}},"parent":{}}],["onclick",{"_index":55,"name":{"65":{}},"parent":{}}],["onclose",{"_index":21,"name":{"21":{}},"parent":{}}],["onexec",{"_index":25,"name":{"29":{}},"parent":{}}],["oninit",{"_index":18,"name":{"18":{}},"parent":{}}],["onmessage",{"_index":115,"name":{"149":{}},"parent":{}}],["onnotealarmtrigger",{"_index":99,"name":{"121":{}},"parent":{}}],["onnotecontentchange",{"_index":98,"name":{"120":{}},"parent":{}}],["onnoteselectionchange",{"_index":97,"name":{"119":{}},"parent":{}}],["onprocessitem",{"_index":19,"name":{"19":{}},"parent":{}}],["onprocessresource",{"_index":20,"name":{"20":{}},"parent":{}}],["onstart",{"_index":39,"name":{"46":{}},"parent":{}}],["onsynccomplete",{"_index":100,"name":{"122":{}},"parent":{}}],["open",{"_index":109,"name":{"134":{}},"parent":{}}],["options",{"_index":33,"name":{"39":{},"43":{},"90":{}},"parent":{}}],["outputformat",{"_index":24,"name":{"28":{}},"parent":{}}],["panels",{"_index":118,"name":{"153":{}},"parent":{}}],["path",{"_index":27,"name":{"32":{},"107":{}},"parent":{}}],["plugins",{"_index":132,"name":{"170":{}},"parent":{}}],["post",{"_index":89,"name":{"110":{}},"parent":{}}],["public",{"_index":72,"name":{"85":{}},"parent":{}}],["put",{"_index":90,"name":{"111":{}},"parent":{}}],["register",{"_index":94,"name":{"115":{},"127":{}},"parent":{}}],["registercontentscript",{"_index":95,"name":{"116":{}},"parent":{}}],["registerexportmodule",{"_index":123,"name":{"158":{}},"parent":{}}],["registerimportmodule",{"_index":124,"name":{"159":{}},"parent":{}}],["registersection",{"_index":127,"name":{"163":{}},"parent":{}}],["registersetting",{"_index":126,"name":{"162":{}},"parent":{}}],["script",{"_index":38,"name":{"45":{}},"parent":{"46":{}}}],["section",{"_index":74,"name":{"89":{}},"parent":{}}],["secure",{"_index":76,"name":{"92":{}},"parent":{}}],["selectednote",{"_index":101,"name":{"123":{}},"parent":{}}],["selectednoteids",{"_index":102,"name":{"124":{}},"parent":{}}],["setbuttons",{"_index":108,"name":{"133":{}},"parent":{}}],["sethtml",{"_index":107,"name":{"132":{},"147":{}},"parent":{}}],["settingitem",{"_index":70,"name":{"82":{}},"parent":{"83":{},"84":{},"85":{},"86":{},"87":{},"88":{},"89":{},"90":{},"91":{},"92":{},"93":{},"94":{},"95":{},"96":{}}}],["settingitemtype",{"_index":63,"name":{"75":{}},"parent":{"76":{},"77":{},"78":{},"79":{},"80":{},"81":{}}}],["settings",{"_index":137,"name":{"175":{}},"parent":{}}],["settingsection",{"_index":81,"name":{"97":{}},"parent":{"98":{},"99":{},"100":{},"101":{}}}],["setvalue",{"_index":128,"name":{"165":{}},"parent":{}}],["showmessagebox",{"_index":106,"name":{"131":{}},"parent":{}}],["sourcefolderids",{"_index":28,"name":{"33":{}},"parent":{}}],["sourcenoteids",{"_index":29,"name":{"34":{}},"parent":{}}],["sourcepath",{"_index":36,"name":{"42":{}},"parent":{}}],["sources",{"_index":23,"name":{"26":{}},"parent":{}}],["step",{"_index":80,"name":{"96":{}},"parent":{}}],["string",{"_index":65,"name":{"77":{}},"parent":{}}],["submenu",{"_index":51,"name":{"60":{}},"parent":{}}],["target",{"_index":15,"name":{"15":{},"36":{}},"parent":{}}],["title",{"_index":54,"name":{"64":{}},"parent":{}}],["toolbarbuttonlocation",{"_index":56,"name":{"66":{}},"parent":{"67":{},"68":{}}}],["toolbarbuttons",{"_index":121,"name":{"156":{}},"parent":{}}],["tools",{"_index":46,"name":{"54":{}},"parent":{}}],["type",{"_index":71,"name":{"84":{}},"parent":{}}],["userdata",{"_index":34,"name":{"40":{}},"parent":{}}],["value",{"_index":60,"name":{"71":{},"83":{},"164":{}},"parent":{}}],["view",{"_index":44,"name":{"52":{}},"parent":{}}],["viewhandle",{"_index":86,"name":{"106":{}},"parent":{}}],["views",{"_index":135,"name":{"173":{}},"parent":{}}],["warnings",{"_index":37,"name":{"44":{}},"parent":{}}],["workspace",{"_index":133,"name":{"171":{}},"parent":{}}]],"pipeline":[]}} \ No newline at end of file diff --git a/docs/api/references/plugin_api/classes/joplin.html b/docs/api/references/plugin_api/classes/joplin.html index 7c71372cb2..fa250b55e3 100644 --- a/docs/api/references/plugin_api/classes/joplin.html +++ b/docs/api/references/plugin_api/classes/joplin.html @@ -69,6 +69,15 @@

This is the main entry point to the Joplin API. You can access various services using the provided accessors.

+

This is a beta API

+

Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to:

+
    +
  • Maintain backward compatibility;
  • +
  • When possible, deprecate features instead of removing them;
  • +
  • Document breaking changes in the changelog;
  • +
+

So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc.

+

Eventually, the plugin API will be versioned to make this process smoother.

@@ -358,6 +359,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/classes/joplinviewsmenuitems.html b/docs/api/references/plugin_api/classes/joplinviewsmenuitems.html index 892cd80b2c..16f96ffb03 100644 --- a/docs/api/references/plugin_api/classes/joplinviewsmenuitems.html +++ b/docs/api/references/plugin_api/classes/joplinviewsmenuitems.html @@ -230,6 +230,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/classes/joplinviewsmenus.html b/docs/api/references/plugin_api/classes/joplinviewsmenus.html index 3668fa2942..f596ab84fd 100644 --- a/docs/api/references/plugin_api/classes/joplinviewsmenus.html +++ b/docs/api/references/plugin_api/classes/joplinviewsmenus.html @@ -231,6 +231,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/classes/joplinviewspanels.html b/docs/api/references/plugin_api/classes/joplinviewspanels.html index 459f450fd6..dbefe6fce8 100644 --- a/docs/api/references/plugin_api/classes/joplinviewspanels.html +++ b/docs/api/references/plugin_api/classes/joplinviewspanels.html @@ -327,6 +327,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/classes/joplinviewstoolbarbuttons.html b/docs/api/references/plugin_api/classes/joplinviewstoolbarbuttons.html index efdfaf6fc6..474b548b7a 100644 --- a/docs/api/references/plugin_api/classes/joplinviewstoolbarbuttons.html +++ b/docs/api/references/plugin_api/classes/joplinviewstoolbarbuttons.html @@ -227,6 +227,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/classes/joplinworkspace.html b/docs/api/references/plugin_api/classes/joplinworkspace.html index 32e2102d6b..608cd92efe 100644 --- a/docs/api/references/plugin_api/classes/joplinworkspace.html +++ b/docs/api/references/plugin_api/classes/joplinworkspace.html @@ -378,6 +378,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/enums/contentscripttype.html b/docs/api/references/plugin_api/enums/contentscripttype.html index 5aec3f4242..24a7becd4c 100644 --- a/docs/api/references/plugin_api/enums/contentscripttype.html +++ b/docs/api/references/plugin_api/enums/contentscripttype.html @@ -219,6 +219,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/enums/filesystemitem.html b/docs/api/references/plugin_api/enums/filesystemitem.html index 5da897b015..1e4607134c 100644 --- a/docs/api/references/plugin_api/enums/filesystemitem.html +++ b/docs/api/references/plugin_api/enums/filesystemitem.html @@ -186,6 +186,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/enums/importmoduleoutputformat.html b/docs/api/references/plugin_api/enums/importmoduleoutputformat.html index 3a004633a9..455c85538a 100644 --- a/docs/api/references/plugin_api/enums/importmoduleoutputformat.html +++ b/docs/api/references/plugin_api/enums/importmoduleoutputformat.html @@ -186,6 +186,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/enums/menuitemlocation.html b/docs/api/references/plugin_api/enums/menuitemlocation.html index 813cb4cd07..8cb1d1e51e 100644 --- a/docs/api/references/plugin_api/enums/menuitemlocation.html +++ b/docs/api/references/plugin_api/enums/menuitemlocation.html @@ -241,6 +241,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/enums/settingitemtype.html b/docs/api/references/plugin_api/enums/settingitemtype.html index 463acec2ac..33a2394df2 100644 --- a/docs/api/references/plugin_api/enums/settingitemtype.html +++ b/docs/api/references/plugin_api/enums/settingitemtype.html @@ -230,6 +230,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/enums/toolbarbuttonlocation.html b/docs/api/references/plugin_api/enums/toolbarbuttonlocation.html index e4e44b2ee9..ba3b94a54c 100644 --- a/docs/api/references/plugin_api/enums/toolbarbuttonlocation.html +++ b/docs/api/references/plugin_api/enums/toolbarbuttonlocation.html @@ -196,6 +196,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/globals.html b/docs/api/references/plugin_api/globals.html index 3c168467e9..bbac5bee2d 100644 --- a/docs/api/references/plugin_api/globals.html +++ b/docs/api/references/plugin_api/globals.html @@ -100,6 +100,7 @@
  • ButtonSpec
  • Command
  • CreateMenuItemOptions
  • +
  • DialogResult
  • EditorCommand
  • ExportContext
  • ExportModule
  • @@ -234,6 +235,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/index.html b/docs/api/references/plugin_api/index.html index df7d0beb54..c5d9d9b42f 100644 --- a/docs/api/references/plugin_api/index.html +++ b/docs/api/references/plugin_api/index.html @@ -146,6 +146,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/interfaces/buttonspec.html b/docs/api/references/plugin_api/interfaces/buttonspec.html index f7d8db8e60..a987324862 100644 --- a/docs/api/references/plugin_api/interfaces/buttonspec.html +++ b/docs/api/references/plugin_api/interfaces/buttonspec.html @@ -228,6 +228,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/interfaces/command.html b/docs/api/references/plugin_api/interfaces/command.html index 9e59621ddc..3cbb92b777 100644 --- a/docs/api/references/plugin_api/interfaces/command.html +++ b/docs/api/references/plugin_api/interfaces/command.html @@ -318,6 +318,9 @@
  • CreateMenuItemOptions
  • +
  • + DialogResult +
  • EditorCommand
  • diff --git a/docs/api/references/plugin_api/interfaces/createmenuitemoptions.html b/docs/api/references/plugin_api/interfaces/createmenuitemoptions.html index e0337d76bb..387ff1ba62 100644 --- a/docs/api/references/plugin_api/interfaces/createmenuitemoptions.html +++ b/docs/api/references/plugin_api/interfaces/createmenuitemoptions.html @@ -187,6 +187,9 @@
    • diff --git a/docs/api/references/plugin_api/interfaces/exportcontext.html b/docs/api/references/plugin_api/interfaces/exportcontext.html index 20f72e5c50..73e4d71366 100644 --- a/docs/api/references/plugin_api/interfaces/exportcontext.html +++ b/docs/api/references/plugin_api/interfaces/exportcontext.html @@ -199,6 +199,9 @@
    • CreateMenuItemOptions
    • +
    • + DialogResult +
    • EditorCommand
    • diff --git a/docs/api/references/plugin_api/interfaces/exportmodule.html b/docs/api/references/plugin_api/interfaces/exportmodule.html index 91ca3c81dd..5dd4cf0868 100644 --- a/docs/api/references/plugin_api/interfaces/exportmodule.html +++ b/docs/api/references/plugin_api/interfaces/exportmodule.html @@ -386,6 +386,9 @@
    • CreateMenuItemOptions
    • +
    • + DialogResult +
    • EditorCommand
    • diff --git a/docs/api/references/plugin_api/interfaces/exportoptions.html b/docs/api/references/plugin_api/interfaces/exportoptions.html index b0a7d8a034..75626f97a4 100644 --- a/docs/api/references/plugin_api/interfaces/exportoptions.html +++ b/docs/api/references/plugin_api/interfaces/exportoptions.html @@ -218,6 +218,9 @@
    • CreateMenuItemOptions
    • +
    • + DialogResult +
    • EditorCommand
    • diff --git a/docs/api/references/plugin_api/interfaces/importcontext.html b/docs/api/references/plugin_api/interfaces/importcontext.html index 70a6de886f..8c69fc45b7 100644 --- a/docs/api/references/plugin_api/interfaces/importcontext.html +++ b/docs/api/references/plugin_api/interfaces/importcontext.html @@ -194,6 +194,9 @@
    • CreateMenuItemOptions
    • +
    • + DialogResult +
    • EditorCommand
    • diff --git a/docs/api/references/plugin_api/interfaces/importmodule.html b/docs/api/references/plugin_api/interfaces/importmodule.html index 38fc31c70b..137d475beb 100644 --- a/docs/api/references/plugin_api/interfaces/importmodule.html +++ b/docs/api/references/plugin_api/interfaces/importmodule.html @@ -288,6 +288,9 @@
    • CreateMenuItemOptions
    • +
    • + DialogResult +
    • EditorCommand
    • diff --git a/docs/api/references/plugin_api/interfaces/menuitem.html b/docs/api/references/plugin_api/interfaces/menuitem.html index e3d8ca2799..51c2ce30e4 100644 --- a/docs/api/references/plugin_api/interfaces/menuitem.html +++ b/docs/api/references/plugin_api/interfaces/menuitem.html @@ -223,6 +223,9 @@
    • CreateMenuItemOptions
    • +
    • + DialogResult +
    • EditorCommand
    • diff --git a/docs/api/references/plugin_api/interfaces/script.html b/docs/api/references/plugin_api/interfaces/script.html index 62d26500f5..c3bacb7fa3 100644 --- a/docs/api/references/plugin_api/interfaces/script.html +++ b/docs/api/references/plugin_api/interfaces/script.html @@ -195,6 +195,9 @@
    • CreateMenuItemOptions
    • +
    • + DialogResult +
    • EditorCommand
    • diff --git a/docs/api/references/plugin_api/interfaces/settingitem.html b/docs/api/references/plugin_api/interfaces/settingitem.html index f10a2b6482..06c87d7fa8 100644 --- a/docs/api/references/plugin_api/interfaces/settingitem.html +++ b/docs/api/references/plugin_api/interfaces/settingitem.html @@ -282,6 +282,9 @@
    • CreateMenuItemOptions
    • +
    • + DialogResult +
    • EditorCommand
    • diff --git a/docs/api/references/plugin_api/interfaces/settingsection.html b/docs/api/references/plugin_api/interfaces/settingsection.html index fe0456e5d3..3e31e659b4 100644 --- a/docs/api/references/plugin_api/interfaces/settingsection.html +++ b/docs/api/references/plugin_api/interfaces/settingsection.html @@ -202,6 +202,9 @@
    • CreateMenuItemOptions
    • +
    • + DialogResult +
    • EditorCommand
    • diff --git a/docs/index.html b/docs/index.html index 288ca6cdc2..efdde01fa2 100644 --- a/docs/index.html +++ b/docs/index.html @@ -682,6 +682,16 @@ Details: Current date and/or time formatted based on a supplied string (using moment.js formatting) {{#custom_datetime}}M d{{/custom_datetime}} + +{{bowm}} +Date of the beginning of the week (when week starts on Monday) based on the settings format + + + +{{bows}} +Date of the beginning of the week (when week starts on Sunday) based on the settings format + +

      Searching🔗

      diff --git a/docs/stats/index.html b/docs/stats/index.html index 9491041aa8..be66f1c3da 100644 --- a/docs/stats/index.html +++ b/docs/stats/index.html @@ -402,15 +402,15 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md Total Windows downloads -1,090,167 +1,093,355 Total macOs downloads -422,857 +424,314 Total Linux downloads -307,611 +308,866 Windows % @@ -441,114 +441,114 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md v1.3.18 2020-11-06T12:07:02Z -8,566 -3,609 -2,837 -15,012 +11,553 +5,028 +4,072 +20,653 v1.3.15 2020-11-04T12:22:50Z -2,121 -1,251 -820 -4,192 +2,130 +1,257 +822 +4,209 v1.2.6 2020-10-09T13:56:59Z -43,259 -17,626 -13,986 -74,871 +43,344 +17,636 +13,990 +74,970 v1.1.4 2020-09-21T11:20:09Z -27,391 -13,455 -7,691 -48,537 +27,401 +13,457 +7,692 +48,550 v1.0.245 2020-09-09T12:56:10Z -20,762 -9,957 +20,766 +9,959 5,617 -36,336 +36,342 v1.0.242 2020-09-04T22:00:34Z 12,299 6,393 -3,003 -21,695 +3,004 +21,696 v1.0.241 2020-09-04T18:06:00Z -23,064 +23,066 5,684 4,959 -33,707 +33,709 v1.0.233 2020-08-01T14:51:15Z -42,160 -18,145 +42,177 +18,149 12,344 -72,649 +72,670 v1.0.227 2020-07-07T20:44:54Z -40,128 -15,234 +40,132 +15,235 9,610 -64,972 +64,977 v1.0.224 2020-06-20T22:26:08Z -24,702 -10,975 +24,705 +10,976 5,999 -41,676 +41,680 v1.0.220 2020-06-13T18:26:22Z -31,505 +31,507 9,887 6,407 -47,799 +47,801 v1.0.218 2020-06-07T10:43:34Z -14,480 +14,485 6,946 2,950 -24,376 +24,381 v1.0.216 2020-05-24T14:21:01Z -36,322 -14,233 +36,341 +14,235 10,169 -60,724 +60,745 v1.0.201 2020-04-15T22:55:13Z -52,335 +52,351 20,032 18,167 -90,534 +90,550 v1.0.200 @@ -561,34 +561,34 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md v1.0.199 2020-04-10T18:41:58Z -19,236 +19,237 5,878 3,783 -28,897 +28,898 v1.0.197 2020-03-30T17:21:22Z -22,059 +22,061 9,506 -5,608 -37,173 +5,610 +37,177 v1.0.195 2020-03-22T19:56:12Z 18,860 -7,941 +7,942 4,502 -31,303 +31,304 v1.0.193 2020-03-08T08:58:53Z -28,593 -10,894 +28,594 +10,895 7,356 -46,843 +46,845 v1.0.179 @@ -609,58 +609,58 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md v1.0.175 2019-12-08T11:48:47Z -71,972 +71,976 16,855 -16,475 -105,302 +16,476 +105,307 v1.0.174 2019-11-12T18:20:58Z -30,387 -11,687 +30,388 +11,688 8,216 -50,290 +50,292 v1.0.173 2019-11-11T08:33:35Z -5,057 +5,058 2,071 739 -7,867 +7,868 v1.0.170 2019-10-13T22:13:04Z -27,369 +27,372 8,737 7,668 -43,774 +43,777 v1.0.169 2019-09-27T18:35:13Z -17,080 +17,081 5,915 3,750 -26,745 +26,746 v1.0.168 2019-09-25T21:21:38Z -5,322 +5,323 2,265 714 -8,301 +8,302 v1.0.167 2019-09-10T08:48:37Z -16,778 -5,698 +16,779 +5,699 3,700 -26,176 +26,178 v1.0.166 @@ -683,16 +683,16 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md 2019-07-13T18:30:00Z 19,272 6,348 -4,132 -29,752 +4,133 +29,753 v1.0.160 2019-06-15T00:21:40Z -30,455 -7,741 +30,457 +7,742 8,098 -46,294 +46,297 v1.0.159 @@ -730,25 +730,25 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md v1.0.151 2019-05-12T15:14:32Z 1,948 -529 +530 955 -3,432 +3,433 v1.0.150 2019-05-12T11:27:48Z -417 -128 +418 +129 66 -611 +613 v1.0.145 2019-05-03T09:16:53Z -6,998 +7,000 2,857 1,434 -11,289 +11,291 v1.0.143 @@ -777,18 +777,18 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md v1.0.135 2019-02-27T23:36:57Z -12,483 +12,484 3,953 4,072 -20,508 +20,509 v1.0.134 2019-02-27T10:21:44Z -1,462 +1,463 563 217 -2,242 +2,243 v1.0.132 @@ -803,8 +803,8 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md 2019-02-14T23:12:48Z 9,734 3,164 -2,927 -15,825 +2,928 +15,826 v1.0.125 @@ -825,10 +825,10 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md v1.0.119 2018-12-18T12:40:22Z -8,901 +8,902 3,257 2,013 -14,171 +14,172 v1.0.118 @@ -874,9 +874,9 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md v1.0.111 2018-09-30T20:15:09Z 12,007 -3,285 +3,286 3,663 -18,955 +18,956 v1.0.110 @@ -915,8 +915,8 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md 2018-09-05T11:29:36Z 4,652 1,585 -1,452 -7,689 +1,453 +7,690 v1.0.104 @@ -938,9 +938,9 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md v1.0.101 2018-06-17T18:35:11Z 1,304 -603 +604 407 -2,314 +2,315 v1.0.100 @@ -971,8 +971,8 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md 2018-05-26T16:36:39Z 2,715 1,221 -1,602 -5,538 +1,606 +5,542 v1.0.95 @@ -1179,8 +1179,8 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md 2018-01-23T11:19:51Z 1,964 1,750 -29 -3,743 +30 +3,744 v0.10.47 @@ -1217,10 +1217,10 @@ https://github.com/laurent22/joplin/blob/dev/readme/stats.md v0.10.39 2017-12-11T21:19:44Z -5,783 -4,256 -3,158 -13,197 +5,784 +4,257 +3,159 +13,200 v0.10.38 diff --git a/readme/stats.md b/readme/stats.md index 9a8d55fd77..5cf5e9618e 100644 --- a/readme/stats.md +++ b/readme/stats.md @@ -2,82 +2,82 @@ Name | Value --- | --- -Total Windows downloads | 1,090,167 -Total macOs downloads | 422,857 -Total Linux downloads | 307,611 +Total Windows downloads | 1,093,355 +Total macOs downloads | 424,314 +Total Linux downloads | 308,866 Windows % | 60% macOS % | 23% Linux % | 17% Version | Date | Windows | macOS | Linux | Total --- | --- | --- | --- | --- | --- -[v1.3.18](https://github.com/laurent22/joplin/releases/tag/v1.3.18) | 2020-11-06T12:07:02Z | 8,566 | 3,609 | 2,837 | 15,012 -[v1.3.15](https://github.com/laurent22/joplin/releases/tag/v1.3.15) | 2020-11-04T12:22:50Z | 2,121 | 1,251 | 820 | 4,192 -[v1.2.6](https://github.com/laurent22/joplin/releases/tag/v1.2.6) | 2020-10-09T13:56:59Z | 43,259 | 17,626 | 13,986 | 74,871 -[v1.1.4](https://github.com/laurent22/joplin/releases/tag/v1.1.4) | 2020-09-21T11:20:09Z | 27,391 | 13,455 | 7,691 | 48,537 -[v1.0.245](https://github.com/laurent22/joplin/releases/tag/v1.0.245) | 2020-09-09T12:56:10Z | 20,762 | 9,957 | 5,617 | 36,336 -[v1.0.242](https://github.com/laurent22/joplin/releases/tag/v1.0.242) | 2020-09-04T22:00:34Z | 12,299 | 6,393 | 3,003 | 21,695 -[v1.0.241](https://github.com/laurent22/joplin/releases/tag/v1.0.241) | 2020-09-04T18:06:00Z | 23,064 | 5,684 | 4,959 | 33,707 -[v1.0.233](https://github.com/laurent22/joplin/releases/tag/v1.0.233) | 2020-08-01T14:51:15Z | 42,160 | 18,145 | 12,344 | 72,649 -[v1.0.227](https://github.com/laurent22/joplin/releases/tag/v1.0.227) | 2020-07-07T20:44:54Z | 40,128 | 15,234 | 9,610 | 64,972 -[v1.0.224](https://github.com/laurent22/joplin/releases/tag/v1.0.224) | 2020-06-20T22:26:08Z | 24,702 | 10,975 | 5,999 | 41,676 -[v1.0.220](https://github.com/laurent22/joplin/releases/tag/v1.0.220) | 2020-06-13T18:26:22Z | 31,505 | 9,887 | 6,407 | 47,799 -[v1.0.218](https://github.com/laurent22/joplin/releases/tag/v1.0.218) | 2020-06-07T10:43:34Z | 14,480 | 6,946 | 2,950 | 24,376 -[v1.0.216](https://github.com/laurent22/joplin/releases/tag/v1.0.216) | 2020-05-24T14:21:01Z | 36,322 | 14,233 | 10,169 | 60,724 -[v1.0.201](https://github.com/laurent22/joplin/releases/tag/v1.0.201) | 2020-04-15T22:55:13Z | 52,335 | 20,032 | 18,167 | 90,534 +[v1.3.18](https://github.com/laurent22/joplin/releases/tag/v1.3.18) | 2020-11-06T12:07:02Z | 11,553 | 5,028 | 4,072 | 20,653 +[v1.3.15](https://github.com/laurent22/joplin/releases/tag/v1.3.15) | 2020-11-04T12:22:50Z | 2,130 | 1,257 | 822 | 4,209 +[v1.2.6](https://github.com/laurent22/joplin/releases/tag/v1.2.6) | 2020-10-09T13:56:59Z | 43,344 | 17,636 | 13,990 | 74,970 +[v1.1.4](https://github.com/laurent22/joplin/releases/tag/v1.1.4) | 2020-09-21T11:20:09Z | 27,401 | 13,457 | 7,692 | 48,550 +[v1.0.245](https://github.com/laurent22/joplin/releases/tag/v1.0.245) | 2020-09-09T12:56:10Z | 20,766 | 9,959 | 5,617 | 36,342 +[v1.0.242](https://github.com/laurent22/joplin/releases/tag/v1.0.242) | 2020-09-04T22:00:34Z | 12,299 | 6,393 | 3,004 | 21,696 +[v1.0.241](https://github.com/laurent22/joplin/releases/tag/v1.0.241) | 2020-09-04T18:06:00Z | 23,066 | 5,684 | 4,959 | 33,709 +[v1.0.233](https://github.com/laurent22/joplin/releases/tag/v1.0.233) | 2020-08-01T14:51:15Z | 42,177 | 18,149 | 12,344 | 72,670 +[v1.0.227](https://github.com/laurent22/joplin/releases/tag/v1.0.227) | 2020-07-07T20:44:54Z | 40,132 | 15,235 | 9,610 | 64,977 +[v1.0.224](https://github.com/laurent22/joplin/releases/tag/v1.0.224) | 2020-06-20T22:26:08Z | 24,705 | 10,976 | 5,999 | 41,680 +[v1.0.220](https://github.com/laurent22/joplin/releases/tag/v1.0.220) | 2020-06-13T18:26:22Z | 31,507 | 9,887 | 6,407 | 47,801 +[v1.0.218](https://github.com/laurent22/joplin/releases/tag/v1.0.218) | 2020-06-07T10:43:34Z | 14,485 | 6,946 | 2,950 | 24,381 +[v1.0.216](https://github.com/laurent22/joplin/releases/tag/v1.0.216) | 2020-05-24T14:21:01Z | 36,341 | 14,235 | 10,169 | 60,745 +[v1.0.201](https://github.com/laurent22/joplin/releases/tag/v1.0.201) | 2020-04-15T22:55:13Z | 52,351 | 20,032 | 18,167 | 90,550 [v1.0.200](https://github.com/laurent22/joplin/releases/tag/v1.0.200) | 2020-04-12T12:17:46Z | 9,543 | 4,885 | 1,898 | 16,326 -[v1.0.199](https://github.com/laurent22/joplin/releases/tag/v1.0.199) | 2020-04-10T18:41:58Z | 19,236 | 5,878 | 3,783 | 28,897 -[v1.0.197](https://github.com/laurent22/joplin/releases/tag/v1.0.197) | 2020-03-30T17:21:22Z | 22,059 | 9,506 | 5,608 | 37,173 -[v1.0.195](https://github.com/laurent22/joplin/releases/tag/v1.0.195) | 2020-03-22T19:56:12Z | 18,860 | 7,941 | 4,502 | 31,303 -[v1.0.193](https://github.com/laurent22/joplin/releases/tag/v1.0.193) | 2020-03-08T08:58:53Z | 28,593 | 10,894 | 7,356 | 46,843 +[v1.0.199](https://github.com/laurent22/joplin/releases/tag/v1.0.199) | 2020-04-10T18:41:58Z | 19,237 | 5,878 | 3,783 | 28,898 +[v1.0.197](https://github.com/laurent22/joplin/releases/tag/v1.0.197) | 2020-03-30T17:21:22Z | 22,061 | 9,506 | 5,610 | 37,177 +[v1.0.195](https://github.com/laurent22/joplin/releases/tag/v1.0.195) | 2020-03-22T19:56:12Z | 18,860 | 7,942 | 4,502 | 31,304 +[v1.0.193](https://github.com/laurent22/joplin/releases/tag/v1.0.193) | 2020-03-08T08:58:53Z | 28,594 | 10,895 | 7,356 | 46,845 [v1.0.179](https://github.com/laurent22/joplin/releases/tag/v1.0.179) | 2020-01-24T22:42:41Z | 70,935 | 28,466 | 22,490 | 121,891 [v1.0.178](https://github.com/laurent22/joplin/releases/tag/v1.0.178) | 2020-01-20T19:06:45Z | 17,525 | 5,956 | 2,578 | 26,059 -[v1.0.175](https://github.com/laurent22/joplin/releases/tag/v1.0.175) | 2019-12-08T11:48:47Z | 71,972 | 16,855 | 16,475 | 105,302 -[v1.0.174](https://github.com/laurent22/joplin/releases/tag/v1.0.174) | 2019-11-12T18:20:58Z | 30,387 | 11,687 | 8,216 | 50,290 -[v1.0.173](https://github.com/laurent22/joplin/releases/tag/v1.0.173) | 2019-11-11T08:33:35Z | 5,057 | 2,071 | 739 | 7,867 -[v1.0.170](https://github.com/laurent22/joplin/releases/tag/v1.0.170) | 2019-10-13T22:13:04Z | 27,369 | 8,737 | 7,668 | 43,774 -[v1.0.169](https://github.com/laurent22/joplin/releases/tag/v1.0.169) | 2019-09-27T18:35:13Z | 17,080 | 5,915 | 3,750 | 26,745 -[v1.0.168](https://github.com/laurent22/joplin/releases/tag/v1.0.168) | 2019-09-25T21:21:38Z | 5,322 | 2,265 | 714 | 8,301 -[v1.0.167](https://github.com/laurent22/joplin/releases/tag/v1.0.167) | 2019-09-10T08:48:37Z | 16,778 | 5,698 | 3,700 | 26,176 +[v1.0.175](https://github.com/laurent22/joplin/releases/tag/v1.0.175) | 2019-12-08T11:48:47Z | 71,976 | 16,855 | 16,476 | 105,307 +[v1.0.174](https://github.com/laurent22/joplin/releases/tag/v1.0.174) | 2019-11-12T18:20:58Z | 30,388 | 11,688 | 8,216 | 50,292 +[v1.0.173](https://github.com/laurent22/joplin/releases/tag/v1.0.173) | 2019-11-11T08:33:35Z | 5,058 | 2,071 | 739 | 7,868 +[v1.0.170](https://github.com/laurent22/joplin/releases/tag/v1.0.170) | 2019-10-13T22:13:04Z | 27,372 | 8,737 | 7,668 | 43,777 +[v1.0.169](https://github.com/laurent22/joplin/releases/tag/v1.0.169) | 2019-09-27T18:35:13Z | 17,081 | 5,915 | 3,750 | 26,746 +[v1.0.168](https://github.com/laurent22/joplin/releases/tag/v1.0.168) | 2019-09-25T21:21:38Z | 5,323 | 2,265 | 714 | 8,302 +[v1.0.167](https://github.com/laurent22/joplin/releases/tag/v1.0.167) | 2019-09-10T08:48:37Z | 16,779 | 5,699 | 3,700 | 26,178 [v1.0.166](https://github.com/laurent22/joplin/releases/tag/v1.0.166) | 2019-09-09T17:35:54Z | 1,950 | 557 | 235 | 2,742 [v1.0.165](https://github.com/laurent22/joplin/releases/tag/v1.0.165) | 2019-08-14T21:46:29Z | 18,875 | 6,968 | 5,459 | 31,302 -[v1.0.161](https://github.com/laurent22/joplin/releases/tag/v1.0.161) | 2019-07-13T18:30:00Z | 19,272 | 6,348 | 4,132 | 29,752 -[v1.0.160](https://github.com/laurent22/joplin/releases/tag/v1.0.160) | 2019-06-15T00:21:40Z | 30,455 | 7,741 | 8,098 | 46,294 +[v1.0.161](https://github.com/laurent22/joplin/releases/tag/v1.0.161) | 2019-07-13T18:30:00Z | 19,272 | 6,348 | 4,133 | 29,753 +[v1.0.160](https://github.com/laurent22/joplin/releases/tag/v1.0.160) | 2019-06-15T00:21:40Z | 30,457 | 7,742 | 8,098 | 46,297 [v1.0.159](https://github.com/laurent22/joplin/releases/tag/v1.0.159) | 2019-06-08T00:00:19Z | 5,188 | 2,174 | 1,105 | 8,467 [v1.0.158](https://github.com/laurent22/joplin/releases/tag/v1.0.158) | 2019-05-27T19:01:18Z | 9,809 | 3,534 | 1,934 | 15,277 [v1.0.157](https://github.com/laurent22/joplin/releases/tag/v1.0.157) | 2019-05-26T17:55:53Z | 2,173 | 840 | 289 | 3,302 [v1.0.152](https://github.com/laurent22/joplin/releases/tag/v1.0.152) | 2019-05-13T09:08:07Z | 13,861 | 4,423 | 4,059 | 22,343 -[v1.0.151](https://github.com/laurent22/joplin/releases/tag/v1.0.151) | 2019-05-12T15:14:32Z | 1,948 | 529 | 955 | 3,432 -[v1.0.150](https://github.com/laurent22/joplin/releases/tag/v1.0.150) | 2019-05-12T11:27:48Z | 417 | 128 | 66 | 611 -[v1.0.145](https://github.com/laurent22/joplin/releases/tag/v1.0.145) | 2019-05-03T09:16:53Z | 6,998 | 2,857 | 1,434 | 11,289 +[v1.0.151](https://github.com/laurent22/joplin/releases/tag/v1.0.151) | 2019-05-12T15:14:32Z | 1,948 | 530 | 955 | 3,433 +[v1.0.150](https://github.com/laurent22/joplin/releases/tag/v1.0.150) | 2019-05-12T11:27:48Z | 418 | 129 | 66 | 613 +[v1.0.145](https://github.com/laurent22/joplin/releases/tag/v1.0.145) | 2019-05-03T09:16:53Z | 7,000 | 2,857 | 1,434 | 11,291 [v1.0.143](https://github.com/laurent22/joplin/releases/tag/v1.0.143) | 2019-04-22T10:51:38Z | 11,911 | 3,546 | 2,776 | 18,233 [v1.0.142](https://github.com/laurent22/joplin/releases/tag/v1.0.142) | 2019-04-02T16:44:51Z | 14,648 | 4,557 | 4,724 | 23,929 [v1.0.140](https://github.com/laurent22/joplin/releases/tag/v1.0.140) | 2019-03-10T20:59:58Z | 13,621 | 4,166 | 3,172 | 20,959 -[v1.0.135](https://github.com/laurent22/joplin/releases/tag/v1.0.135) | 2019-02-27T23:36:57Z | 12,483 | 3,953 | 4,072 | 20,508 -[v1.0.134](https://github.com/laurent22/joplin/releases/tag/v1.0.134) | 2019-02-27T10:21:44Z | 1,462 | 563 | 217 | 2,242 +[v1.0.135](https://github.com/laurent22/joplin/releases/tag/v1.0.135) | 2019-02-27T23:36:57Z | 12,484 | 3,953 | 4,072 | 20,509 +[v1.0.134](https://github.com/laurent22/joplin/releases/tag/v1.0.134) | 2019-02-27T10:21:44Z | 1,463 | 563 | 217 | 2,243 [v1.0.132](https://github.com/laurent22/joplin/releases/tag/v1.0.132) | 2019-02-26T23:02:05Z | 1,081 | 447 | 93 | 1,621 -[v1.0.127](https://github.com/laurent22/joplin/releases/tag/v1.0.127) | 2019-02-14T23:12:48Z | 9,734 | 3,164 | 2,927 | 15,825 +[v1.0.127](https://github.com/laurent22/joplin/releases/tag/v1.0.127) | 2019-02-14T23:12:48Z | 9,734 | 3,164 | 2,928 | 15,826 [v1.0.125](https://github.com/laurent22/joplin/releases/tag/v1.0.125) | 2019-01-26T18:14:33Z | 10,245 | 3,552 | 1,701 | 15,498 [v1.0.120](https://github.com/laurent22/joplin/releases/tag/v1.0.120) | 2019-01-10T21:42:53Z | 15,598 | 5,196 | 6,512 | 27,306 -[v1.0.119](https://github.com/laurent22/joplin/releases/tag/v1.0.119) | 2018-12-18T12:40:22Z | 8,901 | 3,257 | 2,013 | 14,171 +[v1.0.119](https://github.com/laurent22/joplin/releases/tag/v1.0.119) | 2018-12-18T12:40:22Z | 8,902 | 3,257 | 2,013 | 14,172 [v1.0.118](https://github.com/laurent22/joplin/releases/tag/v1.0.118) | 2019-01-11T08:34:13Z | 713 | 244 | 87 | 1,044 [v1.0.117](https://github.com/laurent22/joplin/releases/tag/v1.0.117) | 2018-11-24T12:05:24Z | 16,252 | 4,889 | 6,379 | 27,520 [v1.0.116](https://github.com/laurent22/joplin/releases/tag/v1.0.116) | 2018-11-20T19:09:24Z | 3,468 | 1,117 | 712 | 5,297 [v1.0.115](https://github.com/laurent22/joplin/releases/tag/v1.0.115) | 2018-11-16T16:52:02Z | 3,652 | 1,298 | 797 | 5,747 [v1.0.114](https://github.com/laurent22/joplin/releases/tag/v1.0.114) | 2018-10-24T20:14:10Z | 11,391 | 3,492 | 3,828 | 18,711 -[v1.0.111](https://github.com/laurent22/joplin/releases/tag/v1.0.111) | 2018-09-30T20:15:09Z | 12,007 | 3,285 | 3,663 | 18,955 +[v1.0.111](https://github.com/laurent22/joplin/releases/tag/v1.0.111) | 2018-09-30T20:15:09Z | 12,007 | 3,286 | 3,663 | 18,956 [v1.0.110](https://github.com/laurent22/joplin/releases/tag/v1.0.110) | 2018-09-29T12:29:21Z | 956 | 404 | 116 | 1,476 [v1.0.109](https://github.com/laurent22/joplin/releases/tag/v1.0.109) | 2018-09-27T18:01:41Z | 2,096 | 700 | 326 | 3,122 [v1.0.107](https://github.com/laurent22/joplin/releases/tag/v1.0.107) | 2018-09-16T19:51:07Z | 7,145 | 2,132 | 1,705 | 10,982 [v1.0.106](https://github.com/laurent22/joplin/releases/tag/v1.0.106) | 2018-09-08T15:23:40Z | 4,553 | 1,453 | 316 | 6,322 -[v1.0.105](https://github.com/laurent22/joplin/releases/tag/v1.0.105) | 2018-09-05T11:29:36Z | 4,652 | 1,585 | 1,452 | 7,689 +[v1.0.105](https://github.com/laurent22/joplin/releases/tag/v1.0.105) | 2018-09-05T11:29:36Z | 4,652 | 1,585 | 1,453 | 7,690 [v1.0.104](https://github.com/laurent22/joplin/releases/tag/v1.0.104) | 2018-06-28T20:25:36Z | 15,038 | 4,696 | 7,326 | 27,060 [v1.0.103](https://github.com/laurent22/joplin/releases/tag/v1.0.103) | 2018-06-21T19:38:13Z | 2,048 | 882 | 679 | 3,609 -[v1.0.101](https://github.com/laurent22/joplin/releases/tag/v1.0.101) | 2018-06-17T18:35:11Z | 1,304 | 603 | 407 | 2,314 +[v1.0.101](https://github.com/laurent22/joplin/releases/tag/v1.0.101) | 2018-06-17T18:35:11Z | 1,304 | 604 | 407 | 2,315 [v1.0.100](https://github.com/laurent22/joplin/releases/tag/v1.0.100) | 2018-06-14T17:41:43Z | 875 | 429 | 239 | 1,543 [v1.0.99](https://github.com/laurent22/joplin/releases/tag/v1.0.99) | 2018-06-10T13:18:23Z | 1,250 | 593 | 378 | 2,221 [v1.0.97](https://github.com/laurent22/joplin/releases/tag/v1.0.97) | 2018-06-09T19:23:34Z | 309 | 154 | 59 | 522 -[v1.0.96](https://github.com/laurent22/joplin/releases/tag/v1.0.96) | 2018-05-26T16:36:39Z | 2,715 | 1,221 | 1,602 | 5,538 +[v1.0.96](https://github.com/laurent22/joplin/releases/tag/v1.0.96) | 2018-05-26T16:36:39Z | 2,715 | 1,221 | 1,606 | 5,542 [v1.0.95](https://github.com/laurent22/joplin/releases/tag/v1.0.95) | 2018-05-25T13:04:30Z | 415 | 215 | 116 | 746 [v1.0.94](https://github.com/laurent22/joplin/releases/tag/v1.0.94) | 2018-05-21T20:52:59Z | 1,128 | 580 | 394 | 2,102 [v1.0.93](https://github.com/laurent22/joplin/releases/tag/v1.0.93) | 2018-05-14T11:36:01Z | 1,786 | 1,080 | 755 | 3,621 @@ -103,12 +103,12 @@ Version | Date | Windows | macOS | Linux | Total [v0.10.54](https://github.com/laurent22/joplin/releases/tag/v0.10.54) | 2018-01-31T20:21:30Z | 1,819 | 1,458 | 321 | 3,598 [v0.10.52](https://github.com/laurent22/joplin/releases/tag/v0.10.52) | 2018-01-31T19:25:18Z | 46 | 632 | 15 | 693 [v0.10.51](https://github.com/laurent22/joplin/releases/tag/v0.10.51) | 2018-01-28T18:47:02Z | 1,327 | 1,598 | 327 | 3,252 -[v0.10.48](https://github.com/laurent22/joplin/releases/tag/v0.10.48) | 2018-01-23T11:19:51Z | 1,964 | 1,750 | 29 | 3,743 +[v0.10.48](https://github.com/laurent22/joplin/releases/tag/v0.10.48) | 2018-01-23T11:19:51Z | 1,964 | 1,750 | 30 | 3,744 [v0.10.47](https://github.com/laurent22/joplin/releases/tag/v0.10.47) | 2018-01-16T17:27:17Z | 1,228 | 1,268 | 67 | 2,563 [v0.10.43](https://github.com/laurent22/joplin/releases/tag/v0.10.43) | 2018-01-08T10:12:10Z | 3,437 | 2,354 | 1,205 | 6,996 [v0.10.41](https://github.com/laurent22/joplin/releases/tag/v0.10.41) | 2018-01-05T20:38:12Z | 1,036 | 1,547 | 238 | 2,821 [v0.10.40](https://github.com/laurent22/joplin/releases/tag/v0.10.40) | 2018-01-02T23:16:57Z | 1,594 | 1,786 | 338 | 3,718 -[v0.10.39](https://github.com/laurent22/joplin/releases/tag/v0.10.39) | 2017-12-11T21:19:44Z | 5,783 | 4,256 | 3,158 | 13,197 +[v0.10.39](https://github.com/laurent22/joplin/releases/tag/v0.10.39) | 2017-12-11T21:19:44Z | 5,784 | 4,257 | 3,159 | 13,200 [v0.10.38](https://github.com/laurent22/joplin/releases/tag/v0.10.38) | 2017-12-08T10:12:06Z | 1,048 | 1,229 | 306 | 2,583 [v0.10.37](https://github.com/laurent22/joplin/releases/tag/v0.10.37) | 2017-12-07T19:38:05Z | 264 | 843 | 81 | 1,188 [v0.10.36](https://github.com/laurent22/joplin/releases/tag/v0.10.36) | 2017-12-05T09:34:40Z | 1,014 | 1,354 | 437 | 2,805 From 8305eb4403ebc4a4a72a4e78a5e9019435d849cc Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 13 Nov 2020 21:45:25 +0000 Subject: [PATCH 07/11] API: Fix note and resource association end points --- packages/app-cli/jest.config.js | 3 ++- packages/app-cli/tests/services_rest_Api.ts | 13 ++++++++++++- packages/lib/services/rest/routes/notes.ts | 2 +- packages/lib/services/rest/routes/resources.ts | 10 +++++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/app-cli/jest.config.js b/packages/app-cli/jest.config.js index 5f8b845f26..004ade558b 100644 --- a/packages/app-cli/jest.config.js +++ b/packages/app-cli/jest.config.js @@ -9,7 +9,8 @@ module.exports = { ], testPathIgnorePatterns: [ '/node_modules/', - 'tests/support/', + '/tests\\/support/', + '/build/', 'test-utils.js', 'file_api_driver.js', ], diff --git a/packages/app-cli/tests/services_rest_Api.ts b/packages/app-cli/tests/services_rest_Api.ts index 7c7b68f31b..e8c413a0f6 100644 --- a/packages/app-cli/tests/services_rest_Api.ts +++ b/packages/app-cli/tests/services_rest_Api.ts @@ -696,7 +696,18 @@ describe('services_rest_Api', function() { const r = await api.route(RequestMethod.GET, `resources/${resource.id}/notes`); expect(r.items.length).toBe(1); - expect(r.items[0]).toBe(note.id); + expect(r.items[0].id).toBe(note.id); + })); + + it('should return the resources associated with a note', asyncTest(async () => { + const note = await Note.save({}); + await shim.attachFileToNote(note, `${__dirname}/../tests/support/photo.jpg`); + const resource = (await Resource.all())[0]; + + const r = await api.route(RequestMethod.GET, `notes/${note.id}/resources`); + + expect(r.items.length).toBe(1); + expect(r.items[0].id).toBe(resource.id); })); it('should return search results', asyncTest(async () => { diff --git a/packages/lib/services/rest/routes/notes.ts b/packages/lib/services/rest/routes/notes.ts index 1cb6bca7bd..6a1c57089c 100644 --- a/packages/lib/services/rest/routes/notes.ts +++ b/packages/lib/services/rest/routes/notes.ts @@ -306,7 +306,7 @@ export default async function(request: Request, id: string = null, link: string if (!note) throw new ErrorNotFound(); const resourceIds = await Note.linkedResourceIds(note.body); const output = []; - const loadOptions = defaultLoadOptions(request, BaseModel.TYPE_NOTE); + const loadOptions = defaultLoadOptions(request, BaseModel.TYPE_RESOURCE); for (const resourceId of resourceIds) { output.push(await Resource.load(resourceId, loadOptions)); } diff --git a/packages/lib/services/rest/routes/resources.ts b/packages/lib/services/rest/routes/resources.ts index 85d3c0de1d..0b00bb9d3d 100644 --- a/packages/lib/services/rest/routes/resources.ts +++ b/packages/lib/services/rest/routes/resources.ts @@ -7,7 +7,9 @@ import readonlyProperties from '../utils/readonlyProperties'; import ApiResponse from '../ApiResponse'; import NoteResource from '../../../models/NoteResource'; import collectionToPaginatedResults from '../utils/collectionToPaginatedResults'; +import defaultLoadOptions from '../utils/defaultLoadOptions'; const Resource = require('../../../models/Resource'); +const Note = require('../../../models/Note'); export default async function(request: Request, id: string = null, link: string = null) { // fieldName: "data" @@ -33,7 +35,13 @@ export default async function(request: Request, id: string = null, link: string } if (link === 'notes') { - return collectionToPaginatedResults(await NoteResource.associatedNoteIds(id), request); + const noteIds = await NoteResource.associatedNoteIds(id); + const loadOptions = defaultLoadOptions(request, BaseModel.TYPE_NOTE); + const notes = []; + for (const noteId of noteIds) { + notes.push(await Note.load(noteId, loadOptions)); + } + return collectionToPaginatedResults(notes, request); } if (link) throw new ErrorNotFound(); From 918b76863443f4f3e5f683005c4a3ae50b69189e Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 13 Nov 2020 22:03:10 +0000 Subject: [PATCH 08/11] Plugins: Fix crash when path includes trailing slash --- packages/app-cli/tests/services_PluginService.ts | 8 ++++++++ packages/lib/services/plugins/PluginService.ts | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/packages/app-cli/tests/services_PluginService.ts b/packages/app-cli/tests/services_PluginService.ts index 96454675c8..7eeb41a1af 100644 --- a/packages/app-cli/tests/services_PluginService.ts +++ b/packages/app-cli/tests/services_PluginService.ts @@ -44,6 +44,8 @@ describe('services_PluginService', function() { const service = newPluginService(); await service.loadAndRunPlugins([`${testPluginDir}/simple`]); + expect(() => service.pluginById('simple')).not.toThrowError(); + const allFolders = await Folder.all(); expect(allFolders.length).toBe(1); expect(allFolders[0].title).toBe('my plugin folder'); @@ -54,6 +56,12 @@ describe('services_PluginService', function() { expect(allNotes[0].parent_id).toBe(allFolders[0].id); })); + it('should load and run a simple plugin and handle trailing slash', asyncTest(async () => { + const service = newPluginService(); + await service.loadAndRunPlugins([`${testPluginDir}/simple/`]); + expect(() => service.pluginById('simple')).not.toThrowError(); + })); + it('should load and run a plugin that uses external packages', asyncTest(async () => { const service = newPluginService(); await service.loadAndRunPlugins([`${testPluginDir}/withExternalModules`]); diff --git a/packages/lib/services/plugins/PluginService.ts b/packages/lib/services/plugins/PluginService.ts index 96f7a38e70..5a74d7e98d 100644 --- a/packages/lib/services/plugins/PluginService.ts +++ b/packages/lib/services/plugins/PluginService.ts @@ -4,6 +4,7 @@ import Global from './api/Global'; import BasePluginRunner from './BasePluginRunner'; import BaseService from '../BaseService'; import shim from '../../shim'; +import { rtrimSlashes } from '../../path-utils'; const { filename, dirname } = require('../../path-utils'); const uslug = require('uslug'); @@ -86,11 +87,15 @@ export default class PluginService extends BaseService { } public async loadPluginFromString(pluginId: string, baseDir: string, jsBundleString: string): Promise { + baseDir = rtrimSlashes(baseDir); + const r = await this.parsePluginJsBundle(jsBundleString); return this.loadPlugin(pluginId, baseDir, r.manifestText, r.scriptText); } private async loadPluginFromPath(path: string): Promise { + path = rtrimSlashes(path); + const fsDriver = shim.fsDriver(); if (path.toLowerCase().endsWith('.js')) return this.loadPluginFromString(filename(path), dirname(path), await fsDriver.readFile(path)); @@ -110,6 +115,8 @@ export default class PluginService extends BaseService { } private async loadPlugin(pluginId: string, baseDir: string, manifestText: string, scriptText: string): Promise { + baseDir = rtrimSlashes(baseDir); + const manifest = manifestFromObject(JSON.parse(manifestText)); // After transforming the plugin path to an ID, multiple plugins might end up with the same ID. For From 872d2942b482ff8dc3dd4ebc30dbe12eb090401b Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 13 Nov 2020 22:29:28 +0000 Subject: [PATCH 09/11] All: Allow lowercase filters when doing search --- packages/lib/services/searchengine/filterParser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/lib/services/searchengine/filterParser.ts b/packages/lib/services/searchengine/filterParser.ts index 2e9b01ea4e..3eec4b225f 100644 --- a/packages/lib/services/searchengine/filterParser.ts +++ b/packages/lib/services/searchengine/filterParser.ts @@ -8,8 +8,8 @@ interface Term { } const makeTerm = (name: string, value: string): Term => { - if (name.startsWith('-')) { return { name: name.slice(1), value: value, negated: true }; } - return { name: name, value: value, negated: false }; + if (name.startsWith('-')) { return { name: name.slice(1).toLowerCase(), value: value, negated: true }; } + return { name: name.toLowerCase(), value: value, negated: false }; }; const quoted = (s: string) => s.startsWith('"') && s.endsWith('"'); From 4f41fb7b5408ca205a4e76be17e82ebdf7c4f72f Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Sat, 14 Nov 2020 00:02:17 +0000 Subject: [PATCH 10/11] Plugins: Add support for editor context menu --- .eslintignore | 15 +- .gitignore | 15 +- .../plugins/content_script/api/Joplin.d.ts | 12 + .../api/JoplinViewsDialogs.d.ts | 9 +- .../plugins/content_script/api/types.ts | 10 + .../support/plugins/dialog/api/Joplin.d.ts | 12 + .../dialog/api/JoplinViewsDialogs.d.ts | 9 +- .../tests/support/plugins/dialog/api/types.ts | 10 + .../plugins/editor_context_menu/.gitignore | 2 + .../plugins/editor_context_menu/README.md | 14 + .../editor_context_menu/api/Global.d.ts | 15 + .../editor_context_menu/api/Joplin.d.ts | 50 + .../api/JoplinCommands.d.ts | 61 + .../editor_context_menu/api/JoplinData.d.ts | 47 + .../api/JoplinFilters.d.ts | 10 + .../api/JoplinInterop.d.ts | 17 + .../api/JoplinPlugins.d.ts | 38 + .../api/JoplinSettings.d.ts | 43 + .../editor_context_menu/api/JoplinViews.d.ts | 28 + .../api/JoplinViewsDialogs.d.ts | 37 + .../api/JoplinViewsMenuItems.d.ts | 16 + .../api/JoplinViewsMenus.d.ts | 18 + .../api/JoplinViewsPanels.d.ts | 33 + .../api/JoplinViewsToolbarButtons.d.ts | 16 + .../api/JoplinWorkspace.d.ts | 34 + .../plugins/editor_context_menu/api/index.ts | 5 + .../plugins/editor_context_menu/api/types.ts | 370 ++ .../editor_context_menu/package-lock.json | 4544 +++++++++++++++++ .../plugins/editor_context_menu/package.json | 20 + .../plugins/editor_context_menu/src/index.ts | 16 + .../editor_context_menu/src/manifest.json | 8 + .../plugins/editor_context_menu/tsconfig.json | 10 + .../editor_context_menu/webpack.config.js | 44 + .../support/plugins/events/api/Joplin.d.ts | 12 + .../events/api/JoplinViewsDialogs.d.ts | 9 +- .../tests/support/plugins/events/api/types.ts | 10 + .../plugins/json_export/api/Joplin.d.ts | 12 + .../json_export/api/JoplinViewsDialogs.d.ts | 9 +- .../support/plugins/json_export/api/types.ts | 10 + .../support/plugins/menu/api/Joplin.d.ts | 12 + .../plugins/menu/api/JoplinViewsDialogs.d.ts | 9 +- .../tests/support/plugins/menu/api/types.ts | 10 + .../plugins/multi_selection/api/Joplin.d.ts | 12 + .../api/JoplinViewsDialogs.d.ts | 9 +- .../plugins/multi_selection/api/types.ts | 10 + .../tests/support/plugins/package.json | 19 + .../plugins/register_command/api/Joplin.d.ts | 12 + .../api/JoplinViewsDialogs.d.ts | 9 +- .../plugins/register_command/api/types.ts | 10 + .../plugins/selected_text/api/Joplin.d.ts | 12 + .../selected_text/api/JoplinViewsDialogs.d.ts | 9 +- .../plugins/selected_text/api/types.ts | 10 + .../support/plugins/settings/api/Joplin.d.ts | 12 + .../settings/api/JoplinViewsDialogs.d.ts | 9 +- .../support/plugins/settings/api/types.ts | 10 + .../tests/support/plugins/toc/api/Joplin.d.ts | 12 + .../plugins/toc/api/JoplinViewsDialogs.d.ts | 9 +- .../tests/support/plugins/toc/api/types.ts | 10 + .../tests/support/plugins/updatePlugins.sh | 1 + .../withExternalModules/api/Joplin.d.ts | 12 + .../api/JoplinViewsDialogs.d.ts | 9 +- .../plugins/withExternalModules/api/types.ts | 10 + packages/app-desktop/gui/MenuBar.tsx | 4 +- .../NoteBody/CodeMirror/CodeMirror.tsx | 19 +- .../NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx | 7 +- .../TinyMCE/utils/setupContextMenu.ts | 90 - .../NoteBody/TinyMCE/utils/useContextMenu.ts | 112 + .../app-desktop/gui/NoteEditor/NoteEditor.tsx | 11 +- .../commands/editorCommandDeclarations.ts | 3 + .../utils/useWindowCommandHandler.ts | 11 +- .../hooks/useLayoutItemSizes.js | 68 + .../hooks/useWindowResizeEvent.js | 18 + .../app-desktop/gui/utils/NoteListUtils.ts | 2 +- packages/app-desktop/testPluginDemo.sh | 2 +- packages/lib/services/commands/MenuUtils.ts | 16 + packages/lib/services/plugins/api/types.ts | 3 + packages/lib/tsconfig.json | 1 + 77 files changed, 6096 insertions(+), 158 deletions(-) create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/.gitignore create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/README.md create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/Global.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/Joplin.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinCommands.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinData.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinFilters.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinInterop.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinPlugins.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinSettings.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViews.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsDialogs.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsMenuItems.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsMenus.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsPanels.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsToolbarButtons.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinWorkspace.d.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/index.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/api/types.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/package-lock.json create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/package.json create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/src/index.ts create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/src/manifest.json create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/tsconfig.json create mode 100644 packages/app-cli/tests/support/plugins/editor_context_menu/webpack.config.js create mode 100644 packages/app-cli/tests/support/plugins/package.json delete mode 100644 packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupContextMenu.ts create mode 100644 packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts create mode 100644 packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.js create mode 100644 packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.js diff --git a/.eslintignore b/.eslintignore index 5544ec6d35..90dae9f86a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -208,6 +208,15 @@ packages/app-cli/tests/support/plugins/dialog/api/types.js.map packages/app-cli/tests/support/plugins/dialog/src/index.d.ts packages/app-cli/tests/support/plugins/dialog/src/index.js packages/app-cli/tests/support/plugins/dialog/src/index.js.map +packages/app-cli/tests/support/plugins/editor_context_menu/api/index.d.ts +packages/app-cli/tests/support/plugins/editor_context_menu/api/index.js +packages/app-cli/tests/support/plugins/editor_context_menu/api/index.js.map +packages/app-cli/tests/support/plugins/editor_context_menu/api/types.d.ts +packages/app-cli/tests/support/plugins/editor_context_menu/api/types.js +packages/app-cli/tests/support/plugins/editor_context_menu/api/types.js.map +packages/app-cli/tests/support/plugins/editor_context_menu/src/index.d.ts +packages/app-cli/tests/support/plugins/editor_context_menu/src/index.js +packages/app-cli/tests/support/plugins/editor_context_menu/src/index.js.map packages/app-cli/tests/support/plugins/events/api/index.d.ts packages/app-cli/tests/support/plugins/events/api/index.js packages/app-cli/tests/support/plugins/events/api/index.js.map @@ -499,9 +508,9 @@ packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.js.map packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.d.ts packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js.map -packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupContextMenu.d.ts -packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupContextMenu.js -packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupContextMenu.js.map +packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.d.ts +packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.js +packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.js.map packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.d.ts packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js.map diff --git a/.gitignore b/.gitignore index ce533605be..51435a597e 100644 --- a/.gitignore +++ b/.gitignore @@ -200,6 +200,15 @@ packages/app-cli/tests/support/plugins/dialog/api/types.js.map packages/app-cli/tests/support/plugins/dialog/src/index.d.ts packages/app-cli/tests/support/plugins/dialog/src/index.js packages/app-cli/tests/support/plugins/dialog/src/index.js.map +packages/app-cli/tests/support/plugins/editor_context_menu/api/index.d.ts +packages/app-cli/tests/support/plugins/editor_context_menu/api/index.js +packages/app-cli/tests/support/plugins/editor_context_menu/api/index.js.map +packages/app-cli/tests/support/plugins/editor_context_menu/api/types.d.ts +packages/app-cli/tests/support/plugins/editor_context_menu/api/types.js +packages/app-cli/tests/support/plugins/editor_context_menu/api/types.js.map +packages/app-cli/tests/support/plugins/editor_context_menu/src/index.d.ts +packages/app-cli/tests/support/plugins/editor_context_menu/src/index.js +packages/app-cli/tests/support/plugins/editor_context_menu/src/index.js.map packages/app-cli/tests/support/plugins/events/api/index.d.ts packages/app-cli/tests/support/plugins/events/api/index.js packages/app-cli/tests/support/plugins/events/api/index.js.map @@ -491,9 +500,9 @@ packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.js.map packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.d.ts packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js.map -packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupContextMenu.d.ts -packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupContextMenu.js -packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupContextMenu.js.map +packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.d.ts +packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.js +packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.js.map packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.d.ts packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js.map diff --git a/packages/app-cli/tests/support/plugins/content_script/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/content_script/api/types.ts b/packages/app-cli/tests/support/plugins/content_script/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/content_script/api/types.ts +++ b/packages/app-cli/tests/support/plugins/content_script/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-cli/tests/support/plugins/dialog/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/dialog/api/types.ts b/packages/app-cli/tests/support/plugins/dialog/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/dialog/api/types.ts +++ b/packages/app-cli/tests/support/plugins/dialog/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/.gitignore b/packages/app-cli/tests/support/plugins/editor_context_menu/.gitignore new file mode 100644 index 0000000000..2195be3d80 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/.gitignore @@ -0,0 +1,2 @@ +dist/* +node_modules/ \ No newline at end of file diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/README.md b/packages/app-cli/tests/support/plugins/editor_context_menu/README.md new file mode 100644 index 0000000000..afbea1bd18 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/README.md @@ -0,0 +1,14 @@ +# Joplin Plugin + +This is a template to create a new Joplin plugin. + +The main two files you will want to look at are: + +- `/src/index.ts`, which contains the entry point for the plugin source code. +- `/src/manifest.json`, which is the plugin manifest. It contains information such as the plugin a name, version, etc. + +The plugin is built using webpack, which create the compiled code in `/dist`. The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript. + +## Building the plugin + +To build the plugin, simply run `npm run dist`. diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/Global.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/Global.d.ts new file mode 100644 index 0000000000..f6a0078fa2 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/Global.d.ts @@ -0,0 +1,15 @@ +import Plugin from '../Plugin'; +import Joplin from './Joplin'; +import Logger from '../../../Logger'; +/** + * @ignore + */ +export default class Global { + private joplin_; + private requireWhiteList_; + constructor(logger: Logger, implementation: any, plugin: Plugin, store: any); + get joplin(): Joplin; + private requireWhiteList; + require(filePath: string): any; + get process(): any; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/Joplin.d.ts new file mode 100644 index 0000000000..74494aea09 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/Joplin.d.ts @@ -0,0 +1,50 @@ +import Plugin from '../Plugin'; +import JoplinData from './JoplinData'; +import JoplinPlugins from './JoplinPlugins'; +import JoplinWorkspace from './JoplinWorkspace'; +import JoplinFilters from './JoplinFilters'; +import JoplinCommands from './JoplinCommands'; +import JoplinViews from './JoplinViews'; +import JoplinInterop from './JoplinInterop'; +import JoplinSettings from './JoplinSettings'; +import Logger from '../../../Logger'; +/** + * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. + */ +export default class Joplin { + private data_; + private plugins_; + private workspace_; + private filters_; + private commands_; + private views_; + private interop_; + private settings_; + constructor(logger: Logger, implementation: any, plugin: Plugin, store: any); + get data(): JoplinData; + get plugins(): JoplinPlugins; + get workspace(): JoplinWorkspace; + /** + * @ignore + * + * Not sure if it's the best way to hook into the app + * so for now disable filters. + */ + get filters(): JoplinFilters; + get commands(): JoplinCommands; + get views(): JoplinViews; + get interop(): JoplinInterop; + get settings(): JoplinSettings; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinCommands.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinCommands.d.ts new file mode 100644 index 0000000000..8a9f30451c --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinCommands.d.ts @@ -0,0 +1,61 @@ +import { Command } from './types'; +/** + * This class allows executing or registering new Joplin commands. Commands + * can be executed or associated with + * {@link JoplinViewsToolbarButtons | toolbar buttons} or + * {@link JoplinViewsMenuItems | menu items}. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) + * + * ## Executing Joplin's internal commands + * + * It is also possible to execute internal Joplin's commands which, as of + * now, are not well documented. You can find the list directly on GitHub + * though at the following locations: + * + * * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands) + * * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands) + * * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts) + * + * To view what arguments are supported, you can open any of these files + * and look at the `execute()` command. + */ +export default class JoplinCommands { + /** + * desktop Executes the given + * command. + * + * The command can take any number of arguments, and the supported + * arguments will vary based on the command. For custom commands, this + * is the `args` passed to the `execute()` function. For built-in + * commands, you can find the supported arguments by checking the links + * above. + * + * ```typescript + * // Create a new note in the current notebook: + * await joplin.commands.execute('newNote'); + * + * // Create a new sub-notebook under the provided notebook + * // Note: internally, notebooks are called "folders". + * await joplin.commands.execute('newFolder', "SOME_FOLDER_ID"); + * ``` + */ + execute(commandName: string, ...args: any[]): Promise; + /** + * desktop Registers a new command. + * + * ```typescript + * // Register a new commmand called "testCommand1" + * + * await joplin.commands.register({ + * name: 'testCommand1', + * label: 'My Test Command 1', + * iconName: 'fas fa-music', + * execute: () => { + * alert('Testing plugin command 1'); + * }, + * }); + * ``` + */ + register(command: Command): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinData.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinData.d.ts new file mode 100644 index 0000000000..fbde6ff9a0 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinData.d.ts @@ -0,0 +1,47 @@ +import { Path } from './types'; +/** + * This module provides access to the Joplin data API: https://joplinapp.org/api/references/rest_api/ + * This is the main way to retrieve data, such as notes, notebooks, tags, etc. + * or to update them or delete them. + * + * This is also what you would use to search notes, via the `search` endpoint. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple) + * + * In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls. + * And each method takes these parameters: + * + * * `path`: This is an array that represents the path to the resource in the form `["resouceName", "resourceId", "resourceLink"]` (eg. ["tags", ":id", "notes"]). The "resources" segment is the name of the resources you want to access (eg. "notes", "folders", etc.). If not followed by anything, it will refer to all the resources in that collection. The optional "resourceId" points to a particular resources within the collection. Finally, an optional "link" can be present, which links the resource to a collection of resources. This can be used in the API for example to retrieve all the notes associated with a tag. + * * `query`: (Optional) The query parameters. In a URL, this is the part after the question mark "?". In this case, it should be an object with key/value pairs. + * * `data`: (Optional) Applies to PUT and POST calls only. The request body contains the data you want to create or modify, for example the content of a note or folder. + * * `files`: (Optional) Used to create new resources and associate them with files. + * + * Please refer to the [Joplin API documentation](https://joplinapp.org/api/references/rest_api/) for complete details about each call. As the plugin runs within the Joplin application **you do not need an authorisation token** to use this API. + * + * For example: + * + * ```typescript + * // Get a note ID, title and body + * const noteId = 'some_note_id'; + * const note = await joplin.data.get(['notes', noteId], { fields: ['id', 'title', 'body'] }); + * + * // Get all folders + * const folders = await joplin.data.get(['folders']); + * + * // Set the note body + * await joplin.data.put(['notes', noteId], null, { body: "New note body" }); + * + * // Create a new note under one of the folders + * await joplin.data.post(['notes'], null, { body: "my new note", title: "some title", parent_id: folders[0].id }); + * ``` + */ +export default class JoplinData { + private api_; + private pathSegmentRegex_; + private serializeApiBody; + private pathToString; + get(path: Path, query?: any): Promise; + post(path: Path, query?: any, body?: any, files?: any[]): Promise; + put(path: Path, query?: any, body?: any, files?: any[]): Promise; + delete(path: Path, query?: any): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinFilters.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinFilters.d.ts new file mode 100644 index 0000000000..43bc1b2b70 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinFilters.d.ts @@ -0,0 +1,10 @@ +/** + * @ignore + * + * Not sure if it's the best way to hook into the app + * so for now disable filters. + */ +export default class JoplinFilters { + on(name: string, callback: Function): Promise; + off(name: string, callback: Function): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinInterop.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinInterop.d.ts new file mode 100644 index 0000000000..8de655c83a --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinInterop.d.ts @@ -0,0 +1,17 @@ +import { ExportModule, ImportModule } from './types'; +/** + * Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) + * + * To implement an import or export module, you would simply define an object with various event handlers that are called + * by the application during the import/export process. + * + * See the documentation of the [[ExportModule]] and [[ImportModule]] for more information. + * + * You may also want to refer to the Joplin API documentation to see the list of properties for each item (note, notebook, etc.) - https://joplinapp.org/api/references/rest_api/ + */ +export default class JoplinInterop { + registerExportModule(module: ExportModule): Promise; + registerImportModule(module: ImportModule): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinPlugins.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinPlugins.d.ts new file mode 100644 index 0000000000..fc9fda6a36 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinPlugins.d.ts @@ -0,0 +1,38 @@ +import Plugin from '../Plugin'; +import Logger from '../../../Logger'; +import { ContentScriptType, Script } from './types'; +/** + * This class provides access to plugin-related features. + */ +export default class JoplinPlugins { + private logger; + private plugin; + constructor(logger: Logger, plugin: Plugin); + /** + * Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it. + * That `onStart` method will be executed as soon as the plugin is loaded. + * + * ```typescript + * joplin.plugins.register({ + * onStart: async function() { + * // Run your plugin code here + * } + * }); + * ``` + */ + register(script: Script): Promise; + /** + * Registers a new content script. Unlike regular plugin code, which runs in a separate process, content scripts run within the main process code + * and thus allow improved performances and more customisations in specific cases. It can be used for example to load a Markdown or editor plugin. + * + * Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules + * (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script) + * + * @param type Defines how the script will be used. See the type definition for more information about each supported type. + * @param id A unique ID for the content script. + * @param scriptPath Must be a path relative to the plugin main script. For example, if your file content_script.js is next to your index.ts file, you would set `scriptPath` to `"./content_script.js`. + */ + registerContentScript(type: ContentScriptType, id: string, scriptPath: string): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinSettings.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinSettings.d.ts new file mode 100644 index 0000000000..0fa39d9640 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinSettings.d.ts @@ -0,0 +1,43 @@ +import Plugin from '../Plugin'; +import { SettingItem, SettingSection } from './types'; +/** + * This API allows registering new settings and setting sections, as well as getting and setting settings. Once a setting has been registered it will appear in the config screen and be editable by the user. + * + * Settings are essentially key/value pairs. + * + * Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings) + */ +export default class JoplinSettings { + private plugin_; + constructor(plugin: Plugin); + private namespacedKey; + /** + * Registers a new setting. Note that registering a setting item is dynamic and will be gone next time Joplin starts. + * What it means is that you need to register the setting every time the plugin starts (for example in the onStart event). + * The setting value however will be preserved from one launch to the next so there is no risk that it will be lost even if for some + * reason the plugin fails to start at some point. + */ + registerSetting(key: string, settingItem: SettingItem): Promise; + /** + * Registers a new setting section. Like for registerSetting, it is dynamic and needs to be done every time the plugin starts. + */ + registerSection(name: string, section: SettingSection): Promise; + /** + * Gets a setting value (only applies to setting you registered from your plugin) + */ + value(key: string): Promise; + /** + * Sets a setting value (only applies to setting you registered from your plugin) + */ + setValue(key: string, value: any): Promise; + /** + * Gets a global setting value, including app-specific settings and those set by other plugins. + * + * The list of available settings is not documented yet, but can be found by looking at the source code: + * + * https://github.com/laurent22/joplin/blob/3539a452a359162c461d2849829d2d42973eab50/packages/app-mobile/lib/models/Setting.ts#L142 + */ + globalValue(key: string): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViews.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViews.d.ts new file mode 100644 index 0000000000..235eabfe11 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViews.d.ts @@ -0,0 +1,28 @@ +import Plugin from '../Plugin'; +import JoplinViewsDialogs from './JoplinViewsDialogs'; +import JoplinViewsMenuItems from './JoplinViewsMenuItems'; +import JoplinViewsMenus from './JoplinViewsMenus'; +import JoplinViewsToolbarButtons from './JoplinViewsToolbarButtons'; +import JoplinViewsPanels from './JoplinViewsPanels'; +/** + * This namespace provides access to view-related services. + * + * All view services provide a `create()` method which you would use to create the view object, whether it's a dialog, a toolbar button or a menu item. + * In some cases, the `create()` method will return a [[ViewHandle]], which you would use to act on the view, for example to set certain properties or call some methods. + */ +export default class JoplinViews { + private store; + private plugin; + private dialogs_; + private panels_; + private menuItems_; + private menus_; + private toolbarButtons_; + private implementation_; + constructor(implementation: any, plugin: Plugin, store: any); + get dialogs(): JoplinViewsDialogs; + get panels(): JoplinViewsPanels; + get menuItems(): JoplinViewsMenuItems; + get menus(): JoplinViewsMenus; + get toolbarButtons(): JoplinViewsToolbarButtons; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsDialogs.d.ts new file mode 100644 index 0000000000..5956c0eca4 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsDialogs.d.ts @@ -0,0 +1,37 @@ +import Plugin from '../Plugin'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; +/** + * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) + */ +export default class JoplinViewsDialogs { + private store; + private plugin; + private implementation_; + constructor(implementation: any, plugin: Plugin, store: any); + private controller; + /** + * Creates a new dialog + */ + create(id: string): Promise; + /** + * Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel" + */ + showMessageBox(message: string): Promise; + /** + * Sets the dialog HTML content + */ + setHtml(handle: ViewHandle, html: string): Promise; + /** + * Sets the dialog buttons. + */ + setButtons(handle: ViewHandle, buttons: ButtonSpec[]): Promise; + /** + * Opens the dialog + */ + open(handle: ViewHandle): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsMenuItems.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsMenuItems.d.ts new file mode 100644 index 0000000000..69e2a8f181 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsMenuItems.d.ts @@ -0,0 +1,16 @@ +import { CreateMenuItemOptions, MenuItemLocation } from './types'; +import Plugin from '../Plugin'; +/** + * Allows creating and managing menu items. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) + */ +export default class JoplinViewsMenuItems { + private store; + private plugin; + constructor(plugin: Plugin, store: any); + /** + * Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter. + */ + create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsMenus.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsMenus.d.ts new file mode 100644 index 0000000000..f5f803cb1b --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsMenus.d.ts @@ -0,0 +1,18 @@ +import { MenuItem, MenuItemLocation } from './types'; +import Plugin from '../Plugin'; +/** + * Allows creating menus. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu) + */ +export default class JoplinViewsMenus { + private store; + private plugin; + constructor(plugin: Plugin, store: any); + private registerCommandAccelerators; + /** + * Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the + * menu as a sub-menu of the application build-in menus. + */ + create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsPanels.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsPanels.d.ts new file mode 100644 index 0000000000..3646269eeb --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsPanels.d.ts @@ -0,0 +1,33 @@ +import Plugin from '../Plugin'; +import { ViewHandle } from './types'; +/** + * Allows creating and managing view panels. View panels currently are + * displayed at the right of the sidebar and allows displaying any HTML + * content (within a webview) and update it in real-time. For example it + * could be used to display a table of content for the active note, or + * display various metadata or graph. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc) + */ +export default class JoplinViewsPanels { + private store; + private plugin; + constructor(plugin: Plugin, store: any); + private controller; + /** + * Creates a new panel + */ + create(id: string): Promise; + /** + * Sets the panel webview HTML + */ + setHtml(handle: ViewHandle, html: string): Promise; + /** + * Adds and loads a new JS or CSS files into the panel. + */ + addScript(handle: ViewHandle, scriptPath: string): Promise; + /** + * Called when a message is sent from the webview (using postMessage). + */ + onMessage(handle: ViewHandle, callback: Function): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsToolbarButtons.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsToolbarButtons.d.ts new file mode 100644 index 0000000000..ba17c83e34 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinViewsToolbarButtons.d.ts @@ -0,0 +1,16 @@ +import { ToolbarButtonLocation } from './types'; +import Plugin from '../Plugin'; +/** + * Allows creating and managing toolbar buttons. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command) + */ +export default class JoplinViewsToolbarButtons { + private store; + private plugin; + constructor(plugin: Plugin, store: any); + /** + * Creates a new toolbar button and associate it with the given command. + */ + create(id: string, commandName: string, location: ToolbarButtonLocation): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinWorkspace.d.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinWorkspace.d.ts new file mode 100644 index 0000000000..0686d32a9c --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/JoplinWorkspace.d.ts @@ -0,0 +1,34 @@ +/** + * The workspace service provides access to all the parts of Joplin that are being worked on - i.e. the currently selected notes or notebooks as well + * as various related events, such as when a new note is selected, or when the note content changes. + * + * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins) + */ +export default class JoplinWorkspace { + private store; + constructor(_implementation: any, store: any); + /** + * Called when a new note or notes are selected. + */ + onNoteSelectionChange(callback: Function): Promise; + /** + * Called when the content of a note changes. + */ + onNoteContentChange(callback: Function): Promise; + /** + * Called when an alarm associated with a to-do is triggered. + */ + onNoteAlarmTrigger(callback: Function): Promise; + /** + * Called when the synchronisation process has finished. + */ + onSyncComplete(callback: Function): Promise; + /** + * Gets the currently selected note + */ + selectedNote(): Promise; + /** + * Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes. + */ + selectedNoteIds(): Promise; +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/index.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/index.ts new file mode 100644 index 0000000000..1158f1ed4d --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/index.ts @@ -0,0 +1,5 @@ +import type Joplin from './Joplin'; + +declare const joplin:Joplin; + +export default joplin; diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/api/types.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/api/types.ts new file mode 100644 index 0000000000..ee3e94ae68 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/api/types.ts @@ -0,0 +1,370 @@ +// ================================================================= +// Command API types +// ================================================================= + +export interface Command { + /** + * Name of command - must be globally unique + */ + name: string; + + /** + * Label to be displayed on menu items or keyboard shortcut editor for example. + * If it is missing, it's assumed it's a private command, to be called programmatically only. + * In that case the command will not appear in the shortcut editor or command panel, and logically + * should not be used as a menu item. + */ + label?: string; + + /** + * Icon to be used on toolbar buttons for example + */ + iconName?: string; + + /** + * Code to be ran when the command is executed. It may return a result. + */ + execute(...args: any[]): Promise; + + /** + * Defines whether the command should be enabled or disabled, which in turns affects + * the enabled state of any associated button or menu item. + * + * The condition should be expressed as a "when-clause" (as in Visual Studio Code). It's a simple boolean expression that evaluates to + * `true` or `false`. It supports the following operators: + * + * Operator | Symbol | Example + * -- | -- | -- + * Equality | == | "editorType == markdown" + * Inequality | != | "currentScreen != config" + * Or | \|\| | "noteIsTodo \|\| noteTodoCompleted" + * And | && | "oneNoteSelected && !inConflictFolder" + * + * Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/services/commands/stateToWhenClauseContext.ts). + * + * Note: Commands are enabled by default unless you use this property. + */ + enabledCondition?: string; +} + +// ================================================================= +// Interop API types +// ================================================================= + +export enum FileSystemItem { + File = 'file', + Directory = 'directory', +} + +export enum ImportModuleOutputFormat { + Markdown = 'md', + Html = 'html', +} + +/** + * Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example. + * + * In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported. + * + * To get a better sense of what it will contain it can be useful to print it using `console.info(context)`. + */ +export interface ExportModule { + /** + * The format to be exported, eg "enex", "jex", "json", etc. + */ + format: string; + + /** + * The description that will appear in the UI, for example in the menu item. + */ + description: string; + + /** + * Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter. + */ + target: FileSystemItem; + + /** + * Only applies to single file exporters or importers + * It tells whether the format can package multiple notes into one file. + * For example JEX or ENEX can, but HTML cannot. + */ + isNoteArchive: boolean; + + /** + * The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module. + */ + fileExtensions?: string[]; + + /** + * Called when the export process starts. + */ + onInit(context: ExportContext): Promise; + + /** + * Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc. + */ + onProcessItem(context: ExportContext, itemType: number, item: any): Promise; + + /** + * Called when a resource file needs to be exported. + */ + onProcessResource(context: ExportContext, resource: any, filePath: string): Promise; + + /** + * Called when the export process is done. + */ + onClose(context: ExportContext): Promise; +} + +export interface ImportModule { + /** + * The format to be exported, eg "enex", "jex", "json", etc. + */ + format: string; + + /** + * The description that will appear in the UI, for example in the menu item. + */ + description: string; + + /** + * Only applies to single file exporters or importers + * It tells whether the format can package multiple notes into one file. + * For example JEX or ENEX can, but HTML cannot. + */ + isNoteArchive: boolean; + + /** + * The type of sources that are supported by the module. Tells whether the module can import files or directories or both. + */ + sources: FileSystemItem[]; + + /** + * Tells the file extensions of the exported files. + */ + fileExtensions?: string[]; + + /** + * Tells the type of notes that will be generated, either HTML or Markdown (default). + */ + outputFormat?: ImportModuleOutputFormat; + + /** + * Called when the import process starts. There is only one event handler within which you should import the complete data. + */ + onExec(context: ImportContext): Promise; +} + +export interface ExportOptions { + format?: string; + path?: string; + sourceFolderIds?: string[]; + sourceNoteIds?: string[]; + modulePath?: string; + target?: FileSystemItem; +} + +export interface ExportContext { + destPath: string; + options: ExportOptions; + + /** + * You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next. + */ + userData?: any; +} + +export interface ImportContext { + sourcePath: string; + options: any; + warnings: string[]; +} + +// ================================================================= +// Misc types +// ================================================================= + +export interface Script { + onStart?(event: any): Promise; +} + +// ================================================================= +// Menu types +// ================================================================= + +export interface CreateMenuItemOptions { + accelerator: string; +} + +export enum MenuItemLocation { + File = 'file', + Edit = 'edit', + View = 'view', + Note = 'note', + Tools = 'tools', + Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ + Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', +} + +export interface MenuItem { + /** + * Command that should be associated with the menu item. All menu item should + * have a command associated with them unless they are a sub-menu. + */ + commandName?: string; + + /** + * Accelerator associated with the menu item + */ + accelerator?: string; + + /** + * Menu items that should appear below this menu item. Allows creating a menu tree. + */ + submenu?: MenuItem[]; + + /** + * Menu item label. If not specified, the command label will be used instead. + */ + label?: string; +} + +// ================================================================= +// View API types +// ================================================================= + +export interface ButtonSpec { + id: ButtonId; + title?: string; + onClick?(): void; +} + +export type ButtonId = string; + +export enum ToolbarButtonLocation { + /** + * This toolbar in the top right corner of the application. It applies to the note as a whole, including its metadata. + */ + NoteToolbar = 'noteToolbar', + + /** + * This toolbar is right above the text editor. It applies to the note body only. + */ + EditorToolbar = 'editorToolbar', +} + +export type ViewHandle = string; + +export interface EditorCommand { + name: string; + value?: any; +} + +export interface DialogResult { + id: ButtonId; + formData?: any; +} + +// ================================================================= +// Settings types +// ================================================================= + +export enum SettingItemType { + Int = 1, + String = 2, + Bool = 3, + Array = 4, + Object = 5, + Button = 6, +} + +// Redefine a simplified interface to mask internal details +// and to remove function calls as they would have to be async. +export interface SettingItem { + value: any; + type: SettingItemType; + public: boolean; + label: string; + + description?: string; + isEnum?: boolean; + section?: string; + options?: any; + appTypes?: string[]; + secure?: boolean; + advanced?: boolean; + minimum?: number; + maximum?: number; + step?: number; +} + +export interface SettingSection { + label: string; + iconName?: string; + description?: string; + name?: string; +} + +// ================================================================= +// Data API types +// ================================================================= + +/** + * An array of at least one element and at most three elements. + * + * [0]: Resource name (eg. "notes", "folders", "tags", etc.) + * [1]: (Optional) Resource ID. + * [2]: (Optional) Resource link. + */ +export type Path = string[]; + +// ================================================================= +// Plugins type +// ================================================================= + +export enum ContentScriptType { + /** + * Registers a new Markdown-It plugin, which should follow the template below. + * + * ```javascript + * module.exports = { + * default: function(context) { + * return { + * plugin: function(markdownIt, options) { + * // ... + * }, + * assets: { + * // ... + * }, + * } + * } + * } + * ``` + * + * - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate. + * + * - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code. + * + * - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/app-mobile/lib/joplin-renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured. + * + * To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this: + * + * ```javascript + * module.exports = { + * default: function(context) { + * return { + * plugin: require('markdown-it-toc-done-right'); + * } + * } + * } + * ``` + */ + MarkdownItPlugin = 'markdownItPlugin', + CodeMirrorPlugin = 'codeMirrorPlugin', +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/package-lock.json b/packages/app-cli/tests/support/plugins/editor_context_menu/package-lock.json new file mode 100644 index 0000000000..bbbbd32d4a --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/package-lock.json @@ -0,0 +1,4544 @@ +{ + "name": "joplin_plugin", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@npmcli/move-file": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", + "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4" + } + }, + "@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "dev": true + }, + "@types/node": { + "version": "14.14.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.7.tgz", + "integrity": "sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true, + "optional": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true, + "optional": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "cacache": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz", + "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==", + "dev": true, + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.0", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-webpack-plugin": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.3.1.tgz", + "integrity": "sha512-SyIMdP6H3v+zPU+VIhKRsK0ZEF82KZ93JBlKOoIW8SkkuI84FSrHxG+aMTE1u4csbi9PLRqqWTIK+bfJ2xsFuQ==", + "dev": true, + "requires": { + "cacache": "^15.0.5", + "fast-glob": "^3.2.4", + "find-cache-dir": "^3.3.1", + "glob-parent": "^5.1.1", + "globby": "^11.0.1", + "loader-utils": "^2.0.0", + "normalize-path": "^3.0.0", + "p-limit": "^3.0.2", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", + "webpack-sources": "^1.4.3" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "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" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", + "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "events": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fastq": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz", + "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true, + "optional": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true, + "optional": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-parallel": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", + "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", + "dev": true + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "ssri": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", + "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "tar": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", + "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + }, + "terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-loader": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz", + "integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "optional": true + }, + "uri-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8-compile-cache": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "dev": true, + "requires": { + "chokidar": "^3.4.1", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.1" + } + }, + "watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "optional": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "optional": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "optional": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "optional": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "webpack": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", + "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.3.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/package.json b/packages/app-cli/tests/support/plugins/editor_context_menu/package.json new file mode 100644 index 0000000000..2d9b8a3e83 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/package.json @@ -0,0 +1,20 @@ +{ + "name": "joplin_plugin", + "version": "1.0.0", + "description": "", + "scripts": { + "dist": "webpack", + "postinstall": "npm run dist" + }, + "keywords": [], + "author": "", + "license": "MIT", + "devDependencies": { + "@types/node": "^14.0.14", + "copy-webpack-plugin": "^6.1.0", + "ts-loader": "^7.0.5", + "typescript": "^3.9.3", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.11" + } +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/src/index.ts b/packages/app-cli/tests/support/plugins/editor_context_menu/src/index.ts new file mode 100644 index 0000000000..596698de26 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/src/index.ts @@ -0,0 +1,16 @@ +import joplin from 'api'; +import { MenuItemLocation } from 'api/types'; + +joplin.plugins.register({ + onStart: async function() { + await joplin.commands.register({ + name: 'sayHi', + label: 'Say Hi', + execute: async () => { + await joplin.commands.execute('replaceSelection', 'hi!'); + }, + }); + + await joplin.views.menuItems.create('myContextMenuItem', 'sayHi', MenuItemLocation.EditorContextMenu); + }, +}); diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/src/manifest.json b/packages/app-cli/tests/support/plugins/editor_context_menu/src/manifest.json new file mode 100644 index 0000000000..b4b86089f0 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/src/manifest.json @@ -0,0 +1,8 @@ +{ + "manifest_version": 1, + "name": "Editor Context Menu Demo", + "description": "", + "version": "1.0.0", + "author": "", + "homepage_url": "" +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/tsconfig.json b/packages/app-cli/tests/support/plugins/editor_context_menu/tsconfig.json new file mode 100644 index 0000000000..4474cab3d9 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "module": "commonjs", + "target": "es2015", + "jsx": "react", + "allowJs": true, + "baseUrl": "." + } +} diff --git a/packages/app-cli/tests/support/plugins/editor_context_menu/webpack.config.js b/packages/app-cli/tests/support/plugins/editor_context_menu/webpack.config.js new file mode 100644 index 0000000000..c3d740c885 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/editor_context_menu/webpack.config.js @@ -0,0 +1,44 @@ +const path = require('path'); +const CopyPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'production', + entry: './src/index.ts', + target: 'node', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + alias: { + api: path.resolve(__dirname, 'api') + }, + extensions: [ '.tsx', '.ts', '.js' ], + }, + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CopyPlugin({ + patterns: [ + { + from: "**/*", + context: path.resolve(__dirname, 'src'), + to: path.resolve(__dirname, 'dist'), + globOptions: { + ignore: [ + '**/*.ts', + '**/*.tsx', + ], + }, + }, + ], + }), + ], +}; diff --git a/packages/app-cli/tests/support/plugins/events/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/events/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/events/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/events/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/events/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/events/api/types.ts b/packages/app-cli/tests/support/plugins/events/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/events/api/types.ts +++ b/packages/app-cli/tests/support/plugins/events/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-cli/tests/support/plugins/json_export/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/json_export/api/types.ts b/packages/app-cli/tests/support/plugins/json_export/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/json_export/api/types.ts +++ b/packages/app-cli/tests/support/plugins/json_export/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-cli/tests/support/plugins/menu/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/menu/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/menu/api/types.ts b/packages/app-cli/tests/support/plugins/menu/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/menu/api/types.ts +++ b/packages/app-cli/tests/support/plugins/menu/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/multi_selection/api/types.ts b/packages/app-cli/tests/support/plugins/multi_selection/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/multi_selection/api/types.ts +++ b/packages/app-cli/tests/support/plugins/multi_selection/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-cli/tests/support/plugins/package.json b/packages/app-cli/tests/support/plugins/package.json new file mode 100644 index 0000000000..d6ea7ffccc --- /dev/null +++ b/packages/app-cli/tests/support/plugins/package.json @@ -0,0 +1,19 @@ +{ + "name": "test_plugin", + "version": "1.0.0", + "description": "", + "scripts": { + "dist": "webpack" + }, + "keywords": [], + "author": "", + "license": "MIT", + "devDependencies": { + "@types/node": "^14.0.14", + "copy-webpack-plugin": "^6.0.3", + "ts-loader": "^7.0.5", + "typescript": "^3.9.3", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.11" + } + } \ No newline at end of file diff --git a/packages/app-cli/tests/support/plugins/register_command/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/register_command/api/types.ts b/packages/app-cli/tests/support/plugins/register_command/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/register_command/api/types.ts +++ b/packages/app-cli/tests/support/plugins/register_command/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/selected_text/api/types.ts b/packages/app-cli/tests/support/plugins/selected_text/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/selected_text/api/types.ts +++ b/packages/app-cli/tests/support/plugins/selected_text/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-cli/tests/support/plugins/settings/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/settings/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/settings/api/types.ts b/packages/app-cli/tests/support/plugins/settings/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/settings/api/types.ts +++ b/packages/app-cli/tests/support/plugins/settings/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-cli/tests/support/plugins/toc/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/toc/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/toc/api/types.ts b/packages/app-cli/tests/support/plugins/toc/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/toc/api/types.ts +++ b/packages/app-cli/tests/support/plugins/toc/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-cli/tests/support/plugins/updatePlugins.sh b/packages/app-cli/tests/support/plugins/updatePlugins.sh index 842da54a57..ae315cc19d 100755 --- a/packages/app-cli/tests/support/plugins/updatePlugins.sh +++ b/packages/app-cli/tests/support/plugins/updatePlugins.sh @@ -15,6 +15,7 @@ rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-l rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/multi_selection/" rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/register_command/" rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/selected_text/" +rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/editor_context_menu/" rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/settings/" rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/toc/" rsync -a --delete --exclude "src/" --exclude "package.json" --exclude "package-lock.json" --exclude "node_modules/" --exclude "dist/" "$TEMP_DIR/" "$SCRIPT_DIR/withExternalModules/" diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/Joplin.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/Joplin.d.ts index b6ed5824ce..74494aea09 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/Joplin.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/Joplin.d.ts @@ -10,6 +10,18 @@ import JoplinSettings from './JoplinSettings'; import Logger from '../../../Logger'; /** * This is the main entry point to the Joplin API. You can access various services using the provided accessors. + * + * **This is a beta API** + * + * Please note that the plugin API is relatively new and should be considered Beta state. Besides possible bugs, what it means is that there might be necessary breaking changes from one version to the next. Whenever such change is needed, best effort will be done to: + * + * - Maintain backward compatibility; + * - When possible, deprecate features instead of removing them; + * - Document breaking changes in the changelog; + * + * So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code. There won't be any major API rewrite or architecture changes, but possibly small tweaks like function signature change, type change, etc. + * + * Eventually, the plugin API will be versioned to make this process smoother. */ export default class Joplin { private data_; diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsDialogs.d.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsDialogs.d.ts index 7a9f8e941f..5956c0eca4 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsDialogs.d.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/JoplinViewsDialogs.d.ts @@ -1,9 +1,10 @@ import Plugin from '../Plugin'; -import { ButtonSpec, ViewHandle, ButtonId } from './types'; +import { ButtonSpec, ViewHandle, DialogResult } from './types'; /** * Allows creating and managing dialogs. A dialog is modal window that contains a webview and a row of buttons. You can update the update the webview using the `setHtml` method. - * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return and provide the button ID that was - * clicked on. There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. + * Dialogs are hidden by default and you need to call `open()` to open them. Once the user clicks on a button, the `open` call will return an object indicating what button was clicked + * on. If your HTML content included one or more form, a `formData` object will also be included with the key/value for each form. + * There is currently no "close" method since the dialog should be thought as a modal one and thus can only be closed by clicking on one of the buttons. * * [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog) */ @@ -32,5 +33,5 @@ export default class JoplinViewsDialogs { /** * Opens the dialog */ - open(handle: ViewHandle): Promise; + open(handle: ViewHandle): Promise; } diff --git a/packages/app-cli/tests/support/plugins/withExternalModules/api/types.ts b/packages/app-cli/tests/support/plugins/withExternalModules/api/types.ts index e4da323694..ee3e94ae68 100644 --- a/packages/app-cli/tests/support/plugins/withExternalModules/api/types.ts +++ b/packages/app-cli/tests/support/plugins/withExternalModules/api/types.ts @@ -204,7 +204,12 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + /* + * Deprecated - do not use - same as NoteListContext + */ Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { @@ -261,6 +266,11 @@ export interface EditorCommand { value?: any; } +export interface DialogResult { + id: ButtonId; + formData?: any; +} + // ================================================================= // Settings types // ================================================================= diff --git a/packages/app-desktop/gui/MenuBar.tsx b/packages/app-desktop/gui/MenuBar.tsx index afa6ef9c4e..fb49e65fbf 100644 --- a/packages/app-desktop/gui/MenuBar.tsx +++ b/packages/app-desktop/gui/MenuBar.tsx @@ -697,7 +697,7 @@ function useMenu(props: Props) { for (const view of props.pluginMenuItems) { const location: MenuItemLocation = view.location; - if (location === MenuItemLocation.Context) continue; + if ([MenuItemLocation.Context, MenuItemLocation.EditorContextMenu, MenuItemLocation.NoteListContextMenu].includes(location)) continue; const itemParent = rootMenus[location]; @@ -709,7 +709,7 @@ function useMenu(props: Props) { } for (const view of props.pluginMenus) { - if (view.location === MenuItemLocation.Context) continue; + if ([MenuItemLocation.Context, MenuItemLocation.EditorContextMenu, MenuItemLocation.NoteListContextMenu].includes(view.location)) continue; const itemParent = rootMenus[view.location]; if (!itemParent) { diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx index 247e1c59ad..8d60aee805 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx @@ -17,6 +17,10 @@ import { _ } from '@joplin/lib/locale'; import bridge from '../../../../services/bridge'; import markdownUtils from '@joplin/lib/markdownUtils'; import shim from '@joplin/lib/shim'; +import { MenuItemLocation } from '@joplin/lib/services/plugins/api/types'; +import MenuUtils from '@joplin/lib/services/commands/MenuUtils'; +import CommandService from '@joplin/lib/services/CommandService'; +import { themeStyle } from '@joplin/lib/theme'; const Note = require('@joplin/lib/models/Note.js'); const { clipboard } = require('electron'); @@ -25,7 +29,8 @@ const Menu = bridge().Menu; const MenuItem = bridge().MenuItem; const { reg } = require('@joplin/lib/registry.js'); const dialogs = require('../../../dialogs'); -const { themeStyle } = require('@joplin/lib/theme'); + +const menuUtils = new MenuUtils(CommandService.instance()); function markupRenderOptions(override: any = null) { return { ...override }; @@ -290,8 +295,12 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) { }) ); + menuUtils.pluginContextMenuItems(props.plugins, MenuItemLocation.EditorContextMenu).forEach((item: any) => { + menu.append(new MenuItem(item)); + }); + menu.popup(bridge().window()); - }, [props.content, editorCutText, editorPasteText, editorCopyText, onEditorPaste]); + }, [props.content, editorCutText, editorPasteText, editorCopyText, onEditorPaste, props.plugins]); const loadScript = async (script: any) => { return new Promise((resolve) => { @@ -643,11 +652,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) { return (
      - + {props.noteToolbar}
      diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx index be95987469..bd4f449fbb 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx @@ -11,13 +11,13 @@ import ToolbarButton from '../../../../gui/ToolbarButton/ToolbarButton'; import usePluginServiceRegistration from '../../utils/usePluginServiceRegistration'; import { utils as pluginUtils } from '@joplin/lib/services/plugins/reducer'; import { _, closestSupportedLocale } from '@joplin/lib/locale'; -import setupContextMenu from './utils/setupContextMenu'; +import useContextMenu from './utils/useContextMenu'; +import shim from '@joplin/lib/shim'; const { MarkupToHtml } = require('@joplin/renderer'); const taboverride = require('taboverride'); const { reg } = require('@joplin/lib/registry.js'); const BaseItem = require('@joplin/lib/models/BaseItem'); -const shim = require('@joplin/lib/shim').default; const { themeStyle } = require('@joplin/lib/theme'); const { clipboard } = require('electron'); const supportedLocales = require('./supportedLocales'); @@ -161,6 +161,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { const { scrollToPercent } = useScroll({ editor, onScroll: props.onScroll }); usePluginServiceRegistration(ref); + useContextMenu(editor, props.plugins); const dispatchDidUpdate = (editor: any) => { if (dispatchDidUpdateIID_) shim.clearTimeout(dispatchDidUpdateIID_); @@ -668,7 +669,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { }); } - setupContextMenu(editor); + // setupContextMenu(editor); // TODO: remove event on unmount? editor.on('DblClick', (event: any) => { diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupContextMenu.ts b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupContextMenu.ts deleted file mode 100644 index 9bf0a147da..0000000000 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupContextMenu.ts +++ /dev/null @@ -1,90 +0,0 @@ -import SpellCheckerService from '@joplin/lib/services/spellChecker/SpellCheckerService'; -import bridge from '../../../../../services/bridge'; -import { menuItems, ContextMenuOptions, ContextMenuItemType } from '../../../utils/contextMenu'; -const Resource = require('@joplin/lib/models/Resource'); - -// x and y are the absolute coordinates, as returned by the context-menu event -// handler on the webContent. This function will return null if the point is -// not within the TinyMCE editor. -function contextMenuElement(editor: any, x: number, y: number) { - if (!editor || !editor.getDoc()) return null; - - const iframes = document.getElementsByClassName('tox-edit-area__iframe'); - if (!iframes.length) return null; - - const iframeRect = iframes[0].getBoundingClientRect(); - - if (iframeRect.x < x && iframeRect.y < y && iframeRect.right > x && iframeRect.bottom > y) { - const relativeX = x - iframeRect.x; - const relativeY = y - iframeRect.y; - return editor.getDoc().elementFromPoint(relativeX, relativeY); - } - - return null; -} - -interface ContextMenuActionOptions { - current: ContextMenuOptions; -} - -const contextMenuActionOptions: ContextMenuActionOptions = { current: null }; - -export default function(editor: any) { - const contextMenuItems = menuItems(); - - bridge().window().webContents.on('context-menu', (_event: any, params: any) => { - const element = contextMenuElement(editor, params.x, params.y); - if (!element) return; - - let itemType: ContextMenuItemType = ContextMenuItemType.None; - let resourceId = ''; - let linkToCopy = null; - - if (element.nodeName === 'IMG') { - itemType = ContextMenuItemType.Image; - resourceId = Resource.pathToId(element.src); - } else if (element.nodeName === 'A') { - resourceId = Resource.pathToId(element.href); - itemType = resourceId ? ContextMenuItemType.Resource : ContextMenuItemType.Link; - linkToCopy = element.getAttribute('href') || ''; - } else { - itemType = ContextMenuItemType.Text; - } - - contextMenuActionOptions.current = { - itemType, - resourceId, - linkToCopy, - textToCopy: null, - htmlToCopy: editor.selection ? editor.selection.getContent() : '', - insertContent: (content: string) => { - editor.insertContent(content); - }, - isReadOnly: false, - }; - - const template = []; - - for (const itemName in contextMenuItems) { - const item = contextMenuItems[itemName]; - - if (!item.isActive(itemType, contextMenuActionOptions.current)) continue; - - template.push({ - label: item.label, - click: () => { - item.onAction(contextMenuActionOptions.current); - }, - }); - } - - const spellCheckerMenuItems = SpellCheckerService.instance().contextMenuItems(params.misspelledWord, params.dictionarySuggestions); - - for (const item of spellCheckerMenuItems) { - template.push(item); - } - - const menu = bridge().Menu.buildFromTemplate(template); - menu.popup(bridge().window()); - }); -} diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts new file mode 100644 index 0000000000..a041952270 --- /dev/null +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts @@ -0,0 +1,112 @@ +import { MenuItemLocation } from '@joplin/lib/services/plugins/api/types'; +import { PluginStates } from '@joplin/lib/services/plugins/reducer'; +import SpellCheckerService from '@joplin/lib/services/spellChecker/SpellCheckerService'; +import { useEffect } from 'react'; +import bridge from '../../../../../services/bridge'; +import { menuItems, ContextMenuOptions, ContextMenuItemType } from '../../../utils/contextMenu'; +import MenuUtils from '@joplin/lib/services/commands/MenuUtils'; +import CommandService from '@joplin/lib/services/CommandService'; + +const Resource = require('@joplin/lib/models/Resource'); + +const menuUtils = new MenuUtils(CommandService.instance()); + +// x and y are the absolute coordinates, as returned by the context-menu event +// handler on the webContent. This function will return null if the point is +// not within the TinyMCE editor. +function contextMenuElement(editor: any, x: number, y: number) { + if (!editor || !editor.getDoc()) return null; + + const iframes = document.getElementsByClassName('tox-edit-area__iframe'); + if (!iframes.length) return null; + + const iframeRect = iframes[0].getBoundingClientRect(); + + if (iframeRect.x < x && iframeRect.y < y && iframeRect.right > x && iframeRect.bottom > y) { + const relativeX = x - iframeRect.x; + const relativeY = y - iframeRect.y; + return editor.getDoc().elementFromPoint(relativeX, relativeY); + } + + return null; +} + +interface ContextMenuActionOptions { + current: ContextMenuOptions; +} + +const contextMenuActionOptions: ContextMenuActionOptions = { current: null }; + +export default function(editor: any, plugins: PluginStates) { + useEffect(() => { + if (!editor) return () => {}; + + const contextMenuItems = menuItems(); + + function onContextMenu(_event: any, params: any) { + const element = contextMenuElement(editor, params.x, params.y); + if (!element) return; + + let itemType: ContextMenuItemType = ContextMenuItemType.None; + let resourceId = ''; + let linkToCopy = null; + + if (element.nodeName === 'IMG') { + itemType = ContextMenuItemType.Image; + resourceId = Resource.pathToId(element.src); + } else if (element.nodeName === 'A') { + resourceId = Resource.pathToId(element.href); + itemType = resourceId ? ContextMenuItemType.Resource : ContextMenuItemType.Link; + linkToCopy = element.getAttribute('href') || ''; + } else { + itemType = ContextMenuItemType.Text; + } + + contextMenuActionOptions.current = { + itemType, + resourceId, + linkToCopy, + textToCopy: null, + htmlToCopy: editor.selection ? editor.selection.getContent() : '', + insertContent: (content: string) => { + editor.insertContent(content); + }, + isReadOnly: false, + }; + + let template = []; + + for (const itemName in contextMenuItems) { + const item = contextMenuItems[itemName]; + + if (!item.isActive(itemType, contextMenuActionOptions.current)) continue; + + template.push({ + label: item.label, + click: () => { + item.onAction(contextMenuActionOptions.current); + }, + }); + } + + const spellCheckerMenuItems = SpellCheckerService.instance().contextMenuItems(params.misspelledWord, params.dictionarySuggestions); + + for (const item of spellCheckerMenuItems) { + template.push(item); + } + + template = template.concat(menuUtils.pluginContextMenuItems(plugins, MenuItemLocation.EditorContextMenu)); + + const menu = bridge().Menu.buildFromTemplate(template); + menu.popup(bridge().window()); + } + + bridge().window().webContents.on('context-menu', onContextMenu); + + return () => { + if (bridge().window()?.webContents?.off) { + bridge().window().webContents.off('context-menu', onContextMenu); + } + }; + }, [editor, plugins]); +} diff --git a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx index bb18d13477..df08ff9a13 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx @@ -230,7 +230,16 @@ function NoteEditor(props: NoteEditorProps) { } }, [handleProvisionalFlag, formNote, isNewNote, titleHasBeenManuallyChanged]); - useWindowCommandHandler({ dispatch: props.dispatch, formNote, setShowLocalSearch, noteSearchBarRef, editorRef, titleInputRef, saveNoteAndWait }); + useWindowCommandHandler({ + dispatch: props.dispatch, + formNote, + setShowLocalSearch, + noteSearchBarRef, + editorRef, + titleInputRef, + saveNoteAndWait, + setFormNote, + }); const onDrop = useDropHandler({ editorRef }); diff --git a/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts b/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts index 3f42429ea8..7b591d5346 100644 --- a/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts +++ b/packages/app-desktop/gui/NoteEditor/commands/editorCommandDeclarations.ts @@ -89,6 +89,9 @@ const declarations: CommandDeclaration[] = [ { name: 'replaceSelection', }, + { + name: 'editorSetText', + }, ]; export default declarations; diff --git a/packages/app-desktop/gui/NoteEditor/utils/useWindowCommandHandler.ts b/packages/app-desktop/gui/NoteEditor/utils/useWindowCommandHandler.ts index 03de52253e..1c139328b6 100644 --- a/packages/app-desktop/gui/NoteEditor/utils/useWindowCommandHandler.ts +++ b/packages/app-desktop/gui/NoteEditor/utils/useWindowCommandHandler.ts @@ -19,9 +19,10 @@ interface HookDependencies { editorRef: any; titleInputRef: any; saveNoteAndWait: Function; + setFormNote: Function; } -function editorCommandRuntime(declaration: CommandDeclaration, editorRef: any): CommandRuntime { +function editorCommandRuntime(declaration: CommandDeclaration, editorRef: any, setFormNote: Function): CommandRuntime { return { execute: async (_context: CommandContext, ...args: any[]) => { if (!editorRef.current.execCommand) { @@ -39,6 +40,10 @@ function editorCommandRuntime(declaration: CommandDeclaration, editorRef: any): type: ScrollOptionTypes.Hash, value: args[0], }); + } else if (declaration.name === 'editorSetText') { + setFormNote((prev: FormNote) => { + return { ...prev, body: args[0] }; + }); } else { return editorRef.current.execCommand({ name: declaration.name, @@ -51,11 +56,11 @@ function editorCommandRuntime(declaration: CommandDeclaration, editorRef: any): } export default function useWindowCommandHandler(dependencies: HookDependencies) { - const { setShowLocalSearch, noteSearchBarRef, editorRef, titleInputRef } = dependencies; + const { setShowLocalSearch, noteSearchBarRef, editorRef, titleInputRef, setFormNote } = dependencies; useEffect(() => { for (const declaration of editorCommandDeclarations) { - CommandService.instance().registerRuntime(declaration.name, editorCommandRuntime(declaration, editorRef)); + CommandService.instance().registerRuntime(declaration.name, editorCommandRuntime(declaration, editorRef, setFormNote)); } const dependencies = { diff --git a/packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.js b/packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.js new file mode 100644 index 0000000000..9e68723f83 --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/hooks/useLayoutItemSizes.js @@ -0,0 +1,68 @@ +'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); +exports.itemSize = void 0; +const react_1 = require('react'); +const ResizableLayout_1 = require('../ResizableLayout'); +function itemSize(item, sizes) { + return { + width: 'width' in item ? item.width : sizes[item.key].width, + height: 'height' in item ? item.height : sizes[item.key].height, + }; +} +exports.itemSize = itemSize; +function calculateChildrenSizes(item, sizes) { + if (!item.children) { return sizes; } + const parentSize = itemSize(item, sizes); + const remainingSize = { + width: parentSize.width, + height: parentSize.height, + }; + const noWidthChildren = []; + const noHeightChildren = []; + for (const child of item.children) { + let w = 'width' in child ? child.width : null; + let h = 'height' in child ? child.height : null; + if (child.visible === false) { + w = 0; + h = 0; + } + if (item.resizableRight) { w -= ResizableLayout_1.dragBarThickness; } + if (item.resizableBottom) { h -= ResizableLayout_1.dragBarThickness; } + sizes[child.key] = { width: w, height: h }; + if (w !== null) { remainingSize.width -= w; } + if (h !== null) { remainingSize.height -= h; } + if (w === null) { noWidthChildren.push(child); } + if (h === null) { noHeightChildren.push(child); } + } + if (noWidthChildren.length) { + const w = item.direction === 'row' ? remainingSize.width / noWidthChildren.length : parentSize.width; + for (const child of noWidthChildren) { + sizes[child.key].width = w; + } + } + if (noHeightChildren.length) { + const h = item.direction === 'column' ? remainingSize.height / noHeightChildren.length : parentSize.height; + for (const child of noHeightChildren) { + sizes[child.key].height = h; + } + } + for (const child of item.children) { + const childrenSizes = calculateChildrenSizes(child, sizes); + sizes = Object.assign(Object.assign({}, sizes), childrenSizes); + } + return sizes; +} +function useLayoutItemSizes(layout) { + return react_1.useMemo(() => { + let sizes = {}; + if (!('width' in layout) || !('height' in layout)) { throw new Error('width and height are required on layout root'); } + sizes[layout.key] = { + width: layout.width, + height: layout.height, + }; + sizes = calculateChildrenSizes(layout, sizes); + return sizes; + }, [layout]); +} +exports.default = useLayoutItemSizes; +// # sourceMappingURL=useLayoutItemSizes.js.map diff --git a/packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.js b/packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.js new file mode 100644 index 0000000000..15730246d7 --- /dev/null +++ b/packages/app-desktop/gui/ResizableLayout/hooks/useWindowResizeEvent.js @@ -0,0 +1,18 @@ +'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); +const react_1 = require('react'); +const debounce = require('debounce'); +function useWindowResizeEvent(eventEmitter) { + react_1.useEffect(() => { + const window_resize = debounce(() => { + eventEmitter.current.emit('resize'); + }, 500); + window.addEventListener('resize', window_resize); + return () => { + window_resize.clear(); + window.removeEventListener('resize', window_resize); + }; + }, []); +} +exports.default = useWindowResizeEvent; +// # sourceMappingURL=useWindowResizeEvent.js.map diff --git a/packages/app-desktop/gui/utils/NoteListUtils.ts b/packages/app-desktop/gui/utils/NoteListUtils.ts index a5e946aa84..54c3441ede 100644 --- a/packages/app-desktop/gui/utils/NoteListUtils.ts +++ b/packages/app-desktop/gui/utils/NoteListUtils.ts @@ -179,7 +179,7 @@ export default class NoteListUtils { for (const info of pluginViewInfos) { const location = info.view.location; - if (location !== MenuItemLocation.Context) continue; + if (location !== MenuItemLocation.Context && location !== MenuItemLocation.NoteListContextMenu) continue; menu.append( new MenuItem(menuUtils.commandToStatefulMenuItem(info.view.commandName)) diff --git a/packages/app-desktop/testPluginDemo.sh b/packages/app-desktop/testPluginDemo.sh index 97e09a6e82..c6aa99864e 100755 --- a/packages/app-desktop/testPluginDemo.sh +++ b/packages/app-desktop/testPluginDemo.sh @@ -4,5 +4,5 @@ # It could be used to develop plugins too. SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -PLUGIN_PATH="$SCRIPT_DIR/../app-cli/tests/support/plugins/dialog" +PLUGIN_PATH="$SCRIPT_DIR/../app-cli/tests/support/plugins/editor_context_menu" npm i --prefix="$PLUGIN_PATH" && npm start -- --dev-plugins "$PLUGIN_PATH" \ No newline at end of file diff --git a/packages/lib/services/commands/MenuUtils.ts b/packages/lib/services/commands/MenuUtils.ts index a85540b01b..9bd2542ce9 100644 --- a/packages/lib/services/commands/MenuUtils.ts +++ b/packages/lib/services/commands/MenuUtils.ts @@ -1,5 +1,7 @@ +import { MenuItemLocation } from '../../plugin_types/services/plugins/api/types'; import CommandService from '../CommandService'; import KeymapService from '../KeymapService'; +import { PluginStates, utils as pluginUtils } from '../plugins/reducer'; import propsHaveChanged from './propsHaveChanged'; const { createSelectorCreator, defaultMemoize } = require('reselect'); const { createCachedSelector } = require('re-reselect'); @@ -127,4 +129,18 @@ export default class MenuUtils { return selectObjectByCommands({ array: output }, commandNames); } + public pluginContextMenuItems(plugins: PluginStates, location: MenuItemLocation): MenuItem[] { + const output: MenuItem[] = []; + const pluginViewInfos = pluginUtils.viewInfosByType(plugins, 'menuItem'); + + for (const info of pluginViewInfos) { + if (info.view.location !== location) continue; + output.push(this.commandToStatefulMenuItem(info.view.commandName)); + } + + if (output.length) output.splice(0, 0, { type: 'separator' } as any); + + return output; + } + } diff --git a/packages/lib/services/plugins/api/types.ts b/packages/lib/services/plugins/api/types.ts index d5f0dad55a..a6d7bfe6d6 100644 --- a/packages/lib/services/plugins/api/types.ts +++ b/packages/lib/services/plugins/api/types.ts @@ -204,7 +204,10 @@ export enum MenuItemLocation { Note = 'note', Tools = 'tools', Help = 'help', + // Deprecated - do not use - same as NoteListContext Context = 'context', + NoteListContextMenu = 'noteListContextMenu', + EditorContextMenu = 'editorContextMenu', } export interface MenuItem { diff --git a/packages/lib/tsconfig.json b/packages/lib/tsconfig.json index fc873e9110..9ae51bf4a1 100644 --- a/packages/lib/tsconfig.json +++ b/packages/lib/tsconfig.json @@ -6,5 +6,6 @@ ], "exclude": [ "**/node_modules", + "**/plugin_types", ], } \ No newline at end of file From 83ca33611b1c95362475fe9453c1b3759174f750 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Sat, 14 Nov 2020 00:14:56 +0000 Subject: [PATCH 11/11] Desktop: Make Markdown editor selection more visible in Dark mode --- .../gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx index 8d60aee805..3263d689c1 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx @@ -21,6 +21,7 @@ import { MenuItemLocation } from '@joplin/lib/services/plugins/api/types'; import MenuUtils from '@joplin/lib/services/commands/MenuUtils'; import CommandService from '@joplin/lib/services/CommandService'; import { themeStyle } from '@joplin/lib/theme'; +import { ThemeAppearance } from '@joplin/lib/themes/type'; const Note = require('@joplin/lib/models/Note.js'); const { clipboard } = require('electron'); @@ -379,6 +380,13 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) { useEffect(() => { const theme = themeStyle(props.themeId); + // Selection in dark mode is hard to see so make it brighter. + // https://discourse.joplinapp.org/t/dragging-in-dark-theme/12433/4?u=laurent + const selectionColorCss = theme.appearance === ThemeAppearance.Dark ? + `.CodeMirror-selected { + background: #6b6b6b !important; + }` : ''; + const element = document.createElement('style'); element.setAttribute('id', 'codemirrorStyle'); document.head.appendChild(element); @@ -465,6 +473,8 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) { .cm-s-solarized.cm-s-dark span.cm-comment { color: #8ba1a7 !important; } + + ${selectionColorCss} `)); return () => {