From 7c4b6977cc2f1ebf3085c34c399c33ebcb375977 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Fri, 9 Apr 2021 09:04:30 +0100 Subject: [PATCH 1/9] WIP --- images/serverManager.svg | 14 ++++ images/toolsContainer.svg | 14 ++++ package.json | 77 ++++++++++++++++- src/api/getPortalUriWithCredentials.ts | 29 +++++++ src/api/getServerSpec.ts | 2 +- src/commands/managePasswords.ts | 16 +++- src/extension.ts | 55 ++++++++++-- src/ui/serverManagerView.ts | 111 +++++++++++++++++++++++++ 8 files changed, 303 insertions(+), 15 deletions(-) create mode 100644 images/serverManager.svg create mode 100644 images/toolsContainer.svg create mode 100644 src/api/getPortalUriWithCredentials.ts create mode 100644 src/ui/serverManagerView.ts diff --git a/images/serverManager.svg b/images/serverManager.svg new file mode 100644 index 0000000..53e5be5 --- /dev/null +++ b/images/serverManager.svg @@ -0,0 +1,14 @@ + + + + Slice + Created with Sketch. + + + + + + + + + diff --git a/images/toolsContainer.svg b/images/toolsContainer.svg new file mode 100644 index 0000000..53e5be5 --- /dev/null +++ b/images/toolsContainer.svg @@ -0,0 +1,14 @@ + + + + Slice + Created with Sketch. + + + + + + + + + diff --git a/package.json b/package.json index b8288c3..214b5db 100644 --- a/package.json +++ b/package.json @@ -59,11 +59,32 @@ }, "main": "./out/extension", "activationEvents": [ + "onView:intersystems-community_servermanager", + "onCommand:intersystems-community.servermanager.addServer", "onCommand:intersystems-community.servermanager.storePassword", "onCommand:intersystems-community.servermanager.clearPassword", "onCommand:intersystems-community.servermanager.importServers" ], "contributes": { + "viewsContainers": { + "activitybar": [ + { + "id": "intersystems-community_servermanager", + "title": "InterSystems Tools", + "icon": "images/toolsContainer.svg" + } + ] + }, + "views": { + "intersystems-community_servermanager": [ + { + "id": "intersystems-community_servermanager", + "name": "Server Manager", + "contextualTitle": "InterSystems Server Manager", + "icon": "images/serverManager.svg" + } + ] + }, "configuration": { "title": "InterSystems Server Manager", "properties": { @@ -187,10 +208,28 @@ } }, "commands": [ + { + "command": "intersystems-community.servermanager.addServer", + "category": "InterSystems Server Manager", + "title": "Add Server", + "icon": "$(add)" + }, + { + "command": "intersystems-community.servermanager.openManagementPortalExternal", + "category": "InterSystems Server Manager", + "title": "Open Management Portal in External Browser", + "icon": "$(link-external)" + }, + { + "command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser", + "category": "InterSystems Server Manager", + "title": "Open Management Portal in Simple Browser Tab" + }, { "command": "intersystems-community.servermanager.storePassword", "category": "InterSystems Server Manager", - "title": "Store Password in Keychain" + "title": "Store Password in Keychain", + "icon": "$(key)" }, { "command": "intersystems-community.servermanager.clearPassword", @@ -208,6 +247,42 @@ { "command": "intersystems-community.servermanager.importServers", "when": "isWindows" + }, + { + "command": "intersystems-community.servermanager.openManagementPortalExternal", + "when": "false" + }, + { + "command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser", + "when": "false" + } + ], + "view/title": [ + { + "command": "intersystems-community.servermanager.addServer", + "when": "view == intersystems-community_servermanager", + "group": "navigation" + }, + { + "command": "intersystems-community.servermanager.importServers", + "when": "view == intersystems-community_servermanager && isWindows" + } + ], + "view/item/context": [ + { + "command": "intersystems-community.servermanager.openManagementPortalExternal", + "when": "view == intersystems-community_servermanager && viewItem == server", + "group": "inline" + }, + { + "command": "intersystems-community.servermanager.storePassword", + "when": "view == intersystems-community_servermanager && viewItem == server", + "group": "password@10" + }, + { + "command": "intersystems-community.servermanager.clearPassword", + "when": "view == intersystems-community_servermanager && viewItem == server", + "group": "password@20" } ] } diff --git a/src/api/getPortalUriWithCredentials.ts b/src/api/getPortalUriWithCredentials.ts new file mode 100644 index 0000000..9355702 --- /dev/null +++ b/src/api/getPortalUriWithCredentials.ts @@ -0,0 +1,29 @@ +import * as vscode from 'vscode'; +import { Uri } from 'vscode'; +import { getServerSpec } from './getServerSpec'; + +export async function getPortalUriWithCredentials(name: string, scope?: vscode.ConfigurationScope): Promise { + return getServerSpec(name, scope).then((spec) => { + if (typeof spec !== 'undefined') { + const webServer = spec.webServer; + let queryString = ''; + + // At this point we don't know if the target is IRIS or Cache, so add credentials in both formats. + // Deliberately put password before username, otherwise it is visible in VS Code's confirmation dialog triggered target domain + // hasn't been set as trusted. Likewise, deliberately put IRIS* after Cache* + if (spec?.password) { + const passwordEncoded = encodeURIComponent(spec.password); + queryString += `&CachePassword=${passwordEncoded}&IRISPassword=${passwordEncoded}`; + } + if (spec?.username) { + const usernameEncoded = encodeURIComponent(spec.username); + queryString += `&CacheUsername=${usernameEncoded}&IRISUsername=${usernameEncoded}`; + } + + // Push the credentials offscreen + queryString = '_=' + ' '.padStart(500,' ') + queryString; + + return vscode.Uri.parse(`${webServer.scheme}://${webServer.host}:${webServer.port}${webServer.pathPrefix}/csp/sys/UtilHome.csp?${queryString}`, true); + } + }) +} diff --git a/src/api/getServerSpec.ts b/src/api/getServerSpec.ts index 52db7e7..0eecf89 100644 --- a/src/api/getServerSpec.ts +++ b/src/api/getServerSpec.ts @@ -49,7 +49,7 @@ export async function getServerSpec(name: string, scope?: vscode.ConfigurationSc // Obtain password from session cache or keychain unless trying to connect anonymously if (server.username && !server.password) { if (credentialCache[name] && credentialCache[name].username === server.username) { - server.password = credentialCache[name]; + server.password = credentialCache[name].password; } else { const keychain = new Keychain(name); const password = await keychain.getPassword().then(result => { diff --git a/src/commands/managePasswords.ts b/src/commands/managePasswords.ts index 17db41c..1ea5adc 100644 --- a/src/commands/managePasswords.ts +++ b/src/commands/managePasswords.ts @@ -2,9 +2,14 @@ import * as vscode from 'vscode'; import { extensionId } from '../extension'; import { Keychain } from '../keychain'; import { credentialCache } from '../api/getServerSpec'; +import { getServerNames } from '../api/getServerNames'; +import { ServerTreeItem } from '../ui/serverManagerView'; -export async function storePassword(): Promise { - const name = await commonPickServer({matchOnDetail: true}); +export async function storePassword(treeItem?: ServerTreeItem): Promise { + if (treeItem && !getServerNames().some((value) => value.name === treeItem?.label)) { + treeItem = undefined; + } + const name = treeItem?.label || await commonPickServer({matchOnDetail: true}); let reply = ''; if (name) { await vscode.window @@ -30,9 +35,12 @@ export async function storePassword(): Promise { return reply; } -export async function clearPassword(): Promise { +export async function clearPassword(treeItem?: ServerTreeItem): Promise { + if (treeItem && !getServerNames().some((value) => value.name === treeItem?.label)) { + treeItem = undefined; + } let reply = ''; - const name = await commonPickServer({matchOnDetail: true}); + const name = treeItem?.label || await commonPickServer({matchOnDetail: true}); if (name) { credentialCache[name] = undefined; const keychain = new Keychain(name); diff --git a/src/extension.ts b/src/extension.ts index 1a3100b..dde536d 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -7,6 +7,9 @@ import { getServerNames } from './api/getServerNames'; import { getServerSpec } from './api/getServerSpec'; import { storePassword, clearPassword } from './commands/managePasswords'; import { importFromRegistry } from './commands/importFromRegistry'; +import { ServerManagerView, ServerTreeItem } from './ui/serverManagerView'; +import { addServer } from './api/addServer'; +import { getPortalUriWithCredentials } from './api/getPortalUriWithCredentials'; export interface ServerName { name: string, @@ -42,8 +45,39 @@ export function activate(context: vscode.ExtensionContext) { // Register the commands context.subscriptions.push( - vscode.commands.registerCommand(`${extensionId}.storePassword`, () => { - storePassword() + vscode.commands.registerCommand(`${extensionId}.addServer`, () => { + addServer(); + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.openManagementPortalExternal`, (server?: ServerTreeItem) => { + if (server?.contextValue === 'server' && server.label) { + getPortalUriWithCredentials(server.label).then((uriWithCredentials) => { + if (uriWithCredentials) { + vscode.env.openExternal(uriWithCredentials); + } + }); + } + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.openManagementPortalInSimpleBrowser`, (server?: ServerTreeItem) => { + if (server?.contextValue === 'server' && server.label) { + getPortalUriWithCredentials(server.label).then((uriWithCredentials) => { + if (uriWithCredentials) { + //vscode.commands.executeCommand('simpleBrowser.api.open', uriWithCredentials); + // + // It is essential to pass skipEncoding=true when converting the uri to a string, + // otherwise the encoding done within Simple Browser / webview causes double-encoding of the querystring. + vscode.commands.executeCommand('simpleBrowser.show', uriWithCredentials.toString(true)); + } + }); + } + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.storePassword`, (server?: ServerTreeItem) => { + storePassword(server) .then((name) => { if (name && name.length > 0) { _onDidChangePassword.fire(name); @@ -52,8 +86,8 @@ export function activate(context: vscode.ExtensionContext) { }) ); context.subscriptions.push( - vscode.commands.registerCommand(`${extensionId}.clearPassword`, () => { - clearPassword() + vscode.commands.registerCommand(`${extensionId}.clearPassword`, (server?: ServerTreeItem) => { + clearPassword(server) .then((name) => { if (name && name.length > 0) { _onDidChangePassword.fire(name); @@ -61,11 +95,14 @@ export function activate(context: vscode.ExtensionContext) { }); }) ); - context.subscriptions.push( - vscode.commands.registerCommand(`${extensionId}.importServers`, () => { - importFromRegistry(); - }) - ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.importServers`, () => { + importFromRegistry(); + }) + ); + + // Server Manager View + new ServerManagerView(context); let api = { async pickServer(scope?: vscode.ConfigurationScope, options: vscode.QuickPickOptions = {}): Promise { diff --git a/src/ui/serverManagerView.ts b/src/ui/serverManagerView.ts new file mode 100644 index 0000000..353e820 --- /dev/null +++ b/src/ui/serverManagerView.ts @@ -0,0 +1,111 @@ +import * as vscode from 'vscode'; +import { getServerNames } from '../api/getServerNames'; +import { ServerName } from '../extension'; + +export class ServerManagerView { + + constructor(context: vscode.ExtensionContext) { + const treeDataProvider = new SMNodeProvider(); + const view = vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: false }); + context.subscriptions.push(view); + } +} + +export class SMNodeProvider implements vscode.TreeDataProvider { + + private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); + readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; + + constructor() { + } + + refresh(): void { + this._onDidChangeTreeData.fire(); + } + + getTreeItem(element:SMTreeItem): vscode.TreeItem { + return element; + } + + getChildren(element?: SMTreeItem): SMTreeItem[] { + const children: SMTreeItem[] = []; + if (!element) { + children.push(new SMTreeItem({label: 'Current', codiconName: 'home'})); + children.push(new SMTreeItem({label: 'Starred', codiconName: 'star'})); + children.push(new SMTreeItem({label: 'Recent', codiconName: 'history'})); + children.push(new SMTreeItem({label: 'All : Ordered', tooltip: 'Sequenced as found in settings.json', codiconName: 'list-ordered', getChildren: getChildrenServers, params: {sorted: false}})); + children.push(new SMTreeItem({label: 'All : Sorted', tooltip: 'Alphabetic order', codiconName: 'triangle-down', getChildren: getChildrenServers, params: {sorted: true}})); + return children; + } + else{ + return element.getChildren() + } + } +} + +interface SMItem { + label: string, + contextValue?: string, + tooltip?: string, + description?: string, + codiconName?: string, + getChildren?: Function, + params?: any +} + +export class SMTreeItem extends vscode.TreeItem { + + private readonly _getChildren?: Function; + private readonly _params?: any; + + constructor(item: SMItem) { + const collapsibleState = item.getChildren ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None; + super(item.label, collapsibleState); + + this.contextValue = item.contextValue; + this.tooltip = item.tooltip; + this.description = item.description; + if (item.codiconName) { + this.iconPath = new vscode.ThemeIcon(item.codiconName); + } + this._getChildren = item.getChildren; + this._params = item.params; + } + + public getChildren(): SMTreeItem[] { + if (this._getChildren) { + return this._getChildren(this, this._params); + } + else { + return []; + } + } +} + +function getChildrenServers(element?: SMTreeItem, params?: any): SMTreeItem[] { + const children: SMTreeItem[] = []; + const getAllServers = (sorted?: boolean): ServerTreeItem[] => { + let serverNames = getServerNames(); + if (sorted) { + serverNames = serverNames.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); + } + return serverNames.map((serverName) => { + return new ServerTreeItem(serverName); + }) + } + + getAllServers(params.sorted).map((server) => children.push(server)); + return children; +} + +export class ServerTreeItem extends SMTreeItem { + + constructor( + serverName: ServerName, + ) { + super({label: serverName.name, tooltip: serverName.description, description: serverName.detail}); + this.command = {command: 'intersystems-community.servermanager.openManagementPortalInSimpleBrowser', title: 'Open Management Portal in Simple Browser Tab', arguments: [this]}; + } + iconPath = new vscode.ThemeIcon('server-environment'); + contextValue = 'server'; +} From 9d121fae8807b2b7cc3a18519e35a1fffa2584aa Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Mon, 12 Apr 2021 21:17:05 +0100 Subject: [PATCH 2/9] wip --- package-lock.json | 6870 ++++++++++++++++-------- package.json | 75 +- src/api/getPortalUriWithCredentials.ts | 4 +- src/api/getServerNames.ts | 9 +- src/api/getServerSummary.ts | 14 + src/commands/importFromRegistry.ts | 18 +- src/commands/managePasswords.ts | 4 +- src/extension.ts | 50 +- src/ui/serverManagerView.ts | 102 +- 9 files changed, 4952 insertions(+), 2194 deletions(-) create mode 100644 src/api/getServerSummary.ts diff --git a/package-lock.json b/package-lock.json index 990f993..58a5ebe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,2139 +1,4735 @@ { - "name": "servermanager", - "version": "1.0.3-SNAPSHOT", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@types/glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/keytar": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@types/keytar/-/keytar-4.4.2.tgz", - "integrity": "sha512-xtQcDj9ruGnMwvSu1E2BH4SFa5Dv2PvSPd0CKEBLN5hEj/v5YpXJY+B6hAfuKIbvEomD7vJTc/P1s1xPNh2kRw==", - "dev": true, - "requires": { - "keytar": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.4.tgz", - "integrity": "sha512-M4BwiTJjHmLq6kjON7ZoI2JMlBvpY3BYSdiP6s/qCT3jb1s9/DeJF0JELpAxiVSIxXDzfNKe+r7yedMIoLbknQ==", - "dev": true - }, - "@types/node": { - "version": "8.10.61", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.61.tgz", - "integrity": "sha512-l+zSbvT8TPRaCxL1l9cwHCb0tSqGAGcjPJFItGGYat5oCTiq1uQQKYg5m7AF1mgnEBzFXGLJ2LRmNjtreRX76Q==", - "dev": true - }, - "@types/vscode": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.45.1.tgz", - "integrity": "sha512-0NO9qrrEJBO8FsqHCrFMgR2suKnwCsKBWvRSb2OzH5gs4i3QO5AhEMQYrSzDbU/wLPt7N617/rN9lPY213gmwg==" - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "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, - "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 - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "azure-devops-node-api": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz", - "integrity": "sha512-pMfGJ6gAQ7LRKTHgiRF+8iaUUeGAI0c8puLaqHLc7B8AR7W6GJLozK9RFeUHFjEGybC9/EB3r67WPd7e46zQ8w==", - "dev": true, - "requires": { - "os": "0.1.1", - "tunnel": "0.0.4", - "typed-rest-client": "1.2.0", - "underscore": "1.8.3" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "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 - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.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" - } - } - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "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" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "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" - }, - "dependencies": { - "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" - } - } - } - }, - "cheerio": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", - "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", - "dev": true, - "requires": { - "css-select": "~1.2.0", - "dom-serializer": "~0.1.1", - "entities": "~1.1.1", - "htmlparser2": "^3.9.1", - "lodash": "^4.15.0", - "parse5": "^3.0.1" - } - }, - "chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", - "dev": 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": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "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" - }, - "dependencies": { - "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 - }, - "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" - } - }, - "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" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "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 - }, - "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 - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "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 - }, - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "dev": true, - "requires": { - "mimic-response": "^2.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "denodeify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", - "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", - "dev": true, - "requires": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" - } - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "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.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "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" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, - "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 - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "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-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "follow-redirects": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", - "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==", - "dev": true - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "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 - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "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 - }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", - "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" - } - }, - "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 - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "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-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "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" - } - } - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "dev": true, - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dev": true, - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "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.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "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, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "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-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "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 - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "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" - } - }, - "keytar": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/keytar/-/keytar-6.0.1.tgz", - "integrity": "sha512-1Ihpf2tdM3sLwGMkYHXYhVC/hx5BDR7CWFL4IrBA3IDZo0xHhS2nM+tU9Y+u/U7okNfbVkwmKsieLkcWRMh93g==", - "dev": true, - "requires": { - "node-addon-api": "^3.0.0", - "prebuild-install": "5.3.4" - } - }, - "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 - }, - "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, - "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" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - }, - "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dev": true, - "requires": { - "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 - } - } - }, - "markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "dependencies": { - "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - } - } - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, - "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" - } - }, - "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" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "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 - }, - "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" - } - }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, - "mocha": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", - "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.4.3", - "debug": "4.2.0", - "diff": "4.0.2", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.14.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.2", - "nanoid": "3.1.12", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "7.2.0", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.0.2", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "2.0.0" - }, - "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" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "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 - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "nanoid": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", - "dev": true - }, - "napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true - }, - "node-abi": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.18.0.tgz", - "integrity": "sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw==", - "dev": true, - "requires": { - "semver": "^5.4.1" - } - }, - "node-addon-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz", - "integrity": "sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==", - "dev": true - }, - "node-cmd": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/node-cmd/-/node-cmd-4.0.0.tgz", - "integrity": "sha512-3OHy8KI8MuwADyugQRZBsaqe3c0r3yxQSoLsDBVk7vAjPmfG01512MPBQjfmBJxrH+2qURbiBf/ZyoimrhdA6A==" - }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", - "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 - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "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 - }, - "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": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz", - "integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "ovsx": { - "version": "0.1.0-next.ae88c6d", - "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.1.0-next.ae88c6d.tgz", - "integrity": "sha512-1CeRrtSiQQ15MiQFhmgHkvH0o8zVzAZ5SjZFQWGq4EeEShcUKWOjkNe0/ecAX6DAHpSOtVirM0VT79Oej8kH4Q==", - "dev": true, - "requires": { - "commander": "^6.1.0", - "follow-redirects": "^1.13.0", - "vsce": "~1.81.1" - }, - "dependencies": { - "commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true - }, - "vsce": { - "version": "1.81.1", - "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.81.1.tgz", - "integrity": "sha512-1yWAYRxTx/PKSFZnuELe7GPyIo70H/XKJqf6wGikofUK3f3TCNGI6F9xkTQFvXKNe0AygUuxN7kITyPIQGMP+w==", - "dev": true, - "requires": { - "azure-devops-node-api": "^7.2.0", - "chalk": "^2.4.2", - "cheerio": "^1.0.0-rc.1", - "commander": "^6.1.0", - "denodeify": "^1.2.1", - "glob": "^7.0.6", - "leven": "^3.1.0", - "lodash": "^4.17.15", - "markdown-it": "^10.0.0", - "mime": "^1.3.4", - "minimatch": "^3.0.3", - "osenv": "^0.1.3", - "parse-semver": "^1.1.1", - "read": "^1.0.7", - "semver": "^5.1.0", - "tmp": "0.0.29", - "typed-rest-client": "1.2.0", - "url-join": "^1.1.0", - "yauzl": "^2.3.1", - "yazl": "^2.2.2" - } - } - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "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 - }, - "parse-semver": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", - "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", - "dev": true, - "requires": { - "semver": "^5.1.0" - } - }, - "parse5": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", - "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "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-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "prebuild-install": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.4.tgz", - "integrity": "sha512-AkKN+pf4fSEihjapLEEj8n85YIw/tN6BQqkhzbDc0RvEZGdkpJBGMUYx66AAMcPG2KzmPQS7Cm16an4HVBRRMA==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp": "^0.5.1", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" - } - }, - "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 - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "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" - } - }, - "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" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", - "dev": true, - "requires": { - "mute-stream": "~0.0.4" - } - }, - "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" - } - }, - "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, - "requires": { - "picomatch": "^2.2.1" - } - }, - "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": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "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" - } - }, - "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 - }, - "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": "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 - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", - "dev": true - }, - "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", - "dev": true, - "requires": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.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" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "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" - }, - "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 - } - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-fs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", - "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.0.0" - } - }, - "tar-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz", - "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "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" - } - } - } - }, - "tmp": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", - "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.1" - } - }, - "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": "6.2.2", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", - "integrity": "sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==", - "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": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", - "dev": true - }, - "tslint": { - "version": "5.20.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", - "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "typed-rest-client": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.2.0.tgz", - "integrity": "sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==", - "dev": true, - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - } - }, - "typescript": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", - "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", - "dev": true - }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", - "dev": true - }, - "url-join": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", - "integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=", - "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 - }, - "vsce": { - "version": "1.76.1", - "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.76.1.tgz", - "integrity": "sha512-WNx6JzRywxAOuhVpjmrsI0eHMK0mCA0YKD8u++7sprmhwCHsoQIBpSf0vp6kVMHBmafknr1Z6K7IC5jIjsNL9Q==", - "dev": true, - "requires": { - "azure-devops-node-api": "^7.2.0", - "chalk": "^2.4.2", - "cheerio": "^1.0.0-rc.1", - "commander": "^2.8.1", - "denodeify": "^1.2.1", - "glob": "^7.0.6", - "leven": "^3.1.0", - "lodash": "^4.17.15", - "markdown-it": "^10.0.0", - "mime": "^1.3.4", - "minimatch": "^3.0.3", - "osenv": "^0.1.3", - "parse-semver": "^1.1.1", - "read": "^1.0.7", - "semver": "^5.1.0", - "tmp": "0.0.29", - "typed-rest-client": "1.2.0", - "url-join": "^1.1.0", - "yauzl": "^2.3.1", - "yazl": "^2.2.2" - } - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "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" - } - }, - "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 - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "workerpool": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", - "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", - "dev": true - }, - "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" - }, - "dependencies": { - "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 - }, - "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" - } - }, - "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" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "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": { - "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 - }, - "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 - }, - "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" - } - }, - "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" - } - } - } - }, - "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" - } - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } - } - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } + "name": "servermanager", + "version": "2.0.0-SNAPSHOT", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "servermanager", + "version": "2.0.0-SNAPSHOT", + "license": "MIT", + "dependencies": { + "@types/vscode": "^1.55.0", + "node-cmd": "^4.0.0" + }, + "devDependencies": { + "@types/glob": "^7.1.1", + "@types/keytar": "^4.4.2", + "@types/mocha": "^8.0.4", + "@types/node": "^8.10.60", + "glob": "^7.1.6", + "mocha": "^8.3.2", + "ovsx": "latest", + "ts-loader": "^6.2.2", + "tslint": "^5.20.1", + "typescript": "^3.8.3", + "vsce": "^1.75.0", + "vscode-test": "^1.3.0" + }, + "engines": { + "node": "^10.2.0", + "vscode": "^1.43.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.1" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "dev": true + }, + "node_modules/@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@types/glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/keytar": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@types/keytar/-/keytar-4.4.2.tgz", + "integrity": "sha512-xtQcDj9ruGnMwvSu1E2BH4SFa5Dv2PvSPd0CKEBLN5hEj/v5YpXJY+B6hAfuKIbvEomD7vJTc/P1s1xPNh2kRw==", + "dev": true, + "dependencies": { + "keytar": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.4.tgz", + "integrity": "sha512-M4BwiTJjHmLq6kjON7ZoI2JMlBvpY3BYSdiP6s/qCT3jb1s9/DeJF0JELpAxiVSIxXDzfNKe+r7yedMIoLbknQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "8.10.61", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.61.tgz", + "integrity": "sha512-l+zSbvT8TPRaCxL1l9cwHCb0tSqGAGcjPJFItGGYat5oCTiq1uQQKYg5m7AF1mgnEBzFXGLJ2LRmNjtreRX76Q==", + "dev": true + }, + "node_modules/@types/vscode": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.55.0.tgz", + "integrity": "sha512-49hysH7jneTQoSC8TWbAi7nKK9Lc5osQNjmDHVosrcU8o3jecD9GrK0Qyul8q4aGPSXRfNGqIp9CBdb13akETg==" + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/azure-devops-node-api": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz", + "integrity": "sha512-pMfGJ6gAQ7LRKTHgiRF+8iaUUeGAI0c8puLaqHLc7B8AR7W6GJLozK9RFeUHFjEGybC9/EB3r67WPd7e46zQ8w==", + "dev": true, + "dependencies": { + "os": "0.1.1", + "tunnel": "0.0.4", + "typed-rest-client": "1.2.0", + "underscore": "1.8.3" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "node_modules/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, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", + "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/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, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "node_modules/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, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", + "dev": true, + "dependencies": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.1", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.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" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/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, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/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 + }, + "node_modules/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 + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "node_modules/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 + }, + "node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "node_modules/denodeify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", + "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", + "dev": true + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/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, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "node_modules/errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/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, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "dev": true + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/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 + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/htmlparser2/node_modules/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, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "dependencies": { + "agent-base": "4", + "debug": "3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dev": true, + "dependencies": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/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, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/keytar": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-6.0.1.tgz", + "integrity": "sha512-1Ihpf2tdM3sLwGMkYHXYhVC/hx5BDR7CWFL4IrBA3IDZo0xHhS2nM+tU9Y+u/U7okNfbVkwmKsieLkcWRMh93g==", + "dev": true, + "dependencies": { + "node-addon-api": "^3.0.0", + "prebuild-install": "5.3.4" + } + }, + "node_modules/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, + "engines": { + "node": ">=6" + } + }, + "node_modules/linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/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, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/log-symbols/node_modules/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/log-symbols/node_modules/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/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 + }, + "node_modules/markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "node_modules/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, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/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, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/mocha": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", + "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/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 + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, + "node_modules/node-abi": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.18.0.tgz", + "integrity": "sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw==", + "dev": true, + "dependencies": { + "semver": "^5.4.1" + } + }, + "node_modules/node-addon-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz", + "integrity": "sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==", + "dev": true + }, + "node_modules/node-cmd": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/node-cmd/-/node-cmd-4.0.0.tgz", + "integrity": "sha512-3OHy8KI8MuwADyugQRZBsaqe3c0r3yxQSoLsDBVk7vAjPmfG01512MPBQjfmBJxrH+2qURbiBf/ZyoimrhdA6A==", + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", + "dev": true + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/os": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz", + "integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M=", + "dev": true + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/ovsx": { + "version": "0.1.0-next.ae88c6d", + "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.1.0-next.ae88c6d.tgz", + "integrity": "sha512-1CeRrtSiQQ15MiQFhmgHkvH0o8zVzAZ5SjZFQWGq4EeEShcUKWOjkNe0/ecAX6DAHpSOtVirM0VT79Oej8kH4Q==", + "dev": true, + "dependencies": { + "commander": "^6.1.0", + "follow-redirects": "^1.13.0", + "vsce": "~1.81.1" + }, + "bin": { + "ovsx": "lib/ovsx" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/ovsx/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ovsx/node_modules/vsce": { + "version": "1.81.1", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.81.1.tgz", + "integrity": "sha512-1yWAYRxTx/PKSFZnuELe7GPyIo70H/XKJqf6wGikofUK3f3TCNGI6F9xkTQFvXKNe0AygUuxN7kITyPIQGMP+w==", + "dev": true, + "dependencies": { + "azure-devops-node-api": "^7.2.0", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.1", + "commander": "^6.1.0", + "denodeify": "^1.2.1", + "glob": "^7.0.6", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "markdown-it": "^10.0.0", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "osenv": "^0.1.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^5.1.0", + "tmp": "0.0.29", + "typed-rest-client": "1.2.0", + "url-join": "^1.1.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "bin": { + "vsce": "out/vsce" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/parse-semver": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", + "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", + "dev": true, + "dependencies": { + "semver": "^5.1.0" + } + }, + "node_modules/parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/prebuild-install": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.4.tgz", + "integrity": "sha512-AkKN+pf4fSEihjapLEEj8n85YIw/tN6BQqkhzbDc0RvEZGdkpJBGMUYx66AAMcPG2KzmPQS7Cm16an4HVBRRMA==", + "dev": true, + "dependencies": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp": "^0.5.1", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/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 + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "node_modules/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, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/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, + "dependencies": { + "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" + } + }, + "node_modules/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, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/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 + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/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, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/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 + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "dev": true + }, + "node_modules/simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "dev": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/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, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", + "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "node_modules/tar-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz", + "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==", + "dev": true, + "dependencies": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/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, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tmp": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", + "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/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, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-loader": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", + "integrity": "sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==", + "dev": true, + "dependencies": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ts-loader/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "node_modules/tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + } + }, + "node_modules/tslint/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + } + }, + "node_modules/tunnel": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", + "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=", + "dev": true, + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/typed-rest-client": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.2.0.tgz", + "integrity": "sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==", + "dev": true, + "dependencies": { + "tunnel": "0.0.4", + "underscore": "1.8.3" + } + }, + "node_modules/typescript": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", + "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "node_modules/url-join": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", + "integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/vsce": { + "version": "1.76.1", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.76.1.tgz", + "integrity": "sha512-WNx6JzRywxAOuhVpjmrsI0eHMK0mCA0YKD8u++7sprmhwCHsoQIBpSf0vp6kVMHBmafknr1Z6K7IC5jIjsNL9Q==", + "dev": true, + "dependencies": { + "azure-devops-node-api": "^7.2.0", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.1", + "commander": "^2.8.1", + "denodeify": "^1.2.1", + "glob": "^7.0.6", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "markdown-it": "^10.0.0", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "osenv": "^0.1.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^5.1.0", + "tmp": "0.0.29", + "typed-rest-client": "1.2.0", + "url-join": "^1.1.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "bin": { + "vsce": "out/vsce" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/vscode-test": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", + "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", + "dev": true, + "dependencies": { + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.4", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=8.9.3" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "dev": true + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/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 + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/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, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/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, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@types/glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/keytar": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@types/keytar/-/keytar-4.4.2.tgz", + "integrity": "sha512-xtQcDj9ruGnMwvSu1E2BH4SFa5Dv2PvSPd0CKEBLN5hEj/v5YpXJY+B6hAfuKIbvEomD7vJTc/P1s1xPNh2kRw==", + "dev": true, + "requires": { + "keytar": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/mocha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.4.tgz", + "integrity": "sha512-M4BwiTJjHmLq6kjON7ZoI2JMlBvpY3BYSdiP6s/qCT3jb1s9/DeJF0JELpAxiVSIxXDzfNKe+r7yedMIoLbknQ==", + "dev": true + }, + "@types/node": { + "version": "8.10.61", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.61.tgz", + "integrity": "sha512-l+zSbvT8TPRaCxL1l9cwHCb0tSqGAGcjPJFItGGYat5oCTiq1uQQKYg5m7AF1mgnEBzFXGLJ2LRmNjtreRX76Q==", + "dev": true + }, + "@types/vscode": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.55.0.tgz", + "integrity": "sha512-49hysH7jneTQoSC8TWbAi7nKK9Lc5osQNjmDHVosrcU8o3jecD9GrK0Qyul8q4aGPSXRfNGqIp9CBdb13akETg==" + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "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.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": 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 + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "azure-devops-node-api": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz", + "integrity": "sha512-pMfGJ6gAQ7LRKTHgiRF+8iaUUeGAI0c8puLaqHLc7B8AR7W6GJLozK9RFeUHFjEGybC9/EB3r67WPd7e46zQ8w==", + "dev": true, + "requires": { + "os": "0.1.1", + "tunnel": "0.0.4", + "typed-rest-client": "1.2.0", + "underscore": "1.8.3" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "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.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bl": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", + "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.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" + } + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "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" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "cheerio": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", + "dev": true, + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.1", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "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": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.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 + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "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 + }, + "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 + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "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 + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "requires": { + "mimic-response": "^2.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "denodeify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", + "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", + "dev": true + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dev": true, + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "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.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "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" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "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-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "follow-redirects": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==", + "dev": true + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "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.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "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 + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "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.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "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 + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "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-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "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" + } + } + } + }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dev": true, + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "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.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "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, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "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-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "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 + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "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" + } + }, + "keytar": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-6.0.1.tgz", + "integrity": "sha512-1Ihpf2tdM3sLwGMkYHXYhVC/hx5BDR7CWFL4IrBA3IDZo0xHhS2nM+tU9Y+u/U7okNfbVkwmKsieLkcWRMh93g==", + "dev": true, + "requires": { + "node-addon-api": "^3.0.0", + "prebuild-install": "5.3.4" + } + }, + "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 + }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "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" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "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 + } + } + }, + "markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + } + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "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 + }, + "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" + } + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "mocha": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", + "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "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 + } + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "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 + }, + "js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true + }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, + "node-abi": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.18.0.tgz", + "integrity": "sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw==", + "dev": true, + "requires": { + "semver": "^5.4.1" + } + }, + "node-addon-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz", + "integrity": "sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==", + "dev": true + }, + "node-cmd": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/node-cmd/-/node-cmd-4.0.0.tgz", + "integrity": "sha512-3OHy8KI8MuwADyugQRZBsaqe3c0r3yxQSoLsDBVk7vAjPmfG01512MPBQjfmBJxrH+2qURbiBf/ZyoimrhdA6A==" + }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", + "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 + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "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 + }, + "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": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz", + "integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "ovsx": { + "version": "0.1.0-next.ae88c6d", + "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.1.0-next.ae88c6d.tgz", + "integrity": "sha512-1CeRrtSiQQ15MiQFhmgHkvH0o8zVzAZ5SjZFQWGq4EeEShcUKWOjkNe0/ecAX6DAHpSOtVirM0VT79Oej8kH4Q==", + "dev": true, + "requires": { + "commander": "^6.1.0", + "follow-redirects": "^1.13.0", + "vsce": "~1.81.1" + }, + "dependencies": { + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "vsce": { + "version": "1.81.1", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.81.1.tgz", + "integrity": "sha512-1yWAYRxTx/PKSFZnuELe7GPyIo70H/XKJqf6wGikofUK3f3TCNGI6F9xkTQFvXKNe0AygUuxN7kITyPIQGMP+w==", + "dev": true, + "requires": { + "azure-devops-node-api": "^7.2.0", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.1", + "commander": "^6.1.0", + "denodeify": "^1.2.1", + "glob": "^7.0.6", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "markdown-it": "^10.0.0", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "osenv": "^0.1.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^5.1.0", + "tmp": "0.0.29", + "typed-rest-client": "1.2.0", + "url-join": "^1.1.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + } + } + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parse-semver": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", + "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", + "dev": true, + "requires": { + "semver": "^5.1.0" + } + }, + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "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-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "prebuild-install": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.4.tgz", + "integrity": "sha512-AkKN+pf4fSEihjapLEEj8n85YIw/tN6BQqkhzbDc0RvEZGdkpJBGMUYx66AAMcPG2KzmPQS7Cm16an4HVBRRMA==", + "dev": true, + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp": "^0.5.1", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + } + }, + "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 + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "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" + } + }, + "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" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "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" + } + }, + "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, + "requires": { + "picomatch": "^2.2.1" + } + }, + "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 + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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" + } + }, + "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 + }, + "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": "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 + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "dev": true + }, + "simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "dev": true, + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "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" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "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" + }, + "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 + } + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "tar-fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", + "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "tar-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz", + "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==", + "dev": true, + "requires": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "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" + } + } + } + }, + "tmp": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", + "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "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": "6.2.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", + "integrity": "sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==", + "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": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tunnel": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", + "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "typed-rest-client": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.2.0.tgz", + "integrity": "sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==", + "dev": true, + "requires": { + "tunnel": "0.0.4", + "underscore": "1.8.3" + } + }, + "typescript": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", + "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", + "dev": true + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "url-join": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", + "integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=", + "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 + }, + "vsce": { + "version": "1.76.1", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.76.1.tgz", + "integrity": "sha512-WNx6JzRywxAOuhVpjmrsI0eHMK0mCA0YKD8u++7sprmhwCHsoQIBpSf0vp6kVMHBmafknr1Z6K7IC5jIjsNL9Q==", + "dev": true, + "requires": { + "azure-devops-node-api": "^7.2.0", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.1", + "commander": "^2.8.1", + "denodeify": "^1.2.1", + "glob": "^7.0.6", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "markdown-it": "^10.0.0", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "osenv": "^0.1.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^5.1.0", + "tmp": "0.0.29", + "typed-rest-client": "1.2.0", + "url-join": "^1.1.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + } + }, + "vscode-test": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", + "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", + "dev": true, + "requires": { + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.4", + "rimraf": "^2.6.3" + } + }, + "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" + } + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.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" + } + }, + "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 + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "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 + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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" + } + } + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } } diff --git a/package.json b/package.json index 214b5db..904e501 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "servermanager", "displayName": "InterSystems Server Manager", - "version": "1.0.6-SNAPSHOT", + "version": "2.0.0-SNAPSHOT", "publisher": "intersystems-community", "description": "Helper extension for defining connections to InterSystems servers.", "repository": { @@ -40,7 +40,7 @@ "lint-fix": "tslint --project tsconfig.json -t verbose --fix" }, "dependencies": { - "@types/vscode": "^1.43.0", + "@types/vscode": "^1.55.0", "node-cmd": "^4.0.0" }, "devDependencies": { @@ -49,7 +49,7 @@ "@types/mocha": "^8.0.4", "@types/node": "^8.10.60", "glob": "^7.1.6", - "mocha": "^8.2.1", + "mocha": "^8.3.2", "ovsx": "latest", "ts-loader": "^6.2.2", "tslint": "^5.20.1", @@ -66,15 +66,15 @@ "onCommand:intersystems-community.servermanager.importServers" ], "contributes": { - "viewsContainers": { - "activitybar": [ - { - "id": "intersystems-community_servermanager", - "title": "InterSystems Tools", - "icon": "images/toolsContainer.svg" - } - ] - }, + "viewsContainers": { + "activitybar": [ + { + "id": "intersystems-community_servermanager", + "title": "InterSystems Tools", + "icon": "images/toolsContainer.svg" + } + ] + }, "views": { "intersystems-community_servermanager": [ { @@ -208,12 +208,30 @@ } }, "commands": [ + { + "command": "intersystems-community.servermanager.refreshTree", + "category": "InterSystems Server Manager", + "title": "Refresh", + "icon": "$(refresh)" + }, { "command": "intersystems-community.servermanager.addServer", "category": "InterSystems Server Manager", "title": "Add Server", "icon": "$(add)" }, + { + "command": "intersystems-community.servermanager.addToStarred", + "category": "InterSystems Server Manager", + "title": "Add to Starred", + "icon": "$(star-full)" + }, + { + "command": "intersystems-community.servermanager.removeFromStarred", + "category": "InterSystems Server Manager", + "title": "Remove from Starred", + "icon": "$(star-empty)" + }, { "command": "intersystems-community.servermanager.openManagementPortalExternal", "category": "InterSystems Server Manager", @@ -248,6 +266,14 @@ "command": "intersystems-community.servermanager.importServers", "when": "isWindows" }, + { + "command": "intersystems-community.servermanager.addToStarred", + "when": "false" + }, + { + "command": "intersystems-community.servermanager.removeFromStarred", + "when": "false" + }, { "command": "intersystems-community.servermanager.openManagementPortalExternal", "when": "false" @@ -258,10 +284,15 @@ } ], "view/title": [ + { + "command": "intersystems-community.servermanager.refreshTree", + "when": "view == intersystems-community_servermanager", + "group": "navigation@10" + }, { "command": "intersystems-community.servermanager.addServer", "when": "view == intersystems-community_servermanager", - "group": "navigation" + "group": "navigation@20" }, { "command": "intersystems-community.servermanager.importServers", @@ -269,19 +300,29 @@ } ], "view/item/context": [ + { + "command": "intersystems-community.servermanager.addToStarred", + "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\.$/", + "group": "inline@10" + }, + { + "command": "intersystems-community.servermanager.removeFromStarred", + "when": "view == intersystems-community_servermanager && viewItem == starred.server.starred", + "group": "inline@10" + }, { "command": "intersystems-community.servermanager.openManagementPortalExternal", - "when": "view == intersystems-community_servermanager && viewItem == server", - "group": "inline" + "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", + "group": "inline@90" }, { "command": "intersystems-community.servermanager.storePassword", - "when": "view == intersystems-community_servermanager && viewItem == server", + "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", "group": "password@10" }, { "command": "intersystems-community.servermanager.clearPassword", - "when": "view == intersystems-community_servermanager && viewItem == server", + "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", "group": "password@20" } ] diff --git a/src/api/getPortalUriWithCredentials.ts b/src/api/getPortalUriWithCredentials.ts index 9355702..1281c99 100644 --- a/src/api/getPortalUriWithCredentials.ts +++ b/src/api/getPortalUriWithCredentials.ts @@ -20,8 +20,8 @@ export async function getPortalUriWithCredentials(name: string, scope?: vscode.C queryString += `&CacheUsername=${usernameEncoded}&IRISUsername=${usernameEncoded}`; } - // Push the credentials offscreen - queryString = '_=' + ' '.padStart(500,' ') + queryString; + // Add a dummy cache-buster and push the actual credentials offscreen + queryString = '_=' + new Date().getTime().toString().padEnd(480,' ') + queryString; return vscode.Uri.parse(`${webServer.scheme}://${webServer.host}:${webServer.port}${webServer.pathPrefix}/csp/sys/UtilHome.csp?${queryString}`, true); } diff --git a/src/api/getServerNames.ts b/src/api/getServerNames.ts index fd4c3e2..e2d36cb 100644 --- a/src/api/getServerNames.ts +++ b/src/api/getServerNames.ts @@ -1,5 +1,6 @@ import * as vscode from 'vscode'; -import { ServerName, ServerSpec } from '../extension'; +import { ServerName } from '../extension'; +import { serverDetail } from './getServerSummary'; export function getServerNames(scope?: vscode.ConfigurationScope): ServerName[] { let names: ServerName[] = []; @@ -19,7 +20,7 @@ export function getServerNames(scope?: vscode.ConfigurationScope): ServerName[] if (myDefault.length > 0 && servers[myDefault]) { names.push({ name: myDefault, - description: `${servers[myDefault].description || ''} (default)`, + description: `${servers[myDefault].description || ''} (default)`.trim(), detail: serverDetail(servers[myDefault]) }); } @@ -53,7 +54,3 @@ export function getServerNames(scope?: vscode.ConfigurationScope): ServerName[] } return names; } - -function serverDetail(connSpec: ServerSpec): string { - return `${connSpec.webServer.scheme || 'http'}://${connSpec.webServer.host}:${connSpec.webServer.port}/${connSpec.webServer.pathPrefix || ''}`; -} \ No newline at end of file diff --git a/src/api/getServerSummary.ts b/src/api/getServerSummary.ts new file mode 100644 index 0000000..27bb349 --- /dev/null +++ b/src/api/getServerSummary.ts @@ -0,0 +1,14 @@ +import * as vscode from 'vscode'; +import { ServerName, ServerSpec } from '../extension'; + +export function getServerSummary(name: string, scope?: vscode.ConfigurationScope): ServerName | undefined { + const server: ServerSpec | undefined = vscode.workspace.getConfiguration('intersystems.servers', scope).get(name); + if (!server) { + return undefined + } + return {name, description: server.description || '', detail: serverDetail(server)}; +} + +export function serverDetail(connSpec: ServerSpec): string { + return `${connSpec.webServer.scheme || 'http'}://${connSpec.webServer.host}:${connSpec.webServer.port}/${connSpec.webServer.pathPrefix || ''}`; +} \ No newline at end of file diff --git a/src/commands/importFromRegistry.ts b/src/commands/importFromRegistry.ts index 7531836..82fff9b 100644 --- a/src/commands/importFromRegistry.ts +++ b/src/commands/importFromRegistry.ts @@ -11,6 +11,8 @@ export async function importFromRegistry(scope?: vscode.ConfigurationScope) { const newServerNames = new Array(); const serversMissingUsernames = new Array(); + let overwriteCount: number; + regQueryCache.clear(); return vscode.window.withProgress({ @@ -25,7 +27,7 @@ export async function importFromRegistry(scope?: vscode.ConfigurationScope) { // This forces the progress bar to actually show before the possibly long-running load of registry data await new Promise(resolve => setTimeout(resolve,0)); - await loadRegistryData(config, serverDefinitions, serversMissingUsernames, newServerNames); + overwriteCount = await loadRegistryData(config, serverDefinitions, serversMissingUsernames, newServerNames); if (cancellationToken.isCancellationRequested) { return false; @@ -35,6 +37,13 @@ export async function importFromRegistry(scope?: vscode.ConfigurationScope) { if (!keepGoing) { return; } + + if (overwriteCount > 0) { + if (await vscode.window.showWarningMessage(`${overwriteCount} existing definition${overwriteCount > 1 ? "s" : ""} will be overwritten. Continue?`, { modal: true }, "Yes") !=="Yes") { + vscode.window.showInformationMessage("Cancelled server import."); + return; + } + } if (!await promptForUsernames(serverDefinitions, serversMissingUsernames)) { vscode.window.showInformationMessage("Cancelled server import."); return; @@ -53,10 +62,11 @@ export async function importFromRegistry(scope?: vscode.ConfigurationScope) { }); } -async function loadRegistryData(config, serverDefinitions, serversMissingUsernames, newServerNames): Promise { +async function loadRegistryData(config, serverDefinitions, serversMissingUsernames, newServerNames): Promise { const cmd = require("node-cmd"); const hkeyLocalMachine = "HKEY_LOCAL_MACHINE"; preloadRegistryCache(cmd, "HKEY_CURRENT_USER\\Software\\InterSystems\\Cache\\Servers"); + let overwriteCount = 0; for (const folder of ['','\\WOW6432Node']) { const subFolder = "\\Intersystems\\Cache\\Servers"; const path = hkeyLocalMachine + "\\SOFTWARE" + folder + subFolder; @@ -113,8 +123,12 @@ async function loadRegistryData(config, serverDefinitions, serversMissingUsernam }, } } + else if (!name.startsWith("/")) { + overwriteCount++; + } }); } + return overwriteCount; } async function promptForUsernames(serverDefinitions: any, serversMissingUsernames: string[]): Promise { diff --git a/src/commands/managePasswords.ts b/src/commands/managePasswords.ts index 1ea5adc..1f37296 100644 --- a/src/commands/managePasswords.ts +++ b/src/commands/managePasswords.ts @@ -9,7 +9,7 @@ export async function storePassword(treeItem?: ServerTreeItem): Promise if (treeItem && !getServerNames().some((value) => value.name === treeItem?.label)) { treeItem = undefined; } - const name = treeItem?.label || await commonPickServer({matchOnDetail: true}); + const name = treeItem?.name || await commonPickServer({matchOnDetail: true}); let reply = ''; if (name) { await vscode.window @@ -40,7 +40,7 @@ export async function clearPassword(treeItem?: ServerTreeItem): Promise treeItem = undefined; } let reply = ''; - const name = treeItem?.label || await commonPickServer({matchOnDetail: true}); + const name = treeItem?.name || await commonPickServer({matchOnDetail: true}); if (name) { credentialCache[name] = undefined; const keychain = new Keychain(name); diff --git a/src/extension.ts b/src/extension.ts index dde536d..446a422 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -10,6 +10,7 @@ import { importFromRegistry } from './commands/importFromRegistry'; import { ServerManagerView, ServerTreeItem } from './ui/serverManagerView'; import { addServer } from './api/addServer'; import { getPortalUriWithCredentials } from './api/getPortalUriWithCredentials'; +import { getServerSummary } from './api/getServerSummary'; export interface ServerName { name: string, @@ -43,16 +44,41 @@ export function activate(context: vscode.ExtensionContext) { const _onDidChangePassword = new vscode.EventEmitter(); + // Server Manager View + const view = new ServerManagerView(context); + // Register the commands context.subscriptions.push( - vscode.commands.registerCommand(`${extensionId}.addServer`, () => { - addServer(); + vscode.commands.registerCommand(`${extensionId}.refreshTree`, () => { + view.refreshTree(); + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.addServer`, async () => { + await addServer(); + view.refreshTree(); + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.addToStarred`, async (server?: ServerTreeItem) => { + if (server?.contextValue?.match(/\.server\./) && server.name) { + await view.addToFavorites(server.name); + view.refreshTree(); + } + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.removeFromStarred`, async (server?: ServerTreeItem) => { + if (server?.contextValue?.endsWith('.starred') && server.name) { + await view.removeFromFavorites(server.name); + view.refreshTree(); + } }) ); context.subscriptions.push( vscode.commands.registerCommand(`${extensionId}.openManagementPortalExternal`, (server?: ServerTreeItem) => { - if (server?.contextValue === 'server' && server.label) { - getPortalUriWithCredentials(server.label).then((uriWithCredentials) => { + if (server?.contextValue?.match(/\.server\./) && server.name) { + getPortalUriWithCredentials(server.name).then((uriWithCredentials) => { if (uriWithCredentials) { vscode.env.openExternal(uriWithCredentials); } @@ -62,8 +88,8 @@ export function activate(context: vscode.ExtensionContext) { ); context.subscriptions.push( vscode.commands.registerCommand(`${extensionId}.openManagementPortalInSimpleBrowser`, (server?: ServerTreeItem) => { - if (server?.contextValue === 'server' && server.label) { - getPortalUriWithCredentials(server.label).then((uriWithCredentials) => { + if (server?.contextValue?.match(/\.server\./) && server.name) { + getPortalUriWithCredentials(server.name).then((uriWithCredentials) => { if (uriWithCredentials) { //vscode.commands.executeCommand('simpleBrowser.api.open', uriWithCredentials); // @@ -96,14 +122,12 @@ export function activate(context: vscode.ExtensionContext) { }) ); context.subscriptions.push( - vscode.commands.registerCommand(`${extensionId}.importServers`, () => { - importFromRegistry(); + vscode.commands.registerCommand(`${extensionId}.importServers`, async () => { + await importFromRegistry(); + view.refreshTree(); }) ); - // Server Manager View - new ServerManagerView(context); - let api = { async pickServer(scope?: vscode.ConfigurationScope, options: vscode.QuickPickOptions = {}): Promise { return await pickServer(scope, options); @@ -113,6 +137,10 @@ export function activate(context: vscode.ExtensionContext) { return getServerNames(scope); }, + getServerSummary(name: string, scope?: vscode.ConfigurationScope): ServerName | undefined { + return getServerSummary(name, scope); + }, + async getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false): Promise { return await getServerSpec(name, scope, flushCredentialCache); }, diff --git a/src/ui/serverManagerView.ts b/src/ui/serverManagerView.ts index 353e820..8ab6b6f 100644 --- a/src/ui/serverManagerView.ts +++ b/src/ui/serverManagerView.ts @@ -1,17 +1,54 @@ import * as vscode from 'vscode'; import { getServerNames } from '../api/getServerNames'; +import { getServerSummary } from '../api/getServerSummary'; import { ServerName } from '../extension'; +const SETTINGS_VERSION = 'v1'; + +namespace StorageIds { + export const favorites = `tree.${SETTINGS_VERSION}.favorites`; +} + +const favoritesMap = new Map(); + export class ServerManagerView { + private _globalState: vscode.Memento; + + private _treeDataProvider: SMNodeProvider; + + async addToFavorites(name: string) { + if (!favoritesMap.has(name)) { + favoritesMap.set(name, null); + await this._globalState.update(StorageIds.favorites, Array.from(favoritesMap.keys())); + } + } + + async removeFromFavorites(name: string) { + if (favoritesMap.delete(name)) { + await this._globalState.update(StorageIds.favorites, Array.from(favoritesMap.keys())); + } + }; + + refreshTree() { + this._treeDataProvider.refresh(); + } + constructor(context: vscode.ExtensionContext) { + this._globalState = context.globalState; const treeDataProvider = new SMNodeProvider(); - const view = vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: false }); - context.subscriptions.push(view); + this._treeDataProvider = treeDataProvider; + context.subscriptions.push( + vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: false }) + ); + + // load favoritesMap + const favorites = this._globalState.get(StorageIds.favorites) || []; + favorites.forEach((name) => favoritesMap.set(name, null)); } } -export class SMNodeProvider implements vscode.TreeDataProvider { +class SMNodeProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; @@ -30,11 +67,11 @@ export class SMNodeProvider implements vscode.TreeDataProvider { getChildren(element?: SMTreeItem): SMTreeItem[] { const children: SMTreeItem[] = []; if (!element) { - children.push(new SMTreeItem({label: 'Current', codiconName: 'home'})); - children.push(new SMTreeItem({label: 'Starred', codiconName: 'star'})); - children.push(new SMTreeItem({label: 'Recent', codiconName: 'history'})); - children.push(new SMTreeItem({label: 'All : Ordered', tooltip: 'Sequenced as found in settings.json', codiconName: 'list-ordered', getChildren: getChildrenServers, params: {sorted: false}})); - children.push(new SMTreeItem({label: 'All : Sorted', tooltip: 'Alphabetic order', codiconName: 'triangle-down', getChildren: getChildrenServers, params: {sorted: true}})); + children.push(new SMTreeItem({label: 'Current', tooltip: 'Servers used by current workspace', codiconName: 'home', getChildren: currentServers})); + children.push(new SMTreeItem({label: 'Starred', tooltip: 'Favorite servers', codiconName: 'star-full', getChildren: favoriteServers})); + children.push(new SMTreeItem({label: 'Recent', tooltip: 'Recently used servers', codiconName: 'history'})); + children.push(new SMTreeItem({label: 'Ordered', tooltip: 'All servers in settings.json order', codiconName: 'list-ordered', getChildren: allServers, params: {sorted: false}})); + children.push(new SMTreeItem({label: 'Sorted', tooltip: 'All servers in alphabetical order', codiconName: 'triangle-down', getChildren: allServers, params: {sorted: true}})); return children; } else{ @@ -46,14 +83,14 @@ export class SMNodeProvider implements vscode.TreeDataProvider { interface SMItem { label: string, contextValue?: string, - tooltip?: string, + tooltip?: string | vscode.MarkdownString, description?: string, codiconName?: string, getChildren?: Function, params?: any } -export class SMTreeItem extends vscode.TreeItem { +class SMTreeItem extends vscode.TreeItem { private readonly _getChildren?: Function; private readonly _params?: any; @@ -82,15 +119,15 @@ export class SMTreeItem extends vscode.TreeItem { } } -function getChildrenServers(element?: SMTreeItem, params?: any): SMTreeItem[] { - const children: SMTreeItem[] = []; +function allServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { + const children: ServerTreeItem[] = []; const getAllServers = (sorted?: boolean): ServerTreeItem[] => { let serverNames = getServerNames(); if (sorted) { serverNames = serverNames.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); } return serverNames.map((serverName) => { - return new ServerTreeItem(serverName); + return new ServerTreeItem(serverName, sorted ? 'sorted' : 'ordered'); }) } @@ -98,14 +135,45 @@ function getChildrenServers(element?: SMTreeItem, params?: any): SMTreeItem[] { return children; } -export class ServerTreeItem extends SMTreeItem { +function currentServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { + const children = new Map(); + + vscode.workspace.workspaceFolders?.map((folder) => { + const serverName = folder.uri.authority.split(':')[0]; + if (['isfs', 'isfs-readonly'].includes(folder.uri.scheme)) { + const serverSummary = getServerSummary(serverName); + if (serverSummary) { + children.set(serverName, new ServerTreeItem(serverSummary, 'current')); + } + } + }); + return Array.from(children.values()).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); +} + +function favoriteServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { + const children: ServerTreeItem[] = []; + favoritesMap.forEach((_, name) => { + const serverSummary = getServerSummary(name); + if (serverSummary) { + children.push(new ServerTreeItem(serverSummary, 'starred')); + } + }); + + return children.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); +} + +export class ServerTreeItem extends SMTreeItem { + public readonly name: string; constructor( serverName: ServerName, + parentFolderId: string ) { - super({label: serverName.name, tooltip: serverName.description, description: serverName.detail}); + // Wrap detail (a uri string) as a null link to prevent it from being linkified + super({label: serverName.name, tooltip: new vscode.MarkdownString(`[${serverName.detail}]()`).appendMarkdown(serverName.description ? `\n\n*${serverName.description}*` : '')}); + this.name = serverName.name; this.command = {command: 'intersystems-community.servermanager.openManagementPortalInSimpleBrowser', title: 'Open Management Portal in Simple Browser Tab', arguments: [this]}; + this.contextValue = `${parentFolderId}.server.${favoritesMap.has(this.name) ? 'starred' : ''}`; + this.iconPath = new vscode.ThemeIcon('server-environment'); } - iconPath = new vscode.ThemeIcon('server-environment'); - contextValue = 'server'; } From cec8d85cc6c0db0a2ef8fc5fdb6f3b454b403298 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Tue, 13 Apr 2021 14:19:10 +0100 Subject: [PATCH 3/9] SNAPSHOT.1 --- images/serverManager.svg | 16 +---- images/toolsContainer.svg | 16 +---- package.json | 79 ++++++++++++++++++++++++- src/api/getPortalUriWithCredentials.ts | 7 ++- src/extension.ts | 82 ++++++++++++++++++++++++-- src/ui/serverManagerView.ts | 76 ++++++++++++++++++++++-- 6 files changed, 235 insertions(+), 41 deletions(-) diff --git a/images/serverManager.svg b/images/serverManager.svg index 53e5be5..31a3119 100644 --- a/images/serverManager.svg +++ b/images/serverManager.svg @@ -1,14 +1,4 @@ - - - - Slice - Created with Sketch. - - - - - - - - + + diff --git a/images/toolsContainer.svg b/images/toolsContainer.svg index 53e5be5..27343f8 100644 --- a/images/toolsContainer.svg +++ b/images/toolsContainer.svg @@ -1,14 +1,4 @@ - - - - Slice - Created with Sketch. - - - - - - - - + + diff --git a/package.json b/package.json index 904e501..432bc79 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "servermanager", "displayName": "InterSystems Server Manager", - "version": "2.0.0-SNAPSHOT", + "version": "2.0.0-SNAPSHOT.1", "publisher": "intersystems-community", "description": "Helper extension for defining connections to InterSystems servers.", "repository": { @@ -60,6 +60,7 @@ "main": "./out/extension", "activationEvents": [ "onView:intersystems-community_servermanager", + "onCommand:intersystems-community.servermanager.refreshTree", "onCommand:intersystems-community.servermanager.addServer", "onCommand:intersystems-community.servermanager.storePassword", "onCommand:intersystems-community.servermanager.clearPassword", @@ -241,7 +242,8 @@ { "command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser", "category": "InterSystems Server Manager", - "title": "Open Management Portal in Simple Browser Tab" + "title": "Open Management Portal in Simple Browser Tab", + "icon": "$(tools)" }, { "command": "intersystems-community.servermanager.storePassword", @@ -258,9 +260,73 @@ "command": "intersystems-community.servermanager.importServers", "category": "InterSystems Server Manager", "title": "Import Servers from Registry" + }, + { + "command": "intersystems-community.servermanager.setIconRed", + "title": "Red" + }, + { + "command": "intersystems-community.servermanager.setIconOrange", + "title": "Orange" + }, + { + "command": "intersystems-community.servermanager.setIconYellow", + "title": "Yellow" + }, + { + "command": "intersystems-community.servermanager.setIconGreen", + "title": "Green" + }, + { + "command": "intersystems-community.servermanager.setIconBlue", + "title": "Blue" + }, + { + "command": "intersystems-community.servermanager.setIconPurple", + "title": "Purple" + }, + { + "command": "intersystems-community.servermanager.resetIconColor", + "title": "default" + } + ], + "submenus": [ + { + "id": "intersystems-community.servermanager.iconColor", + "label": "Set Icon Color" } ], "menus": { + "intersystems-community.servermanager.iconColor": [ + { + "command": "intersystems-community.servermanager.setIconRed", + "group": "color" + }, + { + "command": "intersystems-community.servermanager.setIconOrange", + "group": "color" + }, + { + "command": "intersystems-community.servermanager.setIconYellow", + "group": "color" + }, + { + "command": "intersystems-community.servermanager.setIconGreen", + "group": "color" + }, + { + "command": "intersystems-community.servermanager.setIconBlue", + "group": "color" + }, + { + "command": "intersystems-community.servermanager.setIconPurple", + "group": "color" + }, + { + "command": "intersystems-community.servermanager.resetIconColor", + "group": "reset" + } + ], "commandPalette": [ { "command": "intersystems-community.servermanager.importServers", @@ -310,11 +376,20 @@ "when": "view == intersystems-community_servermanager && viewItem == starred.server.starred", "group": "inline@10" }, + { + "command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser", + "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", + "group": "inline@80" + }, { "command": "intersystems-community.servermanager.openManagementPortalExternal", "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", "group": "inline@90" }, + { + "submenu": "intersystems-community.servermanager.iconColor", + "group": "color" + }, { "command": "intersystems-community.servermanager.storePassword", "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", diff --git a/src/api/getPortalUriWithCredentials.ts b/src/api/getPortalUriWithCredentials.ts index 1281c99..21347d1 100644 --- a/src/api/getPortalUriWithCredentials.ts +++ b/src/api/getPortalUriWithCredentials.ts @@ -1,9 +1,12 @@ import * as vscode from 'vscode'; import { Uri } from 'vscode'; -import { getServerSpec } from './getServerSpec'; +import { extensionId } from '../extension'; export async function getPortalUriWithCredentials(name: string, scope?: vscode.ConfigurationScope): Promise { - return getServerSpec(name, scope).then((spec) => { + + // Use our own API so that the Recent folder updates with our activity + const myApi = vscode.extensions.getExtension(extensionId)?.exports; + return myApi.getServerSpec(name, scope).then((spec) => { if (typeof spec !== 'undefined') { const webServer = spec.webServer; let queryString = ''; diff --git a/src/extension.ts b/src/extension.ts index 446a422..763553b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -56,14 +56,12 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand(`${extensionId}.addServer`, async () => { await addServer(); - view.refreshTree(); }) ); context.subscriptions.push( vscode.commands.registerCommand(`${extensionId}.addToStarred`, async (server?: ServerTreeItem) => { if (server?.contextValue?.match(/\.server\./) && server.name) { await view.addToFavorites(server.name); - view.refreshTree(); } }) ); @@ -71,7 +69,6 @@ export function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand(`${extensionId}.removeFromStarred`, async (server?: ServerTreeItem) => { if (server?.contextValue?.endsWith('.starred') && server.name) { await view.removeFromFavorites(server.name); - view.refreshTree(); } }) ); @@ -120,6 +117,62 @@ export function activate(context: vscode.ExtensionContext) { } }); }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.setIconRed`, (server?: ServerTreeItem) => { + if (server?.name) { + view.setIconColor(server.name, 'red'); + view.refreshTree(); + } + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.setIconOrange`, (server?: ServerTreeItem) => { + if (server?.name) { + view.setIconColor(server.name, 'orange'); + view.refreshTree(); + } + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.setIconYellow`, (server?: ServerTreeItem) => { + if (server?.name) { + view.setIconColor(server.name, 'yellow'); + view.refreshTree(); + } + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.setIconGreen`, (server?: ServerTreeItem) => { + if (server?.name) { + view.setIconColor(server.name, 'green'); + view.refreshTree(); + } + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.setIconBlue`, (server?: ServerTreeItem) => { + if (server?.name) { + view.setIconColor(server.name, 'blue'); + view.refreshTree(); + } + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.setIconPurple`, (server?: ServerTreeItem) => { + if (server?.name) { + view.setIconColor(server.name, 'purple'); + view.refreshTree(); + } + }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.resetIconColor`, (server?: ServerTreeItem) => { + if (server?.name) { + view.setIconColor(server.name, undefined); + view.refreshTree(); + } + }) ); context.subscriptions.push( vscode.commands.registerCommand(`${extensionId}.importServers`, async () => { @@ -128,10 +181,25 @@ export function activate(context: vscode.ExtensionContext) { }) ); + // Listen for relevant configuration changes + context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('intersystems.servers') || e.affectsConfiguration('objectscript.conn')) { + view.refreshTree(); + } + })); + + // Expose our API let api = { async pickServer(scope?: vscode.ConfigurationScope, options: vscode.QuickPickOptions = {}): Promise { - return await pickServer(scope, options); + const name = await pickServer(scope, options); + /* + if (name) { + view.addToRecents(name); + } + */ + + return name; }, getServerNames(scope?: vscode.ConfigurationScope): ServerName[] { return getServerNames(scope); @@ -142,7 +210,11 @@ export function activate(context: vscode.ExtensionContext) { }, async getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false): Promise { - return await getServerSpec(name, scope, flushCredentialCache); + const spec = await getServerSpec(name, scope, flushCredentialCache); + if (spec) { + view.addToRecents(name); + } + return spec; }, onDidChangePassword(): vscode.Event { diff --git a/src/ui/serverManagerView.ts b/src/ui/serverManagerView.ts index 8ab6b6f..e340111 100644 --- a/src/ui/serverManagerView.ts +++ b/src/ui/serverManagerView.ts @@ -7,26 +7,59 @@ const SETTINGS_VERSION = 'v1'; namespace StorageIds { export const favorites = `tree.${SETTINGS_VERSION}.favorites`; + export const iconColors = `tree.${SETTINGS_VERSION}.iconColors`; } const favoritesMap = new Map(); +const colorsMap = new Map(); + +let recentsArray: string[] = []; + export class ServerManagerView { private _globalState: vscode.Memento; private _treeDataProvider: SMNodeProvider; + addToRecents(name: string) { + if (recentsArray[0] !== name) { + recentsArray = recentsArray.filter((n) => n !== name); + if (recentsArray.unshift(name) > 8) { + recentsArray.pop() + } + + // Delay the refresh to avoid startling the user by updating the tree the instant they click on a command button + setTimeout(() => this.refreshTree(), 1000); + } + } + async addToFavorites(name: string) { if (!favoritesMap.has(name)) { favoritesMap.set(name, null); await this._globalState.update(StorageIds.favorites, Array.from(favoritesMap.keys())); + this.refreshTree(); } } async removeFromFavorites(name: string) { if (favoritesMap.delete(name)) { await this._globalState.update(StorageIds.favorites, Array.from(favoritesMap.keys())); + this.refreshTree(); + } + }; + + async setIconColor(name: string, color: string | undefined) { + let changed = false; + if (typeof color === 'undefined') { + changed = colorsMap.delete(name); + } + else if (colorsMap.get(name) !== color) { + colorsMap.set(name, color); + changed = true; + } + if (changed) { + await this._globalState.update(StorageIds.iconColors, Array.from(colorsMap.entries())); } }; @@ -39,12 +72,16 @@ export class ServerManagerView { const treeDataProvider = new SMNodeProvider(); this._treeDataProvider = treeDataProvider; context.subscriptions.push( - vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: false }) + vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: true }) ); // load favoritesMap const favorites = this._globalState.get(StorageIds.favorites) || []; favorites.forEach((name) => favoritesMap.set(name, null)); + + // load colorsMap + const colors = this._globalState.get(StorageIds.iconColors) || []; + colors.forEach((pair) => colorsMap.set(pair[0], pair[1])); } } @@ -67,9 +104,13 @@ class SMNodeProvider implements vscode.TreeDataProvider { getChildren(element?: SMTreeItem): SMTreeItem[] { const children: SMTreeItem[] = []; if (!element) { - children.push(new SMTreeItem({label: 'Current', tooltip: 'Servers used by current workspace', codiconName: 'home', getChildren: currentServers})); - children.push(new SMTreeItem({label: 'Starred', tooltip: 'Favorite servers', codiconName: 'star-full', getChildren: favoriteServers})); - children.push(new SMTreeItem({label: 'Recent', tooltip: 'Recently used servers', codiconName: 'history'})); + if (vscode.workspace.workspaceFolders?.length || 0 > 0) { + children.push(new SMTreeItem({label: 'Current', tooltip: 'Servers used by current workspace', codiconName: 'home', getChildren: currentServers})); + } + if (favoritesMap.size > 0) { + children.push(new SMTreeItem({label: 'Starred', tooltip: 'Favorite servers', codiconName: 'star-full', getChildren: favoriteServers})); + } + children.push(new SMTreeItem({label: 'Recent', tooltip: 'Recently used servers', codiconName: 'history', getChildren: recentServers})); children.push(new SMTreeItem({label: 'Ordered', tooltip: 'All servers in settings.json order', codiconName: 'list-ordered', getChildren: allServers, params: {sorted: false}})); children.push(new SMTreeItem({label: 'Sorted', tooltip: 'All servers in alphabetical order', codiconName: 'triangle-down', getChildren: allServers, params: {sorted: true}})); return children; @@ -146,7 +187,16 @@ function currentServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { children.set(serverName, new ServerTreeItem(serverSummary, 'current')); } } + const conn = vscode.workspace.getConfiguration('objectscript.conn', folder); + const connServer = conn.get('server'); + if (connServer) { + const serverSummary = getServerSummary(connServer); + if (serverSummary) { + children.set(connServer, new ServerTreeItem(serverSummary, 'current')); + } + } }); + return Array.from(children.values()).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); } @@ -163,6 +213,19 @@ function favoriteServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { return children.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); } +function recentServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { + const children: ServerTreeItem[] = []; + + recentsArray.map((name) => { + const serverSummary = getServerSummary(name); + if (serverSummary) { + children.push(new ServerTreeItem(serverSummary, 'recent')); + } + }); + + return children; +} + export class ServerTreeItem extends SMTreeItem { public readonly name: string; constructor( @@ -172,8 +235,9 @@ export class ServerTreeItem extends SMTreeItem { // Wrap detail (a uri string) as a null link to prevent it from being linkified super({label: serverName.name, tooltip: new vscode.MarkdownString(`[${serverName.detail}]()`).appendMarkdown(serverName.description ? `\n\n*${serverName.description}*` : '')}); this.name = serverName.name; - this.command = {command: 'intersystems-community.servermanager.openManagementPortalInSimpleBrowser', title: 'Open Management Portal in Simple Browser Tab', arguments: [this]}; + //this.command = {command: 'intersystems-community.servermanager.openManagementPortalInSimpleBrowser', title: 'Open Management Portal in Simple Browser Tab', arguments: [this]}; this.contextValue = `${parentFolderId}.server.${favoritesMap.has(this.name) ? 'starred' : ''}`; - this.iconPath = new vscode.ThemeIcon('server-environment'); + const color = colorsMap.get(this.name); + this.iconPath = new vscode.ThemeIcon('server-environment', color ? new vscode.ThemeColor('charts.' + color) : undefined); } } From 6cd479231405482a0a12346daa448fc8b1c1cc11 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Wed, 14 Apr 2021 01:40:33 +0100 Subject: [PATCH 4/9] SNAPSHOT.2 --- package-lock.json | 155 +++++++++++++++++++++++++++++++-- package.json | 10 ++- src/extension.ts | 16 +--- src/makeRESTRequest.ts | 118 ++++++++++++++++++++++++++ src/ui/serverManagerView.ts | 165 +++++++++++++++++++++++++++--------- 5 files changed, 404 insertions(+), 60 deletions(-) create mode 100644 src/makeRESTRequest.ts diff --git a/package-lock.json b/package-lock.json index 58a5ebe..4e6ed8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,19 @@ { "name": "servermanager", - "version": "2.0.0-SNAPSHOT", + "version": "2.0.0-SNAPSHOT.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "servermanager", - "version": "2.0.0-SNAPSHOT", + "version": "2.0.0-SNAPSHOT.1", "license": "MIT", "dependencies": { "@types/vscode": "^1.55.0", - "node-cmd": "^4.0.0" + "axios": "^0.21.1", + "axios-cookiejar-support": "^1.0.1", + "node-cmd": "^4.0.0", + "tough-cookie": "^4.0.0" }, "devDependencies": { "@types/glob": "^7.1.1", @@ -94,6 +97,12 @@ "integrity": "sha512-l+zSbvT8TPRaCxL1l9cwHCb0tSqGAGcjPJFItGGYat5oCTiq1uQQKYg5m7AF1mgnEBzFXGLJ2LRmNjtreRX76Q==", "dev": true }, + "node_modules/@types/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==", + "peer": true + }, "node_modules/@types/vscode": { "version": "1.55.0", "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.55.0.tgz", @@ -185,6 +194,31 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "dependencies": { + "follow-redirects": "^1.10.0" + } + }, + "node_modules/axios-cookiejar-support": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-1.0.1.tgz", + "integrity": "sha512-IZJxnAJ99XxiLqNeMOqrPbfR7fRyIfaoSLdPUf4AMQEGkH8URs0ghJK/xtqBsD+KsSr3pKl4DEQjCn834pHMig==", + "dependencies": { + "is-redirect": "^1.0.0", + "pify": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@types/tough-cookie": ">=2.3.3", + "axios": ">=0.16.2", + "tough-cookie": ">=2.3.3" + } + }, "node_modules/azure-devops-node-api": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz", @@ -764,7 +798,6 @@ "version": "1.13.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==", - "dev": true, "engines": { "node": ">=4.0" } @@ -1098,6 +1131,14 @@ "node": ">=8" } }, + "node_modules/is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -1791,6 +1832,17 @@ "node": ">=8.6" } }, + "node_modules/pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/prebuild-install": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.4.tgz", @@ -1832,6 +1884,11 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -1842,6 +1899,14 @@ "once": "^1.3.1" } }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -2133,6 +2198,19 @@ "node": ">=8.0" } }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/ts-loader": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", @@ -2265,6 +2343,14 @@ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", "dev": true }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/url-join": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", @@ -2667,6 +2753,12 @@ "integrity": "sha512-l+zSbvT8TPRaCxL1l9cwHCb0tSqGAGcjPJFItGGYat5oCTiq1uQQKYg5m7AF1mgnEBzFXGLJ2LRmNjtreRX76Q==", "dev": true }, + "@types/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==", + "peer": true + }, "@types/vscode": { "version": "1.55.0", "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.55.0.tgz", @@ -2743,6 +2835,23 @@ "sprintf-js": "~1.0.2" } }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "axios-cookiejar-support": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-1.0.1.tgz", + "integrity": "sha512-IZJxnAJ99XxiLqNeMOqrPbfR7fRyIfaoSLdPUf4AMQEGkH8URs0ghJK/xtqBsD+KsSr3pKl4DEQjCn834pHMig==", + "requires": { + "is-redirect": "^1.0.0", + "pify": "^5.0.0" + } + }, "azure-devops-node-api": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz", @@ -3228,8 +3337,7 @@ "follow-redirects": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", - "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==", - "dev": true + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==" }, "fs-constants": { "version": "1.0.0", @@ -3502,6 +3610,11 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -4063,6 +4176,11 @@ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "dev": true }, + "pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==" + }, "prebuild-install": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.4.tgz", @@ -4098,6 +4216,11 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -4108,6 +4231,11 @@ "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==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -4355,6 +4483,16 @@ "is-number": "^7.0.0" } }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, "ts-loader": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", @@ -4463,6 +4601,11 @@ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", "dev": true }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, "url-join": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", diff --git a/package.json b/package.json index 432bc79..caf2e1c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "servermanager", "displayName": "InterSystems Server Manager", - "version": "2.0.0-SNAPSHOT.1", + "version": "2.0.0-SNAPSHOT.2", "publisher": "intersystems-community", "description": "Helper extension for defining connections to InterSystems servers.", "repository": { @@ -41,7 +41,10 @@ }, "dependencies": { "@types/vscode": "^1.55.0", - "node-cmd": "^4.0.0" + "axios": "^0.21.1", + "axios-cookiejar-support": "^1.0.1", + "node-cmd": "^4.0.0", + "tough-cookie": "^4.0.0" }, "devDependencies": { "@types/glob": "^7.1.1", @@ -289,7 +292,7 @@ "command": "intersystems-community.servermanager.resetIconColor", "title": "default" } - ], + ], "submenus": [ { "id": "intersystems-community.servermanager.iconColor", @@ -388,6 +391,7 @@ }, { "submenu": "intersystems-community.servermanager.iconColor", + "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", "group": "color" }, { diff --git a/src/extension.ts b/src/extension.ts index 763553b..197fb95 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -191,15 +191,7 @@ export function activate(context: vscode.ExtensionContext) { // Expose our API let api = { async pickServer(scope?: vscode.ConfigurationScope, options: vscode.QuickPickOptions = {}): Promise { - const name = await pickServer(scope, options); - - /* - if (name) { - view.addToRecents(name); - } - */ - - return name; + return await pickServer(scope, options); }, getServerNames(scope?: vscode.ConfigurationScope): ServerName[] { return getServerNames(scope); @@ -209,10 +201,10 @@ export function activate(context: vscode.ExtensionContext) { return getServerSummary(name, scope); }, - async getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false): Promise { + async getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false, options?: { hideFromRecents?: boolean}): Promise { const spec = await getServerSpec(name, scope, flushCredentialCache); - if (spec) { - view.addToRecents(name); + if (spec && !options?.hideFromRecents) { + await view.addToRecents(name); } return spec; }, diff --git a/src/makeRESTRequest.ts b/src/makeRESTRequest.ts new file mode 100644 index 0000000..0bd6673 --- /dev/null +++ b/src/makeRESTRequest.ts @@ -0,0 +1,118 @@ +// Derived from https://github.com/intersystems/language-server/blob/bdeea88d1900a3aff35d5ac373436899f3904a7e/server/src/server.ts + +import axios, { AxiosResponse } from 'axios'; +import axiosCookieJarSupport from 'axios-cookiejar-support'; +import tough = require('tough-cookie'); +import { ServerSpec } from './extension'; + +axiosCookieJarSupport(axios); + +/** + * Cookie jar for REST requests to InterSystems servers. + */ +let cookieJar: tough.CookieJar = new tough.CookieJar(); + +export interface AtelierRESTEndpoint { + apiVersion: number, + namespace: string, + path: string +}; + +/** + * Make a REST request to an InterSystems server. + * + * @param method The REST method. + * @param server The server to send the request to. + * @param endpoint Optional endpoint object. If omitted the request will be to /api/atelier/ + * @param data Optional request data. Usually passed for POST requests. + */ + export async function makeRESTRequest(method: "GET"|"POST", server: ServerSpec, endpoint?: AtelierRESTEndpoint, data?: any): Promise { + + // Build the URL + var url = server.webServer.scheme + "://" + server.webServer.host + ":" + String(server.webServer.port); + const pathPrefix = server.webServer.pathPrefix; + if (pathPrefix && pathPrefix !== "") { + url = url.concat("/",pathPrefix) + } + url += "/api/atelier/"; + if (endpoint) { + url += "/api/atelier/v" + String(endpoint.apiVersion) + "/" + endpoint.namespace + endpoint.path; + } + + // Make the request (SASchema support removed) + try { + var respdata: AxiosResponse; + if (data !== undefined) { + // There is a data payload + respdata = await axios.request( + { + method: method, + url: encodeURI(url), + data: data, + headers: { + 'Content-Type': 'application/json' + }, + withCredentials: true, + jar: cookieJar, + validateStatus: function (status) { + return status < 500; + } + } + ); + if (respdata.status === 401) { + // Either we had no cookies or they expired, so resend the request with basic auth + + respdata = await axios.request( + { + method: method, + url: url, + data: data, + headers: { + 'Content-Type': 'application/json' + }, + auth: { + username: server.username || "", + password: server.password || "" + }, + withCredentials: true, + jar: cookieJar + } + ); + } + } + else { + // No data payload + respdata = await axios.request( + { + method: method, + url: url, + withCredentials: true, + jar: cookieJar, + validateStatus: function (status) { + return status < 500; + } + } + ); + if (respdata.status === 401) { + // Either we had no cookies or they expired, so resend the request with basic auth + + respdata = await axios.request( + { + method: method, + url: url, + auth: { + username: server.username || "", + password: server.password || "" + }, + withCredentials: true, + jar: cookieJar + } + ); + } + } + return respdata; + } catch (error) { + console.log(error); + return undefined; + } +}; diff --git a/src/ui/serverManagerView.ts b/src/ui/serverManagerView.ts index e340111..7fc0986 100644 --- a/src/ui/serverManagerView.ts +++ b/src/ui/serverManagerView.ts @@ -1,12 +1,15 @@ import * as vscode from 'vscode'; import { getServerNames } from '../api/getServerNames'; +import { getServerSpec } from '../api/getServerSpec'; import { getServerSummary } from '../api/getServerSummary'; import { ServerName } from '../extension'; +import { makeRESTRequest } from '../makeRESTRequest'; const SETTINGS_VERSION = 'v1'; namespace StorageIds { export const favorites = `tree.${SETTINGS_VERSION}.favorites`; + export const recents = `tree.${SETTINGS_VERSION}.recents`; export const iconColors = `tree.${SETTINGS_VERSION}.iconColors`; } @@ -22,7 +25,27 @@ export class ServerManagerView { private _treeDataProvider: SMNodeProvider; - addToRecents(name: string) { + constructor(context: vscode.ExtensionContext) { + this._globalState = context.globalState; + const treeDataProvider = new SMNodeProvider(); + this._treeDataProvider = treeDataProvider; + context.subscriptions.push( + vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: true }) + ); + + // load favoritesMap + const favorites = this._globalState.get(StorageIds.favorites) || []; + favorites.forEach((name) => favoritesMap.set(name, null)); + + // load recentsArray + recentsArray = this._globalState.get(StorageIds.recents) || []; + + // load colorsMap + const colors = this._globalState.get(StorageIds.iconColors) || []; + colors.forEach((pair) => colorsMap.set(pair[0], pair[1])); + } + + async addToRecents(name: string) { if (recentsArray[0] !== name) { recentsArray = recentsArray.filter((n) => n !== name); if (recentsArray.unshift(name) > 8) { @@ -31,6 +54,7 @@ export class ServerManagerView { // Delay the refresh to avoid startling the user by updating the tree the instant they click on a command button setTimeout(() => this.refreshTree(), 1000); + await this._globalState.update(StorageIds.recents, recentsArray); } } @@ -67,22 +91,6 @@ export class ServerManagerView { this._treeDataProvider.refresh(); } - constructor(context: vscode.ExtensionContext) { - this._globalState = context.globalState; - const treeDataProvider = new SMNodeProvider(); - this._treeDataProvider = treeDataProvider; - context.subscriptions.push( - vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: true }) - ); - - // load favoritesMap - const favorites = this._globalState.get(StorageIds.favorites) || []; - favorites.forEach((name) => favoritesMap.set(name, null)); - - // load colorsMap - const colors = this._globalState.get(StorageIds.iconColors) || []; - colors.forEach((pair) => colorsMap.set(pair[0], pair[1])); - } } class SMNodeProvider implements vscode.TreeDataProvider { @@ -101,28 +109,30 @@ class SMNodeProvider implements vscode.TreeDataProvider { return element; } - getChildren(element?: SMTreeItem): SMTreeItem[] { + async getChildren(element?: SMTreeItem): Promise { const children: SMTreeItem[] = []; if (!element) { + // Root folders if (vscode.workspace.workspaceFolders?.length || 0 > 0) { - children.push(new SMTreeItem({label: 'Current', tooltip: 'Servers used by current workspace', codiconName: 'home', getChildren: currentServers})); + children.push(new SMTreeItem({label: 'Current', id: 'current', tooltip: 'Servers used by current workspace', codiconName: 'home', getChildren: currentServers})); } if (favoritesMap.size > 0) { - children.push(new SMTreeItem({label: 'Starred', tooltip: 'Favorite servers', codiconName: 'star-full', getChildren: favoriteServers})); + children.push(new SMTreeItem({label: 'Starred', id: 'starred', tooltip: 'Favorite servers', codiconName: 'star-full', getChildren: favoriteServers})); } - children.push(new SMTreeItem({label: 'Recent', tooltip: 'Recently used servers', codiconName: 'history', getChildren: recentServers})); - children.push(new SMTreeItem({label: 'Ordered', tooltip: 'All servers in settings.json order', codiconName: 'list-ordered', getChildren: allServers, params: {sorted: false}})); - children.push(new SMTreeItem({label: 'Sorted', tooltip: 'All servers in alphabetical order', codiconName: 'triangle-down', getChildren: allServers, params: {sorted: true}})); + children.push(new SMTreeItem({label: 'Recent', id: 'recent', tooltip: 'Recently used servers', codiconName: 'history', getChildren: recentServers})); + children.push(new SMTreeItem({label: 'Ordered', id: 'ordered', tooltip: 'All servers in settings.json order', codiconName: 'list-ordered', getChildren: allServers, params: {sorted: false}})); + children.push(new SMTreeItem({label: 'Sorted', id: 'sorted', tooltip: 'All servers in alphabetical order', codiconName: 'triangle-down', getChildren: allServers, params: {sorted: true}})); return children; } - else{ - return element.getChildren() + else { + return await element.getChildren(); } } } interface SMItem { label: string, + id: string, contextValue?: string, tooltip?: string | vscode.MarkdownString, description?: string, @@ -140,6 +150,7 @@ class SMTreeItem extends vscode.TreeItem { const collapsibleState = item.getChildren ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None; super(item.label, collapsibleState); + this.id = item.id; this.contextValue = item.contextValue; this.tooltip = item.tooltip; this.description = item.description; @@ -150,9 +161,9 @@ class SMTreeItem extends vscode.TreeItem { this._params = item.params; } - public getChildren(): SMTreeItem[] { + public async getChildren(): Promise { if (this._getChildren) { - return this._getChildren(this, this._params); + return await this._getChildren(this, this._params) || []; } else { return []; @@ -160,7 +171,7 @@ class SMTreeItem extends vscode.TreeItem { } } -function allServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { +function allServers(element: SMTreeItem, params?: any): ServerTreeItem[] { const children: ServerTreeItem[] = []; const getAllServers = (sorted?: boolean): ServerTreeItem[] => { let serverNames = getServerNames(); @@ -168,7 +179,7 @@ function allServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { serverNames = serverNames.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); } return serverNames.map((serverName) => { - return new ServerTreeItem(serverName, sorted ? 'sorted' : 'ordered'); + return new ServerTreeItem(sorted ? 'sorted' : 'ordered', serverName); }) } @@ -176,7 +187,7 @@ function allServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { return children; } -function currentServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { +function currentServers(element: SMTreeItem, params?: any): ServerTreeItem[] { const children = new Map(); vscode.workspace.workspaceFolders?.map((folder) => { @@ -184,7 +195,7 @@ function currentServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { if (['isfs', 'isfs-readonly'].includes(folder.uri.scheme)) { const serverSummary = getServerSummary(serverName); if (serverSummary) { - children.set(serverName, new ServerTreeItem(serverSummary, 'current')); + children.set(serverName, new ServerTreeItem('current', serverSummary)); } } const conn = vscode.workspace.getConfiguration('objectscript.conn', folder); @@ -192,7 +203,7 @@ function currentServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { if (connServer) { const serverSummary = getServerSummary(connServer); if (serverSummary) { - children.set(connServer, new ServerTreeItem(serverSummary, 'current')); + children.set(connServer, new ServerTreeItem('current', serverSummary)); } } }); @@ -200,26 +211,26 @@ function currentServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { return Array.from(children.values()).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); } -function favoriteServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { +function favoriteServers(element: SMTreeItem, params?: any): ServerTreeItem[] { const children: ServerTreeItem[] = []; favoritesMap.forEach((_, name) => { const serverSummary = getServerSummary(name); if (serverSummary) { - children.push(new ServerTreeItem(serverSummary, 'starred')); + children.push(new ServerTreeItem('starred', serverSummary)); } }); return children.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); } -function recentServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { +function recentServers(element: SMTreeItem, params?: any): ServerTreeItem[] { const children: ServerTreeItem[] = []; recentsArray.map((name) => { const serverSummary = getServerSummary(name); if (serverSummary) { - children.push(new ServerTreeItem(serverSummary, 'recent')); + children.push(new ServerTreeItem('recent', serverSummary)); } }); @@ -229,11 +240,16 @@ function recentServers(element?: SMTreeItem, params?: any): ServerTreeItem[] { export class ServerTreeItem extends SMTreeItem { public readonly name: string; constructor( - serverName: ServerName, - parentFolderId: string + parentFolderId: string, + serverName: ServerName ) { // Wrap detail (a uri string) as a null link to prevent it from being linkified - super({label: serverName.name, tooltip: new vscode.MarkdownString(`[${serverName.detail}]()`).appendMarkdown(serverName.description ? `\n\n*${serverName.description}*` : '')}); + super({ + label: serverName.name, + id: parentFolderId + ':' + serverName.name, + tooltip: new vscode.MarkdownString(`[${serverName.detail}]()`).appendMarkdown(serverName.description ? `\n\n*${serverName.description}*` : ''), + getChildren: serverFeatures + }); this.name = serverName.name; //this.command = {command: 'intersystems-community.servermanager.openManagementPortalInSimpleBrowser', title: 'Open Management Portal in Simple Browser Tab', arguments: [this]}; this.contextValue = `${parentFolderId}.server.${favoritesMap.has(this.name) ? 'starred' : ''}`; @@ -241,3 +257,74 @@ export class ServerTreeItem extends SMTreeItem { this.iconPath = new vscode.ThemeIcon('server-environment', color ? new vscode.ThemeColor('charts.' + color) : undefined); } } + +async function serverFeatures(element: ServerTreeItem, params?: any): Promise { + const children: FeatureTreeItem[] = []; + + children.push(new NamespacesTreeItem(element.id || '', element.name)); + + return children; +} + +export class FeatureTreeItem extends SMTreeItem { +} + +export class NamespacesTreeItem extends FeatureTreeItem { + public readonly name: string; + constructor( + parentFolderId: string, + serverName: string + ) { + super({ + label: 'Namespaces', + id: parentFolderId + ':namespaces', + tooltip: `Namespaces you can access`, + getChildren: serverNamespaces, + params: { serverName } + }); + this.name = 'Namespaces'; + this.contextValue = 'namespaces'; + this.iconPath = new vscode.ThemeIcon('library'); + } +} + +async function serverNamespaces(element: ServerTreeItem, params?: any): Promise { + const children: NamespaceTreeItem[] = []; + + if (params?.serverName) { + const server = await getServerSpec(params.serverName) + if (!server) { + return undefined + } + + const response = await makeRESTRequest("GET", server) + + if (response) { + + response.data.result.content.namespaces.map((name) => { + children.push(new NamespaceTreeItem(element.id || '', name, server.name)); + }); + } + } + + return children; +} + +export class NamespaceTreeItem extends SMTreeItem { + public readonly name: string; + constructor( + parentFolderId: string, + name: string, + serverName: string + ) { + const id = parentFolderId + ':' + name; + super({ + label: name, + id, + tooltip: `${name} on ${serverName}` + }); + this.name = name; + this.contextValue = name === '%SYS' ? 'sysnamespace' : 'namespace'; + this.iconPath = new vscode.ThemeIcon('archive'); + } +} From 9e94aaf396ae72bba291a0ff897dcddc485b7387 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Thu, 15 Apr 2021 03:38:56 +0100 Subject: [PATCH 5/9] WIP --- package.json | 43 +++++++++++++++------- src/api/getServerSpec.ts | 72 ++++++++++++++++++++++--------------- src/extension.ts | 14 +++++--- src/makeRESTRequest.ts | 14 ++++---- src/ui/serverManagerView.ts | 67 +++++++++++++++++++++++++++++----- 5 files changed, 149 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index caf2e1c..b613dc2 100644 --- a/package.json +++ b/package.json @@ -83,8 +83,8 @@ "intersystems-community_servermanager": [ { "id": "intersystems-community_servermanager", - "name": "Server Manager", - "contextualTitle": "InterSystems Server Manager", + "name": "Servers", + "contextualTitle": "InterSystems Tools", "icon": "images/serverManager.svg" } ] @@ -237,17 +237,23 @@ "icon": "$(star-empty)" }, { - "command": "intersystems-community.servermanager.openManagementPortalExternal", + "command": "intersystems-community.servermanager.openPortalExternal", "category": "InterSystems Server Manager", "title": "Open Management Portal in External Browser", "icon": "$(link-external)" }, { - "command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser", + "command": "intersystems-community.servermanager.openPortalTab", "category": "InterSystems Server Manager", - "title": "Open Management Portal in Simple Browser Tab", + "title": "Open Management Portal in Tab", "icon": "$(tools)" }, + { + "command": "intersystems-community.servermanager.editSettings", + "category": "InterSystems Server Manager", + "title": "Edit Settings", + "icon": "$(edit)" + }, { "command": "intersystems-community.servermanager.storePassword", "category": "InterSystems Server Manager", @@ -344,11 +350,11 @@ "when": "false" }, { - "command": "intersystems-community.servermanager.openManagementPortalExternal", + "command": "intersystems-community.servermanager.openPortalExternal", "when": "false" }, { - "command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser", + "command": "intersystems-community.servermanager.openPortalTab", "when": "false" } ], @@ -363,9 +369,15 @@ "when": "view == intersystems-community_servermanager", "group": "navigation@20" }, + { + "command": "intersystems-community.servermanager.editSettings", + "when": "view == intersystems-community_servermanager", + "group": "1_edit" + }, { "command": "intersystems-community.servermanager.importServers", - "when": "view == intersystems-community_servermanager && isWindows" + "when": "view == intersystems-community_servermanager && isWindows", + "group": "2_import" } ], "view/item/context": [ @@ -380,29 +392,34 @@ "group": "inline@10" }, { - "command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser", + "command": "intersystems-community.servermanager.openPortalTab", "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", "group": "inline@80" }, { - "command": "intersystems-community.servermanager.openManagementPortalExternal", + "command": "intersystems-community.servermanager.openPortalExternal", "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", "group": "inline@90" }, { "submenu": "intersystems-community.servermanager.iconColor", "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", - "group": "color" + "group": "1_edit@10" + }, + { + "command": "intersystems-community.servermanager.editSettings", + "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", + "group": "1_edit@20" }, { "command": "intersystems-community.servermanager.storePassword", "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", - "group": "password@10" + "group": "2_password@10" }, { "command": "intersystems-community.servermanager.clearPassword", "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", - "group": "password@20" + "group": "2_password@20" } ] } diff --git a/src/api/getServerSpec.ts b/src/api/getServerSpec.ts index 0eecf89..1f18347 100644 --- a/src/api/getServerSpec.ts +++ b/src/api/getServerSpec.ts @@ -9,7 +9,16 @@ interface CredentialSet { export let credentialCache = new Map(); -export async function getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false): Promise { +/** + * Get a server specification. + * + * @param name The name. + * @param scope The settings scope to use for the lookup. + * @param flushCredentialCache Flush the session's cache of credentials obtained from keystore and/or user prompting. + * @param noCredentials Set username and password as undefined; do not fetch credentials from anywhere. + * @returns Server specification or undefined. + */ +export async function getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false, noCredentials: boolean = false): Promise { if (flushCredentialCache) { credentialCache[name] = undefined; } @@ -25,9 +34,15 @@ export async function getServerSpec(name: string, scope?: vscode.ConfigurationSc server.webServer.scheme = server.webServer.scheme || 'http'; server.webServer.pathPrefix = server.webServer.pathPrefix || ''; - // Obtain a username (including blank to try connecting anonymously) - if (!server.username) { - await vscode.window + if (noCredentials) { + server.username = undefined; + server.password = undefined; + } + else { + + // Obtain a username (including blank to try connecting anonymously) + if (!server.username) { + await vscode.window .showInputBox({ placeHolder: `Username to connect to InterSystems server '${name}' as`, prompt: 'Leave empty to attempt unauthenticated access', @@ -40,34 +55,34 @@ export async function getServerSpec(name: string, scope?: vscode.ConfigurationSc return undefined; } }); - if (!server.username) { - server.username = ''; - server.password = ''; + if (!server.username) { + server.username = ''; + server.password = ''; + } } - } - - // Obtain password from session cache or keychain unless trying to connect anonymously - if (server.username && !server.password) { - if (credentialCache[name] && credentialCache[name].username === server.username) { - server.password = credentialCache[name].password; - } else { - const keychain = new Keychain(name); - const password = await keychain.getPassword().then(result => { - if (typeof result === 'string') { - return result; - } else { - return undefined; + + // Obtain password from session cache or keychain unless trying to connect anonymously + if (server.username && !server.password) { + if (credentialCache[name] && credentialCache[name].username === server.username) { + server.password = credentialCache[name].password; + } else { + const keychain = new Keychain(name); + const password = await keychain.getPassword().then(result => { + if (typeof result === 'string') { + return result; + } else { + return undefined; + } + }); + if (password) { + server.password = password; + credentialCache[name] = {username: server.username, password: password}; } - }); - if (password) { - server.password = password; - credentialCache[name] = {username: server.username, password: password}; } + } - - } - if (server.username && !server.password) { - await vscode.window + if (server.username && !server.password) { + await vscode.window .showInputBox({ password: true, placeHolder: `Password for user '${server.username}' on InterSystems server '${name}'`, @@ -84,6 +99,7 @@ export async function getServerSpec(name: string, scope?: vscode.ConfigurationSc server = undefined; } }) + } } return server; } diff --git a/src/extension.ts b/src/extension.ts index 197fb95..b15df35 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -73,7 +73,7 @@ export function activate(context: vscode.ExtensionContext) { }) ); context.subscriptions.push( - vscode.commands.registerCommand(`${extensionId}.openManagementPortalExternal`, (server?: ServerTreeItem) => { + vscode.commands.registerCommand(`${extensionId}.openPortalExternal`, (server?: ServerTreeItem) => { if (server?.contextValue?.match(/\.server\./) && server.name) { getPortalUriWithCredentials(server.name).then((uriWithCredentials) => { if (uriWithCredentials) { @@ -84,7 +84,7 @@ export function activate(context: vscode.ExtensionContext) { }) ); context.subscriptions.push( - vscode.commands.registerCommand(`${extensionId}.openManagementPortalInSimpleBrowser`, (server?: ServerTreeItem) => { + vscode.commands.registerCommand(`${extensionId}.openPortalTab`, (server?: ServerTreeItem) => { if (server?.contextValue?.match(/\.server\./) && server.name) { getPortalUriWithCredentials(server.name).then((uriWithCredentials) => { if (uriWithCredentials) { @@ -97,6 +97,12 @@ export function activate(context: vscode.ExtensionContext) { }); } }) + ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.editSettings`, (server?: ServerTreeItem) => { + // Until there's a dedicated settings editor the best we can do is jump to the right section + vscode.commands.executeCommand('workbench.action.openSettings', `@ext:${extensionId}`); + }) ); context.subscriptions.push( vscode.commands.registerCommand(`${extensionId}.storePassword`, (server?: ServerTreeItem) => { @@ -201,8 +207,8 @@ export function activate(context: vscode.ExtensionContext) { return getServerSummary(name, scope); }, - async getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false, options?: { hideFromRecents?: boolean}): Promise { - const spec = await getServerSpec(name, scope, flushCredentialCache); + async getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false, options?: { hideFromRecents?: boolean, noCredentials?: boolean}): Promise { + const spec = await getServerSpec(name, scope, flushCredentialCache, options?.noCredentials); if (spec && !options?.hideFromRecents) { await view.addToRecents(name); } diff --git a/src/makeRESTRequest.ts b/src/makeRESTRequest.ts index 0bd6673..1d425cb 100644 --- a/src/makeRESTRequest.ts +++ b/src/makeRESTRequest.ts @@ -26,7 +26,7 @@ export interface AtelierRESTEndpoint { * @param endpoint Optional endpoint object. If omitted the request will be to /api/atelier/ * @param data Optional request data. Usually passed for POST requests. */ - export async function makeRESTRequest(method: "GET"|"POST", server: ServerSpec, endpoint?: AtelierRESTEndpoint, data?: any): Promise { + export async function makeRESTRequest(method: "HEAD"|"GET"|"POST", server: ServerSpec, endpoint?: AtelierRESTEndpoint, data?: any): Promise { // Build the URL var url = server.webServer.scheme + "://" + server.webServer.host + ":" + String(server.webServer.port); @@ -59,7 +59,7 @@ export interface AtelierRESTEndpoint { } } ); - if (respdata.status === 401) { + if (respdata.status === 401 && typeof server.username !== 'undefined' && typeof server.password !== 'undefined') { // Either we had no cookies or they expired, so resend the request with basic auth respdata = await axios.request( @@ -71,8 +71,8 @@ export interface AtelierRESTEndpoint { 'Content-Type': 'application/json' }, auth: { - username: server.username || "", - password: server.password || "" + username: server.username, + password: server.password }, withCredentials: true, jar: cookieJar @@ -93,7 +93,7 @@ export interface AtelierRESTEndpoint { } } ); - if (respdata.status === 401) { + if (respdata.status === 401 && typeof server.username !== 'undefined' && typeof server.password !== 'undefined') { // Either we had no cookies or they expired, so resend the request with basic auth respdata = await axios.request( @@ -101,8 +101,8 @@ export interface AtelierRESTEndpoint { method: method, url: url, auth: { - username: server.username || "", - password: server.password || "" + username: server.username, + password: server.password }, withCredentials: true, jar: cookieJar diff --git a/src/ui/serverManagerView.ts b/src/ui/serverManagerView.ts index 7fc0986..ba2a07f 100644 --- a/src/ui/serverManagerView.ts +++ b/src/ui/serverManagerView.ts @@ -29,9 +29,10 @@ export class ServerManagerView { this._globalState = context.globalState; const treeDataProvider = new SMNodeProvider(); this._treeDataProvider = treeDataProvider; - context.subscriptions.push( - vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: true }) - ); + + const treeView = vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: true }) + context.subscriptions.push(treeView); + treeDataProvider.view = treeView; // load favoritesMap const favorites = this._globalState.get(StorageIds.favorites) || []; @@ -98,6 +99,10 @@ class SMNodeProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; + view: vscode.TreeView; + private _firstRevealDone = false; + private _firstRevealItem: SMTreeItem; + constructor() { } @@ -109,19 +114,49 @@ class SMNodeProvider implements vscode.TreeDataProvider { return element; } + getParent(element: SMTreeItem): SMTreeItem | undefined { + return undefined; + } + async getChildren(element?: SMTreeItem): Promise { const children: SMTreeItem[] = []; if (!element) { // Root folders + let firstRevealId = favoritesMap.size > 0 ? 'starred' : recentsArray.length > 0 ? 'recent' : 'sorted'; + if (vscode.workspace.workspaceFolders?.length || 0 > 0) { - children.push(new SMTreeItem({label: 'Current', id: 'current', tooltip: 'Servers used by current workspace', codiconName: 'home', getChildren: currentServers})); + children.push(new SMTreeItem({label: 'Current', id: 'current', tooltip: 'Servers referenced by current workspace', codiconName: 'home', getChildren: currentServers})); + firstRevealId = 'current'; + this._firstRevealItem = children[children.length - 1]; } + if (favoritesMap.size > 0) { children.push(new SMTreeItem({label: 'Starred', id: 'starred', tooltip: 'Favorite servers', codiconName: 'star-full', getChildren: favoriteServers})); + if (firstRevealId === 'starred') { + this._firstRevealItem = children[children.length - 1]; + } } children.push(new SMTreeItem({label: 'Recent', id: 'recent', tooltip: 'Recently used servers', codiconName: 'history', getChildren: recentServers})); - children.push(new SMTreeItem({label: 'Ordered', id: 'ordered', tooltip: 'All servers in settings.json order', codiconName: 'list-ordered', getChildren: allServers, params: {sorted: false}})); - children.push(new SMTreeItem({label: 'Sorted', id: 'sorted', tooltip: 'All servers in alphabetical order', codiconName: 'triangle-down', getChildren: allServers, params: {sorted: true}})); + if (firstRevealId === 'recent') { + this._firstRevealItem = children[children.length - 1]; + } + + // TODO - use this when we can implement resequencing in the UI + // children.push(new SMTreeItem({label: 'Ordered', id: 'ordered', tooltip: 'All servers in settings.json order', codiconName: 'list-ordered', getChildren: allServers, params: {sorted: false}})); + + children.push(new SMTreeItem({label: 'All Servers', id: 'sorted', tooltip: 'All servers in alphabetical order', codiconName: 'server-environment', getChildren: allServers, params: {sorted: true}})); + if (firstRevealId === 'sorted') { + this._firstRevealItem = children[children.length - 1]; + } + + setTimeout(async () => { + if (!this._firstRevealDone && this._firstRevealItem) { + await this.view.reveal(this._firstRevealItem, {select: false, expand: 1}); + this._firstRevealDone = true; + } + + }, 20); + return children; } else { @@ -251,14 +286,21 @@ export class ServerTreeItem extends SMTreeItem { getChildren: serverFeatures }); this.name = serverName.name; - //this.command = {command: 'intersystems-community.servermanager.openManagementPortalInSimpleBrowser', title: 'Open Management Portal in Simple Browser Tab', arguments: [this]}; + //this.command = {command: 'intersystems-community.servermanager.openPortalTab', title: 'Open Management Portal in Simple Browser Tab', arguments: [this]}; this.contextValue = `${parentFolderId}.server.${favoritesMap.has(this.name) ? 'starred' : ''}`; const color = colorsMap.get(this.name); this.iconPath = new vscode.ThemeIcon('server-environment', color ? new vscode.ThemeColor('charts.' + color) : undefined); } } -async function serverFeatures(element: ServerTreeItem, params?: any): Promise { +/** + * getChildren function returning starred servers, + * + * @param element parent + * @param params (unused) + * @returns feature folders of a server. + */ + async function serverFeatures(element: ServerTreeItem, params?: any): Promise { const children: FeatureTreeItem[] = []; children.push(new NamespacesTreeItem(element.id || '', element.name)); @@ -288,7 +330,14 @@ export class NamespacesTreeItem extends FeatureTreeItem { } } -async function serverNamespaces(element: ServerTreeItem, params?: any): Promise { +/** + * getChildren function returning namespaces of a server, + * + * @param element parent + * @param params (unused) + * @returns namespaces of a server. + */ + async function serverNamespaces(element: ServerTreeItem, params?: any): Promise { const children: NamespaceTreeItem[] = []; if (params?.serverName) { From d2d06e64577f3c3c243464619b2a804e9587db0a Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Thu, 15 Apr 2021 05:52:34 +0100 Subject: [PATCH 6/9] SNAPSHOT.3 --- package.json | 22 +++++++++++++++++++++- src/extension.ts | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index b613dc2..5290ca4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "servermanager", "displayName": "InterSystems Server Manager", - "version": "2.0.0-SNAPSHOT.2", + "version": "2.0.0-SNAPSHOT.3", "publisher": "intersystems-community", "description": "Helper extension for defining connections to InterSystems servers.", "repository": { @@ -297,6 +297,16 @@ { "command": "intersystems-community.servermanager.resetIconColor", "title": "default" + }, + { + "command": "intersystems-community.servermanager.editNamespace", + "title": "Edit Code in Namespace", + "icon": "$(edit)" + }, + { + "command": "intersystems-community.servermanager.viewNamespace", + "title": "View Code in Namespace", + "icon": "$(eye)" } ], "submenus": [ @@ -391,6 +401,16 @@ "when": "view == intersystems-community_servermanager && viewItem == starred.server.starred", "group": "inline@10" }, + { + "command": "intersystems-community.servermanager.editNamespace", + "when": "view == intersystems-community_servermanager && viewItem =~ /namespace$/", + "group": "inline@10" + }, + { + "command": "intersystems-community.servermanager.viewNamespace", + "when": "view == intersystems-community_servermanager && viewItem =~ /namespace$/", + "group": "inline@20" + }, { "command": "intersystems-community.servermanager.openPortalTab", "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", diff --git a/src/extension.ts b/src/extension.ts index b15df35..b9847f6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -187,6 +187,43 @@ export function activate(context: vscode.ExtensionContext) { }) ); + const addWorkspaceFolderAsync = async (readonly: boolean, namespaceTreeItem?: ServerTreeItem) => { + if (namespaceTreeItem) { + const pathParts = namespaceTreeItem.id?.split(':'); + if (pathParts && pathParts.length === 4) { + const serverName = pathParts[1]; + const namespace = pathParts[3]; + const serverSpec = await getServerSpec(serverName, undefined, undefined, true); + if (serverSpec) { + const uri = vscode.Uri.parse(`isfs${readonly ? "-readonly" : ""}://${serverName}:${namespace}/${serverSpec.webServer.pathPrefix || ''}`); + const label = `${serverName}:${namespace}${readonly ? " (read-only)" : ""}`; + const added = vscode.workspace.updateWorkspaceFolders( + vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0, + 0, + { uri, name: label } + ); + // Switch to Explorer view so user sees the outcome + await vscode.commands.executeCommand("workbench.view.explorer"); + // Handle failure + if (added) { + await view.addToRecents(serverName); + } + else { + vscode.window.showErrorMessage(`Folder ${uri.toString()} could not be added. Maybe it already exists in the workspace.`, "Close") + } + } + } + } + } + + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.editNamespace`, async (namespaceTreeItem?: ServerTreeItem) => {await addWorkspaceFolderAsync(false, namespaceTreeItem)}) + ); + + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.viewNamespace`, async (namespaceTreeItem?: ServerTreeItem) => {await addWorkspaceFolderAsync(true, namespaceTreeItem)}) + ); + // Listen for relevant configuration changes context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(e => { if (e.affectsConfiguration('intersystems.servers') || e.affectsConfiguration('objectscript.conn')) { From 1c5b2e0f77c91aea9a93e828aa1f1b41bb7f76c5 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Thu, 15 Apr 2021 19:00:51 +0100 Subject: [PATCH 7/9] WIP --- package.json | 16 ++-- src/api/getServerSpec.ts | 43 ++++++++--- src/commands/managePasswords.ts | 8 +- src/extension.ts | 6 ++ src/ui/serverManagerView.ts | 127 ++++++++++++++++++++++---------- 5 files changed, 146 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 5290ca4..315108e 100644 --- a/package.json +++ b/package.json @@ -226,28 +226,29 @@ }, { "command": "intersystems-community.servermanager.addToStarred", - "category": "InterSystems Server Manager", "title": "Add to Starred", "icon": "$(star-full)" }, { "command": "intersystems-community.servermanager.removeFromStarred", - "category": "InterSystems Server Manager", "title": "Remove from Starred", "icon": "$(star-empty)" }, { "command": "intersystems-community.servermanager.openPortalExternal", - "category": "InterSystems Server Manager", "title": "Open Management Portal in External Browser", "icon": "$(link-external)" }, { "command": "intersystems-community.servermanager.openPortalTab", - "category": "InterSystems Server Manager", "title": "Open Management Portal in Tab", "icon": "$(tools)" }, + { + "command": "intersystems-community.servermanager.retryServer", + "title": "Reconnect", + "icon": "$(refresh)" + }, { "command": "intersystems-community.servermanager.editSettings", "category": "InterSystems Server Manager", @@ -268,7 +269,7 @@ { "command": "intersystems-community.servermanager.importServers", "category": "InterSystems Server Manager", - "title": "Import Servers from Registry" + "title": "Import Servers from Windows Registry" }, { "command": "intersystems-community.servermanager.setIconRed", @@ -401,6 +402,11 @@ "when": "view == intersystems-community_servermanager && viewItem == starred.server.starred", "group": "inline@10" }, + { + "command": "intersystems-community.servermanager.retryServer", + "when": "view == intersystems-community_servermanager && viewItem =~ /offline$/", + "group": "inline@10" + }, { "command": "intersystems-community.servermanager.editNamespace", "when": "view == intersystems-community_servermanager && viewItem =~ /namespace$/", diff --git a/src/api/getServerSpec.ts b/src/api/getServerSpec.ts index 1f18347..802a19f 100644 --- a/src/api/getServerSpec.ts +++ b/src/api/getServerSpec.ts @@ -1,4 +1,5 @@ import * as vscode from 'vscode'; +import { filePassword } from '../commands/managePasswords'; import { ServerSpec } from '../extension'; import { Keychain } from '../keychain'; @@ -82,16 +83,38 @@ export async function getServerSpec(name: string, scope?: vscode.ConfigurationSc } if (server.username && !server.password) { - await vscode.window - .showInputBox({ - password: true, - placeHolder: `Password for user '${server.username}' on InterSystems server '${name}'`, - validateInput: (value => { - return value.length > 0 ? '' : 'Mandatory field'; - }), - ignoreFocusOut: true, - }) - .then((password) => { + const doInputBox = async (): Promise => { + return await new Promise((resolve, reject) => { + const inputBox = vscode.window.createInputBox(); + inputBox.password = true, + inputBox.title = `Password for InterSystems server '${name}'`, + inputBox.placeholder = `Password for user '${server?.username}' on '${name}'`, + inputBox.prompt = 'To store your password securely, submit it using the $(key) button', + inputBox.ignoreFocusOut = true, + inputBox.buttons = [{ iconPath: new vscode.ThemeIcon('key'), tooltip: 'Store Password in Keychain' }] + + async function done(store: boolean) { + // File the password and return it + if (store) { + await filePassword(name, inputBox.value) + } + // Resolve the promise and tidy up + resolve(inputBox.value); + inputBox.hide(); + inputBox.dispose(); + } + + inputBox.onDidTriggerButton((button) => { + // We only added one button + done(true); + }); + inputBox.onDidAccept(() => { + done(false); + }); + inputBox.show(); + }) + }; + await doInputBox().then((password) => { if (password && server) { server.password = password; credentialCache[name] = {username: server.username, password: password}; diff --git a/src/commands/managePasswords.ts b/src/commands/managePasswords.ts index 1f37296..3a6fef6 100644 --- a/src/commands/managePasswords.ts +++ b/src/commands/managePasswords.ts @@ -24,8 +24,7 @@ export async function storePassword(treeItem?: ServerTreeItem): Promise }) .then((password) => { if (password) { - credentialCache[name] = undefined; - new Keychain(name).setPassword(password).then(() => { + filePassword(name, password).then(() => { vscode.window.showInformationMessage(`Password for '${name}' stored in keychain.`); }); reply = name; @@ -35,6 +34,11 @@ export async function storePassword(treeItem?: ServerTreeItem): Promise return reply; } +export async function filePassword(serverName: string, password: string): Promise { + credentialCache[serverName] = undefined; + return new Keychain(serverName).setPassword(password).then(() => true, () => false); +} + export async function clearPassword(treeItem?: ServerTreeItem): Promise { if (treeItem && !getServerNames().some((value) => value.name === treeItem?.label)) { treeItem = undefined; diff --git a/src/extension.ts b/src/extension.ts index b9847f6..74e32cf 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -187,6 +187,12 @@ export function activate(context: vscode.ExtensionContext) { }) ); + context.subscriptions.push( + vscode.commands.registerCommand(`${extensionId}.retryServer`, () => { + view.refreshTree(); + }) + ); + const addWorkspaceFolderAsync = async (readonly: boolean, namespaceTreeItem?: ServerTreeItem) => { if (namespaceTreeItem) { const pathParts = namespaceTreeItem.id?.split(':'); diff --git a/src/ui/serverManagerView.ts b/src/ui/serverManagerView.ts index ba2a07f..4de8d9d 100644 --- a/src/ui/serverManagerView.ts +++ b/src/ui/serverManagerView.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; import { getServerNames } from '../api/getServerNames'; -import { getServerSpec } from '../api/getServerSpec'; +import { credentialCache, getServerSpec } from '../api/getServerSpec'; import { getServerSummary } from '../api/getServerSummary'; import { ServerName } from '../extension'; import { makeRESTRequest } from '../makeRESTRequest'; @@ -23,6 +23,8 @@ export class ServerManagerView { private _globalState: vscode.Memento; + private _treeView: vscode.TreeView; + private _treeDataProvider: SMNodeProvider; constructor(context: vscode.ExtensionContext) { @@ -31,6 +33,7 @@ export class ServerManagerView { this._treeDataProvider = treeDataProvider; const treeView = vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: true }) + this._treeView = treeView; context.subscriptions.push(treeView); treeDataProvider.view = treeView; @@ -115,36 +118,39 @@ class SMNodeProvider implements vscode.TreeDataProvider { } getParent(element: SMTreeItem): SMTreeItem | undefined { + // This is a hack to allow reveal() to work on the first-level folders, + // so we can open one of them automatically at startup. + // TODO implement it properly for all items. return undefined; } - async getChildren(element?: SMTreeItem): Promise { + async getChildren(element?: SMTreeItem): Promise { const children: SMTreeItem[] = []; if (!element) { // Root folders let firstRevealId = favoritesMap.size > 0 ? 'starred' : recentsArray.length > 0 ? 'recent' : 'sorted'; if (vscode.workspace.workspaceFolders?.length || 0 > 0) { - children.push(new SMTreeItem({label: 'Current', id: 'current', tooltip: 'Servers referenced by current workspace', codiconName: 'home', getChildren: currentServers})); + children.push(new SMTreeItem({parent: element, label: 'Current', id: 'current', tooltip: 'Servers referenced by current workspace', codiconName: 'home', getChildren: currentServers})); firstRevealId = 'current'; this._firstRevealItem = children[children.length - 1]; } if (favoritesMap.size > 0) { - children.push(new SMTreeItem({label: 'Starred', id: 'starred', tooltip: 'Favorite servers', codiconName: 'star-full', getChildren: favoriteServers})); + children.push(new SMTreeItem({parent: element, label: 'Starred', id: 'starred', tooltip: 'Favorite servers', codiconName: 'star-full', getChildren: favoriteServers})); if (firstRevealId === 'starred') { this._firstRevealItem = children[children.length - 1]; } } - children.push(new SMTreeItem({label: 'Recent', id: 'recent', tooltip: 'Recently used servers', codiconName: 'history', getChildren: recentServers})); + children.push(new SMTreeItem({parent: element, label: 'Recent', id: 'recent', tooltip: 'Recently used servers', codiconName: 'history', getChildren: recentServers})); if (firstRevealId === 'recent') { this._firstRevealItem = children[children.length - 1]; } // TODO - use this when we can implement resequencing in the UI - // children.push(new SMTreeItem({label: 'Ordered', id: 'ordered', tooltip: 'All servers in settings.json order', codiconName: 'list-ordered', getChildren: allServers, params: {sorted: false}})); + // children.push(new SMTreeItem({parent: element, label: 'Ordered', id: 'ordered', tooltip: 'All servers in settings.json order', codiconName: 'list-ordered', getChildren: allServers, params: {sorted: false}})); - children.push(new SMTreeItem({label: 'All Servers', id: 'sorted', tooltip: 'All servers in alphabetical order', codiconName: 'server-environment', getChildren: allServers, params: {sorted: true}})); + children.push(new SMTreeItem({parent: element, label: 'All Servers', id: 'sorted', tooltip: 'All servers in alphabetical order', codiconName: 'server-environment', getChildren: allServers, params: {sorted: true}})); if (firstRevealId === 'sorted') { this._firstRevealItem = children[children.length - 1]; } @@ -168,12 +174,13 @@ class SMNodeProvider implements vscode.TreeDataProvider { interface SMItem { label: string, id: string, + parent: SMTreeItem | undefined, contextValue?: string, tooltip?: string | vscode.MarkdownString, description?: string, codiconName?: string, getChildren?: Function, - params?: any + params?: any, } class SMTreeItem extends vscode.TreeItem { @@ -181,11 +188,14 @@ class SMTreeItem extends vscode.TreeItem { private readonly _getChildren?: Function; private readonly _params?: any; + readonly parent: SMTreeItem | undefined; + constructor(item: SMItem) { const collapsibleState = item.getChildren ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None; super(item.label, collapsibleState); this.id = item.id; + this.parent = item.parent; this.contextValue = item.contextValue; this.tooltip = item.tooltip; this.description = item.description; @@ -196,17 +206,17 @@ class SMTreeItem extends vscode.TreeItem { this._params = item.params; } - public async getChildren(): Promise { + public async getChildren(): Promise { if (this._getChildren) { - return await this._getChildren(this, this._params) || []; + return await this._getChildren(this, this._params); } else { - return []; + return; } } } -function allServers(element: SMTreeItem, params?: any): ServerTreeItem[] { +function allServers(treeItem: SMTreeItem, params?: any): ServerTreeItem[] { const children: ServerTreeItem[] = []; const getAllServers = (sorted?: boolean): ServerTreeItem[] => { let serverNames = getServerNames(); @@ -214,7 +224,7 @@ function allServers(element: SMTreeItem, params?: any): ServerTreeItem[] { serverNames = serverNames.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); } return serverNames.map((serverName) => { - return new ServerTreeItem(sorted ? 'sorted' : 'ordered', serverName); + return new ServerTreeItem({ label: serverName.name, id:serverName.name, parent: treeItem }, serverName); }) } @@ -230,7 +240,7 @@ function currentServers(element: SMTreeItem, params?: any): ServerTreeItem[] { if (['isfs', 'isfs-readonly'].includes(folder.uri.scheme)) { const serverSummary = getServerSummary(serverName); if (serverSummary) { - children.set(serverName, new ServerTreeItem('current', serverSummary)); + children.set(serverName, new ServerTreeItem({ parent: element, label: serverName, id: serverName }, serverSummary)); } } const conn = vscode.workspace.getConfiguration('objectscript.conn', folder); @@ -238,7 +248,7 @@ function currentServers(element: SMTreeItem, params?: any): ServerTreeItem[] { if (connServer) { const serverSummary = getServerSummary(connServer); if (serverSummary) { - children.set(connServer, new ServerTreeItem('current', serverSummary)); + children.set(connServer, new ServerTreeItem({ parent: element, label: serverName, id: serverName }, serverSummary)); } } }); @@ -252,7 +262,7 @@ function favoriteServers(element: SMTreeItem, params?: any): ServerTreeItem[] { favoritesMap.forEach((_, name) => { const serverSummary = getServerSummary(name); if (serverSummary) { - children.push(new ServerTreeItem('starred', serverSummary)); + children.push(new ServerTreeItem({ parent: element, label: name, id: name}, serverSummary)); } }); @@ -265,7 +275,7 @@ function recentServers(element: SMTreeItem, params?: any): ServerTreeItem[] { recentsArray.map((name) => { const serverSummary = getServerSummary(name); if (serverSummary) { - children.push(new ServerTreeItem('recent', serverSummary)); + children.push(new ServerTreeItem({ parent: element, label: name, id: name}, serverSummary)); } }); @@ -275,17 +285,20 @@ function recentServers(element: SMTreeItem, params?: any): ServerTreeItem[] { export class ServerTreeItem extends SMTreeItem { public readonly name: string; constructor( - parentFolderId: string, - serverName: ServerName + element: SMItem, + serverSummary: ServerName ) { + const parentFolderId = element.parent?.id || ""; // Wrap detail (a uri string) as a null link to prevent it from being linkified super({ - label: serverName.name, - id: parentFolderId + ':' + serverName.name, - tooltip: new vscode.MarkdownString(`[${serverName.detail}]()`).appendMarkdown(serverName.description ? `\n\n*${serverName.description}*` : ''), - getChildren: serverFeatures + parent: element.parent, + label: serverSummary.name, + id: parentFolderId + ':' + serverSummary.name, + tooltip: new vscode.MarkdownString(`[${serverSummary.detail}]()`).appendMarkdown(serverSummary.description ? `\n\n*${serverSummary.description}*` : ''), + getChildren: serverFeatures, + params: { serverSummary } }); - this.name = serverName.name; + this.name = serverSummary.name; //this.command = {command: 'intersystems-community.servermanager.openPortalTab', title: 'Open Management Portal in Simple Browser Tab', arguments: [this]}; this.contextValue = `${parentFolderId}.server.${favoritesMap.has(this.name) ? 'starred' : ''}`; const color = colorsMap.get(this.name); @@ -294,7 +307,7 @@ export class ServerTreeItem extends SMTreeItem { } /** - * getChildren function returning starred servers, + * getChildren function returning server features (the child nodes of a server), * * @param element parent * @param params (unused) @@ -303,21 +316,56 @@ export class ServerTreeItem extends SMTreeItem { async function serverFeatures(element: ServerTreeItem, params?: any): Promise { const children: FeatureTreeItem[] = []; - children.push(new NamespacesTreeItem(element.id || '', element.name)); - + if (params?.serverSummary) { + const name = params.serverSummary.name; + const serverSpec = await getServerSpec(name) + if (!serverSpec) { + return undefined + } + + const response = await makeRESTRequest("HEAD", serverSpec) + if (!response) { + children.push(new OfflineTreeItem({ parent: element, label: name, id: name }, element.name)); + credentialCache[name] = undefined; + } + else { + children.push(new NamespacesTreeItem({ parent: element, label: name, id: name }, element.name)); + } + } return children; } export class FeatureTreeItem extends SMTreeItem { } +export class OfflineTreeItem extends FeatureTreeItem { + public readonly name: string; + constructor( + element: SMItem, + serverName: string + ) { + const parentFolderId = element.parent?.id || ''; + super({ + parent: element.parent, + label: `Offline at ${new Date().toLocaleTimeString()}`, + id: parentFolderId + ':offline', + tooltip: `Server could not be reached`, + }); + this.name = 'offline'; + this.contextValue = 'offline'; + this.iconPath = new vscode.ThemeIcon('warning'); + } +} + export class NamespacesTreeItem extends FeatureTreeItem { public readonly name: string; constructor( - parentFolderId: string, + element: SMItem, serverName: string ) { + const parentFolderId = element.parent?.id || ''; super({ + parent: element.parent, label: 'Namespaces', id: parentFolderId + ':namespaces', tooltip: `Namespaces you can access`, @@ -341,17 +389,20 @@ export class NamespacesTreeItem extends FeatureTreeItem { const children: NamespaceTreeItem[] = []; if (params?.serverName) { - const server = await getServerSpec(params.serverName) - if (!server) { + const name: string = params.serverName; + const serverSpec = await getServerSpec(name) + if (!serverSpec) { return undefined } - const response = await makeRESTRequest("GET", server) - - if (response) { - - response.data.result.content.namespaces.map((name) => { - children.push(new NamespaceTreeItem(element.id || '', name, server.name)); + const response = await makeRESTRequest("GET", serverSpec) + if (!response) { + children.push(new OfflineTreeItem({ parent: element, label: name, id: name }, element.name)); + credentialCache[params.serverName] = undefined; + } + else { + response.data.result.content.namespaces.map((namespace) => { + children.push(new NamespaceTreeItem({ parent: element, label: name, id: name }, namespace, name)); }); } } @@ -362,12 +413,14 @@ export class NamespacesTreeItem extends FeatureTreeItem { export class NamespaceTreeItem extends SMTreeItem { public readonly name: string; constructor( - parentFolderId: string, + element: SMItem, name: string, serverName: string ) { + const parentFolderId = element.parent?.id || ''; const id = parentFolderId + ':' + name; super({ + parent: element.parent, label: name, id, tooltip: `${name} on ${serverName}` From 85b494118831f6eb11b5196c1662ff3e34fd116e Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Thu, 15 Apr 2021 21:22:36 +0100 Subject: [PATCH 8/9] SNAPSHOT.4 --- package.json | 9 +++++++-- src/extension.ts | 15 ++++++++++++--- src/ui/serverManagerView.ts | 13 +++++-------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 315108e..d537777 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "servermanager", "displayName": "InterSystems Server Manager", - "version": "2.0.0-SNAPSHOT.3", + "version": "2.0.0-SNAPSHOT.4", "publisher": "intersystems-community", "description": "Helper extension for defining connections to InterSystems servers.", "repository": { @@ -246,7 +246,7 @@ }, { "command": "intersystems-community.servermanager.retryServer", - "title": "Reconnect", + "title": "Refresh", "icon": "$(refresh)" }, { @@ -427,6 +427,11 @@ "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", "group": "inline@90" }, + { + "command": "intersystems-community.servermanager.retryServer", + "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", + "group": "0_refresh@10" + }, { "submenu": "intersystems-community.servermanager.iconColor", "when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./", diff --git a/src/extension.ts b/src/extension.ts index 74e32cf..99a6bda 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -7,7 +7,7 @@ import { getServerNames } from './api/getServerNames'; import { getServerSpec } from './api/getServerSpec'; import { storePassword, clearPassword } from './commands/managePasswords'; import { importFromRegistry } from './commands/importFromRegistry'; -import { ServerManagerView, ServerTreeItem } from './ui/serverManagerView'; +import { ServerManagerView, ServerTreeItem, SMTreeItem } from './ui/serverManagerView'; import { addServer } from './api/addServer'; import { getPortalUriWithCredentials } from './api/getPortalUriWithCredentials'; import { getServerSummary } from './api/getServerSummary'; @@ -188,8 +188,17 @@ export function activate(context: vscode.ExtensionContext) { ); context.subscriptions.push( - vscode.commands.registerCommand(`${extensionId}.retryServer`, () => { - view.refreshTree(); + vscode.commands.registerCommand(`${extensionId}.retryServer`, (treeItem: SMTreeItem) => { + const depth = treeItem.id?.split(':').length; + if (depth === 2) { + view.refreshTree(treeItem); + } + else if (depth === 3) { + view.refreshTree(treeItem.parent); + } + else if (depth === 4) { + view.refreshTree(treeItem.parent?.parent); + } }) ); diff --git a/src/ui/serverManagerView.ts b/src/ui/serverManagerView.ts index 4de8d9d..45e8ca3 100644 --- a/src/ui/serverManagerView.ts +++ b/src/ui/serverManagerView.ts @@ -23,8 +23,6 @@ export class ServerManagerView { private _globalState: vscode.Memento; - private _treeView: vscode.TreeView; - private _treeDataProvider: SMNodeProvider; constructor(context: vscode.ExtensionContext) { @@ -33,7 +31,6 @@ export class ServerManagerView { this._treeDataProvider = treeDataProvider; const treeView = vscode.window.createTreeView('intersystems-community_servermanager', { treeDataProvider, showCollapseAll: true }) - this._treeView = treeView; context.subscriptions.push(treeView); treeDataProvider.view = treeView; @@ -91,8 +88,8 @@ export class ServerManagerView { } }; - refreshTree() { - this._treeDataProvider.refresh(); + refreshTree(item?: SMTreeItem | undefined) { + this._treeDataProvider.refresh(item); } } @@ -109,8 +106,8 @@ class SMNodeProvider implements vscode.TreeDataProvider { constructor() { } - refresh(): void { - this._onDidChangeTreeData.fire(); + refresh(item: SMTreeItem | undefined): void { + this._onDidChangeTreeData.fire(item); } getTreeItem(element:SMTreeItem): vscode.TreeItem { @@ -183,7 +180,7 @@ interface SMItem { params?: any, } -class SMTreeItem extends vscode.TreeItem { +export class SMTreeItem extends vscode.TreeItem { private readonly _getChildren?: Function; private readonly _params?: any; From e0448feab874531aa4aaed68f9566b37e859d571 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Fri, 16 Apr 2021 13:59:00 +0100 Subject: [PATCH 9/9] 2.0.0 candidate, implementing a tree UI --- CHANGELOG.md | 3 + README.md | 106 ++++++++++++++++++----- images/README/editSettings.png | Bin 0 -> 35733 bytes images/README/portalWebAppSetting.png | Bin 0 -> 5638 bytes images/README/portalWebApps.png | Bin 0 -> 34498 bytes images/README/tree.png | Bin 0 -> 19073 bytes package.json | 16 +++- src/api/addServer.ts | 119 ++++++++++++++------------ src/ui/serverManagerView.ts | 24 ++++-- 9 files changed, 183 insertions(+), 85 deletions(-) create mode 100644 images/README/editSettings.png create mode 100644 images/README/portalWebAppSetting.png create mode 100644 images/README/portalWebApps.png create mode 100644 images/README/tree.png diff --git a/CHANGELOG.md b/CHANGELOG.md index f60a817..11344c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2.0.0 (16-Apr-2021) +* Add tree view interface. + ## 1.0.5 (02-Feb-2021) * Fix publication problem (#69). diff --git a/README.md b/README.md index c47b44e..4a8a273 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,75 @@ # InterSystems Server Manager -This is a VS Code helper extension for defining connections to [InterSystems®](https://www.intersystems.com/) servers. These connection definitions can used by other VS Code extensions when they make connections. One example is the [ObjectScript extension](https://github.com/intersystems-community/vscode-objectscript). + +InterSystems Server Manager is a Visual Studio Code extension for defining connections to [InterSystems](https://www.intersystems.com/) servers. These definitions can used by other VS Code extensions when they make connections. One example is the [ObjectScript extension](https://github.com/intersystems-community/vscode-objectscript) for code editing. + +# New in 2.0 - April 2021 + +> We are pleased to publish version 2.0 of this extension, adding a tree-style user interface. This significant new release is competing in the April 2021 InterSystems Programming Contest for Developer Tools. If you like the new 2.0 features please visit the [contest page](https://openexchange.intersystems.com/contest/13) no later than April 25 and vote for us. + +> Thanks to [George James Software](https://georgejames.com) for backing this development effort. + +## The Server Tree + +Server Manager displays connection definitions as a tree on an InterSystems Tools view: + +![Server Manager tree](images/README/tree.png) + +In this tree you can: + +- Launch the InterSystems Management Portal, either in a VS Code tab or in your default browser. +- List namespaces. +- Add namespaces to your VS Code workspace for viewing or editing code on the server with the [ObjectScript extension](https://github.com/intersystems-community/vscode-objectscript). +- Tag favorite servers. +- Set icon colors. +- Focus on recently used connections. +- Manage stored passwords. +- Add new servers, and edit existing ones. In common with the rest of VS Code, Server Manager stores your connection settings in JSON files. VS Code settings are arranged in a hierarchy that you can learn more about [here](https://code.visualstudio.com/docs/getstarted/settings). -Using Server Manager you can store connection passwords in the native keystore of your workstation's operating system instead of as plaintext in JSON files. +Server Manager can store connection passwords in the native keystore of your workstation's operating system. This is a more secure alternative to you putting them as plaintext in your JSON files. + +On Windows, Server Manager can create connection entries for all connections you previously defined with the original Windows app called InterSystems Server Manager. This action is available from the '`...`' menu at the top right corner of Server Manager's tree. + +## Defining a New Server + +1. Click the '`+`' button on Server Manager's title bar. +2. Complete the sequence of prompts. +3. Expand `All Servers` to see your new entry in the tree. + +The server definition is added to your [user-level](https://code.visualstudio.com/docs/getstarted/settings) `settings.json` file. + +Optionally use its context menu to store the password for the username you entered when defining the server. You can also set the color of the server icon. -On Windows you can run `Import Servers from Registry` from [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) to create connection entries for all connections you previously defined with the InterSystems Server Manager. +The 'star' button that appears when you hover over the row lets you add the server to the `Favorites` list at the top of the tree. -## Defining a new connection +## Launching Management Portal -1. Open the VS Code [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) by typing Ctrl+Shift+P (Cmd+Shift+P on macOS) or F1. -2. Start typing "Server Manager" to locate `InterSystems Server Manager: Store Password in Keychain`. -3. Type the '+' character into the quickpick input field. Alternatively click the '+' button on the top right of the quickpick. -4. Complete the prompts. By the time you reach the password prompt your connection definition has already been saved in **user-level** JSON. If you prefer to enter your password whenever a VS Code extension connects via Server Manager for the first time in a session, press Esc here. +When you hover over a server entry in the tree, two command buttons let you launch InterSystems Management Portal. -## Amending and removing definitions +The first button uses VS Code's Simple Browser feature, which creates a tab alongside any documents you may have open. The second button opens Portal in your workstation's default web browser. -To manage your definitions, [edit the relevant JSON file](https://code.visualstudio.com/docs/getstarted/settings). VS Code offers several routes to these files. One way is to type "json" into the Command Palette. +### Notes About Simple Browser +- There is only ever a single Simple Browser tab. Launching another server's Management Portal in it will replace the previous one. +- If the server version is InterSystems IRIS 2021.1.1 or later you will need to change a setting on the suite of web applications that implement Management Portal. This is a consequence of change [SGM031 - Support SameSite for CSP session and user cookies](https://docs.intersystems.com/iris20201/csp/docbook/relnotes/index.html#SGM031). Simple Browser will not be permitted to store Portal's session management cookies, so Portal must be willing to fall back to using the CSPCHD query parameter mechanism. + - Locate the five web applications whose path begins with `/csp/sys` + ![Portal web app list](images/README/portalWebApps.png) + + - Alter the `Use Cookie for Session` setting on each of them so it is `Autodetect` instead of `Always`. + ![Portal web app detail](images/README/portalWebAppSetting.png) + Remember to save the change. The change is not thought to have any adverse effects on the usage of Portal from ordinary browsers, which will continue to use session cookies. +- When a 2020.1.1+ Portal has resorted to using CSPCHD (see above) a few inter-page links fail because they don't add the CSPCHD queryparam. One specific case is the breadcrumb links. Pending the arrival of an InterSystems correction (JIRA DP-404817) these links will take you to the login page. Either enter your credentials to proceed, or launch Simple Browser again from the Server Manager tree. + +## Amending and Removing Servers + +To manage your server definitions, including changing the username it connects with, [edit the relevant JSON file](https://code.visualstudio.com/docs/getstarted/settings). + +1. From a server's context menu, or from Server Manager's top-right '`...`' menu, choose `Edit Settings`. This opens VS Code's Settings Editor and filters its contents. + +![Edit Settings](images/README/editSettings.png) + +2. Click the `Edit in settings.json` link. In this example two connections have been defined: @@ -48,25 +100,37 @@ In this example two connections have been defined: The JSON editor offers the usual [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense) as you work in this structure. -Notice how you can add a `description` property to each connection. This will be shown alongside its entry in the server quickpick. +Notice how you can add a `description` property to each connection. This will be shown in the hover in Server Manager's tree, and alongside the entry if a server quickpick is used. Servers are displayed in the quickpick in the order they are defined in the JSON file. The exception is that if a server name is set as the value of the `/default` property (see example above) it will be shown first in the list. -A set of embedded servers with names beginning `default~` will appear at the end of the quickpick unless you add the property `"/hideEmbeddedEntries": true` to your `intersystems.server` object (see above). +A set of embedded servers with names beginning `default~` will appear at the end of the lists unless you add the property `"/hideEmbeddedEntries": true` to your `intersystems.server` object to hide them (see above). + +## Removing a Stored Password + +Use the server's context menu. Alternatively, run `InterSystems Server Manager: Clear Password from Keychain` from Command Palette. + +--- + +## Technical Notes + +### Colors, Favorites and Recents + +These features use VS Code's extension-private global state storage. Data is not present in your `settings.json` file. + +### The 'All Servers' Folder -## Removing a stored password +The `All Servers` tree respects the optional `/default` and `/hideEmbeddedEntries` settings in the `intersystems.servers` JSON. -The command `InterSystems Server Manager: Clear Password from Keychain` removes a stored password. +If a server has been named in `/default` it is promoted to the top of the list, which is otherwise presented in alphabetical order. -**Usage:** +Embedded entries (built-in default ones) are demoted to the end of the list, or omitted completely if `/hideEmbeddedEntries` is true. -1. Bring up the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) by typing Ctrl+Shift+P (Cmd+Shift+P on Mac) or F1. -2. Start typing "Server Manager" to locate the `InterSystems Server Manager: Clear Password from Keychain` command. -3. Pick a server. +--- -## For VS Code Extension Developers: Use By Other Extensions +## Information for VS Code Extension Developers - How To Leverage Server Manager -An extension XYZ needing to connect to InterSystems servers can define this extension as a dependency in its `package.json` +An extension XYZ needing to connect to InterSystems servers can define Server Manager as a dependency in its `package.json` like this: ```json "extensionDependencies": [ @@ -74,7 +138,7 @@ An extension XYZ needing to connect to InterSystems servers can define this exte ], ``` -Alternatively the `activate` method of XYZ can detect if the extension is already available, then offer to install it if necessary: +Alternatively the `activate` method of XYZ can detect whether the extension is already available, then offer to install it if necessary: ```ts const extId = "intersystems-community.servermanager"; diff --git a/images/README/editSettings.png b/images/README/editSettings.png new file mode 100644 index 0000000000000000000000000000000000000000..79cff415516e679c88359d55634b4a755fe577a4 GIT binary patch literal 35733 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 literal 0 HcmV?d00001 diff --git a/images/README/portalWebApps.png b/images/README/portalWebApps.png new file mode 100644 index 0000000000000000000000000000000000000000..153af917318fe78aca844668388ba4089de8beb4 GIT binary patch literal 34498 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 a#4qqY#lcfOY3$jje5|acRHR_`?tcJ=NBQ&s literal 0 HcmV?d00001 diff --git a/images/README/tree.png b/images/README/tree.png new file mode 100644 index 0000000000000000000000000000000000000000..49255ebcc16ef23efd10f0d34787fcff10f281d1 GIT binary patch literal 19073 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 => { if (name) { - const host = await vscode.window.showInputBox({ - placeHolder: "Hostname or IP address of web server", - validateInput: (value) => { - return value.trim().length ? undefined : "Required"; - }, + const description = await vscode.window.showInputBox({ + placeHolder: "Optional description", ignoreFocusOut: true }); - if (host) { - spec.webServer.host = host.trim(); - const portString = await vscode.window.showInputBox({ - placeHolder: "Port of web server", + if (typeof description !== 'undefined') { + if (description) { + spec.description = description.trim(); + } + const host = await vscode.window.showInputBox({ + placeHolder: "Hostname or IP address of web server", validateInput: (value) => { - const port = +value; - return value.match(/\d+/) && - port.toString() === value && - port > 0 && - port < 65536 - ? undefined - : "Required, 1-65535"; + return value.trim().length ? undefined : "Required"; }, ignoreFocusOut: true }); - if (portString) { - spec.webServer.port = +portString; - const username = await vscode.window.showInputBox({ - placeHolder: - "Username", - prompt: - "Leave empty to be prompted when connecting.", + if (host) { + spec.webServer.host = host.trim(); + const portString = await vscode.window.showInputBox({ + placeHolder: "Port of web server", + validateInput: (value) => { + const port = +value; + return value.match(/\d+/) && + port.toString() === value && + port > 0 && + port < 65536 + ? undefined + : "Required, 1-65535"; + }, ignoreFocusOut: true - }); - if (typeof username !== 'undefined') { - const usernameTrimmed = username.trim(); - if (usernameTrimmed !== "") { - spec.username = usernameTrimmed; - } - const scheme = await vscode.window.showQuickPick( - ["http", "https"], - { - placeHolder: - "Confirm connection type, then the definition will be stored in your User Settings. 'Escape' to cancel.", - ignoreFocusOut: true + }); + if (portString) { + spec.webServer.port = +portString; + const username = await vscode.window.showInputBox({ + placeHolder: + "Username", + prompt: + "Leave empty to be prompted when connecting.", + ignoreFocusOut: true + }); + if (typeof username !== 'undefined') { + const usernameTrimmed = username.trim(); + if (usernameTrimmed !== "") { + spec.username = usernameTrimmed; + } + const scheme = await vscode.window.showQuickPick( + ["http", "https"], + { + placeHolder: + "Confirm connection type, then the definition will be stored in your User Settings. 'Escape' to cancel.", + ignoreFocusOut: true + } + ); + if (scheme) { + spec.webServer.scheme = scheme; + try { + const config = vscode.workspace.getConfiguration( + "intersystems", + scope + ); + // For simplicity we always add to the user-level (aka Global) settings + const servers: any = + config.inspect("servers")?.globalValue || {}; + servers[name] = spec; + await config.update("servers", servers, true); + vscode.window.showInformationMessage(`Server '${name}' stored in user-level settings.`); + return name; + } catch (error) { + vscode.window.showErrorMessage( + "Failed to store server '${name}' definition." + ); + return undefined; } - ); - if (scheme) { - spec.webServer.scheme = scheme; - try { - const config = vscode.workspace.getConfiguration( - "intersystems", - scope - ); - // For simplicity we always add to the user-level (aka Global) settings - const servers: any = - config.inspect("servers")?.globalValue || {}; - servers[name] = spec; - await config.update("servers", servers, true); - vscode.window.showInformationMessage(`Server '${name}' stored in user-level settings.`); - return name; - } catch (error) { - vscode.window.showErrorMessage( - "Failed to store server '${name}' definition." - ); - return undefined; } } } diff --git a/src/ui/serverManagerView.ts b/src/ui/serverManagerView.ts index 45e8ca3..943e2e5 100644 --- a/src/ui/serverManagerView.ts +++ b/src/ui/serverManagerView.ts @@ -128,26 +128,26 @@ class SMNodeProvider implements vscode.TreeDataProvider { let firstRevealId = favoritesMap.size > 0 ? 'starred' : recentsArray.length > 0 ? 'recent' : 'sorted'; if (vscode.workspace.workspaceFolders?.length || 0 > 0) { - children.push(new SMTreeItem({parent: element, label: 'Current', id: 'current', tooltip: 'Servers referenced by current workspace', codiconName: 'home', getChildren: currentServers})); + children.push(new SMTreeItem({parent: element, label: 'Current', id: 'current', contextValue: 'current', tooltip: 'Servers referenced by current workspace', codiconName: 'home', getChildren: currentServers})); firstRevealId = 'current'; this._firstRevealItem = children[children.length - 1]; } if (favoritesMap.size > 0) { - children.push(new SMTreeItem({parent: element, label: 'Starred', id: 'starred', tooltip: 'Favorite servers', codiconName: 'star-full', getChildren: favoriteServers})); + children.push(new SMTreeItem({parent: element, label: 'Favorites', id: 'starred', contextValue: 'starred', tooltip: 'Favorite servers', codiconName: 'star-full', getChildren: favoriteServers})); if (firstRevealId === 'starred') { this._firstRevealItem = children[children.length - 1]; } } - children.push(new SMTreeItem({parent: element, label: 'Recent', id: 'recent', tooltip: 'Recently used servers', codiconName: 'history', getChildren: recentServers})); + children.push(new SMTreeItem({parent: element, label: 'Recent', id: 'recent', contextValue: 'recent', tooltip: 'Recently used servers', codiconName: 'history', getChildren: recentServers})); if (firstRevealId === 'recent') { this._firstRevealItem = children[children.length - 1]; } // TODO - use this when we can implement resequencing in the UI - // children.push(new SMTreeItem({parent: element, label: 'Ordered', id: 'ordered', tooltip: 'All servers in settings.json order', codiconName: 'list-ordered', getChildren: allServers, params: {sorted: false}})); + // children.push(new SMTreeItem({parent: element, label: 'Ordered', id: 'ordered', contextValue: 'ordered', tooltip: 'All servers in settings.json order', codiconName: 'list-ordered', getChildren: allServers, params: {sorted: false}})); - children.push(new SMTreeItem({parent: element, label: 'All Servers', id: 'sorted', tooltip: 'All servers in alphabetical order', codiconName: 'server-environment', getChildren: allServers, params: {sorted: true}})); + children.push(new SMTreeItem({parent: element, label: 'All Servers', id: 'sorted', contextValue: 'sorted', tooltip: 'All servers in alphabetical order', codiconName: 'server-environment', getChildren: allServers, params: {sorted: true}})); if (firstRevealId === 'sorted') { this._firstRevealItem = children[children.length - 1]; } @@ -286,20 +286,30 @@ export class ServerTreeItem extends SMTreeItem { serverSummary: ServerName ) { const parentFolderId = element.parent?.id || ""; + // Convert linebreaks etc, escape Markdown characters, truncate + const escapedDescription = serverSummary.description + .replace(/[\n\t]/g, ' ') + .replace(/[\r\f\b]/g, '') + .replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&') + .substr(0,90) + .trim(); // Wrap detail (a uri string) as a null link to prevent it from being linkified + const wrappedDetail = `[${serverSummary.detail}]()`; super({ parent: element.parent, label: serverSummary.name, id: parentFolderId + ':' + serverSummary.name, - tooltip: new vscode.MarkdownString(`[${serverSummary.detail}]()`).appendMarkdown(serverSummary.description ? `\n\n*${serverSummary.description}*` : ''), + tooltip: new vscode.MarkdownString(wrappedDetail).appendMarkdown(escapedDescription ? `\n\n*${escapedDescription}*` : ''), getChildren: serverFeatures, params: { serverSummary } }); this.name = serverSummary.name; - //this.command = {command: 'intersystems-community.servermanager.openPortalTab', title: 'Open Management Portal in Simple Browser Tab', arguments: [this]}; this.contextValue = `${parentFolderId}.server.${favoritesMap.has(this.name) ? 'starred' : ''}`; const color = colorsMap.get(this.name); this.iconPath = new vscode.ThemeIcon('server-environment', color ? new vscode.ThemeColor('charts.' + color) : undefined); + + // TODO If single click on server item should open Portal tab + // this.command = {command: 'intersystems-community.servermanager.openPortalTab', title: 'Open Management Portal in Simple Browser Tab', arguments: [this]}; } }